From f5a6797e563bef66df62bb904caca972d81fbf06 Mon Sep 17 00:00:00 2001 From: Dave Chen Date: Thu, 13 Jul 2023 14:33:00 +0800 Subject: [PATCH] kubeadm: Make `dry-run` is configurable in `initConfiguration` The `dry-run` flag was able to use with the config file, since it was not configurable in the config file. Make it configurable in v1beta4, so that eventually, kubeadm could deprecate the flag and suggest to use the config file instead. Signed-off-by: Dave Chen --- cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go | 1 + cmd/kubeadm/app/apis/kubeadm/types.go | 3 ++ .../v1beta3/zz_generated.conversion.go | 1 + cmd/kubeadm/app/apis/kubeadm/v1beta4/doc.go | 1 + cmd/kubeadm/app/apis/kubeadm/v1beta4/types.go | 4 ++ .../v1beta4/zz_generated.conversion.go | 2 + cmd/kubeadm/app/cmd/init.go | 38 +++++++++---------- 7 files changed, 31 insertions(+), 19 deletions(-) diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go index e6ac80a88c5..06d6e29d69b 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go @@ -64,6 +64,7 @@ func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c fuzz.Continue) { obj.SkipPhases = nil obj.NodeRegistration.ImagePullPolicy = corev1.PullIfNotPresent obj.Patches = nil + obj.DryRun = false } func fuzzNodeRegistration(obj *kubeadm.NodeRegistrationOptions, c fuzz.Continue) { diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go index b1d1a515a98..598d6fa76ba 100644 --- a/cmd/kubeadm/app/apis/kubeadm/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/types.go @@ -44,6 +44,9 @@ type InitConfiguration struct { // BootstrapTokens is respected at `kubeadm init` time and describes a set of Bootstrap Tokens to create. BootstrapTokens []bootstraptokenv1.BootstrapToken + // DryRun tells if the dry run mode is enabled, don't apply any change if it is and just output what would be done. + DryRun bool + // NodeRegistration holds fields that relate to registering the new control-plane node to the cluster NodeRegistration NodeRegistrationOptions diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta3/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1beta3/zz_generated.conversion.go index e9f6c0cf6fa..5ee53dcb68c 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta3/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta3/zz_generated.conversion.go @@ -591,6 +591,7 @@ func autoConvert_v1beta3_InitConfiguration_To_kubeadm_InitConfiguration(in *Init func autoConvert_kubeadm_InitConfiguration_To_v1beta3_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error { // WARNING: in.ClusterConfiguration requires manual conversion: does not exist in peer-type out.BootstrapTokens = *(*[]bootstraptokenv1.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) + // WARNING: in.DryRun requires manual conversion: does not exist in peer-type if err := Convert_kubeadm_NodeRegistrationOptions_To_v1beta3_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta4/doc.go b/cmd/kubeadm/app/apis/kubeadm/v1beta4/doc.go index e22dd4f04e7..b285de25b08 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta4/doc.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta4/doc.go @@ -28,6 +28,7 @@ limitations under the License. // - Support custom environment variables in control plane components under `ClusterConfiguration`. // Use `APIServer.ExtraEnvs`, `ControllerManager.ExtraEnvs`, `Scheduler.ExtraEnvs`, `Etcd.Local.ExtraEnvs`. // - The ResetConfiguration API type is now supported in v1beta4. Users are able to reset a node by passing a --config file to "kubeadm reset". +// - `dry-run` mode in is now configurable in InitConfiguration config file. // // Migration from old kubeadm config versions // diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta4/types.go b/cmd/kubeadm/app/apis/kubeadm/v1beta4/types.go index bcd5140048e..fca554b47c9 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta4/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta4/types.go @@ -39,6 +39,10 @@ type InitConfiguration struct { // +optional BootstrapTokens []bootstraptokenv1.BootstrapToken `json:"bootstrapTokens,omitempty"` + // DryRun tells if the dry run mode is enabled, don't apply any change if it is and just output what would be done. + // +optional + DryRun bool `json:"dryRun,omitempty"` + // NodeRegistration holds fields that relate to registering the new control-plane node to the cluster // +optional NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"` diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta4/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1beta4/zz_generated.conversion.go index 62b3e335f8e..4caff36c802 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta4/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta4/zz_generated.conversion.go @@ -581,6 +581,7 @@ func Convert_kubeadm_ImageMeta_To_v1beta4_ImageMeta(in *kubeadm.ImageMeta, out * func autoConvert_v1beta4_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { out.BootstrapTokens = *(*[]bootstraptokenv1.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) + out.DryRun = in.DryRun if err := Convert_v1beta4_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err } @@ -596,6 +597,7 @@ func autoConvert_v1beta4_InitConfiguration_To_kubeadm_InitConfiguration(in *Init func autoConvert_kubeadm_InitConfiguration_To_v1beta4_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error { // WARNING: in.ClusterConfiguration requires manual conversion: does not exist in peer-type out.BootstrapTokens = *(*[]bootstraptokenv1.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) + out.DryRun = in.DryRun if err := Convert_kubeadm_NodeRegistrationOptions_To_v1beta4_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err } diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index 06f64a91565..1b3940cd38e 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -279,15 +279,15 @@ func newInitOptions() *initOptions { // newInitData returns a new initData struct to be used for the execution of the kubeadm init workflow. // This func takes care of validating initOptions passed to the command, and then it converts // options into the internal InitConfiguration type that is used as input all the phases in the kubeadm init workflow -func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io.Writer) (*initData, error) { +func newInitData(cmd *cobra.Command, args []string, initOptions *initOptions, out io.Writer) (*initData, error) { // Re-apply defaults to the public kubeadm API (this will set only values not exposed/not set as a flags) - kubeadmscheme.Scheme.Default(options.externalInitCfg) - kubeadmscheme.Scheme.Default(options.externalClusterCfg) + kubeadmscheme.Scheme.Default(initOptions.externalInitCfg) + kubeadmscheme.Scheme.Default(initOptions.externalClusterCfg) // Validate standalone flags values and/or combination of flags and then assigns // validated values to the public kubeadm config API when applicable var err error - if options.externalClusterCfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, options.featureGatesString); err != nil { + if initOptions.externalClusterCfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, initOptions.featureGatesString); err != nil { return nil, err } @@ -295,18 +295,18 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io return nil, err } - if err = options.bto.ApplyTo(options.externalInitCfg); err != nil { + if err = initOptions.bto.ApplyTo(initOptions.externalInitCfg); err != nil { return nil, err } // Either use the config file if specified, or convert public kubeadm API to the internal InitConfiguration // and validates InitConfiguration - cfg, err := configutil.LoadOrDefaultInitConfiguration(options.cfgPath, options.externalInitCfg, options.externalClusterCfg) + cfg, err := configutil.LoadOrDefaultInitConfiguration(initOptions.cfgPath, initOptions.externalInitCfg, initOptions.externalClusterCfg) if err != nil { return nil, err } - ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(options.ignorePreflightErrors, cfg.NodeRegistration.IgnorePreflightErrors) + ignorePreflightErrorsSet, err := validation.ValidateIgnorePreflightErrors(initOptions.ignorePreflightErrors, cfg.NodeRegistration.IgnorePreflightErrors) if err != nil { return nil, err } @@ -314,8 +314,8 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io cfg.NodeRegistration.IgnorePreflightErrors = sets.List(ignorePreflightErrorsSet) // override node name from the command line option - if options.externalInitCfg.NodeRegistration.Name != "" { - cfg.NodeRegistration.Name = options.externalInitCfg.NodeRegistration.Name + if initOptions.externalInitCfg.NodeRegistration.Name != "" { + cfg.NodeRegistration.Name = initOptions.externalInitCfg.NodeRegistration.Name } if err := configutil.VerifyAPIServerBindAddress(cfg.LocalAPIEndpoint.AdvertiseAddress); err != nil { @@ -327,7 +327,7 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io // if dry running creates a temporary folder for saving kubeadm generated files dryRunDir := "" - if options.dryRun { + if initOptions.dryRun || cfg.DryRun { // the KUBEADM_INIT_DRYRUN_DIR environment variable allows overriding the dry-run temporary // directory from the command line. This makes it possible to run "kubeadm init" integration // tests without root. @@ -347,7 +347,7 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io // Validate that also the required kubeconfig files exists and are invalid, because // kubeadm can't regenerate them without the CA Key - kubeconfigDir := options.kubeconfigDir + kubeconfigDir := initOptions.kubeconfigDir if err := kubeconfigphase.ValidateKubeconfigsForExternalCA(kubeconfigDir, cfg); err != nil { return nil, err } @@ -363,24 +363,24 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io } } - if options.uploadCerts && (externalCA || externalFrontProxyCA) { + if initOptions.uploadCerts && (externalCA || externalFrontProxyCA) { return nil, errors.New("can't use upload-certs with an external CA or an external front-proxy CA") } return &initData{ cfg: cfg, certificatesDir: cfg.CertificatesDir, - skipTokenPrint: options.skipTokenPrint, - dryRun: options.dryRun, + skipTokenPrint: initOptions.skipTokenPrint, + dryRun: cmdutil.ValueFromFlagsOrConfig(cmd.Flags(), options.DryRun, cfg.DryRun, initOptions.dryRun).(bool), dryRunDir: dryRunDir, - kubeconfigDir: options.kubeconfigDir, - kubeconfigPath: options.kubeconfigPath, + kubeconfigDir: initOptions.kubeconfigDir, + kubeconfigPath: initOptions.kubeconfigPath, ignorePreflightErrors: ignorePreflightErrorsSet, externalCA: externalCA, outputWriter: out, - uploadCerts: options.uploadCerts, - skipCertificateKeyPrint: options.skipCertificateKeyPrint, - patchesDir: options.patchesDir, + uploadCerts: initOptions.uploadCerts, + skipCertificateKeyPrint: initOptions.skipCertificateKeyPrint, + patchesDir: initOptions.patchesDir, }, nil }