From 5671ea9cf14e33a326df52373595027844b00f35 Mon Sep 17 00:00:00 2001 From: "Rostislav M. Georgiev" Date: Wed, 8 May 2019 12:02:32 +0300 Subject: [PATCH] kubeadm: Remove ClusterConfiguration from InitConfiguration in v1beta2 Ever since v1alpha3, InitConfiguration is containing ClusterConfiguration embedded in it. This was done to mimic the internal InitConfiguration, which in turn is used throughout the kubeadm code base as if it is the old MasterConfiguration of v1alpha2. This, however, is confusing to users who vendor in kubeadm as the embedded ClusterConfiguration inside InitConfiguration is not marshalled to YAML. For this to happen, special care must be taken for the ClusterConfiguration field to marshalled separately. Thus, to make things smooth for users and to reduce third party exposure to technical debt, this change removes ClusterConfiguration embedding from InitConfiguration. Signed-off-by: Rostislav M. Georgiev --- cmd/kubeadm/app/apis/kubeadm/v1beta2/BUILD | 1 + .../app/apis/kubeadm/v1beta2/conversion.go | 38 ++++++++++ .../app/apis/kubeadm/v1beta2/defaults.go | 1 - cmd/kubeadm/app/apis/kubeadm/v1beta2/types.go | 6 -- .../v1beta2/zz_generated.conversion.go | 27 +++----- .../kubeadm/v1beta2/zz_generated.deepcopy.go | 1 - .../kubeadm/v1beta2/zz_generated.defaults.go | 1 - cmd/kubeadm/app/cmd/alpha/certs.go | 24 +++---- cmd/kubeadm/app/cmd/alpha/kubeconfig.go | 22 +++--- cmd/kubeadm/app/cmd/alpha/selfhosting.go | 6 +- cmd/kubeadm/app/cmd/config.go | 63 ++++++++++------- cmd/kubeadm/app/cmd/config_test.go | 54 +++++---------- cmd/kubeadm/app/cmd/init.go | 69 +++++++++++-------- cmd/kubeadm/app/cmd/token.go | 17 +++-- cmd/kubeadm/app/cmd/token_test.go | 12 ++-- .../app/phases/addons/proxy/proxy_test.go | 16 ++--- .../phases/uploadconfig/uploadconfig_test.go | 8 +-- cmd/kubeadm/app/util/config/common_test.go | 8 +-- .../app/util/config/initconfiguration.go | 17 +++-- cmd/kubeadm/test/util.go | 2 +- 20 files changed, 211 insertions(+), 182 deletions(-) create mode 100644 cmd/kubeadm/app/apis/kubeadm/v1beta2/conversion.go diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/BUILD b/cmd/kubeadm/app/apis/kubeadm/v1beta2/BUILD index f556100f2d5..fa48d5c8e23 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta2/BUILD +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/BUILD @@ -4,6 +4,7 @@ go_library( name = "go_default_library", srcs = [ "bootstraptokenstring.go", + "conversion.go", "defaults.go", "defaults_unix.go", "defaults_windows.go", diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1beta2/conversion.go new file mode 100644 index 00000000000..d92ce96f289 --- /dev/null +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/conversion.go @@ -0,0 +1,38 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta2 + +import ( + conversion "k8s.io/apimachinery/pkg/conversion" + kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" +) + +func Convert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error { + return autoConvert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in, out, s) +} + +func Convert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { + err := autoConvert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s) + if err != nil { + return err + } + + // Keep the fuzzer test happy by setting out.ClusterConfiguration to defaults + clusterCfg := &ClusterConfiguration{} + SetDefaults_ClusterConfiguration(clusterCfg) + return Convert_v1beta2_ClusterConfiguration_To_kubeadm_ClusterConfiguration(clusterCfg, &out.ClusterConfiguration, s) +} diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1beta2/defaults.go index 282651f66b1..86e4f507ad2 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta2/defaults.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/defaults.go @@ -67,7 +67,6 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error { // SetDefaults_InitConfiguration assigns default values for the InitConfiguration func SetDefaults_InitConfiguration(obj *InitConfiguration) { - SetDefaults_ClusterConfiguration(&obj.ClusterConfiguration) SetDefaults_BootstrapTokens(obj) SetDefaults_APIEndpoint(&obj.LocalAPIEndpoint) } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/types.go b/cmd/kubeadm/app/apis/kubeadm/v1beta2/types.go index d9d578b8108..b0d761aff00 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta2/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/types.go @@ -28,12 +28,6 @@ import ( type InitConfiguration struct { metav1.TypeMeta `json:",inline"` - // ClusterConfiguration holds the cluster-wide information, and embeds that struct (which can be (un)marshalled separately as well) - // When InitConfiguration is marshalled to bytes in the external version, this information IS NOT preserved (which can be seen from - // the `json:"-"` tag. This is due to that when InitConfiguration is (un)marshalled, it turns into two YAML documents, one for the - // InitConfiguration and ClusterConfiguration. Hence, the information must not be duplicated, and is therefore omitted here. - ClusterConfiguration `json:"-"` - // `kubeadm init`-only information. These fields are solely used the first time `kubeadm init` runs. // After that, the information in the fields IS NOT uploaded to the `kubeadm-config` ConfigMap // that is used by `kubeadm upgrade` for instance. These fields must be omitempty. diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.conversion.go index d7498eb1fa1..4fa20ab2504 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.conversion.go @@ -247,6 +247,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*kubeadm.InitConfiguration)(nil), (*InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(a.(*kubeadm.InitConfiguration), b.(*InitConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*InitConfiguration)(nil), (*kubeadm.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(a.(*InitConfiguration), b.(*kubeadm.InitConfiguration), scope) + }); err != nil { + return err + } return nil } @@ -661,9 +671,6 @@ func Convert_kubeadm_ImageMeta_To_v1beta2_ImageMeta(in *kubeadm.ImageMeta, out * } func autoConvert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { - if err := Convert_v1beta2_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil { - return err - } out.BootstrapTokens = *(*[]kubeadm.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) if err := Convert_v1beta2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err @@ -675,15 +682,8 @@ func autoConvert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in *Init return nil } -// Convert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration is an autogenerated conversion function. -func Convert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { - return autoConvert_v1beta2_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s) -} - func autoConvert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error { - if err := Convert_kubeadm_ClusterConfiguration_To_v1beta2_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil { - return err - } + // WARNING: in.ClusterConfiguration requires manual conversion: does not exist in peer-type out.BootstrapTokens = *(*[]BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) if err := Convert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err @@ -695,11 +695,6 @@ func autoConvert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in *kube return nil } -// Convert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration is an autogenerated conversion function. -func Convert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error { - return autoConvert_kubeadm_InitConfiguration_To_v1beta2_InitConfiguration(in, out, s) -} - func autoConvert_v1beta2_JoinConfiguration_To_kubeadm_JoinConfiguration(in *JoinConfiguration, out *kubeadm.JoinConfiguration, s conversion.Scope) error { if err := Convert_v1beta2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.deepcopy.go index 6e4945ce374..399923a6164 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.deepcopy.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.deepcopy.go @@ -391,7 +391,6 @@ func (in *ImageMeta) DeepCopy() *ImageMeta { func (in *InitConfiguration) DeepCopyInto(out *InitConfiguration) { *out = *in out.TypeMeta = in.TypeMeta - in.ClusterConfiguration.DeepCopyInto(&out.ClusterConfiguration) if in.BootstrapTokens != nil { in, out := &in.BootstrapTokens, &out.BootstrapTokens *out = make([]BootstrapToken, len(*in)) diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.defaults.go index ceb1951e0f9..5267e05f6e2 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.defaults.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.defaults.go @@ -45,7 +45,6 @@ func SetObjectDefaults_ClusterStatus(in *ClusterStatus) { func SetObjectDefaults_InitConfiguration(in *InitConfiguration) { SetDefaults_InitConfiguration(in) - SetObjectDefaults_ClusterConfiguration(&in.ClusterConfiguration) for i := range in.BootstrapTokens { a := &in.BootstrapTokens[i] SetDefaults_BootstrapToken(a) diff --git a/cmd/kubeadm/app/cmd/alpha/certs.go b/cmd/kubeadm/app/cmd/alpha/certs.go index 6dcedd579d7..203eb60723a 100644 --- a/cmd/kubeadm/app/cmd/alpha/certs.go +++ b/cmd/kubeadm/app/cmd/alpha/certs.go @@ -119,7 +119,7 @@ func newCmdCertsRenewal() *cobra.Command { type renewFlags struct { cfgPath string kubeconfigPath string - cfg kubeadmapiv1beta2.InitConfiguration + cfg kubeadmapiv1beta2.ClusterConfiguration useAPI bool csrOnly bool csrPath string @@ -127,11 +127,9 @@ type renewFlags struct { func getRenewSubCommands(kdir string) []*cobra.Command { flags := &renewFlags{ - cfg: kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - // Setting kubernetes version to a default value in order to allow a not necessary internet lookup - KubernetesVersion: constants.CurrentKubernetesVersion.String(), - }, + cfg: kubeadmapiv1beta2.ClusterConfiguration{ + // Setting kubernetes version to a default value in order to allow a not necessary internet lookup + KubernetesVersion: constants.CurrentKubernetesVersion.String(), }, } // Default values for the cobra help text @@ -190,7 +188,7 @@ func addRenewFlags(cmd *cobra.Command, flags *renewFlags) { } func renewCert(flags *renewFlags, kdir string, handler *renewal.CertificateRenewHandler) { - internalcfg, err := configutil.LoadOrDefaultInitConfiguration(flags.cfgPath, &flags.cfg) + internalcfg, err := configutil.LoadOrDefaultInitConfiguration(flags.cfgPath, &kubeadmapiv1beta2.InitConfiguration{}, &flags.cfg) kubeadmutil.CheckErr(err) // Get a renewal manager for the given cluster configuration @@ -235,11 +233,9 @@ func renewCert(flags *renewFlags, kdir string, handler *renewal.CertificateRenew // newCmdCertsExpiration creates a new `cert check-expiration` command. func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command { flags := &expirationFlags{ - cfg: kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - // Setting kubernetes version to a default value in order to allow a not necessary internet lookup - KubernetesVersion: constants.CurrentKubernetesVersion.String(), - }, + cfg: kubeadmapiv1beta2.ClusterConfiguration{ + // Setting kubernetes version to a default value in order to allow a not necessary internet lookup + KubernetesVersion: constants.CurrentKubernetesVersion.String(), }, } // Default values for the cobra help text @@ -250,7 +246,7 @@ func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command { Short: "Check certificates expiration for a Kubernetes cluster", Long: expirationLongDesc, Run: func(cmd *cobra.Command, args []string) { - internalcfg, err := configutil.LoadOrDefaultInitConfiguration(flags.cfgPath, &flags.cfg) + internalcfg, err := configutil.LoadOrDefaultInitConfiguration(flags.cfgPath, &kubeadmapiv1beta2.InitConfiguration{}, &flags.cfg) kubeadmutil.CheckErr(err) // Get a renewal manager for the given cluster configuration @@ -291,7 +287,7 @@ func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command { type expirationFlags struct { cfgPath string - cfg kubeadmapiv1beta2.InitConfiguration + cfg kubeadmapiv1beta2.ClusterConfiguration } func addExpirationFlags(cmd *cobra.Command, flags *expirationFlags) { diff --git a/cmd/kubeadm/app/cmd/alpha/kubeconfig.go b/cmd/kubeadm/app/cmd/alpha/kubeconfig.go index 2f359b1b087..31a507e83b4 100644 --- a/cmd/kubeadm/app/cmd/alpha/kubeconfig.go +++ b/cmd/kubeadm/app/cmd/alpha/kubeconfig.go @@ -61,10 +61,12 @@ func newCmdKubeConfigUtility(out io.Writer) *cobra.Command { // newCmdUserKubeConfig returns sub commands for kubeconfig phase func newCmdUserKubeConfig(out io.Writer) *cobra.Command { - cfg := &kubeadmapiv1beta2.InitConfiguration{} + initCfg := &kubeadmapiv1beta2.InitConfiguration{} + clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{} // Default values for the cobra help text - kubeadmscheme.Scheme.Default(cfg) + kubeadmscheme.Scheme.Default(initCfg) + kubeadmscheme.Scheme.Default(clusterCfg) var token, clientName string var organizations []string @@ -80,8 +82,8 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command { kubeadmutil.CheckErr(errors.New("missing required argument --client-name")) } - // This call returns the ready-to-use configuration based on the default cfg populated by flags - internalcfg, err := configutil.DefaultedInitConfiguration(cfg) + // This call returns the ready-to-use configuration based on the defaults populated by flags + internalcfg, err := configutil.DefaultedInitConfiguration(initCfg, clusterCfg) kubeadmutil.CheckErr(err) // if the kubeconfig file for an additional user has to use a token, use it @@ -95,10 +97,14 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command { }, } - // Add flags to the command - cmd.Flags().StringVar(&cfg.CertificatesDir, options.CertificatesDir, cfg.CertificatesDir, "The path where certificates are stored") - cmd.Flags().StringVar(&cfg.LocalAPIEndpoint.AdvertiseAddress, options.APIServerAdvertiseAddress, cfg.LocalAPIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on") - cmd.Flags().Int32Var(&cfg.LocalAPIEndpoint.BindPort, options.APIServerBindPort, cfg.LocalAPIEndpoint.BindPort, "The port the API server is accessible on") + // Add ClusterConfiguration backed flags to the command + cmd.Flags().StringVar(&clusterCfg.CertificatesDir, options.CertificatesDir, clusterCfg.CertificatesDir, "The path where certificates are stored") + + // Add ClusterConfiguration backed flags to the command + cmd.Flags().StringVar(&initCfg.LocalAPIEndpoint.AdvertiseAddress, options.APIServerAdvertiseAddress, initCfg.LocalAPIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on") + cmd.Flags().Int32Var(&initCfg.LocalAPIEndpoint.BindPort, options.APIServerBindPort, initCfg.LocalAPIEndpoint.BindPort, "The port the API server is accessible on") + + // Add command specific flags cmd.Flags().StringVar(&token, options.TokenStr, token, "The token that should be used as the authentication mechanism for this kubeconfig, instead of client certificates") cmd.Flags().StringVar(&clientName, "client-name", clientName, "The name of user. It will be used as the CN if client certificates are created") cmd.Flags().StringSliceVar(&organizations, "org", organizations, "The orgnizations of the client certificate. It will be used as the O if client certificates are created") diff --git a/cmd/kubeadm/app/cmd/alpha/selfhosting.go b/cmd/kubeadm/app/cmd/alpha/selfhosting.go index 07483ec7000..f80dabd370e 100644 --- a/cmd/kubeadm/app/cmd/alpha/selfhosting.go +++ b/cmd/kubeadm/app/cmd/alpha/selfhosting.go @@ -75,7 +75,7 @@ func NewCmdSelfhosting(in io.Reader) *cobra.Command { // getSelfhostingSubCommand returns sub commands for Self-hosting phase func getSelfhostingSubCommand(in io.Reader) *cobra.Command { - cfg := &kubeadmapiv1beta2.InitConfiguration{} + cfg := &kubeadmapiv1beta2.ClusterConfiguration{} // Default values for the cobra help text kubeadmscheme.Scheme.Default(cfg) @@ -124,10 +124,10 @@ func getSelfhostingSubCommand(in io.Reader) *cobra.Command { // KubernetesVersion is not used, but we set it explicitly to avoid the lookup // of the version from the internet when executing LoadOrDefaultInitConfiguration - phases.SetKubernetesVersion(&cfg.ClusterConfiguration) + phases.SetKubernetesVersion(cfg) // This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags - internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, cfg) + internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, &kubeadmapiv1beta2.InitConfiguration{}, cfg) kubeadmutil.CheckErr(err) // Converts the Static Pod-hosted control plane into a self-hosted one diff --git a/cmd/kubeadm/app/cmd/config.go b/cmd/kubeadm/app/cmd/config.go index d321d2092c8..0c1708c7b34 100644 --- a/cmd/kubeadm/app/cmd/config.go +++ b/cmd/kubeadm/app/cmd/config.go @@ -176,17 +176,17 @@ func getSupportedComponentConfigAPIObjects() []string { } func getDefaultedInitConfig() (*kubeadmapi.InitConfiguration, error) { - return configutil.DefaultedInitConfiguration(&kubeadmapiv1beta2.InitConfiguration{ - // TODO: Probably move to getDefaultedClusterConfig? + initCfg := &kubeadmapiv1beta2.InitConfiguration{ LocalAPIEndpoint: kubeadmapiv1beta2.APIEndpoint{AdvertiseAddress: "1.2.3.4"}, - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - KubernetesVersion: fmt.Sprintf("v1.%d.0", constants.MinimumControlPlaneVersion.Minor()+1), - }, - BootstrapTokens: []kubeadmapiv1beta2.BootstrapToken{placeholderToken}, + BootstrapTokens: []kubeadmapiv1beta2.BootstrapToken{placeholderToken}, NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{ CRISocket: constants.DefaultDockerCRISocket, // avoid CRI detection }, - }) + } + clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{ + KubernetesVersion: constants.CurrentKubernetesVersion.String(), // avoid going to the Internet for the current Kubernetes version + } + return configutil.DefaultedInitConfiguration(initCfg, clusterCfg) } func getDefaultInitConfigBytes() ([]byte, error) { @@ -341,8 +341,11 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co // NewCmdConfigUploadFromFlags returns cobra.Command for "kubeadm config upload from-flags" command // Deprecated: please see kubeadm init phase upload-config func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.Command { - cfg := &kubeadmapiv1beta2.InitConfiguration{} - kubeadmscheme.Scheme.Default(cfg) + initCfg := &kubeadmapiv1beta2.InitConfiguration{} + kubeadmscheme.Scheme.Default(initCfg) + + clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{} + kubeadmscheme.Scheme.Default(clusterCfg) var featureGatesString string @@ -360,7 +363,7 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C Run: func(cmd *cobra.Command, args []string) { var err error klog.V(1).Infoln("[config] creating new FeatureGates") - if cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil { + if clusterCfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString); err != nil { kubeadmutil.CheckErr(err) } klog.V(1).Infoln("[config] retrieving ClientSet from file") @@ -369,11 +372,11 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C // KubernetesVersion is not used, but we set it explicitly to avoid the lookup // of the version from the internet when executing DefaultedInitConfiguration - phaseutil.SetKubernetesVersion(&cfg.ClusterConfiguration) + phaseutil.SetKubernetesVersion(clusterCfg) // Default both statically and dynamically, convert to internal API type, and validate everything klog.V(1).Infoln("[config] converting to internal API type") - internalcfg, err := configutil.DefaultedInitConfiguration(cfg) + internalcfg, err := configutil.DefaultedInitConfiguration(initCfg, clusterCfg) kubeadmutil.CheckErr(err) // Finally, upload the configuration @@ -382,7 +385,8 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C kubeadmutil.CheckErr(err) }, } - AddInitConfigFlags(cmd.PersistentFlags(), cfg, &featureGatesString) + AddInitConfigFlags(cmd.PersistentFlags(), initCfg) + AddClusterConfigFlags(cmd.PersistentFlags(), clusterCfg, &featureGatesString) return cmd } @@ -413,8 +417,10 @@ func NewCmdConfigImages(out io.Writer) *cobra.Command { // NewCmdConfigImagesPull returns the `kubeadm config images pull` command func NewCmdConfigImagesPull() *cobra.Command { - externalcfg := &kubeadmapiv1beta2.InitConfiguration{} - kubeadmscheme.Scheme.Default(externalcfg) + externalClusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{} + kubeadmscheme.Scheme.Default(externalClusterCfg) + externalInitCfg := &kubeadmapiv1beta2.InitConfiguration{} + kubeadmscheme.Scheme.Default(externalInitCfg) var cfgPath, featureGatesString string var err error @@ -422,17 +428,17 @@ func NewCmdConfigImagesPull() *cobra.Command { Use: "pull", Short: "Pull images used by kubeadm", Run: func(_ *cobra.Command, _ []string) { - externalcfg.ClusterConfiguration.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString) + externalClusterCfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString) kubeadmutil.CheckErr(err) - internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, externalcfg) + internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, externalInitCfg, externalClusterCfg) kubeadmutil.CheckErr(err) containerRuntime, err := utilruntime.NewContainerRuntime(utilsexec.New(), internalcfg.NodeRegistration.CRISocket) kubeadmutil.CheckErr(err) PullControlPlaneImages(containerRuntime, &internalcfg.ClusterConfiguration) }, } - AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalcfg, &cfgPath, &featureGatesString) - cmdutil.AddCRISocketFlag(cmd.PersistentFlags(), &externalcfg.NodeRegistration.CRISocket) + AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalClusterCfg, &cfgPath, &featureGatesString) + cmdutil.AddCRISocketFlag(cmd.PersistentFlags(), &externalInitCfg.NodeRegistration.CRISocket) return cmd } @@ -465,7 +471,7 @@ func PullControlPlaneImages(runtime utilruntime.ContainerRuntime, cfg *kubeadmap // NewCmdConfigImagesList returns the "kubeadm config images list" command func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Command { - externalcfg := &kubeadmapiv1beta2.InitConfiguration{} + externalcfg := &kubeadmapiv1beta2.ClusterConfiguration{} kubeadmscheme.Scheme.Default(externalcfg) var cfgPath, featureGatesString string var err error @@ -480,7 +486,7 @@ func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Comman Use: "list", Short: "Print a list of images kubeadm will use. The configuration file is used in case any images or image repositories are customized", Run: func(_ *cobra.Command, _ []string) { - externalcfg.ClusterConfiguration.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString) + externalcfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString) kubeadmutil.CheckErr(err) imagesList, err := NewImagesList(cfgPath, externalcfg) kubeadmutil.CheckErr(err) @@ -492,8 +498,15 @@ func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Comman } // NewImagesList returns the underlying struct for the "kubeadm config images list" command -func NewImagesList(cfgPath string, cfg *kubeadmapiv1beta2.InitConfiguration) (*ImagesList, error) { - initcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, cfg) +func NewImagesList(cfgPath string, cfg *kubeadmapiv1beta2.ClusterConfiguration) (*ImagesList, error) { + // Avoid running the CRI auto-detection code as we don't need it + versionedInitCfg := &kubeadmapiv1beta2.InitConfiguration{ + NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{ + CRISocket: constants.DefaultDockerCRISocket, + }, + } + + initcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, versionedInitCfg, cfg) if err != nil { return nil, errors.Wrap(err, "could not convert cfg to an internal cfg") } @@ -519,8 +532,8 @@ func (i *ImagesList) Run(out io.Writer) error { } // AddImagesCommonConfigFlags adds the flags that configure kubeadm (and affect the images kubeadm will use) -func AddImagesCommonConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfiguration, cfgPath *string, featureGatesString *string) { - options.AddKubernetesVersionFlag(flagSet, &cfg.ClusterConfiguration.KubernetesVersion) +func AddImagesCommonConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.ClusterConfiguration, cfgPath *string, featureGatesString *string) { + options.AddKubernetesVersionFlag(flagSet, &cfg.KubernetesVersion) options.AddFeatureGatesStringFlag(flagSet, featureGatesString) options.AddImageMetaFlags(flagSet, &cfg.ImageRepository) flagSet.StringVar(cfgPath, "config", *cfgPath, "Path to kubeadm config file.") diff --git a/cmd/kubeadm/app/cmd/config_test.go b/cmd/kubeadm/app/cmd/config_test.go index fa4d3b442f3..52e9628ef28 100644 --- a/cmd/kubeadm/app/cmd/config_test.go +++ b/cmd/kubeadm/app/cmd/config_test.go @@ -106,10 +106,8 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) { t.Fatalf("Failed writing a config file: %v", err) } - i, err := NewImagesList(configFilePath, &kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - KubernetesVersion: dummyKubernetesVersion, - }, + i, err := NewImagesList(configFilePath, &kubeadmapiv1beta2.ClusterConfiguration{ + KubernetesVersion: dummyKubernetesVersion, }) if err != nil { t.Fatalf("Failed getting the kubeadm images command: %v", err) @@ -135,61 +133,41 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) { func TestConfigImagesListRunWithoutPath(t *testing.T) { testcases := []struct { name string - cfg kubeadmapiv1beta2.InitConfiguration + cfg kubeadmapiv1beta2.ClusterConfiguration expectedImages int }{ { name: "empty config", expectedImages: defaultNumberOfImages, - cfg: kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - KubernetesVersion: dummyKubernetesVersion, - }, - NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{ - CRISocket: constants.DefaultDockerCRISocket, - }, + cfg: kubeadmapiv1beta2.ClusterConfiguration{ + KubernetesVersion: dummyKubernetesVersion, }, }, { name: "external etcd configuration", - cfg: kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - Etcd: kubeadmapiv1beta2.Etcd{ - External: &kubeadmapiv1beta2.ExternalEtcd{ - Endpoints: []string{"https://some.etcd.com:2379"}, - }, + cfg: kubeadmapiv1beta2.ClusterConfiguration{ + Etcd: kubeadmapiv1beta2.Etcd{ + External: &kubeadmapiv1beta2.ExternalEtcd{ + Endpoints: []string{"https://some.etcd.com:2379"}, }, - KubernetesVersion: dummyKubernetesVersion, - }, - NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{ - CRISocket: constants.DefaultDockerCRISocket, }, + KubernetesVersion: dummyKubernetesVersion, }, expectedImages: defaultNumberOfImages - 1, }, { name: "coredns enabled", - cfg: kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - KubernetesVersion: dummyKubernetesVersion, - }, - NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{ - CRISocket: constants.DefaultDockerCRISocket, - }, + cfg: kubeadmapiv1beta2.ClusterConfiguration{ + KubernetesVersion: dummyKubernetesVersion, }, expectedImages: defaultNumberOfImages, }, { name: "kube-dns enabled", - cfg: kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - KubernetesVersion: dummyKubernetesVersion, - DNS: kubeadmapiv1beta2.DNS{ - Type: kubeadmapiv1beta2.KubeDNS, - }, - }, - NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{ - CRISocket: constants.DefaultDockerCRISocket, + cfg: kubeadmapiv1beta2.ClusterConfiguration{ + KubernetesVersion: dummyKubernetesVersion, + DNS: kubeadmapiv1beta2.DNS{ + Type: kubeadmapiv1beta2.KubeDNS, }, }, expectedImages: defaultNumberOfImages + 2, diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index 8eb7467d45f..00a3d8497b7 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -95,7 +95,8 @@ type initOptions struct { featureGatesString string ignorePreflightErrors []string bto *options.BootstrapTokenOptions - externalcfg *kubeadmapiv1beta2.InitConfiguration + externalInitCfg *kubeadmapiv1beta2.InitConfiguration + externalClusterCfg *kubeadmapiv1beta2.ClusterConfiguration uploadCerts bool skipCertificateKeyPrint bool } @@ -151,18 +152,19 @@ func NewCmdInit(out io.Writer, initOptions *initOptions) *cobra.Command { // adds flags to the init command // init command local flags could be eventually inherited by the sub-commands automatically generated for phases - AddInitConfigFlags(cmd.Flags(), initOptions.externalcfg, &initOptions.featureGatesString) + AddInitConfigFlags(cmd.Flags(), initOptions.externalInitCfg) + AddClusterConfigFlags(cmd.Flags(), initOptions.externalClusterCfg, &initOptions.featureGatesString) AddInitOtherFlags(cmd.Flags(), initOptions) initOptions.bto.AddTokenFlag(cmd.Flags()) initOptions.bto.AddTTLFlag(cmd.Flags()) - options.AddImageMetaFlags(cmd.Flags(), &initOptions.externalcfg.ImageRepository) + options.AddImageMetaFlags(cmd.Flags(), &initOptions.externalClusterCfg.ImageRepository) // defines additional flag that are not used by the init command but that could be eventually used // by the sub-commands automatically generated for phases initRunner.SetAdditionalFlags(func(flags *flag.FlagSet) { options.AddKubeConfigFlag(flags, &initOptions.kubeconfigPath) options.AddKubeConfigDirFlag(flags, &initOptions.kubeconfigDir) - options.AddControlPlanExtraArgsFlags(flags, &initOptions.externalcfg.APIServer.ExtraArgs, &initOptions.externalcfg.ControllerManager.ExtraArgs, &initOptions.externalcfg.Scheduler.ExtraArgs) + options.AddControlPlanExtraArgsFlags(flags, &initOptions.externalClusterCfg.APIServer.ExtraArgs, &initOptions.externalClusterCfg.ControllerManager.ExtraArgs, &initOptions.externalClusterCfg.Scheduler.ExtraArgs) }) // initialize the workflow runner with the list of phases @@ -193,7 +195,7 @@ func NewCmdInit(out io.Writer, initOptions *initOptions) *cobra.Command { } // AddInitConfigFlags adds init flags bound to the config to the specified flagset -func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfiguration, featureGatesString *string) { +func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfiguration) { flagSet.StringVar( &cfg.LocalAPIEndpoint.AdvertiseAddress, options.APIServerAdvertiseAddress, cfg.LocalAPIEndpoint.AdvertiseAddress, "The IP address the API Server will advertise it's listening on. If not set the default network interface will be used.", @@ -202,6 +204,19 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfig &cfg.LocalAPIEndpoint.BindPort, options.APIServerBindPort, cfg.LocalAPIEndpoint.BindPort, "Port for the API Server to bind to.", ) + flagSet.StringVar( + &cfg.NodeRegistration.Name, options.NodeName, cfg.NodeRegistration.Name, + `Specify the node name.`, + ) + flagSet.StringVar( + &cfg.CertificateKey, options.CertificateKey, "", + "Key used to encrypt the control-plane certificates in the kubeadm-certs Secret.", + ) + cmdutil.AddCRISocketFlag(flagSet, &cfg.NodeRegistration.CRISocket) +} + +// AddClusterConfigFlags adds cluster flags bound to the config to the specified flagset +func AddClusterConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.ClusterConfiguration, featureGatesString *string) { flagSet.StringVar( &cfg.Networking.ServiceSubnet, options.NetworkingServiceSubnet, cfg.Networking.ServiceSubnet, "Use alternative range of IP address for service VIPs.", @@ -225,15 +240,6 @@ func AddInitConfigFlags(flagSet *flag.FlagSet, cfg *kubeadmapiv1beta2.InitConfig &cfg.APIServer.CertSANs, options.APIServerCertSANs, cfg.APIServer.CertSANs, `Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names.`, ) - flagSet.StringVar( - &cfg.NodeRegistration.Name, options.NodeName, cfg.NodeRegistration.Name, - `Specify the node name.`, - ) - flagSet.StringVar( - &cfg.CertificateKey, options.CertificateKey, "", - "Key used to encrypt the control-plane certificates in the kubeadm-certs Secret.", - ) - cmdutil.AddCRISocketFlag(flagSet, &cfg.NodeRegistration.CRISocket) options.AddFeatureGatesStringFlag(flagSet, featureGatesString) } @@ -266,19 +272,23 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, initOptions *initOptions) { // newInitOptions returns a struct ready for being used for creating cmd init flags. func newInitOptions() *initOptions { // initialize the public kubeadm config API by applying defaults - externalcfg := &kubeadmapiv1beta2.InitConfiguration{} - kubeadmscheme.Scheme.Default(externalcfg) + externalInitCfg := &kubeadmapiv1beta2.InitConfiguration{} + kubeadmscheme.Scheme.Default(externalInitCfg) + + externalClusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{} + kubeadmscheme.Scheme.Default(externalClusterCfg) // Create the options object for the bootstrap token-related flags, and override the default value for .Description bto := options.NewBootstrapTokenOptions() bto.Description = "The default bootstrap token generated by 'kubeadm init'." return &initOptions{ - externalcfg: externalcfg, - bto: bto, - kubeconfigDir: kubeadmconstants.KubernetesDir, - kubeconfigPath: kubeadmconstants.GetAdminKubeConfigPath(), - uploadCerts: false, + externalInitCfg: externalInitCfg, + externalClusterCfg: externalClusterCfg, + bto: bto, + kubeconfigDir: kubeadmconstants.KubernetesDir, + kubeconfigPath: kubeadmconstants.GetAdminKubeConfigPath(), + uploadCerts: false, } } @@ -287,12 +297,13 @@ func newInitOptions() *initOptions { // 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) { // Re-apply defaults to the public kubeadm API (this will set only values not exposed/not set as a flags) - kubeadmscheme.Scheme.Default(options.externalcfg) + kubeadmscheme.Scheme.Default(options.externalInitCfg) + kubeadmscheme.Scheme.Default(options.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.externalcfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, options.featureGatesString); err != nil { + if options.externalClusterCfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, options.featureGatesString); err != nil { return nil, err } @@ -300,13 +311,13 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io return nil, err } - if err = options.bto.ApplyTo(options.externalcfg); err != nil { + if err = options.bto.ApplyTo(options.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.externalcfg) + cfg, err := configutil.LoadOrDefaultInitConfiguration(options.cfgPath, options.externalInitCfg, options.externalClusterCfg) if err != nil { return nil, err } @@ -319,11 +330,11 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io cfg.NodeRegistration.IgnorePreflightErrors = ignorePreflightErrorsSet.List() // override node name and CRI socket from the command line options - if options.externalcfg.NodeRegistration.Name != "" { - cfg.NodeRegistration.Name = options.externalcfg.NodeRegistration.Name + if options.externalInitCfg.NodeRegistration.Name != "" { + cfg.NodeRegistration.Name = options.externalInitCfg.NodeRegistration.Name } - if options.externalcfg.NodeRegistration.CRISocket != "" { - cfg.NodeRegistration.CRISocket = options.externalcfg.NodeRegistration.CRISocket + if options.externalInitCfg.NodeRegistration.CRISocket != "" { + cfg.NodeRegistration.CRISocket = options.externalInitCfg.NodeRegistration.CRISocket } if err := configutil.VerifyAPIServerBindAddress(cfg.LocalAPIEndpoint.AdvertiseAddress); err != nil { diff --git a/cmd/kubeadm/app/cmd/token.go b/cmd/kubeadm/app/cmd/token.go index 419193648d2..f09c07ae599 100644 --- a/cmd/kubeadm/app/cmd/token.go +++ b/cmd/kubeadm/app/cmd/token.go @@ -40,7 +40,6 @@ import ( kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/cmd/options" - phaseutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" tokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node" @@ -209,10 +208,14 @@ func NewCmdTokenGenerate(out io.Writer) *cobra.Command { } // RunCreateToken generates a new bootstrap token and stores it as a secret on the server. -func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, cfg *kubeadmapiv1beta2.InitConfiguration, printJoinCommand bool, kubeConfigFile string) error { - // KubernetesVersion is not used, but we set it explicitly to avoid the lookup - // of the version from the internet when executing LoadOrDefaultInitConfiguration - phaseutil.SetKubernetesVersion(&cfg.ClusterConfiguration) +func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, initCfg *kubeadmapiv1beta2.InitConfiguration, printJoinCommand bool, kubeConfigFile string) error { + // ClusterConfiguration is needed just for the call to LoadOrDefaultInitConfiguration + clusterCfg := &kubeadmapiv1beta2.ClusterConfiguration{ + // KubernetesVersion is not used, but we set this explicitly to avoid + // the lookup of the version from the internet when executing LoadOrDefaultInitConfiguration + KubernetesVersion: kubeadmconstants.CurrentKubernetesVersion.String(), + } + kubeadmscheme.Scheme.Default(clusterCfg) // This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags klog.V(1).Infoln("[token] loading configurations") @@ -220,9 +223,9 @@ func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, c // In fact, we don't do any CRI ops at all. // This is just to force skipping the CRI detection. // Ref: https://github.com/kubernetes/kubeadm/issues/1559 - cfg.NodeRegistration.CRISocket = kubeadmconstants.DefaultDockerCRISocket + initCfg.NodeRegistration.CRISocket = kubeadmconstants.DefaultDockerCRISocket - internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, cfg) + internalcfg, err := configutil.LoadOrDefaultInitConfiguration(cfgPath, initCfg, clusterCfg) if err != nil { return err } diff --git a/cmd/kubeadm/app/cmd/token_test.go b/cmd/kubeadm/app/cmd/token_test.go index 1c9c1095bec..7fc2d5bd5fd 100644 --- a/cmd/kubeadm/app/cmd/token_test.go +++ b/cmd/kubeadm/app/cmd/token_test.go @@ -32,7 +32,6 @@ import ( core "k8s.io/client-go/testing" "k8s.io/client-go/tools/clientcmd" kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2" - "k8s.io/kubernetes/cmd/kubeadm/app/constants" ) const ( @@ -160,11 +159,6 @@ func TestRunCreateToken(t *testing.T) { } cfg := &kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - // KubernetesVersion is not used, but we set this explicitly to avoid - // the lookup of the version from the internet when executing LoadOrDefaultInitConfiguration - KubernetesVersion: constants.MinimumControlPlaneVersion.String(), - }, BootstrapTokens: []kubeadmapiv1beta2.BootstrapToken{ { Token: bts, @@ -176,8 +170,10 @@ func TestRunCreateToken(t *testing.T) { } err = RunCreateToken(&buf, fakeClient, "", cfg, tc.printJoin, "") - if (err != nil) != tc.expectedError { - t.Errorf("Test case %s: RunCreateToken expected error: %v, saw: %v", tc.name, tc.expectedError, (err != nil)) + if tc.expectedError && err == nil { + t.Error("unexpected success") + } else if !tc.expectedError && err != nil { + t.Errorf("unexpected error: %v", err) } }) } diff --git a/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go b/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go index c8a6f123f3a..c035006249e 100644 --- a/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go +++ b/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go @@ -179,13 +179,13 @@ func TestEnsureProxyAddon(t *testing.T) { AdvertiseAddress: "1.2.3.4", BindPort: 1234, }, - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - Networking: kubeadmapiv1beta2.Networking{ - PodSubnet: "5.6.7.8/24", - }, - ImageRepository: "someRepo", - KubernetesVersion: constants.MinimumControlPlaneVersion.String(), + } + controlPlaneClusterConfig := &kubeadmapiv1beta2.ClusterConfiguration{ + Networking: kubeadmapiv1beta2.Networking{ + PodSubnet: "5.6.7.8/24", }, + ImageRepository: "someRepo", + KubernetesVersion: constants.MinimumControlPlaneVersion.String(), } // Simulate an error if necessary @@ -198,10 +198,10 @@ func TestEnsureProxyAddon(t *testing.T) { controlPlaneConfig.LocalAPIEndpoint.AdvertiseAddress = "1.2.3" case IPv6SetBindAddress: controlPlaneConfig.LocalAPIEndpoint.AdvertiseAddress = "1:2::3:4" - controlPlaneConfig.Networking.PodSubnet = "2001:101::/96" + controlPlaneClusterConfig.Networking.PodSubnet = "2001:101::/96" } - intControlPlane, err := configutil.DefaultedInitConfiguration(controlPlaneConfig) + intControlPlane, err := configutil.DefaultedInitConfiguration(controlPlaneConfig, controlPlaneClusterConfig) if err != nil { t.Errorf("test failed to convert external to internal version") return diff --git a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go index 9e8e212671d..83db2f366c3 100644 --- a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go +++ b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go @@ -69,9 +69,6 @@ func TestUploadConfiguration(t *testing.T) { LocalAPIEndpoint: kubeadmapiv1beta2.APIEndpoint{ AdvertiseAddress: "1.2.3.4", }, - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - KubernetesVersion: kubeadmconstants.MinimumControlPlaneVersion.WithPatch(10).String(), - }, BootstrapTokens: []kubeadmapiv1beta2.BootstrapToken{ { Token: &kubeadmapiv1beta2.BootstrapTokenString{ @@ -85,7 +82,10 @@ func TestUploadConfiguration(t *testing.T) { CRISocket: "/var/run/custom-cri.sock", }, } - cfg, err := configutil.DefaultedInitConfiguration(initialcfg) + clustercfg := &kubeadmapiv1beta2.ClusterConfiguration{ + KubernetesVersion: kubeadmconstants.MinimumControlPlaneVersion.WithPatch(10).String(), + } + cfg, err := configutil.DefaultedInitConfiguration(initialcfg, clustercfg) // cleans up component config to make cfg and decodedcfg comparable (now component config are not stored anymore in kubeadm-config config map) cfg.ComponentConfigs = kubeadmapi.ComponentConfigs{} diff --git a/cmd/kubeadm/app/util/config/common_test.go b/cmd/kubeadm/app/util/config/common_test.go index 2b75586dd50..a9f1d6f0e2a 100644 --- a/cmd/kubeadm/app/util/config/common_test.go +++ b/cmd/kubeadm/app/util/config/common_test.go @@ -125,11 +125,9 @@ func TestLowercaseSANs(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - cfg := &kubeadmapiv1beta2.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1beta2.ClusterConfiguration{ - APIServer: kubeadmapiv1beta2.APIServer{ - CertSANs: test.in, - }, + cfg := &kubeadmapiv1beta2.ClusterConfiguration{ + APIServer: kubeadmapiv1beta2.APIServer{ + CertSANs: test.in, }, } diff --git a/cmd/kubeadm/app/util/config/initconfiguration.go b/cmd/kubeadm/app/util/config/initconfiguration.go index 9c92c26b135..3fd70eccd95 100644 --- a/cmd/kubeadm/app/util/config/initconfiguration.go +++ b/cmd/kubeadm/app/util/config/initconfiguration.go @@ -162,13 +162,16 @@ func SetClusterDynamicDefaults(cfg *kubeadmapi.ClusterConfiguration, advertiseAd } // DefaultedInitConfiguration takes a versioned init config (often populated by flags), defaults it and converts it into internal InitConfiguration -func DefaultedInitConfiguration(defaultversionedcfg *kubeadmapiv1beta2.InitConfiguration) (*kubeadmapi.InitConfiguration, error) { +func DefaultedInitConfiguration(versionedInitCfg *kubeadmapiv1beta2.InitConfiguration, versionedClusterCfg *kubeadmapiv1beta2.ClusterConfiguration) (*kubeadmapi.InitConfiguration, error) { internalcfg := &kubeadmapi.InitConfiguration{} // Takes passed flags into account; the defaulting is executed once again enforcing assignment of // static default values to cfg only for values not provided with flags - kubeadmscheme.Scheme.Default(defaultversionedcfg) - kubeadmscheme.Scheme.Convert(defaultversionedcfg, internalcfg, nil) + kubeadmscheme.Scheme.Default(versionedInitCfg) + kubeadmscheme.Scheme.Convert(versionedInitCfg, internalcfg, nil) + + kubeadmscheme.Scheme.Default(versionedClusterCfg) + kubeadmscheme.Scheme.Convert(versionedClusterCfg, &internalcfg.ClusterConfiguration, nil) // Applies dynamic defaults to settings not provided with flags if err := SetInitDynamicDefaults(internalcfg); err != nil { @@ -194,18 +197,18 @@ func LoadInitConfigurationFromFile(cfgPath string) (*kubeadmapi.InitConfiguratio } // LoadOrDefaultInitConfiguration takes a path to a config file and a versioned configuration that can serve as the default config -// If cfgPath is specified, defaultversionedcfg will always get overridden. Otherwise, the default config (often populated by flags) will be used. -// Then the external, versioned configuration is defaulted and converted to the internal type. +// If cfgPath is specified, the versioned configs will always get overridden with the one in the file (specified by cfgPath). +// The the external, versioned configuration is defaulted and converted to the internal type. // Right thereafter, the configuration is defaulted again with dynamic values (like IP addresses of a machine, etc) // Lastly, the internal config is validated and returned. -func LoadOrDefaultInitConfiguration(cfgPath string, defaultversionedcfg *kubeadmapiv1beta2.InitConfiguration) (*kubeadmapi.InitConfiguration, error) { +func LoadOrDefaultInitConfiguration(cfgPath string, versionedInitCfg *kubeadmapiv1beta2.InitConfiguration, versionedClusterCfg *kubeadmapiv1beta2.ClusterConfiguration) (*kubeadmapi.InitConfiguration, error) { if cfgPath != "" { // Loads configuration from config file, if provided // Nb. --config overrides command line flags return LoadInitConfigurationFromFile(cfgPath) } - return DefaultedInitConfiguration(defaultversionedcfg) + return DefaultedInitConfiguration(versionedInitCfg, versionedClusterCfg) } // BytesToInitConfiguration converts a byte slice to an internal, defaulted and validated InitConfiguration object. diff --git a/cmd/kubeadm/test/util.go b/cmd/kubeadm/test/util.go index 950369f00b8..a0bbc253f4a 100644 --- a/cmd/kubeadm/test/util.go +++ b/cmd/kubeadm/test/util.go @@ -157,7 +157,7 @@ func AssertError(t *testing.T, err error, expected string) { // GetDefaultInternalConfig returns a defaulted kubeadmapi.InitConfiguration func GetDefaultInternalConfig(t *testing.T) *kubeadmapi.InitConfiguration { - internalcfg, err := configutil.DefaultedInitConfiguration(&kubeadmapiv1beta2.InitConfiguration{}) + internalcfg, err := configutil.DefaultedInitConfiguration(&kubeadmapiv1beta2.InitConfiguration{}, &kubeadmapiv1beta2.ClusterConfiguration{}) if err != nil { t.Fatalf("unexpected error getting default config: %v", err) }