-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a service account and token for use in ~/.kube/config #1458
base: master
Are you sure you want to change the base?
Changes from 5 commits
ae86c28
ab3a108
e9fc165
32d69bc
074adb4
3b37658
c59ae39
39b7d44
5be5ced
f70d81f
dc6e523
c0b7278
e18ead5
ddd82af
890788f
b08de30
324c8ed
888c5b9
6a7e4e5
5e4f466
986c2a4
c23f89c
053ffab
2701644
1792003
aea1b80
a91e213
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# frozen_string_literal: true | ||
|
||
module Pharos | ||
module Phases | ||
class ConfigureServiceAccount < Pharos::Phase | ||
title "Configure 'pharos-admin' service account" | ||
|
||
ADMIN_USER = 'pharos-admin' | ||
KUBECONFIG_PARAM = '--kubeconfig=/etc/kubernetes/admin.conf' | ||
|
||
def call | ||
create_service_account | ||
create_cluster_role_binding | ||
|
||
config = build_config | ||
|
||
if config_file.exist? | ||
existing_config = Pharos::Kube::Config.new(config_file.read) | ||
config << existing_config | ||
end | ||
|
||
config_file.write(config.dump, overwrite: true) | ||
config_file.chmod('0600') | ||
|
||
validate | ||
end | ||
|
||
def validate | ||
transport.exec!('kubectl get -n kube-system serviceaccount/pharos-admin') | ||
end | ||
|
||
def config_file | ||
@config_file ||= transport.file(File.join(home_kube_dir.path, 'config')) | ||
end | ||
|
||
def home_kube_dir | ||
transport.file(transport.file('~/.kube').readlink(escape: false, canonicalize: true)).tap do |dir| | ||
transport.exec!("mkdir '#{dir}' && chmod 0700 '#{dir}") unless dir.exist? | ||
end | ||
end | ||
|
||
def create_service_account | ||
transport.exec!("sudo kubectl get #{KUBECONFIG_PARAM} -n kube-system serviceaccount/#{ADMIN_USER} || sudo kubectl #{KUBECONFIG_PARAM} -n kube-system create serviceaccount #{ADMIN_USER}") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO we don't need sudo for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, maybe we need because this points to root readable kubeconfig? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
end | ||
|
||
def create_cluster_role_binding | ||
transport.exec!("sudo kubectl get #{KUBECONFIG_PARAM} clusterrolebinding pharos-cluster-admin || sudo kubectl create #{KUBECONFIG_PARAM} clusterrolebinding pharos-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:#{ADMIN_USER}") | ||
end | ||
|
||
# @return token_name [String] | ||
def token_name | ||
transport.exec!("sudo kubectl -n kube-system #{KUBECONFIG_PARAM} get serviceaccount/#{ADMIN_USER} -o jsonpath='{.secrets[0].name}'") | ||
end | ||
|
||
# @return token [String] | ||
def token | ||
@token ||= transport.exec!("sudo kubectl -n kube-system #{KUBECONFIG_PARAM} get secret #{token_name} -o jsonpath='{.data.token}' | base64 -d") | ||
end | ||
|
||
# @return [Pharos::Kube::Config] | ||
def build_config | ||
config = Pharos::Kube::Config.new | ||
config.config['clusters'] << { | ||
'cluster' => { | ||
'certificate-authority-data' => certificate_authority_data, | ||
'server' => "https://#{master_host.api_address}:6443" | ||
}, | ||
'name' => @config.name | ||
} | ||
|
||
config.config['users'] << { | ||
'user' => { | ||
'token' => token | ||
}, | ||
'name' => ADMIN_USER | ||
} | ||
|
||
config.config['contexts'] << { | ||
'context' => { | ||
'cluster' => @config.name, | ||
'user' => ADMIN_USER | ||
}, | ||
'name' => context_name | ||
} | ||
|
||
config.config['current-context'] = context_name | ||
|
||
config | ||
end | ||
|
||
# @return [String] | ||
def context_name | ||
@context_name ||= "#{ADMIN_USER}@#{@config.name}" | ||
end | ||
|
||
# @return [String] | ||
def certificate_authority_data | ||
transport.exec!("sudo kubectl config view #{KUBECONFIG_PARAM} --raw --minify --flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}'") | ||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are using
kubectl
here because client is not yet configured?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added that just to validate that
kubectl
without sudo on master works withoutKUBECONFIG=
or--kubeconfig=
.The next phase actually probably should be changed to use the file from home instead of
/etc/kubernetes