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) }