kubeadm: make super-admin.conf changes to app/cmd

- Update unit tests in certs_test.go related to the "renew" CLI command.
- In /init, (d *initData) Client(), make sure that the new logic
for bootstrapping an "admin.conf" user is performed, by calling
EnsureAdminClusterRoleBinding() from the phases backend. Add a
"adminKubeConfigBootstrapped" flag that helps call this logic only
once per "kubeadm init" binary execution.
- In /phases/init include a new subphase for generating
the "super-admin.conf" file.
- In /phases/reset make sure the file "super-admin.conf" is
cleaned if present. Update unit tests.
This commit is contained in:
Lubomir I. Ivanov 2023-10-19 20:41:23 +03:00
parent 30ed50d32e
commit 837090135f
5 changed files with 46 additions and 19 deletions

View File

@ -134,6 +134,7 @@ func TestRunRenewCommands(t *testing.T) {
// Generate all the kubeconfig files with embedded certs
for _, kubeConfig := range []string{
kubeadmconstants.AdminKubeConfigFileName,
kubeadmconstants.SuperAdminKubeConfigFileName,
kubeadmconstants.SchedulerKubeConfigFileName,
kubeadmconstants.ControllerManagerKubeConfigFileName,
} {
@ -162,6 +163,7 @@ func TestRunRenewCommands(t *testing.T) {
},
KubeconfigFiles: []string{
kubeadmconstants.AdminKubeConfigFileName,
kubeadmconstants.SuperAdminKubeConfigFileName,
kubeadmconstants.SchedulerKubeConfigFileName,
kubeadmconstants.ControllerManagerKubeConfigFileName,
},
@ -214,6 +216,12 @@ func TestRunRenewCommands(t *testing.T) {
kubeadmconstants.AdminKubeConfigFileName,
},
},
{
command: "super-admin.conf",
KubeconfigFiles: []string{
kubeadmconstants.SuperAdminKubeConfigFileName,
},
},
{
command: "scheduler.conf",
KubeconfigFiles: []string{

View File

@ -72,20 +72,21 @@ var _ phases.InitData = &initData{}
// initData defines all the runtime information used when running the kubeadm init workflow;
// this data is shared across all the phases that are included in the workflow.
type initData struct {
cfg *kubeadmapi.InitConfiguration
skipTokenPrint bool
dryRun bool
kubeconfigDir string
kubeconfigPath string
ignorePreflightErrors sets.Set[string]
certificatesDir string
dryRunDir string
externalCA bool
client clientset.Interface
outputWriter io.Writer
uploadCerts bool
skipCertificateKeyPrint bool
patchesDir string
cfg *kubeadmapi.InitConfiguration
skipTokenPrint bool
dryRun bool
kubeconfigDir string
kubeconfigPath string
ignorePreflightErrors sets.Set[string]
certificatesDir string
dryRunDir string
externalCA bool
client clientset.Interface
outputWriter io.Writer
uploadCerts bool
skipCertificateKeyPrint bool
patchesDir string
adminKubeConfigBootstrapped bool
}
// newCmdInit returns "kubeadm init" command.
@ -495,12 +496,22 @@ func (d *initData) Client() (clientset.Interface, error) {
// If we're dry-running, we should create a faked client that answers some GETs in order to be able to do the full init flow and just logs the rest of requests
dryRunGetter := apiclient.NewInitDryRunGetter(d.cfg.NodeRegistration.Name, svcSubnetCIDR.String())
d.client = apiclient.NewDryRunClient(dryRunGetter, os.Stdout)
} else {
// If we're acting for real, we should create a connection to the API server and wait for it to come up
} else { // Use a real client
var err error
d.client, err = kubeconfigutil.ClientSetFromFile(d.KubeConfigPath())
if err != nil {
return nil, err
if !d.adminKubeConfigBootstrapped {
// Call EnsureAdminClusterRoleBinding() to obtain a working client from admin.conf.
d.client, err = kubeconfigphase.EnsureAdminClusterRoleBinding(kubeadmconstants.KubernetesDir, nil)
if err != nil {
return nil, errors.Wrapf(err, "could not bootstrap the admin user in file %s", kubeadmconstants.AdminKubeConfigFileName)
}
d.adminKubeConfigBootstrapped = true
} else {
// In case adminKubeConfigBootstrapped is already set just return a client from the default
// kubeconfig location.
d.client, err = kubeconfigutil.ClientSetFromFile(d.KubeConfigPath())
if err != nil {
return nil, err
}
}
}
}

View File

@ -41,6 +41,11 @@ var (
short: "Generate a kubeconfig file for the admin to use and for kubeadm itself",
long: "Generate the kubeconfig file for the admin and for kubeadm itself, and save it to %s file.",
},
kubeadmconstants.SuperAdminKubeConfigFileName: {
name: "super-admin",
short: "Generate a kubeconfig file for the super-admin",
long: "Generate a kubeconfig file for the super-admin, and save it to %s file.",
},
kubeadmconstants.KubeletKubeConfigFileName: {
name: "kubelet",
short: "Generate a kubeconfig file for the kubelet to use *only* for cluster bootstrapping purposes",
@ -77,6 +82,7 @@ func NewKubeConfigPhase() workflow.Phase {
RunAllSiblings: true,
},
NewKubeConfigFilePhase(kubeadmconstants.AdminKubeConfigFileName),
NewKubeConfigFilePhase(kubeadmconstants.SuperAdminKubeConfigFileName),
NewKubeConfigFilePhase(kubeadmconstants.KubeletKubeConfigFileName),
NewKubeConfigFilePhase(kubeadmconstants.ControllerManagerKubeConfigFileName),
NewKubeConfigFilePhase(kubeadmconstants.SchedulerKubeConfigFileName),

View File

@ -169,6 +169,7 @@ func resetConfigDir(configPathDir string, dirsToClean []string, isDryRun bool) {
filesToClean := []string{
filepath.Join(configPathDir, kubeadmconstants.AdminKubeConfigFileName),
filepath.Join(configPathDir, kubeadmconstants.SuperAdminKubeConfigFileName),
filepath.Join(configPathDir, kubeadmconstants.KubeletKubeConfigFileName),
filepath.Join(configPathDir, kubeadmconstants.KubeletBootstrapKubeConfigFileName),
filepath.Join(configPathDir, kubeadmconstants.ControllerManagerKubeConfigFileName),

View File

@ -68,6 +68,7 @@ func TestConfigDirCleaner(t *testing.T) {
"manifests/kube-apiserver.yaml",
"pki/ca.pem",
kubeadmconstants.AdminKubeConfigFileName,
kubeadmconstants.SuperAdminKubeConfigFileName,
kubeadmconstants.KubeletKubeConfigFileName,
},
verifyExists: []string{