From 5224551fa148aa0a9cecb90ec54caf4adba3ac87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20K=C3=A4ldstr=C3=B6m?= Date: Fri, 10 Aug 2018 21:30:54 +0300 Subject: [PATCH 1/2] kubeadm: Split out ClusterConfiguration from InitConfiguration Trivial rebasement, fixed some broken tests, and inserted some TODOs: Rostislav M. Georgiev --- cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD | 4 - cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go | 96 ++--- .../app/apis/kubeadm/fuzzer/fuzzer_test.go | 9 +- cmd/kubeadm/app/apis/kubeadm/register.go | 1 + cmd/kubeadm/app/apis/kubeadm/types.go | 31 +- .../app/apis/kubeadm/v1alpha2/conversion.go | 82 +++++ .../app/apis/kubeadm/v1alpha3/conversion.go | 8 +- .../app/apis/kubeadm/v1alpha3/defaults.go | 15 +- .../app/apis/kubeadm/v1alpha3/register.go | 1 + .../app/apis/kubeadm/v1alpha3/types.go | 19 +- .../app/apis/kubeadm/validation/validation.go | 13 +- .../kubeadm/validation/validation_test.go | 344 ++++++++++-------- cmd/kubeadm/app/cmd/config.go | 62 ++-- cmd/kubeadm/app/cmd/config_test.go | 53 +-- cmd/kubeadm/app/cmd/phases/certs.go | 8 +- cmd/kubeadm/app/cmd/phases/certs_test.go | 8 +- cmd/kubeadm/app/cmd/phases/kubeconfig_test.go | 6 +- cmd/kubeadm/app/cmd/token_test.go | 9 +- cmd/kubeadm/app/cmd/upgrade/apply.go | 3 +- cmd/kubeadm/app/cmd/upgrade/apply_test.go | 8 +- cmd/kubeadm/app/cmd/upgrade/common.go | 8 +- cmd/kubeadm/app/cmd/upgrade/common_test.go | 12 +- cmd/kubeadm/app/componentconfigs/defaults.go | 4 +- .../app/componentconfigs/registrations.go | 20 +- .../app/componentconfigs/validation.go | 4 +- .../app/componentconfigs/validation_test.go | 32 +- cmd/kubeadm/app/constants/constants.go | 6 + .../app/phases/addons/proxy/proxy_test.go | 18 +- cmd/kubeadm/app/phases/certs/certlist_test.go | 4 +- cmd/kubeadm/app/phases/certs/certs_test.go | 22 +- .../phases/certs/pkiutil/pki_helpers_test.go | 56 +-- .../app/phases/controlplane/manifests_test.go | 81 +++-- .../app/phases/controlplane/volumes_test.go | 12 +- cmd/kubeadm/app/phases/etcd/local_test.go | 54 +-- .../app/phases/kubeconfig/kubeconfig_test.go | 57 +-- cmd/kubeadm/app/phases/kubelet/config_test.go | 10 +- cmd/kubeadm/app/phases/upgrade/BUILD | 5 +- .../app/phases/upgrade/postupgrade_test.go | 6 +- .../app/phases/upgrade/staticpods_test.go | 38 +- cmd/kubeadm/app/phases/uploadconfig/BUILD | 1 + .../app/phases/uploadconfig/uploadconfig.go | 9 +- .../phases/uploadconfig/uploadconfig_test.go | 38 +- cmd/kubeadm/app/preflight/checks_test.go | 19 +- cmd/kubeadm/app/util/config/cluster.go | 16 +- cmd/kubeadm/app/util/config/cluster_test.go | 113 +++--- cmd/kubeadm/app/util/config/common.go | 6 +- cmd/kubeadm/app/util/config/common_test.go | 4 +- cmd/kubeadm/app/util/config/masterconfig.go | 226 +++++++----- .../testdata/conversion/master/v1alpha3.yaml | 33 +- .../testdata/defaulting/master/defaulted.yaml | 33 +- cmd/kubeadm/app/util/marshal.go | 5 + cmd/kubeadm/app/util/marshal_test.go | 13 +- cmd/kubeadm/app/util/staticpod/utils_test.go | 48 ++- cmd/kubeadm/test/util.go | 7 +- 54 files changed, 1082 insertions(+), 718 deletions(-) diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD b/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD index 930d1e1833936..7bad79a2a2e62 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/BUILD @@ -42,8 +42,4 @@ go_test( name = "go_default_test", srcs = ["fuzzer_test.go"], embed = [":go_default_library"], - deps = [ - "//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/api/apitesting/roundtrip:go_default_library", - ], ) diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go index be693f73c81d2..ad73e7870cfa2 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go @@ -33,18 +33,18 @@ import ( utilpointer "k8s.io/utils/pointer" ) +// NOTE: Right now this code is unused, as the test utilizing this is disabled. + // Funcs returns the fuzzer functions for the kubeadm apis. func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { return []interface{}{ + func(obj *kubeadm.ClusterConfiguration, c fuzz.Continue) { + c.FuzzNoCustom(obj) + fuzzClusterConfig(obj) + }, func(obj *kubeadm.InitConfiguration, c fuzz.Continue) { c.FuzzNoCustom(obj) - obj.KubernetesVersion = "v10" - obj.API.BindPort = 20 - obj.API.AdvertiseAddress = "foo" - obj.Networking.ServiceSubnet = "10.96.0.0/12" - obj.Networking.DNSDomain = "cluster.local" - obj.CertificatesDir = "foo" - obj.APIServerCertSANs = []string{"foo"} + fuzzClusterConfig(&obj.ClusterConfiguration) obj.BootstrapTokens = []kubeadm.BootstrapToken{ { Token: &kubeadm.BootstrapTokenString{ @@ -56,47 +56,11 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { Groups: []string{"foo"}, }, } - obj.ImageRepository = "foo" - obj.CIImageRepository = "" - obj.UnifiedControlPlaneImage = "foo" - obj.FeatureGates = map[string]bool{"foo": true} - obj.ClusterName = "foo" - obj.APIServerExtraArgs = map[string]string{"foo": "foo"} - obj.APIServerExtraVolumes = []kubeadm.HostPathMount{{ - Name: "foo", - HostPath: "foo", - MountPath: "foo", - Writable: false, - }} - obj.Etcd.Local = &kubeadm.LocalEtcd{ - Image: "foo", - DataDir: "foo", - ServerCertSANs: []string{"foo"}, - PeerCertSANs: []string{"foo"}, - ExtraArgs: map[string]string{"foo": "foo"}, - } obj.NodeRegistration = kubeadm.NodeRegistrationOptions{ CRISocket: "foo", Name: "foo", Taints: []v1.Taint{}, } - obj.AuditPolicyConfiguration = kubeadm.AuditPolicyConfiguration{ - Path: "foo", - LogDir: "/foo", - LogMaxAge: utilpointer.Int32Ptr(0), - } - // Set the Kubelet ComponentConfig to an empty, defaulted struct - extkubeletconfig := &kubeletconfigv1beta1.KubeletConfiguration{} - obj.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{} - componentconfigs.Scheme.Default(extkubeletconfig) - componentconfigs.Scheme.Convert(extkubeletconfig, obj.ComponentConfigs.Kubelet, nil) - componentconfigs.DefaultKubeletConfiguration(obj) - // Set the KubeProxy ComponentConfig to an empty, defaulted struct - extkubeproxyconfig := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{} - obj.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{} - componentconfigs.Scheme.Default(extkubeproxyconfig) - componentconfigs.Scheme.Convert(extkubeproxyconfig, obj.ComponentConfigs.KubeProxy, nil) - componentconfigs.DefaultKubeProxyConfiguration(obj) }, func(obj *kubeadm.JoinConfiguration, c fuzz.Continue) { c.FuzzNoCustom(obj) @@ -115,3 +79,49 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { }, } } + +func fuzzClusterConfig(obj *kubeadm.ClusterConfiguration) { + obj.KubernetesVersion = "v10" + obj.API.BindPort = 20 + obj.API.AdvertiseAddress = "foo" + obj.Networking.ServiceSubnet = "10.96.0.0/12" + obj.Networking.DNSDomain = "cluster.local" + obj.CertificatesDir = "foo" + obj.APIServerCertSANs = []string{"foo"} + obj.ImageRepository = "foo" + obj.CIImageRepository = "" + obj.UnifiedControlPlaneImage = "foo" + obj.FeatureGates = map[string]bool{"foo": true} + obj.ClusterName = "foo" + obj.APIServerExtraArgs = map[string]string{"foo": "foo"} + obj.APIServerExtraVolumes = []kubeadm.HostPathMount{{ + Name: "foo", + HostPath: "foo", + MountPath: "foo", + Writable: false, + }} + obj.Etcd.Local = &kubeadm.LocalEtcd{ + Image: "foo", + DataDir: "foo", + ServerCertSANs: []string{"foo"}, + PeerCertSANs: []string{"foo"}, + ExtraArgs: map[string]string{"foo": "foo"}, + } + obj.AuditPolicyConfiguration = kubeadm.AuditPolicyConfiguration{ + Path: "foo", + LogDir: "/foo", + LogMaxAge: utilpointer.Int32Ptr(0), + } + // Set the Kubelet ComponentConfig to an empty, defaulted struct + extkubeletconfig := &kubeletconfigv1beta1.KubeletConfiguration{} + obj.ComponentConfigs.Kubelet = &kubeletconfig.KubeletConfiguration{} + componentconfigs.Scheme.Default(extkubeletconfig) + componentconfigs.Scheme.Convert(extkubeletconfig, obj.ComponentConfigs.Kubelet, nil) + componentconfigs.DefaultKubeletConfiguration(obj) + // Set the KubeProxy ComponentConfig to an empty, defaulted struct + extkubeproxyconfig := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{} + obj.ComponentConfigs.KubeProxy = &kubeproxyconfig.KubeProxyConfiguration{} + componentconfigs.Scheme.Default(extkubeproxyconfig) + componentconfigs.Scheme.Convert(extkubeproxyconfig, obj.ComponentConfigs.KubeProxy, nil) + componentconfigs.DefaultKubeProxyConfiguration(obj) +} diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer_test.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer_test.go index 76014a56ff1db..5d44a1e1669a3 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer_test.go @@ -16,7 +16,12 @@ limitations under the License. package fuzzer -import ( +// TODO: Fuzzing rouudtrip tests are currently disabled in the v1.12 cycle due to the +// v1alpha2 -> v1alpha3 migration. As the ComponentConfigs were embedded in the structs +// earlier now have moved out it's not possible to do a lossless roundtrip "the normal way" +// When we support v1alpha3 and higher only, we can reenable this + +/*import ( "testing" "k8s.io/apimachinery/pkg/api/apitesting/roundtrip" @@ -25,4 +30,4 @@ import ( func TestRoundTripTypes(t *testing.T) { roundtrip.RoundTripTestForAPIGroup(t, scheme.AddToScheme, Funcs) -} +}*/ diff --git a/cmd/kubeadm/app/apis/kubeadm/register.go b/cmd/kubeadm/app/apis/kubeadm/register.go index e5b84abd16006..c85e1c34908bc 100644 --- a/cmd/kubeadm/app/apis/kubeadm/register.go +++ b/cmd/kubeadm/app/apis/kubeadm/register.go @@ -47,6 +47,7 @@ func Resource(resource string) schema.GroupResource { func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &InitConfiguration{}, + &ClusterConfiguration{}, &JoinConfiguration{}, ) return nil diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go index 8b46a0450d729..5701d6aa30d90 100644 --- a/cmd/kubeadm/app/apis/kubeadm/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/types.go @@ -19,7 +19,7 @@ package kubeadm import ( fuzz "github.com/google/gofuzz" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig" "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig" @@ -27,30 +27,38 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// InitConfiguration contains a list of elements which make up master's -// configuration object. +// InitConfiguration contains a list of fields that are specifically "kubeadm init"-only runtime +// information. The cluster-wide config is stored in ClusterConfiguration. The InitConfiguration +// object IS NOT uploaded to the kubeadm-config ConfigMap in the cluster, only the +// ClusterConfiguration is. type InitConfiguration struct { metav1.TypeMeta - // `kubeadm init`-only information. These fields are solely used the first time `kubeadm init` runs. - // After that, the information in the fields ARE NOT uploaded to the `kubeadm-config` ConfigMap - // that is used by `kubeadm upgrade` for instance. + // 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 in the external variant of these API types. Here, in the internal version `json:",inline"` is used, which means + // that all of ClusterConfiguration's fields will appear as they would be InitConfiguration's fields. This is used in practice solely + // in kubeadm API roundtrip unit testing. Check out `cmd/kubeadm/app/util/config/*_test.go` for more information. Normally, the internal + // type is NEVER marshalled, but always converted to some external version first. + ClusterConfiguration `json:",inline"` // BootstrapTokens is respected at `kubeadm init` time and describes a set of Bootstrap Tokens to create. - // This information IS NOT uploaded to the kubeadm cluster configmap, partly because of its sensitive nature BootstrapTokens []BootstrapToken // NodeRegistration holds fields that relate to registering the new master node to the cluster NodeRegistration NodeRegistrationOptions +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterConfiguration contains cluster-wide configuration for a kubeadm cluster +type ClusterConfiguration struct { + metav1.TypeMeta // ComponentConfigs holds internal ComponentConfig struct types known to kubeadm, should long-term only exist in the internal kubeadm API // +k8s:conversion-gen=false ComponentConfigs ComponentConfigs - // Cluster-wide configuration - // TODO: Move these fields under some kind of ClusterConfiguration or similar struct that describes - // one cluster. Eventually we want this kind of spec to align well with the Cluster API spec. - // API holds configuration for the k8s apiserver. API API // Etcd holds configuration for etcd. @@ -254,7 +262,6 @@ type ExternalEtcd struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // JoinConfiguration contains elements describing a particular node. -// TODO: This struct should be replaced by dynamic kubelet configuration. type JoinConfiguration struct { metav1.TypeMeta diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go index ccf5bc336655c..bd48348752628 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go @@ -17,6 +17,8 @@ limitations under the License. package v1alpha2 import ( + "unsafe" + "k8s.io/apimachinery/pkg/conversion" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs" @@ -50,6 +52,31 @@ func Convert_v1alpha2_InitConfiguration_To_kubeadm_InitConfiguration(in *InitCon } } + if err := Convert_v1alpha2_API_To_kubeadm_API(&in.API, &out.ClusterConfiguration.API, s); err != nil { + return err + } + if err := Convert_v1alpha2_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.ClusterConfiguration.Etcd, s); err != nil { + return err + } + if err := Convert_v1alpha2_Networking_To_kubeadm_Networking(&in.Networking, &out.ClusterConfiguration.Networking, s); err != nil { + return err + } + out.ClusterConfiguration.KubernetesVersion = in.KubernetesVersion + out.ClusterConfiguration.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) + out.ClusterConfiguration.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) + out.ClusterConfiguration.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) + out.ClusterConfiguration.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) + out.ClusterConfiguration.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) + out.ClusterConfiguration.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) + out.ClusterConfiguration.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + out.ClusterConfiguration.CertificatesDir = in.CertificatesDir + out.ClusterConfiguration.ImageRepository = in.ImageRepository + out.ClusterConfiguration.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage + if err := Convert_v1alpha2_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.ClusterConfiguration.AuditPolicyConfiguration, s); err != nil { + return err + } + out.ClusterConfiguration.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) + out.ClusterConfiguration.ClusterName = in.ClusterName return nil } @@ -76,5 +103,60 @@ func Convert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(in *kubeadm return err } } + + if err := Convert_kubeadm_API_To_v1alpha2_API(&in.ClusterConfiguration.API, &out.API, s); err != nil { + return err + } + if err := Convert_kubeadm_Etcd_To_v1alpha2_Etcd(&in.ClusterConfiguration.Etcd, &out.Etcd, s); err != nil { + return err + } + if err := Convert_kubeadm_Networking_To_v1alpha2_Networking(&in.ClusterConfiguration.Networking, &out.Networking, s); err != nil { + return err + } + out.KubernetesVersion = in.ClusterConfiguration.KubernetesVersion + out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ClusterConfiguration.APIServerExtraArgs)) + out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ClusterConfiguration.ControllerManagerExtraArgs)) + out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ClusterConfiguration.SchedulerExtraArgs)) + out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ClusterConfiguration.APIServerExtraVolumes)) + out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ClusterConfiguration.ControllerManagerExtraVolumes)) + out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ClusterConfiguration.SchedulerExtraVolumes)) + out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ClusterConfiguration.APIServerCertSANs)) + out.CertificatesDir = in.ClusterConfiguration.CertificatesDir + out.ImageRepository = in.ClusterConfiguration.ImageRepository + out.UnifiedControlPlaneImage = in.ClusterConfiguration.UnifiedControlPlaneImage + if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha2_AuditPolicyConfiguration(&in.ClusterConfiguration.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { + return err + } + out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.ClusterConfiguration.FeatureGates)) + out.ClusterName = in.ClusterConfiguration.ClusterName + return nil } +/* + if err := Convert_v1alpha2_API_To_kubeadm_API(&in.API, &out.ClusterConfiguration.API, s); err != nil { + return err + } + if err := Convert_v1alpha2_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.ClusterConfiguration.Etcd, s); err != nil { + return err + } + if err := Convert_v1alpha2_Networking_To_kubeadm_Networking(&in.Networking, &out.ClusterConfiguration.Networking, s); err != nil { + return err + } + out.ClusterConfiguration.KubernetesVersion = in.KubernetesVersion + out.ClusterConfiguration.APIServerExtraArgs = in.APIServerExtraArgs + out.ClusterConfiguration.ControllerManagerExtraArgs = in.ControllerManagerExtraArgs + out.ClusterConfiguration.SchedulerExtraArgs = in.SchedulerExtraArgs + out.ClusterConfiguration.APIServerExtraVolumes = in.APIServerExtraVolumes + out.ClusterConfiguration.ControllerManagerExtraVolumes = in.ControllerManagerExtraVolumes + out.ClusterConfiguration.SchedulerExtraVolumes = in.SchedulerExtraVolumes + out.ClusterConfiguration.APIServerCertSANs = in.APIServerCertSANs + out.ClusterConfiguration.CertificatesDir = in.CertificatesDir + out.ClusterConfiguration.ImageRepository = in.ImageRepository + out.ClusterConfiguration.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage + if err := Convert_v1alpha2_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.ClusterConfiguration.AuditPolicyConfiguration, s); err != nil { + return err + } + out.ClusterConfiguration.FeatureGates = in.FeatureGates + out.ClusterConfiguration.ClusterName = in.ClusterName + +*/ \ No newline at end of file diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go index e1ec3eb791694..babd4367b3619 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go @@ -28,8 +28,8 @@ import ( kubeproxyconfigv1alpha1 "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig/v1alpha1" ) -func Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { - if err := autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s); err != nil { +func Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *ClusterConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error { + if err := autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in, out, s); err != nil { return err } @@ -60,7 +60,7 @@ func Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitCon return nil } -func defaultKubeProxyConfiguration(internalcfg *InitConfiguration, obj *kubeproxyconfig.KubeProxyConfiguration) { +func defaultKubeProxyConfiguration(internalcfg *ClusterConfiguration, obj *kubeproxyconfig.KubeProxyConfiguration) { // NOTE: This code should be mirrored from cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go and cmd/kubeadm/app/componentconfig/defaults.go if obj.ClusterCIDR == "" && internalcfg.Networking.PodSubnet != "" { obj.ClusterCIDR = internalcfg.Networking.PodSubnet @@ -71,7 +71,7 @@ func defaultKubeProxyConfiguration(internalcfg *InitConfiguration, obj *kubeprox } } -func defaultKubeletConfiguration(internalcfg *InitConfiguration, obj *kubeletconfig.KubeletConfiguration) { +func defaultKubeletConfiguration(internalcfg *ClusterConfiguration, obj *kubeletconfig.KubeletConfiguration) { // NOTE: This code should be mirrored from cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go and cmd/kubeadm/app/componentconfig/defaults.go if obj.StaticPodPath == "" { obj.StaticPodPath = DefaultManifestsDir diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults.go index 9faa837795383..63381b9118e3a 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/defaults.go @@ -67,8 +67,15 @@ func addDefaultingFuncs(scheme *runtime.Scheme) error { return RegisterDefaults(scheme) } -// SetDefaults_InitConfiguration assigns default values to Master node +// SetDefaults_InitConfiguration assigns default values for the InitConfiguration func SetDefaults_InitConfiguration(obj *InitConfiguration) { + SetDefaults_ClusterConfiguration(&obj.ClusterConfiguration) + SetDefaults_NodeRegistrationOptions(&obj.NodeRegistration) + SetDefaults_BootstrapTokens(obj) +} + +// SetDefaults_ClusterConfiguration assigns default values for the ClusterConfiguration +func SetDefaults_ClusterConfiguration(obj *ClusterConfiguration) { if obj.KubernetesVersion == "" { obj.KubernetesVersion = DefaultKubernetesVersion } @@ -97,14 +104,12 @@ func SetDefaults_InitConfiguration(obj *InitConfiguration) { obj.ClusterName = DefaultClusterName } - SetDefaults_NodeRegistrationOptions(&obj.NodeRegistration) - SetDefaults_BootstrapTokens(obj) SetDefaults_Etcd(obj) SetDefaults_AuditPolicyConfiguration(obj) } // SetDefaults_Etcd assigns default values for the Proxy -func SetDefaults_Etcd(obj *InitConfiguration) { +func SetDefaults_Etcd(obj *ClusterConfiguration) { if obj.Etcd.External == nil && obj.Etcd.Local == nil { obj.Etcd.Local = &LocalEtcd{} } @@ -152,7 +157,7 @@ func SetDefaults_NodeRegistrationOptions(obj *NodeRegistrationOptions) { } // SetDefaults_AuditPolicyConfiguration sets default values for the AuditPolicyConfiguration -func SetDefaults_AuditPolicyConfiguration(obj *InitConfiguration) { +func SetDefaults_AuditPolicyConfiguration(obj *ClusterConfiguration) { if obj.AuditPolicyConfiguration.LogDir == "" { obj.AuditPolicyConfiguration.LogDir = constants.StaticPodAuditPolicyLogDir } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/register.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/register.go index dd8c4d6279315..0ecc9977ec8df 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/register.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/register.go @@ -59,6 +59,7 @@ func Resource(resource string) schema.GroupResource { func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &InitConfiguration{}, + &ClusterConfiguration{}, &JoinConfiguration{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go index 39d072b794641..82242126a698c 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/types.go @@ -23,11 +23,17 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// InitConfiguration contains a list of elements which make up master's -// configuration object. +// InitConfiguration contains a list of elements that is specific "kubeadm init"-only runtime +// information. 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 ARE NOT uploaded to the `kubeadm-config` ConfigMap // that is used by `kubeadm upgrade` for instance. These fields must be omitempty. @@ -38,10 +44,13 @@ type InitConfiguration struct { // NodeRegistration holds fields that relate to registering the new master node to the cluster NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"` +} - // Cluster-wide configuration - // TODO: Move these fields under some kind of ClusterConfiguration or similar struct that describes - // one cluster. Eventually we want this kind of spec to align well with the Cluster API spec. +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterConfiguration contains cluster-wide configuration for a kubeadm cluster +type ClusterConfiguration struct { + metav1.TypeMeta `json:",inline"` // API holds configuration for the k8s apiserver. API API `json:"api"` diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go index bd2aee684e5c1..c2933ff1fb091 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/validation.go +++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation.go @@ -41,14 +41,21 @@ import ( "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" ) -// ValidateInitConfiguration validates master configuration and collects all encountered errors +// ValidateInitConfiguration validates an InitConfiguration object and collects all encountered errors func ValidateInitConfiguration(c *kubeadm.InitConfiguration) field.ErrorList { + allErrs := field.ErrorList{} + allErrs = append(allErrs, ValidateNodeRegistrationOptions(&c.NodeRegistration, field.NewPath("nodeRegistration"))...) + allErrs = append(allErrs, ValidateBootstrapTokens(c.BootstrapTokens, field.NewPath("bootstrapTokens"))...) + allErrs = append(allErrs, ValidateClusterConfiguration(&c.ClusterConfiguration)...) + return allErrs +} + +// ValidateClusterConfiguration validates an ClusterConfiguration object and collects all encountered errors +func ValidateClusterConfiguration(c *kubeadm.ClusterConfiguration) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...) allErrs = append(allErrs, ValidateCertSANs(c.APIServerCertSANs, field.NewPath("apiServerCertSANs"))...) allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificatesDir"))...) - allErrs = append(allErrs, ValidateNodeRegistrationOptions(&c.NodeRegistration, field.NewPath("nodeRegistration"))...) - allErrs = append(allErrs, ValidateBootstrapTokens(c.BootstrapTokens, field.NewPath("bootstrapTokens"))...) allErrs = append(allErrs, ValidateFeatureGates(c.FeatureGates, field.NewPath("featureGates"))...) allErrs = append(allErrs, ValidateAPIEndpoint(&c.API, field.NewPath("api"))...) allErrs = append(allErrs, ValidateEtcd(&c.Etcd, field.NewPath("etcd"))...) diff --git a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go index 412dcbaec7522..aef7ec03ba074 100644 --- a/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go @@ -232,10 +232,12 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Valid DNS ControlPlaneEndpoint (with port), AdvertiseAddress and default port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "cp.k8s.io:8081", - AdvertiseAddress: "4.5.6.7", - BindPort: 6443, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "cp.k8s.io:8081", + AdvertiseAddress: "4.5.6.7", + BindPort: 6443, + }, }, }, expected: true, @@ -243,10 +245,12 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Valid IPv4 ControlPlaneEndpoint (with port), AdvertiseAddress and default port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1.2.3.4:8081", - AdvertiseAddress: "4.5.6.7", - BindPort: 6443, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "1.2.3.4:8081", + AdvertiseAddress: "4.5.6.7", + BindPort: 6443, + }, }, }, expected: true, @@ -254,10 +258,12 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Valid IPv6 ControlPlaneEndpoint (with port), ControlPlaneEndpoint and port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "[2001:db7::1]:8081", - AdvertiseAddress: "2001:db7::2", - BindPort: 6443, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "[2001:db7::1]:8081", + AdvertiseAddress: "2001:db7::2", + BindPort: 6443, + }, }, }, expected: true, @@ -265,10 +271,12 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Valid DNS ControlPlaneEndpoint (without port), AdvertiseAddress and default port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "cp.k8s.io", - AdvertiseAddress: "4.5.6.7", - BindPort: 6443, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "cp.k8s.io", + AdvertiseAddress: "4.5.6.7", + BindPort: 6443, + }, }, }, expected: true, @@ -276,10 +284,12 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Valid IPv4 ControlPlaneEndpoint (without port), AdvertiseAddress and default port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1.2.3.4", - AdvertiseAddress: "4.5.6.7", - BindPort: 6443, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "1.2.3.4", + AdvertiseAddress: "4.5.6.7", + BindPort: 6443, + }, }, }, expected: true, @@ -287,10 +297,12 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Valid IPv6 ControlPlaneEndpoint (without port), ControlPlaneEndpoint and port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "2001:db7::1", - AdvertiseAddress: "2001:db7::2", - BindPort: 6443, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "2001:db7::1", + AdvertiseAddress: "2001:db7::2", + BindPort: 6443, + }, }, }, expected: true, @@ -298,9 +310,11 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Valid IPv4 AdvertiseAddress and default port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, + }, }, }, expected: true, @@ -308,9 +322,11 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Valid IPv6 AdvertiseAddress and port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "2001:db7::1", - BindPort: 3446, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "2001:db7::1", + BindPort: 3446, + }, }, }, expected: true, @@ -318,9 +334,11 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Invalid IPv4 AdvertiseAddress", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.34", - BindPort: 6443, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1.2.34", + BindPort: 6443, + }, }, }, expected: false, @@ -328,9 +346,11 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Invalid IPv6 AdvertiseAddress", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "2001:db7:1", - BindPort: 3446, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "2001:db7:1", + BindPort: 3446, + }, }, }, expected: false, @@ -338,9 +358,11 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Invalid BindPort", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 0, + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 0, + }, }, }, expected: false, @@ -348,8 +370,10 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Invalid DNS ControlPlaneEndpoint", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "bad!!.k8s.io", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "bad!!.k8s.io", + }, }, }, expected: false, @@ -357,8 +381,10 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Invalid ipv4 ControlPlaneEndpoint", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1..3.4", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "1..3.4", + }, }, }, expected: false, @@ -366,8 +392,10 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Invalid ipv6 ControlPlaneEndpoint", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "1200::AB00:1234::2552:7777:1313", + }, }, }, expected: false, @@ -375,8 +403,10 @@ func TestValidateAPIEndpoint(t *testing.T) { { name: "Invalid ControlPlaneEndpoint port", s: &kubeadm.InitConfiguration{ - API: kubeadm.API{ - ControlPlaneEndpoint: "1.2.3.4:0", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + ControlPlaneEndpoint: "1.2.3.4:0", + }, }, }, expected: false, @@ -406,143 +436,155 @@ func TestValidateInitConfiguration(t *testing.T) { &kubeadm.InitConfiguration{}, false}, {"invalid missing token with IPv4 service subnet", &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - Networking: kubeadm.Networking{ - ServiceSubnet: "10.96.0.1/12", - DNSDomain: "cluster.local", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, + }, + Networking: kubeadm.Networking{ + ServiceSubnet: "10.96.0.1/12", + DNSDomain: "cluster.local", + }, + CertificatesDir: "/some/cert/dir", }, - CertificatesDir: "/some/cert/dir", NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"}, }, false}, {"invalid missing token with IPv6 service subnet", &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - Networking: kubeadm.Networking{ - ServiceSubnet: "2001:db8::1/98", - DNSDomain: "cluster.local", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, + }, + Networking: kubeadm.Networking{ + ServiceSubnet: "2001:db8::1/98", + DNSDomain: "cluster.local", + }, + CertificatesDir: "/some/cert/dir", }, - CertificatesDir: "/some/cert/dir", NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"}, }, false}, {"invalid missing node name", &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - Networking: kubeadm.Networking{ - ServiceSubnet: "10.96.0.1/12", - DNSDomain: "cluster.local", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, + }, + Networking: kubeadm.Networking{ + ServiceSubnet: "10.96.0.1/12", + DNSDomain: "cluster.local", + }, + CertificatesDir: "/some/other/cert/dir", }, - CertificatesDir: "/some/other/cert/dir", }, false}, {"valid master configuration with incorrect IPv4 pod subnet", &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - Networking: kubeadm.Networking{ - ServiceSubnet: "10.96.0.1/12", - DNSDomain: "cluster.local", - PodSubnet: "10.0.1.15", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, + }, + Networking: kubeadm.Networking{ + ServiceSubnet: "10.96.0.1/12", + DNSDomain: "cluster.local", + PodSubnet: "10.0.1.15", + }, + CertificatesDir: "/some/other/cert/dir", }, - CertificatesDir: "/some/other/cert/dir", NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"}, }, false}, {"valid master configuration with IPv4 service subnet", &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - Etcd: kubeadm.Etcd{ - Local: &kubeadm.LocalEtcd{ - DataDir: "/some/path", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, }, - }, - ComponentConfigs: kubeadm.ComponentConfigs{ - KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ - BindAddress: "192.168.59.103", - HealthzBindAddress: "0.0.0.0:10256", - MetricsBindAddress: "127.0.0.1:10249", - ClusterCIDR: "192.168.59.0/24", - UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, - ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, - IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ - MasqueradeAll: true, - SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, - MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, - }, - IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{ - SyncPeriod: metav1.Duration{Duration: 10 * time.Second}, - MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second}, + Etcd: kubeadm.Etcd{ + Local: &kubeadm.LocalEtcd{ + DataDir: "/some/path", }, - Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ - Max: utilpointer.Int32Ptr(2), - MaxPerCore: utilpointer.Int32Ptr(1), - Min: utilpointer.Int32Ptr(1), - TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, - TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, + }, + ComponentConfigs: kubeadm.ComponentConfigs{ + KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ + BindAddress: "192.168.59.103", + HealthzBindAddress: "0.0.0.0:10256", + MetricsBindAddress: "127.0.0.1:10249", + ClusterCIDR: "192.168.59.0/24", + UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, + ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, + IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ + MasqueradeAll: true, + SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, + MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, + }, + IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{ + SyncPeriod: metav1.Duration{Duration: 10 * time.Second}, + MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second}, + }, + Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ + Max: utilpointer.Int32Ptr(2), + MaxPerCore: utilpointer.Int32Ptr(1), + Min: utilpointer.Int32Ptr(1), + TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, + TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, + }, }, }, + Networking: kubeadm.Networking{ + ServiceSubnet: "10.96.0.1/12", + DNSDomain: "cluster.local", + PodSubnet: "10.0.1.15/16", + }, + CertificatesDir: "/some/other/cert/dir", }, - Networking: kubeadm.Networking{ - ServiceSubnet: "10.96.0.1/12", - DNSDomain: "cluster.local", - PodSubnet: "10.0.1.15/16", - }, - CertificatesDir: "/some/other/cert/dir", NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"}, }, true}, {"valid master configuration using IPv6 service subnet", &kubeadm.InitConfiguration{ - API: kubeadm.API{ - AdvertiseAddress: "1:2:3::4", - BindPort: 3446, - }, - Etcd: kubeadm.Etcd{ - Local: &kubeadm.LocalEtcd{ - DataDir: "/some/path", + ClusterConfiguration: kubeadm.ClusterConfiguration{ + API: kubeadm.API{ + AdvertiseAddress: "1:2:3::4", + BindPort: 3446, }, - }, - ComponentConfigs: kubeadm.ComponentConfigs{ - KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ - BindAddress: "192.168.59.103", - HealthzBindAddress: "0.0.0.0:10256", - MetricsBindAddress: "127.0.0.1:10249", - ClusterCIDR: "192.168.59.0/24", - UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, - ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, - IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ - MasqueradeAll: true, - SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, - MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, + Etcd: kubeadm.Etcd{ + Local: &kubeadm.LocalEtcd{ + DataDir: "/some/path", }, - IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{ - SyncPeriod: metav1.Duration{Duration: 10 * time.Second}, - MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second}, - }, - Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ - Max: utilpointer.Int32Ptr(2), - MaxPerCore: utilpointer.Int32Ptr(1), - Min: utilpointer.Int32Ptr(1), - TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, - TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, + }, + ComponentConfigs: kubeadm.ComponentConfigs{ + KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ + BindAddress: "192.168.59.103", + HealthzBindAddress: "0.0.0.0:10256", + MetricsBindAddress: "127.0.0.1:10249", + ClusterCIDR: "192.168.59.0/24", + UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, + ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, + IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ + MasqueradeAll: true, + SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, + MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, + }, + IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{ + SyncPeriod: metav1.Duration{Duration: 10 * time.Second}, + MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second}, + }, + Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ + Max: utilpointer.Int32Ptr(2), + MaxPerCore: utilpointer.Int32Ptr(1), + Min: utilpointer.Int32Ptr(1), + TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, + TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, + }, }, }, + Networking: kubeadm.Networking{ + ServiceSubnet: "2001:db8::1/98", + DNSDomain: "cluster.local", + }, + CertificatesDir: "/some/other/cert/dir", }, - Networking: kubeadm.Networking{ - ServiceSubnet: "2001:db8::1/98", - DNSDomain: "cluster.local", - }, - CertificatesDir: "/some/other/cert/dir", NodeRegistration: kubeadm.NodeRegistrationOptions{Name: nodename, CRISocket: "/some/path"}, }, true}, } diff --git a/cmd/kubeadm/app/cmd/config.go b/cmd/kubeadm/app/cmd/config.go index bc645afb84bb6..d3280e0cb1f0d 100644 --- a/cmd/kubeadm/app/cmd/config.go +++ b/cmd/kubeadm/app/cmd/config.go @@ -126,7 +126,10 @@ func NewCmdConfigPrintDefault(out io.Writer) *cobra.Command { func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) { switch apiObject { case constants.InitConfigurationKind, constants.MasterConfigurationKind: - return getDefaultInitConfigBytes() + return getDefaultInitConfigBytes(constants.InitConfigurationKind) + + case constants.ClusterConfigurationKind: + return getDefaultInitConfigBytes(constants.ClusterConfigurationKind) case constants.JoinConfigurationKind, constants.NodeConfigurationKind: return getDefaultNodeConfigBytes() @@ -143,7 +146,7 @@ func getDefaultAPIObjectBytes(apiObject string) ([]byte, error) { // getSupportedAPIObjects returns all currently supported API object names func getSupportedAPIObjects() []string { - objects := []string{constants.InitConfigurationKind, constants.JoinConfigurationKind} + objects := []string{constants.InitConfigurationKind, constants.ClusterConfigurationKind, constants.JoinConfigurationKind} for componentType := range componentconfigs.Known { objects = append(objects, string(componentType)) } @@ -160,19 +163,31 @@ func getAllAPIObjectNames() []string { func getDefaultedInitConfig() (*kubeadmapi.InitConfiguration, error) { return configutil.ConfigFileAndDefaultsToInternalConfig("", &kubeadmapiv1alpha3.InitConfiguration{ - API: kubeadmapiv1alpha3.API{AdvertiseAddress: "1.2.3.4"}, - BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{sillyToken}, - KubernetesVersion: fmt.Sprintf("v1.%d.0", constants.MinimumControlPlaneVersion.Minor()+1), + // TODO: Probably move to getDefaultedClusterConfig? + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + API: kubeadmapiv1alpha3.API{AdvertiseAddress: "1.2.3.4"}, + KubernetesVersion: fmt.Sprintf("v1.%d.0", constants.MinimumControlPlaneVersion.Minor()+1), + }, + BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{sillyToken}, }) } -func getDefaultInitConfigBytes() ([]byte, error) { +// TODO: This is now invoked for both InitConfiguration and ClusterConfiguration, we should make separate versions of it +func getDefaultInitConfigBytes(kind string) ([]byte, error) { internalcfg, err := getDefaultedInitConfig() if err != nil { return []byte{}, err } - return configutil.MarshalKubeadmConfigObject(internalcfg) + b, err := configutil.MarshalKubeadmConfigObject(internalcfg) + if err != nil { + return []byte{}, err + } + gvkmap, err := kubeadmutil.SplitYAMLDocuments(b) + if err != nil { + return []byte{}, err + } + return gvkmap[kubeadmapiv1alpha3.SchemeGroupVersion.WithKind(kind)], nil } func getDefaultNodeConfigBytes() ([]byte, error) { @@ -194,7 +209,7 @@ func getDefaultComponentConfigBytes(registration componentconfigs.Registration) return []byte{}, err } - realobj, ok := registration.GetFromInternalConfig(defaultedInitConfig) + realobj, ok := registration.GetFromInternalConfig(&defaultedInitConfig.ClusterConfiguration) if !ok { return []byte{}, fmt.Errorf("GetFromInternalConfig failed") } @@ -404,8 +419,8 @@ func NewCmdConfigImages(out io.Writer) *cobra.Command { // NewCmdConfigImagesPull returns the `kubeadm config images pull` command func NewCmdConfigImagesPull() *cobra.Command { - cfg := &kubeadmapiv1alpha3.InitConfiguration{} - kubeadmscheme.Scheme.Default(cfg) + externalcfg := &kubeadmapiv1alpha3.InitConfiguration{} + kubeadmscheme.Scheme.Default(externalcfg) var cfgPath, featureGatesString string var err error @@ -413,9 +428,9 @@ func NewCmdConfigImagesPull() *cobra.Command { Use: "pull", Short: "Pull images used by kubeadm.", Run: func(_ *cobra.Command, _ []string) { - cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString) + externalcfg.ClusterConfiguration.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString) kubeadmutil.CheckErr(err) - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) + internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, externalcfg) kubeadmutil.CheckErr(err) containerRuntime, err := utilruntime.NewContainerRuntime(utilsexec.New(), internalcfg.GetCRISocket()) kubeadmutil.CheckErr(err) @@ -423,8 +438,8 @@ func NewCmdConfigImagesPull() *cobra.Command { kubeadmutil.CheckErr(imagesPull.PullAll()) }, } - AddImagesCommonConfigFlags(cmd.PersistentFlags(), cfg, &cfgPath, &featureGatesString) - AddImagesPullFlags(cmd.PersistentFlags(), cfg) + AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalcfg, &cfgPath, &featureGatesString) + AddImagesPullFlags(cmd.PersistentFlags(), externalcfg) return cmd } @@ -456,42 +471,41 @@ func (ip *ImagesPull) PullAll() error { // NewCmdConfigImagesList returns the "kubeadm config images list" command func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Command { - cfg := &kubeadmapiv1alpha3.InitConfiguration{} - kubeadmscheme.Scheme.Default(cfg) + externalcfg := &kubeadmapiv1alpha3.InitConfiguration{} + kubeadmscheme.Scheme.Default(externalcfg) var cfgPath, featureGatesString string var err error // This just sets the kubernetes version for unit testing so kubeadm won't try to // lookup the latest release from the internet. if mockK8sVersion != nil { - cfg.KubernetesVersion = *mockK8sVersion + externalcfg.KubernetesVersion = *mockK8sVersion } cmd := &cobra.Command{ 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) { - cfg.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString) + externalcfg.ClusterConfiguration.FeatureGates, err = features.NewFeatureGate(&features.InitFeatureGates, featureGatesString) kubeadmutil.CheckErr(err) - imagesList, err := NewImagesList(cfgPath, cfg) + imagesList, err := NewImagesList(cfgPath, externalcfg) kubeadmutil.CheckErr(err) kubeadmutil.CheckErr(imagesList.Run(out)) }, } - AddImagesCommonConfigFlags(cmd.PersistentFlags(), cfg, &cfgPath, &featureGatesString) - + AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalcfg, &cfgPath, &featureGatesString) return cmd } // NewImagesList returns the underlying struct for the "kubeadm config images list" command func NewImagesList(cfgPath string, cfg *kubeadmapiv1alpha3.InitConfiguration) (*ImagesList, error) { - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) + initcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg) if err != nil { return nil, fmt.Errorf("could not convert cfg to an internal cfg: %v", err) } return &ImagesList{ - cfg: internalcfg, + cfg: initcfg, }, nil } @@ -513,7 +527,7 @@ 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 *kubeadmapiv1alpha3.InitConfiguration, cfgPath *string, featureGatesString *string) { flagSet.StringVar( - &cfg.KubernetesVersion, "kubernetes-version", cfg.KubernetesVersion, + &cfg.ClusterConfiguration.KubernetesVersion, "kubernetes-version", cfg.ClusterConfiguration.KubernetesVersion, `Choose a specific Kubernetes version for the control plane.`, ) flagSet.StringVar(featureGatesString, "feature-gates", *featureGatesString, "A set of key=value pairs that describe feature gates for various features. "+ diff --git a/cmd/kubeadm/app/cmd/config_test.go b/cmd/kubeadm/app/cmd/config_test.go index b7c97d0a15969..f001e174e973d 100644 --- a/cmd/kubeadm/app/cmd/config_test.go +++ b/cmd/kubeadm/app/cmd/config_test.go @@ -69,7 +69,7 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) { }, configContents: []byte(dedent.Dedent(` apiVersion: kubeadm.k8s.io/v1alpha3 - kind: InitConfiguration + kind: ClusterConfiguration kubernetesVersion: v1.10.1 `)), }, @@ -81,10 +81,10 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) { }, configContents: []byte(dedent.Dedent(` apiVersion: kubeadm.k8s.io/v1alpha3 - kind: InitConfiguration + kind: ClusterConfiguration kubernetesVersion: v1.11.0 featureGates: - CoreDNS: True + CoreDNS: true `)), }, } @@ -98,13 +98,14 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) { defer os.RemoveAll(tmpDir) configFilePath := filepath.Join(tmpDir, "test-config-file") - err = ioutil.WriteFile(configFilePath, tc.configContents, 0644) - if err != nil { + if err := ioutil.WriteFile(configFilePath, tc.configContents, 0644); err != nil { t.Fatalf("Failed writing a config file: %v", err) } i, err := cmd.NewImagesList(configFilePath, &kubeadmapiv1alpha3.InitConfiguration{ - KubernetesVersion: dummyKubernetesVersion, + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + KubernetesVersion: dummyKubernetesVersion, + }, }) if err != nil { t.Fatalf("Failed getting the kubeadm images command: %v", err) @@ -137,28 +138,34 @@ func TestConfigImagesListRunWithoutPath(t *testing.T) { name: "empty config", expectedImages: defaultNumberOfImages, cfg: kubeadmapiv1alpha3.InitConfiguration{ - KubernetesVersion: dummyKubernetesVersion, + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + KubernetesVersion: dummyKubernetesVersion, + }, }, }, { name: "external etcd configuration", cfg: kubeadmapiv1alpha3.InitConfiguration{ - Etcd: kubeadmapiv1alpha3.Etcd{ - External: &kubeadmapiv1alpha3.ExternalEtcd{ - Endpoints: []string{"https://some.etcd.com:2379"}, + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + Etcd: kubeadmapiv1alpha3.Etcd{ + External: &kubeadmapiv1alpha3.ExternalEtcd{ + Endpoints: []string{"https://some.etcd.com:2379"}, + }, }, + KubernetesVersion: dummyKubernetesVersion, }, - KubernetesVersion: dummyKubernetesVersion, }, expectedImages: defaultNumberOfImages - 1, }, { name: "coredns enabled", cfg: kubeadmapiv1alpha3.InitConfiguration{ - FeatureGates: map[string]bool{ - features.CoreDNS: true, + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + FeatureGates: map[string]bool{ + features.CoreDNS: true, + }, + KubernetesVersion: dummyKubernetesVersion, }, - KubernetesVersion: dummyKubernetesVersion, }, expectedImages: defaultNumberOfImages, }, @@ -226,8 +233,9 @@ func TestImagesPull(t *testing.T) { func TestMigrate(t *testing.T) { cfg := []byte(dedent.Dedent(` - apiVersion: kubeadm.k8s.io/v1alpha3 - kind: InitConfiguration + # This is intentionally testing an old API version and the old kind naming and making sure the output is correct + apiVersion: kubeadm.k8s.io/v1alpha2 + kind: MasterConfiguration kubernetesVersion: v1.10.0 `)) configFile, cleanup := tempConfig(t, cfg) @@ -235,13 +243,15 @@ func TestMigrate(t *testing.T) { var output bytes.Buffer command := cmd.NewCmdConfigMigrate(&output) - err := command.Flags().Set("old-config", configFile) - if err != nil { + if err := command.Flags().Set("old-config", configFile); err != nil { t.Fatalf("failed to set old-config flag") } + newConfigPath := filepath.Join(filepath.Dir(configFile), "new-migrated-config") + if err := command.Flags().Set("new-config", newConfigPath); err != nil { + t.Fatalf("failed to set new-config flag") + } command.Run(nil, nil) - _, err = config.BytesToInternalConfig(output.Bytes()) - if err != nil { + if _, err := config.ConfigFileAndDefaultsToInternalConfig(newConfigPath, &kubeadmapiv1alpha3.InitConfiguration{}); err != nil { t.Fatalf("Could not read output back into internal type: %v", err) } } @@ -254,8 +264,7 @@ func tempConfig(t *testing.T, config []byte) (string, func()) { t.Fatalf("Unable to create temporary directory: %v", err) } configFilePath := filepath.Join(tmpDir, "test-config-file") - err = ioutil.WriteFile(configFilePath, config, 0644) - if err != nil { + if err := ioutil.WriteFile(configFilePath, config, 0644); err != nil { os.RemoveAll(tmpDir) t.Fatalf("Failed writing a config file: %v", err) } diff --git a/cmd/kubeadm/app/cmd/phases/certs.go b/cmd/kubeadm/app/cmd/phases/certs.go index 234862b045943..599b156244b2d 100644 --- a/cmd/kubeadm/app/cmd/phases/certs.go +++ b/cmd/kubeadm/app/cmd/phases/certs.go @@ -152,9 +152,11 @@ func makeCmd(certSpec *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv func getSANDescription(certSpec *certsphase.KubeadmCert) string { //Defaulted config we will use to get SAN certs defaultConfig := &kubeadmapiv1alpha3.InitConfiguration{ - API: kubeadmapiv1alpha3.API{ - // GetAPIServerAltNames errors without an AdvertiseAddress; this is as good as any. - AdvertiseAddress: "127.0.0.1", + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + API: kubeadmapiv1alpha3.API{ + // GetAPIServerAltNames errors without an AdvertiseAddress; this is as good as any. + AdvertiseAddress: "127.0.0.1", + }, }, } defaultInternalConfig := &kubeadmapi.InitConfiguration{} diff --git a/cmd/kubeadm/app/cmd/phases/certs_test.go b/cmd/kubeadm/app/cmd/phases/certs_test.go index aa1e00df7ca18..9f6d5fa66859f 100644 --- a/cmd/kubeadm/app/cmd/phases/certs_test.go +++ b/cmd/kubeadm/app/cmd/phases/certs_test.go @@ -259,14 +259,16 @@ func TestSubCmdCertsCreateFilesWithConfigFile(t *testing.T) { for _, test := range tests { t.Run(strings.Join(test.subCmds, ","), func(t *testing.T) { - // Create temp folder for the test case + // Create temp folder for the test case tmpdir := testutil.SetupTempDir(t) defer os.RemoveAll(tmpdir) cfg := &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, - CertificatesDir: tmpdir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + CertificatesDir: tmpdir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, } configPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg) diff --git a/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go b/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go index 3a39a8a0d6d33..e090f888ebe6b 100644 --- a/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go +++ b/cmd/kubeadm/app/cmd/phases/kubeconfig_test.go @@ -277,8 +277,10 @@ func TestKubeConfigSubCommandsThatCreateFilesWithConfigFile(t *testing.T) { // Adds a master configuration file cfg := &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, - CertificatesDir: pkidir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + CertificatesDir: pkidir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, } cfgPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg) diff --git a/cmd/kubeadm/app/cmd/token_test.go b/cmd/kubeadm/app/cmd/token_test.go index 16517e1e331ae..3d8dd15e93f1a 100644 --- a/cmd/kubeadm/app/cmd/token_test.go +++ b/cmd/kubeadm/app/cmd/token_test.go @@ -179,10 +179,11 @@ func TestRunCreateToken(t *testing.T) { } cfg := &kubeadmapiv1alpha3.InitConfiguration{ - - // KubernetesVersion is not used, but we set this explicitly to avoid - // the lookup of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig - KubernetesVersion: "v1.10.0", + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + // KubernetesVersion is not used, but we set this explicitly to avoid + // the lookup of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig + KubernetesVersion: "v1.10.0", + }, BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{ { Token: bts, diff --git a/cmd/kubeadm/app/cmd/upgrade/apply.go b/cmd/kubeadm/app/cmd/upgrade/apply.go index 8669d4e9f4175..2c52a7e90675a 100644 --- a/cmd/kubeadm/app/cmd/upgrade/apply.go +++ b/cmd/kubeadm/app/cmd/upgrade/apply.go @@ -90,6 +90,7 @@ func NewCmdApply(apf *applyPlanFlags) *cobra.Command { // If the version is specified in config file, pick up that value. if flags.cfgPath != "" { glog.V(1).Infof("fetching configuration from file %s", flags.cfgPath) + // Note that cfg isn't preserved here, it's just an one-off to populate flags.newK8sVersionStr based on --config cfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(flags.cfgPath, &kubeadmapiv1alpha3.InitConfiguration{}) kubeadmutil.CheckErr(err) @@ -160,7 +161,7 @@ func RunApply(flags *applyFlags) error { // Validate requested and validate actual version glog.V(1).Infof("[upgrade/apply] validating requested and actual version") - if err := configutil.NormalizeKubernetesVersion(upgradeVars.cfg); err != nil { + if err := configutil.NormalizeKubernetesVersion(&upgradeVars.cfg.ClusterConfiguration); err != nil { return err } diff --git a/cmd/kubeadm/app/cmd/upgrade/apply_test.go b/cmd/kubeadm/app/cmd/upgrade/apply_test.go index 28ac1759bfe2e..80d55ac152978 100644 --- a/cmd/kubeadm/app/cmd/upgrade/apply_test.go +++ b/cmd/kubeadm/app/cmd/upgrade/apply_test.go @@ -154,9 +154,11 @@ func TestSetImplicitFlags(t *testing.T) { func TestGetPathManagerForUpgrade(t *testing.T) { haEtcd := &kubeadmapi.InitConfiguration{ - Etcd: kubeadmapi.Etcd{ - External: &kubeadmapi.ExternalEtcd{ - Endpoints: []string{"10.100.0.1:2379", "10.100.0.2:2379", "10.100.0.3:2379"}, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + Etcd: kubeadmapi.Etcd{ + External: &kubeadmapi.ExternalEtcd{ + Endpoints: []string{"10.100.0.1:2379", "10.100.0.2:2379", "10.100.0.3:2379"}, + }, }, }, } diff --git a/cmd/kubeadm/app/cmd/upgrade/common.go b/cmd/kubeadm/app/cmd/upgrade/common.go index 1f366c44a2ed9..bdc3e466473e8 100644 --- a/cmd/kubeadm/app/cmd/upgrade/common.go +++ b/cmd/kubeadm/app/cmd/upgrade/common.go @@ -95,7 +95,7 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin // If the user told us to print this information out; do it! if flags.printConfig { - printConfiguration(cfg, os.Stdout) + printConfiguration(&cfg.ClusterConfiguration, os.Stdout) } return &upgradeVariables{ @@ -109,13 +109,13 @@ func enforceRequirements(flags *applyPlanFlags, dryRun bool, newK8sVersion strin } // printConfiguration prints the external version of the API to yaml -func printConfiguration(cfg *kubeadmapi.InitConfiguration, w io.Writer) { +func printConfiguration(clustercfg *kubeadmapi.ClusterConfiguration, w io.Writer) { // Short-circuit if cfg is nil, so we can safely get the value of the pointer below - if cfg == nil { + if clustercfg == nil { return } - cfgYaml, err := configutil.MarshalKubeadmConfigObject(cfg) + cfgYaml, err := configutil.MarshalKubeadmConfigObject(clustercfg) if err == nil { fmt.Fprintln(w, "[upgrade/config] Configuration used:") diff --git a/cmd/kubeadm/app/cmd/upgrade/common_test.go b/cmd/kubeadm/app/cmd/upgrade/common_test.go index 236767baf2bb2..fde2b8a82b884 100644 --- a/cmd/kubeadm/app/cmd/upgrade/common_test.go +++ b/cmd/kubeadm/app/cmd/upgrade/common_test.go @@ -25,7 +25,7 @@ import ( func TestPrintConfiguration(t *testing.T) { var tests = []struct { - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration buf *bytes.Buffer expectedBytes []byte }{ @@ -34,7 +34,7 @@ func TestPrintConfiguration(t *testing.T) { expectedBytes: []byte(""), }, { - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ KubernetesVersion: "v1.7.1", Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ @@ -57,18 +57,17 @@ func TestPrintConfiguration(t *testing.T) { dataDir: /some/path image: "" imageRepository: "" - kind: InitConfiguration + kind: ClusterConfiguration kubernetesVersion: v1.7.1 networking: dnsDomain: "" podSubnet: "" serviceSubnet: "" - nodeRegistration: {} unifiedControlPlaneImage: "" `), }, { - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ KubernetesVersion: "v1.7.1", Networking: kubeadmapi.Networking{ ServiceSubnet: "10.96.0.1/12", @@ -97,13 +96,12 @@ func TestPrintConfiguration(t *testing.T) { - https://one-etcd-instance:2379 keyFile: "" imageRepository: "" - kind: InitConfiguration + kind: ClusterConfiguration kubernetesVersion: v1.7.1 networking: dnsDomain: "" podSubnet: "" serviceSubnet: 10.96.0.1/12 - nodeRegistration: {} unifiedControlPlaneImage: "" `), }, diff --git a/cmd/kubeadm/app/componentconfigs/defaults.go b/cmd/kubeadm/app/componentconfigs/defaults.go index 63f1cd5971f46..3efb0d1d5fbe9 100644 --- a/cmd/kubeadm/app/componentconfigs/defaults.go +++ b/cmd/kubeadm/app/componentconfigs/defaults.go @@ -33,7 +33,7 @@ const ( ) // DefaultKubeProxyConfiguration assigns default values for the kube-proxy ComponentConfig -func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.InitConfiguration) { +func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) { // IMPORTANT NOTE: If you're changing this code you should mirror it to cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go // and cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go. TODO: Remove this requirement when v1alpha2 is removed. externalproxycfg := &kubeproxyconfigv1alpha1.KubeProxyConfiguration{} @@ -62,7 +62,7 @@ func DefaultKubeProxyConfiguration(internalcfg *kubeadmapi.InitConfiguration) { } // DefaultKubeletConfiguration assigns default values for the kubelet ComponentConfig -func DefaultKubeletConfiguration(internalcfg *kubeadmapi.InitConfiguration) { +func DefaultKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration) { // IMPORTANT NOTE: If you're changing this code you should mirror it to cmd/kubeadm/app/apis/kubeadm/v1alpha2/defaults.go // and cmd/kubeadm/app/apis/kubeadm/v1alpha3/conversion.go. TODO: Remove this requirement when v1alpha2 is removed. externalkubeletcfg := &kubeletconfigv1beta1.KubeletConfiguration{} diff --git a/cmd/kubeadm/app/componentconfigs/registrations.go b/cmd/kubeadm/app/componentconfigs/registrations.go index 7718d80ba837f..a88b2a4bb8b83 100644 --- a/cmd/kubeadm/app/componentconfigs/registrations.go +++ b/cmd/kubeadm/app/componentconfigs/registrations.go @@ -38,15 +38,15 @@ type Registration struct { // AddToSchemeFuncs are a set of functions that register APIs to the scheme AddToSchemeFuncs []AddToSchemeFunc // DefaulterFunc is a function that based on the internal kubeadm configuration defaults the ComponentConfig struct - DefaulterFunc func(*kubeadmapi.InitConfiguration) + DefaulterFunc func(*kubeadmapi.ClusterConfiguration) // ValidateFunc is a function that should validate the ComponentConfig type embedded in the internal kubeadm config struct - ValidateFunc func(*kubeadmapi.InitConfiguration, *field.Path) field.ErrorList + ValidateFunc func(*kubeadmapi.ClusterConfiguration, *field.Path) field.ErrorList // EmptyValue holds a pointer to an empty struct of the internal ComponentConfig type EmptyValue runtime.Object // GetFromInternalConfig returns the pointer to the ComponentConfig API object from the internal kubeadm config struct - GetFromInternalConfig func(*kubeadmapi.InitConfiguration) (runtime.Object, bool) + GetFromInternalConfig func(*kubeadmapi.ClusterConfiguration) (runtime.Object, bool) // SetToInternalConfig sets the pointer to a ComponentConfig API object embedded in the internal kubeadm config struct - SetToInternalConfig func(runtime.Object, *kubeadmapi.InitConfiguration) bool + SetToInternalConfig func(runtime.Object, *kubeadmapi.ClusterConfiguration) bool } // Marshal marshals obj to bytes for the current Registration @@ -89,10 +89,10 @@ var Known Registrations = map[RegistrationKind]Registration{ DefaulterFunc: DefaultKubeProxyConfiguration, ValidateFunc: ValidateKubeProxyConfiguration, EmptyValue: &kubeproxyconfig.KubeProxyConfiguration{}, - GetFromInternalConfig: func(cfg *kubeadmapi.InitConfiguration) (runtime.Object, bool) { + GetFromInternalConfig: func(cfg *kubeadmapi.ClusterConfiguration) (runtime.Object, bool) { return cfg.ComponentConfigs.KubeProxy, cfg.ComponentConfigs.KubeProxy != nil }, - SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.InitConfiguration) bool { + SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.ClusterConfiguration) bool { kubeproxyConfig, ok := obj.(*kubeproxyconfig.KubeProxyConfiguration) if ok { cfg.ComponentConfigs.KubeProxy = kubeproxyConfig @@ -106,10 +106,10 @@ var Known Registrations = map[RegistrationKind]Registration{ DefaulterFunc: DefaultKubeletConfiguration, ValidateFunc: ValidateKubeletConfiguration, EmptyValue: &kubeletconfig.KubeletConfiguration{}, - GetFromInternalConfig: func(cfg *kubeadmapi.InitConfiguration) (runtime.Object, bool) { + GetFromInternalConfig: func(cfg *kubeadmapi.ClusterConfiguration) (runtime.Object, bool) { return cfg.ComponentConfigs.Kubelet, cfg.ComponentConfigs.Kubelet != nil }, - SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.InitConfiguration) bool { + SetToInternalConfig: func(obj runtime.Object, cfg *kubeadmapi.ClusterConfiguration) bool { kubeletConfig, ok := obj.(*kubeletconfig.KubeletConfiguration) if ok { cfg.ComponentConfigs.Kubelet = kubeletConfig @@ -132,14 +132,14 @@ func (rs *Registrations) AddToScheme(scheme *runtime.Scheme) error { } // Default applies to the ComponentConfig defaults to the internal kubeadm API type -func (rs *Registrations) Default(internalcfg *kubeadmapi.InitConfiguration) { +func (rs *Registrations) Default(internalcfg *kubeadmapi.ClusterConfiguration) { for _, registration := range *rs { registration.DefaulterFunc(internalcfg) } } // Validate validates the ComponentConfig parts of the internal kubeadm API type -func (rs *Registrations) Validate(internalcfg *kubeadmapi.InitConfiguration) field.ErrorList { +func (rs *Registrations) Validate(internalcfg *kubeadmapi.ClusterConfiguration) field.ErrorList { allErrs := field.ErrorList{} for kind, registration := range *rs { allErrs = append(allErrs, registration.ValidateFunc(internalcfg, field.NewPath(string(kind)))...) diff --git a/cmd/kubeadm/app/componentconfigs/validation.go b/cmd/kubeadm/app/componentconfigs/validation.go index 2aa508a896237..8794a523dc6f7 100644 --- a/cmd/kubeadm/app/componentconfigs/validation.go +++ b/cmd/kubeadm/app/componentconfigs/validation.go @@ -24,7 +24,7 @@ import ( ) // ValidateKubeProxyConfiguration validates proxy configuration and collects all encountered errors -func ValidateKubeProxyConfiguration(internalcfg *kubeadmapi.InitConfiguration, _ *field.Path) field.ErrorList { +func ValidateKubeProxyConfiguration(internalcfg *kubeadmapi.ClusterConfiguration, _ *field.Path) field.ErrorList { allErrs := field.ErrorList{} if internalcfg.ComponentConfigs.KubeProxy == nil { return allErrs @@ -33,7 +33,7 @@ func ValidateKubeProxyConfiguration(internalcfg *kubeadmapi.InitConfiguration, _ } // ValidateKubeletConfiguration validates kubelet configuration and collects all encountered errors -func ValidateKubeletConfiguration(internalcfg *kubeadmapi.InitConfiguration, fldPath *field.Path) field.ErrorList { +func ValidateKubeletConfiguration(internalcfg *kubeadmapi.ClusterConfiguration, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if internalcfg.ComponentConfigs.Kubelet == nil { return allErrs diff --git a/cmd/kubeadm/app/componentconfigs/validation_test.go b/cmd/kubeadm/app/componentconfigs/validation_test.go index e57766bb567f9..900fed8c22469 100644 --- a/cmd/kubeadm/app/componentconfigs/validation_test.go +++ b/cmd/kubeadm/app/componentconfigs/validation_test.go @@ -31,12 +31,12 @@ import ( func TestValidateKubeProxyConfiguration(t *testing.T) { var tests = []struct { - masterConfig *kubeadm.InitConfiguration - msg string - expectErr bool + clusterConfig *kubeadm.ClusterConfiguration + msg string + expectErr bool }{ { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ BindAddress: "192.168.59.103", @@ -67,7 +67,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { expectErr: false, }, { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ // only BindAddress is invalid @@ -100,7 +100,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { expectErr: true, }, { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", @@ -133,7 +133,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { expectErr: true, }, { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", @@ -166,7 +166,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { expectErr: true, }, { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", @@ -199,7 +199,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { expectErr: true, }, { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", @@ -232,7 +232,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { expectErr: true, }, { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ KubeProxy: &kubeproxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", @@ -266,7 +266,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { }, } for i, rt := range tests { - err := ValidateKubeProxyConfiguration(rt.masterConfig, nil).ToAggregate() + err := ValidateKubeProxyConfiguration(rt.clusterConfig, nil).ToAggregate() if (err != nil) != rt.expectErr { t.Errorf("%d failed ValidateKubeProxyConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil) } @@ -278,11 +278,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { func TestValidateKubeletConfiguration(t *testing.T) { var tests = []struct { - masterConfig *kubeadm.InitConfiguration - expectErr bool + clusterConfig *kubeadm.ClusterConfiguration + expectErr bool }{ { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ Kubelet: &kubeletconfig.KubeletConfiguration{ CgroupsPerQOS: true, @@ -313,7 +313,7 @@ func TestValidateKubeletConfiguration(t *testing.T) { expectErr: false, }, { - masterConfig: &kubeadm.InitConfiguration{ + clusterConfig: &kubeadm.ClusterConfiguration{ ComponentConfigs: kubeadm.ComponentConfigs{ Kubelet: &kubeletconfig.KubeletConfiguration{ CgroupsPerQOS: false, @@ -344,7 +344,7 @@ func TestValidateKubeletConfiguration(t *testing.T) { }, } for i, rt := range tests { - err := ValidateKubeletConfiguration(rt.masterConfig, nil).ToAggregate() + err := ValidateKubeletConfiguration(rt.clusterConfig, nil).ToAggregate() if (err != nil) != rt.expectErr { t.Errorf("%d failed ValidateKubeletConfiguration: expected error %t, got error %t", i, rt.expectErr, err != nil) } diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go index f3bd49a29fed2..7dc5f472df010 100644 --- a/cmd/kubeadm/app/constants/constants.go +++ b/cmd/kubeadm/app/constants/constants.go @@ -187,9 +187,12 @@ const ( AnnotationKubeadmCRISocket = "kubeadm.alpha.kubernetes.io/cri-socket" // InitConfigurationConfigMap specifies in what ConfigMap in the kube-system namespace the `kubeadm init` configuration should be stored + // TODO: Rename this to ClusterConfigurationConfigMap InitConfigurationConfigMap = "kubeadm-config" // InitConfigurationConfigMapKey specifies in what ConfigMap key the master configuration should be stored + // TODO: Rename this to ClusterConfigurationConfigMapKey, and migrate the value to ClusterConfiguration, + // but still support the old MasterConfiguration naming in earlier versions InitConfigurationConfigMapKey = "InitConfiguration" // KubeletBaseConfigurationConfigMapPrefix specifies in what ConfigMap in the kube-system namespace the initial remote configuration of kubelet should be stored @@ -288,6 +291,9 @@ const ( // CoreDNSVersion is the version of CoreDNS to be deployed if it is used CoreDNSVersion = "1.1.3" + // ClusterConfigurationKind is the string kind value for the ClusterConfiguration struct + ClusterConfigurationKind = "ClusterConfiguration" + // InitConfigurationKind is the string kind value for the InitConfiguration struct InitConfigurationKind = "InitConfiguration" diff --git a/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go b/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go index 17d307f5c6db9..a8a798f47ee5d 100644 --- a/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go +++ b/cmd/kubeadm/app/phases/addons/proxy/proxy_test.go @@ -171,15 +171,17 @@ func TestEnsureProxyAddon(t *testing.T) { client := clientsetfake.NewSimpleClientset() // TODO: Consider using a YAML file instead for this that makes it possible to specify YAML documents for the ComponentConfigs masterConfig := &kubeadmapiv1alpha3.InitConfiguration{ - API: kubeadmapiv1alpha3.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 1234, + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + API: kubeadmapiv1alpha3.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 1234, + }, + Networking: kubeadmapiv1alpha3.Networking{ + PodSubnet: "5.6.7.8/24", + }, + ImageRepository: "someRepo", + KubernetesVersion: "v1.10.0", }, - Networking: kubeadmapiv1alpha3.Networking{ - PodSubnet: "5.6.7.8/24", - }, - ImageRepository: "someRepo", - KubernetesVersion: "v1.10.0", } // Simulate an error if necessary diff --git a/cmd/kubeadm/app/phases/certs/certlist_test.go b/cmd/kubeadm/app/phases/certs/certlist_test.go index a5ef1866c44ad..2392dc271b30f 100644 --- a/cmd/kubeadm/app/phases/certs/certlist_test.go +++ b/cmd/kubeadm/app/phases/certs/certlist_test.go @@ -116,10 +116,12 @@ func TestCreateCertificateChain(t *testing.T) { defer os.RemoveAll(dir) ic := &kubeadmapi.InitConfiguration{ - CertificatesDir: dir, NodeRegistration: kubeadmapi.NodeRegistrationOptions{ Name: "test-node", }, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + CertificatesDir: dir, + }, } caCfg := Certificates{ diff --git a/cmd/kubeadm/app/phases/certs/certs_test.go b/cmd/kubeadm/app/phases/certs/certs_test.go index f476086d5bd2d..27d0e748f9c5c 100644 --- a/cmd/kubeadm/app/phases/certs/certs_test.go +++ b/cmd/kubeadm/app/phases/certs/certs_test.go @@ -351,7 +351,9 @@ func TestSharedCertificateExists(t *testing.T) { defer os.RemoveAll(tmpdir) cfg := &kubeadmapi.InitConfiguration{ - CertificatesDir: tmpdir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + CertificatesDir: tmpdir, + }, } // created expected keys @@ -398,10 +400,12 @@ func TestUsingExternalCA(t *testing.T) { defer os.RemoveAll(dir) cfg := &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, + Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + CertificatesDir: dir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, - CertificatesDir: dir, } for _, f := range test.setupFuncs { @@ -565,11 +569,13 @@ func TestCreateCertificateFilesMethods(t *testing.T) { defer os.RemoveAll(tmpdir) cfg := &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, - Etcd: kubeadmapi.Etcd{Local: &kubeadmapi.LocalEtcd{}}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, + Etcd: kubeadmapi.Etcd{Local: &kubeadmapi.LocalEtcd{}}, + Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + CertificatesDir: tmpdir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, - CertificatesDir: tmpdir, } if test.externalEtcd { diff --git a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go index 6e3464b9fb511..86b00146e514d 100644 --- a/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go +++ b/cmd/kubeadm/app/phases/certs/pkiutil/pki_helpers_test.go @@ -446,10 +446,12 @@ func TestGetAPIServerAltNames(t *testing.T) { { name: "ControlPlaneEndpoint DNS", cfg: &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:6443"}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, - APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:6443"}, + Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + }, + NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, }, expectedDNSNames: []string{"valid-hostname", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local", "api.k8s.io"}, expectedIPAddresses: []string{"10.96.0.1", "1.2.3.4", "10.1.245.94", "10.1.245.95"}, @@ -457,10 +459,12 @@ func TestGetAPIServerAltNames(t *testing.T) { { name: "ControlPlaneEndpoint IP", cfg: &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "4.5.6.7:6443"}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, - APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "4.5.6.7:6443"}, + Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + APIServerCertSANs: []string{"10.1.245.94", "10.1.245.95", "1.2.3.L", "invalid,commas,in,DNS"}, + }, + NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, }, expectedDNSNames: []string{"valid-hostname", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local"}, expectedIPAddresses: []string{"10.96.0.1", "1.2.3.4", "10.1.245.94", "10.1.245.95", "4.5.6.7"}, @@ -507,13 +511,15 @@ func TestGetEtcdAltNames(t *testing.T) { proxy := "user-etcd-proxy" proxyIP := "10.10.10.100" cfg := &kubeadmapi.InitConfiguration{ - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{ - ServerCertSANs: []string{ - proxy, - proxyIP, - "1.2.3.L", - "invalid,commas,in,DNS", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{ + ServerCertSANs: []string{ + proxy, + proxyIP, + "1.2.3.L", + "invalid,commas,in,DNS", + }, }, }, }, @@ -561,18 +567,20 @@ func TestGetEtcdPeerAltNames(t *testing.T) { proxyIP := "10.10.10.100" advertiseIP := "1.2.3.4" cfg := &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: advertiseIP}, - NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: hostname}, - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{ - PeerCertSANs: []string{ - proxy, - proxyIP, - "1.2.3.L", - "invalid,commas,in,DNS", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: advertiseIP}, + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{ + PeerCertSANs: []string{ + proxy, + proxyIP, + "1.2.3.L", + "invalid,commas,in,DNS", + }, }, }, }, + NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: hostname}, } altNames, err := GetEtcdPeerAltNames(cfg) diff --git a/cmd/kubeadm/app/phases/controlplane/manifests_test.go b/cmd/kubeadm/app/phases/controlplane/manifests_test.go index 37d1cce37451a..0fe37b6081633 100644 --- a/cmd/kubeadm/app/phases/controlplane/manifests_test.go +++ b/cmd/kubeadm/app/phases/controlplane/manifests_test.go @@ -46,7 +46,9 @@ func TestGetStaticPodSpecs(t *testing.T) { // Creates a Master Configuration cfg := &kubeadmapi.InitConfiguration{ - KubernetesVersion: "v1.9.0", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + KubernetesVersion: "v1.9.0", + }, } // Executes GetStaticPodSpecs @@ -118,7 +120,9 @@ func TestCreateStaticPodFilesAndWrappers(t *testing.T) { // Creates a Master Configuration cfg := &kubeadmapi.InitConfiguration{ - KubernetesVersion: "v1.9.0", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + KubernetesVersion: "v1.9.0", + }, } // Execute createStaticPodFunction @@ -141,12 +145,12 @@ func TestCreateStaticPodFilesAndWrappers(t *testing.T) { func TestGetAPIServerCommand(t *testing.T) { var tests = []struct { name string - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration expected []string }{ { name: "testing defaults", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, @@ -183,7 +187,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "ignores the audit policy if the feature gate is not enabled", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "4.3.2.1"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, @@ -225,7 +229,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "ipv6 advertise address", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "2001:db8::1"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, @@ -262,7 +266,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "an external etcd with custom ca, certs and keys", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "2001:db8::1"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, FeatureGates: map[string]bool{features.HighAvailability: true}, @@ -309,7 +313,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "an insecure etcd", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "2001:db8::1"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, Etcd: kubeadmapi.Etcd{ @@ -348,7 +352,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "auditing and HA are enabled with a custom log max age of 0", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "2001:db8::1"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, FeatureGates: map[string]bool{features.HighAvailability: true, features.Auditing: true}, @@ -393,7 +397,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "ensure the DynamicKubelet flag gets passed through", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, @@ -432,7 +436,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "test APIServerExtraArgs works as expected", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, @@ -480,7 +484,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "authorization-mode extra-args ABAC", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, @@ -520,7 +524,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "insecure-port extra-args", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, @@ -560,7 +564,7 @@ func TestGetAPIServerCommand(t *testing.T) { }, { name: "authorization-mode extra-args Webhook", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{BindPort: 123, AdvertiseAddress: "1.2.3.4"}, Networking: kubeadmapi.Networking{ServiceSubnet: "bar"}, CertificatesDir: testCertsDir, @@ -602,7 +606,11 @@ func TestGetAPIServerCommand(t *testing.T) { for _, rt := range tests { t.Run(rt.name, func(t *testing.T) { - actual := getAPIServerCommand(rt.cfg) + // TODO: Make getAPIServerCommand accept a ClusterConfiguration object instead of InitConfiguration + initcfg := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: *rt.cfg, + } + actual := getAPIServerCommand(initcfg) sort.Strings(actual) sort.Strings(rt.expected) if !reflect.DeepEqual(actual, rt.expected) { @@ -633,12 +641,12 @@ func removeCommon(left, right []string) []string { func TestGetControllerManagerCommand(t *testing.T) { var tests = []struct { name string - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration expected []string }{ { name: "custom certs dir", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ CertificatesDir: testCertsDir, KubernetesVersion: "v1.7.0", }, @@ -657,7 +665,7 @@ func TestGetControllerManagerCommand(t *testing.T) { }, { name: "custom cloudprovider", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Networking: kubeadmapi.Networking{PodSubnet: "10.0.1.15/16"}, CertificatesDir: testCertsDir, KubernetesVersion: "v1.7.0", @@ -680,7 +688,7 @@ func TestGetControllerManagerCommand(t *testing.T) { }, { name: "custom extra-args", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Networking: kubeadmapi.Networking{PodSubnet: "10.0.1.15/16"}, ControllerManagerExtraArgs: map[string]string{"node-cidr-mask-size": "20"}, CertificatesDir: testCertsDir, @@ -704,7 +712,7 @@ func TestGetControllerManagerCommand(t *testing.T) { }, { name: "custom IPv6 networking", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Networking: kubeadmapi.Networking{PodSubnet: "2001:db8::/64"}, CertificatesDir: testCertsDir, KubernetesVersion: "v1.7.0", @@ -728,7 +736,11 @@ func TestGetControllerManagerCommand(t *testing.T) { } for _, rt := range tests { - actual := getControllerManagerCommand(rt.cfg, version.MustParseSemantic(rt.cfg.KubernetesVersion)) + // TODO: Make getControllerManagerCommand accept a ClusterConfiguration object instead of InitConfiguration + initcfg := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: *rt.cfg, + } + actual := getControllerManagerCommand(initcfg, version.MustParseSemantic(rt.cfg.KubernetesVersion)) sort.Strings(actual) sort.Strings(rt.expected) if !reflect.DeepEqual(actual, rt.expected) { @@ -817,17 +829,16 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) { tests := []struct { name string - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration caKeyPresent bool expectedArgFunc func(dir string) []string }{ { name: "caKeyPresent-false", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ KubernetesVersion: "v1.7.0", API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, }, caKeyPresent: false, expectedArgFunc: func(tmpdir string) []string { @@ -847,11 +858,10 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) { }, { name: "caKeyPresent true", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ KubernetesVersion: "v1.7.0", API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, - NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, }, caKeyPresent: true, expectedArgFunc: func(tmpdir string) []string { @@ -877,7 +887,12 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) { defer os.RemoveAll(tmpdir) test.cfg.CertificatesDir = tmpdir - if err := certs.CreatePKIAssets(test.cfg); err != nil { + // TODO: Make getControllerManagerCommand and CreatePKIAssets accept a ClusterConfiguration object instead of InitConfiguration + initcfg := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: *test.cfg, + } + + if err := certs.CreatePKIAssets(initcfg); err != nil { t.Errorf("failed creating pki assets: %v", err) } @@ -891,7 +906,7 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) { } } - actual := getControllerManagerCommand(test.cfg, version.MustParseSemantic(test.cfg.KubernetesVersion)) + actual := getControllerManagerCommand(initcfg, version.MustParseSemantic(test.cfg.KubernetesVersion)) expected := test.expectedArgFunc(tmpdir) sort.Strings(actual) sort.Strings(expected) @@ -904,12 +919,12 @@ func TestGetControllerManagerCommandExternalCA(t *testing.T) { func TestGetSchedulerCommand(t *testing.T) { var tests = []struct { name string - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration expected []string }{ { name: "scheduler defaults", - cfg: &kubeadmapi.InitConfiguration{}, + cfg: &kubeadmapi.ClusterConfiguration{}, expected: []string{ "kube-scheduler", "--address=127.0.0.1", @@ -920,7 +935,11 @@ func TestGetSchedulerCommand(t *testing.T) { } for _, rt := range tests { - actual := getSchedulerCommand(rt.cfg) + // TODO: Make getSchedulerCommand accept a ClusterConfiguration object instead of InitConfiguration + initcfg := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: *rt.cfg, + } + actual := getSchedulerCommand(initcfg) sort.Strings(actual) sort.Strings(rt.expected) if !reflect.DeepEqual(actual, rt.expected) { diff --git a/cmd/kubeadm/app/phases/controlplane/volumes_test.go b/cmd/kubeadm/app/phases/controlplane/volumes_test.go index 088c1b5c87dce..2f3b7649dd985 100644 --- a/cmd/kubeadm/app/phases/controlplane/volumes_test.go +++ b/cmd/kubeadm/app/phases/controlplane/volumes_test.go @@ -502,13 +502,13 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) { ReadOnly: true, } var tests = []struct { - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration vol map[string]map[string]v1.Volume volMount map[string]map[string]v1.VolumeMount }{ { // Should ignore files in /etc/ssl/certs - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ CertificatesDir: testCertsDir, Etcd: kubeadmapi.Etcd{}, FeatureGates: map[string]bool{features.Auditing: true}, @@ -522,7 +522,7 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) { }, { // Should ignore files in /etc/ssl/certs and in CertificatesDir - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ CertificatesDir: testCertsDir, Etcd: kubeadmapi.Etcd{ External: &kubeadmapi.ExternalEtcd{ @@ -549,7 +549,11 @@ func TestGetHostPathVolumesForTheControlPlane(t *testing.T) { defer func() { caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates"} }() for _, rt := range tests { - mounts := getHostPathVolumesForTheControlPlane(rt.cfg) + // TODO: Make getHostPathVolumesForTheControlPlane accept a ClusterConfiguration object instead of InitConfiguration + initcfg := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: *rt.cfg, + } + mounts := getHostPathVolumesForTheControlPlane(initcfg) // Avoid unit test errors when the flexvolume is mounted if _, ok := mounts.volumes[kubeadmconstants.KubeControllerManager][flexvolumeDirVolumeName]; ok { diff --git a/cmd/kubeadm/app/phases/etcd/local_test.go b/cmd/kubeadm/app/phases/etcd/local_test.go index e77adf7e84a79..1401b091d8be6 100644 --- a/cmd/kubeadm/app/phases/etcd/local_test.go +++ b/cmd/kubeadm/app/phases/etcd/local_test.go @@ -33,11 +33,13 @@ func TestGetEtcdPodSpec(t *testing.T) { // Creates a Master Configuration cfg := &kubeadmapi.InitConfiguration{ - KubernetesVersion: "v1.7.0", - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{ - DataDir: "/var/lib/etcd", - Image: "", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + KubernetesVersion: "v1.7.0", + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{ + DataDir: "/var/lib/etcd", + Image: "", + }, }, }, } @@ -59,11 +61,13 @@ func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) { // Creates a Master Configuration cfg := &kubeadmapi.InitConfiguration{ - KubernetesVersion: "v1.7.0", - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{ - DataDir: "/var/lib/etcd", - Image: "k8s.gcr.io/etcd", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + KubernetesVersion: "v1.7.0", + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{ + DataDir: "/var/lib/etcd", + Image: "k8s.gcr.io/etcd", + }, }, }, } @@ -90,9 +94,11 @@ func TestGetEtcdCommand(t *testing.T) { NodeRegistration: kubeadmapi.NodeRegistrationOptions{ Name: "foo", }, - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{ - DataDir: "/var/lib/etcd", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{ + DataDir: "/var/lib/etcd", + }, }, }, }, @@ -121,12 +127,14 @@ func TestGetEtcdCommand(t *testing.T) { NodeRegistration: kubeadmapi.NodeRegistrationOptions{ Name: "bar", }, - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{ - DataDir: "/var/lib/etcd", - ExtraArgs: map[string]string{ - "listen-client-urls": "https://10.0.1.10:2379", - "advertise-client-urls": "https://10.0.1.10:2379", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{ + DataDir: "/var/lib/etcd", + ExtraArgs: map[string]string{ + "listen-client-urls": "https://10.0.1.10:2379", + "advertise-client-urls": "https://10.0.1.10:2379", + }, }, }, }, @@ -156,9 +164,11 @@ func TestGetEtcdCommand(t *testing.T) { NodeRegistration: kubeadmapi.NodeRegistrationOptions{ Name: "wombat", }, - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{ - DataDir: "/etc/foo", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{ + DataDir: "/etc/foo", + }, }, }, }, diff --git a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go index 0c065688bf52d..3817e2f890eb5 100644 --- a/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go +++ b/cmd/kubeadm/app/phases/kubeconfig/kubeconfig_test.go @@ -26,14 +26,11 @@ import ( "reflect" "testing" - kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" - "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" - + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" + kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" pkiutil "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" - kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" testutil "k8s.io/kubernetes/cmd/kubeadm/test" certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs" @@ -47,7 +44,9 @@ func TestGetKubeConfigSpecsFailsIfCADoesntExists(t *testing.T) { // Creates a Master Configuration pointing to the pkidir folder cfg := &kubeadmapi.InitConfiguration{ - CertificatesDir: tmpdir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + CertificatesDir: tmpdir, + }, } // Executes getKubeConfigSpecs @@ -67,28 +66,38 @@ func TestGetKubeConfigSpecs(t *testing.T) { // Creates Master Configurations pointing to the pkidir folder cfgs := []*kubeadmapi.InitConfiguration{ { - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, - CertificatesDir: pkidir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + CertificatesDir: pkidir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, { - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234}, - CertificatesDir: pkidir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234}, + CertificatesDir: pkidir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, { - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234}, - CertificatesDir: pkidir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234}, + CertificatesDir: pkidir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, { - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234}, - CertificatesDir: pkidir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io", BindPort: 1234}, + CertificatesDir: pkidir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, { - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234}, - CertificatesDir: pkidir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", ControlPlaneEndpoint: "api.k8s.io:4321", BindPort: 1234}, + CertificatesDir: pkidir, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"}, }, } @@ -307,8 +316,10 @@ func TestCreateKubeconfigFilesAndWrappers(t *testing.T) { // Creates a Master Configuration pointing to the pkidir folder cfg := &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, - CertificatesDir: pkidir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + CertificatesDir: pkidir, + }, } // Execs the createKubeConfigFunction @@ -335,7 +346,9 @@ func TestWriteKubeConfigFailsIfCADoesntExists(t *testing.T) { // Creates a Master Configuration pointing to the tmpdir folder cfg := &kubeadmapi.InitConfiguration{ - CertificatesDir: tmpdir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + CertificatesDir: tmpdir, + }, } var tests = []struct { @@ -380,8 +393,10 @@ func TestWriteKubeConfig(t *testing.T) { // Creates a Master Configuration pointing to the pkidir folder cfg := &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, - CertificatesDir: pkidir, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234}, + CertificatesDir: pkidir, + }, } var tests = []struct { diff --git a/cmd/kubeadm/app/phases/kubelet/config_test.go b/cmd/kubeadm/app/phases/kubelet/config_test.go index 769ae2900281d..697fcd61da7a9 100644 --- a/cmd/kubeadm/app/phases/kubelet/config_test.go +++ b/cmd/kubeadm/app/phases/kubelet/config_test.go @@ -33,10 +33,12 @@ func TestCreateConfigMap(t *testing.T) { nodeName := "fake-node" client := fake.NewSimpleClientset() cfg := &kubeadmapi.InitConfiguration{ - NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodeName}, - KubernetesVersion: "v1.11.0", - ComponentConfigs: kubeadmapi.ComponentConfigs{ - Kubelet: &kubeletconfig.KubeletConfiguration{}, + NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: nodeName}, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + KubernetesVersion: "v1.11.0", + ComponentConfigs: kubeadmapi.ComponentConfigs{ + Kubelet: &kubeletconfig.KubeletConfiguration{}, + }, }, } diff --git a/cmd/kubeadm/app/phases/upgrade/BUILD b/cmd/kubeadm/app/phases/upgrade/BUILD index f7fd5a520c704..74637b304ea65 100644 --- a/cmd/kubeadm/app/phases/upgrade/BUILD +++ b/cmd/kubeadm/app/phases/upgrade/BUILD @@ -76,20 +76,19 @@ go_test( embed = [":go_default_library"], deps = [ "//cmd/kubeadm/app/apis/kubeadm:go_default_library", - "//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library", - "//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library", + "//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", "//cmd/kubeadm/app/phases/certs:go_default_library", "//cmd/kubeadm/app/phases/controlplane:go_default_library", "//cmd/kubeadm/app/phases/etcd:go_default_library", "//cmd/kubeadm/app/util/apiclient:go_default_library", + "//cmd/kubeadm/app/util/config:go_default_library", "//cmd/kubeadm/app/util/etcd:go_default_library", "//cmd/kubeadm/test:go_default_library", "//pkg/util/version:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//vendor/github.com/coreos/etcd/clientv3:go_default_library", "//vendor/github.com/coreos/etcd/pkg/transport:go_default_library", diff --git a/cmd/kubeadm/app/phases/upgrade/postupgrade_test.go b/cmd/kubeadm/app/phases/upgrade/postupgrade_test.go index 5fd1763f92802..d8df2cb5df4da 100644 --- a/cmd/kubeadm/app/phases/upgrade/postupgrade_test.go +++ b/cmd/kubeadm/app/phases/upgrade/postupgrade_test.go @@ -130,8 +130,10 @@ func TestRollbackFiles(t *testing.T) { func TestShouldBackupAPIServerCertAndKey(t *testing.T) { cfg := &kubeadmapi.InitConfiguration{ - API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, - Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"}, + Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, + }, NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "test-node"}, } diff --git a/cmd/kubeadm/app/phases/upgrade/staticpods_test.go b/cmd/kubeadm/app/phases/upgrade/staticpods_test.go index 197a56664d7a7..1eb41f35cb29c 100644 --- a/cmd/kubeadm/app/phases/upgrade/staticpods_test.go +++ b/cmd/kubeadm/app/phases/upgrade/staticpods_test.go @@ -28,15 +28,14 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/pkg/transport" - "k8s.io/apimachinery/pkg/runtime" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" - kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3" + "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/constants" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane" etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" + configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd" ) @@ -48,6 +47,12 @@ const ( testConfiguration = ` apiVersion: kubeadm.k8s.io/v1alpha3 kind: InitConfiguration +nodeRegistration: + name: foo + criSocket: "" +--- +apiVersion: kubeadm.k8s.io/v1alpha3 +kind: ClusterConfiguration api: advertiseAddress: 1.2.3.4 bindPort: 6443 @@ -415,7 +420,7 @@ func TestStaticPodControlPlane(t *testing.T) { } defer os.RemoveAll(tmpEtcdDataDir) - oldcfg, err := getConfig("v1.9.0", tempCertsDir, tmpEtcdDataDir) + oldcfg, err := getConfig("v1.12.0", tempCertsDir, tmpEtcdDataDir) if err != nil { t.Fatalf("couldn't create config: %v", err) } @@ -502,15 +507,26 @@ func getAPIServerHash(dir string) (string, error) { return fmt.Sprintf("%x", sha256.Sum256(fileBytes)), nil } -// TODO: Make this test function use the rest of the "official" API machinery helper funcs we have inside of kubeadm func getConfig(version, certsDir, etcdDataDir string) (*kubeadmapi.InitConfiguration, error) { - externalcfg := &kubeadmapiv1alpha3.InitConfiguration{} - internalcfg := &kubeadmapi.InitConfiguration{} - if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(fmt.Sprintf(testConfiguration, certsDir, etcdDataDir, version)), externalcfg); err != nil { - return nil, fmt.Errorf("unable to decode config: %v", err) + configBytes := []byte(fmt.Sprintf(testConfiguration, certsDir, etcdDataDir, version)) + + // Unmarshal the config + cfg, err := configutil.BytesToInternalConfig(configBytes) + if err != nil { + return nil, err } - kubeadmscheme.Scheme.Convert(externalcfg, internalcfg, nil) - return internalcfg, nil + + // Applies dynamic defaults to settings not provided with flags + if err = configutil.SetInitDynamicDefaults(cfg); err != nil { + return nil, err + } + + // Validates cfg (flags/configs + defaults + dynamic defaults) + if err = validation.ValidateInitConfiguration(cfg).ToAggregate(); err != nil { + return nil, err + } + + return cfg, nil } func getTempDir(t *testing.T, name string) (string, func()) { diff --git a/cmd/kubeadm/app/phases/uploadconfig/BUILD b/cmd/kubeadm/app/phases/uploadconfig/BUILD index 7786368fbd48b..77201659d64aa 100644 --- a/cmd/kubeadm/app/phases/uploadconfig/BUILD +++ b/cmd/kubeadm/app/phases/uploadconfig/BUILD @@ -45,6 +45,7 @@ go_test( "//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library", "//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library", "//cmd/kubeadm/app/constants:go_default_library", + "//cmd/kubeadm/app/util/config:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go index 0377ec54c6a1c..38e6506982521 100644 --- a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go +++ b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go @@ -43,11 +43,7 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int fmt.Printf("[uploadconfig] storing the configuration used in ConfigMap %q in the %q Namespace\n", kubeadmconstants.InitConfigurationConfigMap, metav1.NamespaceSystem) // We don't want to mutate the cfg itself, so create a copy of it using .DeepCopy of it first - cfgToUpload := cfg.DeepCopy() - // Removes sensitive info from the data that will be stored in the config map - cfgToUpload.BootstrapTokens = nil - // Clear the NodeRegistration object. - cfgToUpload.NodeRegistration = kubeadmapi.NodeRegistrationOptions{} + clusterConfigToUpload := cfg.ClusterConfiguration.DeepCopy() // TODO: Reset the .ComponentConfig struct like this: // cfgToUpload.ComponentConfigs = kubeadmapi.ComponentConfigs{} // in order to not upload any other components' config to the kubeadm-config @@ -56,9 +52,8 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int // needs to support reading the different components' ConfigMaps first. // Marshal the object into YAML - cfgYaml, err := configutil.MarshalKubeadmConfigObject(cfgToUpload) + cfgYaml, err := configutil.MarshalKubeadmConfigObject(clusterConfigToUpload) if err != nil { - fmt.Println("err", err.Error()) return err } diff --git a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go index 0ca33efc5f2b7..ad2a7ba288dd9 100644 --- a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go +++ b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig_test.go @@ -17,6 +17,7 @@ limitations under the License. package uploadconfig import ( + "reflect" "testing" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -28,6 +29,7 @@ import ( kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" + configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" ) func TestUploadConfiguration(t *testing.T) { @@ -62,21 +64,31 @@ func TestUploadConfiguration(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t2 *testing.T) { - cfg := &kubeadmapi.InitConfiguration{ - KubernetesVersion: "v1.10.3", - BootstrapTokens: []kubeadmapi.BootstrapToken{ + initialcfg := &kubeadmapiv1alpha3.InitConfiguration{ + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + API: kubeadmapiv1alpha3.API{ + AdvertiseAddress: "1.2.3.4", + }, + KubernetesVersion: "v1.10.10", + }, + BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{ { - Token: &kubeadmapi.BootstrapTokenString{ + Token: &kubeadmapiv1alpha3.BootstrapTokenString{ ID: "abcdef", Secret: "abcdef0123456789", }, }, }, - NodeRegistration: kubeadmapi.NodeRegistrationOptions{ + NodeRegistration: kubeadmapiv1alpha3.NodeRegistrationOptions{ Name: "node-foo", CRISocket: "/var/run/custom-cri.sock", }, } + cfg, err := configutil.ConfigFileAndDefaultsToInternalConfig("", initialcfg) + if err != nil { + t2.Fatalf("UploadConfiguration() error = %v", err) + } + client := clientsetfake.NewSimpleClientset() if tt.errOnCreate != nil { client.PrependReactor("create", "configmaps", func(action core.Action) (bool, runtime.Object, error) { @@ -107,23 +119,13 @@ func TestUploadConfiguration(t *testing.T) { t2.Fatalf("Fail to find ConfigMap key") } - decodedCfg := &kubeadmapi.InitConfiguration{} + decodedCfg := &kubeadmapi.ClusterConfiguration{} if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), []byte(configData), decodedCfg); err != nil { t2.Fatalf("unable to decode config from bytes: %v", err) } - if decodedCfg.KubernetesVersion != cfg.KubernetesVersion { - t2.Errorf("Decoded value doesn't match, decoded = %#v, expected = %#v", decodedCfg.KubernetesVersion, cfg.KubernetesVersion) - } - - // If the decoded cfg has a BootstrapTokens array, verify the sensitive information we had isn't still there. - if len(decodedCfg.BootstrapTokens) > 0 && decodedCfg.BootstrapTokens[0].Token != nil && decodedCfg.BootstrapTokens[0].Token.String() == cfg.BootstrapTokens[0].Token.String() { - t2.Errorf("Decoded value contains .BootstrapTokens (sensitive info), decoded = %#v, expected = empty", decodedCfg.BootstrapTokens) - } - - // Make sure no information from NodeRegistrationOptions was uploaded. - if decodedCfg.NodeRegistration.Name == cfg.NodeRegistration.Name || decodedCfg.NodeRegistration.CRISocket != kubeadmapiv1alpha3.DefaultCRISocket { - t2.Errorf("Decoded value contains .NodeRegistration (node-specific info shouldn't be uploaded), decoded = %#v, expected = empty", decodedCfg.NodeRegistration) + if !reflect.DeepEqual(decodedCfg, &cfg.ClusterConfiguration) { + t2.Errorf("the initial and decoded ClusterConfiguration didn't match") } } }) diff --git a/cmd/kubeadm/app/preflight/checks_test.go b/cmd/kubeadm/app/preflight/checks_test.go index c66979d021928..84e0ab0c0d9e7 100644 --- a/cmd/kubeadm/app/preflight/checks_test.go +++ b/cmd/kubeadm/app/preflight/checks_test.go @@ -186,46 +186,49 @@ func (pfct preflightCheckTest) Check() (warning, errors []error) { func TestRunInitMasterChecks(t *testing.T) { var tests = []struct { name string - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration expected bool }{ {name: "Test valid advertised address", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{AdvertiseAddress: "foo"}, }, expected: false, }, { name: "Test CA file exists if specfied", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{External: &kubeadmapi.ExternalEtcd{CAFile: "/foo"}}, }, expected: false, }, { name: "Test Cert file exists if specfied", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{External: &kubeadmapi.ExternalEtcd{CertFile: "/foo"}}, }, expected: false, }, { name: "Test Key file exists if specfied", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{External: &kubeadmapi.ExternalEtcd{CertFile: "/foo"}}, }, expected: false, }, { - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{AdvertiseAddress: "2001:1234::1:15"}, }, expected: false, }, } - for _, rt := range tests { - actual := RunInitMasterChecks(exec.New(), rt.cfg, sets.NewString()) + // TODO: Make RunInitMasterChecks accept a ClusterConfiguration object instead of InitConfiguration + initcfg := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: *rt.cfg, + } + actual := RunInitMasterChecks(exec.New(), initcfg, sets.NewString()) if (actual == nil) != rt.expected { t.Errorf( "failed RunInitMasterChecks:\n\texpected: %t\n\t actual: %t\n\t error: %v", diff --git a/cmd/kubeadm/app/util/config/cluster.go b/cmd/kubeadm/app/util/config/cluster.go index 239f0520accce..fdcfaeadb893a 100644 --- a/cmd/kubeadm/app/util/config/cluster.go +++ b/cmd/kubeadm/app/util/config/cluster.go @@ -29,6 +29,7 @@ import ( ) // FetchConfigFromFileOrCluster fetches configuration required for upgrading your cluster from a file (which has precedence) or a ConfigMap in the cluster +// TODO: This func should be renamed FetchClusterConfigFromFileOrCluster, and return a ClusterConfiguration instead of an InitConfiguration func FetchConfigFromFileOrCluster(client clientset.Interface, w io.Writer, logPrefix, cfgPath string) (*kubeadmapi.InitConfiguration, error) { // Load the configuration from a file or the cluster configBytes, err := loadConfigurationBytes(client, w, logPrefix, cfgPath) @@ -36,8 +37,17 @@ func FetchConfigFromFileOrCluster(client clientset.Interface, w io.Writer, logPr return nil, err } - // Take the versioned configuration populated from the file or ConfigMap, convert it to internal, default and validate - return BytesToInternalConfig(configBytes) + // Unmarshal the versioned configuration populated from the file or ConfigMap, convert it to the internal API types, then default and validate + initcfg, err := BytesToInternalConfig(configBytes) + if err != nil { + return nil, err + } + // In this function we're only interested in the ClusterConfiguration part. + // TODO: As described above, the return value of this func actually should be a ClusterConfiguration + if err := SetClusterDynamicDefaults(&initcfg.ClusterConfiguration); err != nil { + return nil, err + } + return initcfg, err } // loadConfigurationBytes loads the configuration byte slice from either a file or the cluster ConfigMap @@ -50,6 +60,8 @@ func loadConfigurationBytes(client clientset.Interface, w io.Writer, logPrefix, fmt.Fprintf(w, "[%s] Reading configuration from the cluster...\n", logPrefix) + // TODO: This code should support reading the MasterConfiguration key as well for backwards-compat + // Also, the key really should be ClusterConfiguration... configMap, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(constants.InitConfigurationConfigMap, metav1.GetOptions{}) if apierrors.IsNotFound(err) { // Return the apierror directly so the caller of this function can know what type of error occurred and act based on that diff --git a/cmd/kubeadm/app/util/config/cluster_test.go b/cmd/kubeadm/app/util/config/cluster_test.go index 36ad8e6ec4649..24e6edaca3879 100644 --- a/cmd/kubeadm/app/util/config/cluster_test.go +++ b/cmd/kubeadm/app/util/config/cluster_test.go @@ -17,7 +17,6 @@ limitations under the License. package config import ( - "fmt" "os" "strings" "testing" @@ -42,22 +41,24 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) { { name: "fetch valid config from configMap", testCfg: &kubeadmapi.InitConfiguration{ - KubernetesVersion: "v1.10.3", - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - Etcd: kubeadm.Etcd{ - Local: &kubeadm.LocalEtcd{ - DataDir: "/some/path", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + KubernetesVersion: "v1.10.3", + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, }, + Etcd: kubeadm.Etcd{ + Local: &kubeadm.LocalEtcd{ + DataDir: "/some/path", + }, + }, + Networking: kubeadm.Networking{ + ServiceSubnet: "10.96.0.1/12", + DNSDomain: "cluster.local", + PodSubnet: "10.0.1.15/16", + }, + CertificatesDir: "/some/other/cert/dir", }, - Networking: kubeadm.Networking{ - ServiceSubnet: "10.96.0.1/12", - DNSDomain: "cluster.local", - PodSubnet: "10.0.1.15/16", - }, - CertificatesDir: "/some/other/cert/dir", BootstrapTokens: []kubeadm.BootstrapToken{ { Token: &kubeadm.BootstrapTokenString{ @@ -75,22 +76,24 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) { { name: "fetch invalid config from configMap", testCfg: &kubeadmapi.InitConfiguration{ - KubernetesVersion: "v1.10.3", - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - Etcd: kubeadm.Etcd{ - Local: &kubeadm.LocalEtcd{ - DataDir: "/some/path", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + KubernetesVersion: "v1.10.3", + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, }, + Etcd: kubeadm.Etcd{ + Local: &kubeadm.LocalEtcd{ + DataDir: "/some/path", + }, + }, + Networking: kubeadm.Networking{ + ServiceSubnet: "10.96.0.1/12", + DNSDomain: "cluster.local", + PodSubnet: "10.0.1.15", // wrong + }, + CertificatesDir: "/some/other/cert/dir", }, - Networking: kubeadm.Networking{ - ServiceSubnet: "10.96.0.1/12", - DNSDomain: "cluster.local", - PodSubnet: "10.0.1.15", - }, - CertificatesDir: "/some/other/cert/dir", BootstrapTokens: []kubeadm.BootstrapToken{ { Token: &kubeadm.BootstrapTokenString{ @@ -108,24 +111,26 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) { }, { name: "fetch valid config from cfgPath", - cfgPath: "testdata/conversion/master/v1alpha2.yaml", + cfgPath: "testdata/conversion/master/v1alpha3.yaml", testCfg: &kubeadmapi.InitConfiguration{ - KubernetesVersion: "v1.10.3", - API: kubeadm.API{ - AdvertiseAddress: "1.2.3.4", - BindPort: 6443, - }, - Etcd: kubeadm.Etcd{ - Local: &kubeadm.LocalEtcd{ - DataDir: "/some/path", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + KubernetesVersion: "v1.10.3", + API: kubeadm.API{ + AdvertiseAddress: "1.2.3.4", + BindPort: 6443, }, + Etcd: kubeadm.Etcd{ + Local: &kubeadm.LocalEtcd{ + DataDir: "/some/path", + }, + }, + Networking: kubeadm.Networking{ + ServiceSubnet: "10.96.0.1/12", + DNSDomain: "cluster.local", + PodSubnet: "10.0.1.15", + }, + CertificatesDir: "/some/other/cert/dir", }, - Networking: kubeadm.Networking{ - ServiceSubnet: "10.96.0.1/12", - DNSDomain: "cluster.local", - PodSubnet: "10.0.1.15", - }, - CertificatesDir: "/some/other/cert/dir", BootstrapTokens: []kubeadm.BootstrapToken{ { Token: &kubeadm.BootstrapTokenString{ @@ -147,7 +152,7 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) { }, { name: "fetch config from not exist cfgPath", - cfgPath: "testdata231/defaulting/master/defaulted.yaml", + cfgPath: "doesnotexist.yaml", expectErr: "no such file or directory", }, { @@ -160,18 +165,17 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) { t.Run(tt.name, func(t *testing.T) { client := clientsetfake.NewSimpleClientset() if tt.testCfg != nil { - err := createConfigMapWithCfg(tt.testCfg, client) - if err != nil { + if err := createConfigMapWithCfg(tt.testCfg, client); err != nil { t.Errorf("UploadConfiguration failed err: %v", err) } } _, err := FetchConfigFromFileOrCluster(client, os.Stdout, "upgrade/config", tt.cfgPath) - if len(tt.expectErr) == 0 { - if err != nil { + if err != nil { + if len(tt.expectErr) == 0 { t.Fatalf("expected no err, but got err: %v", err) + } else if !strings.Contains(err.Error(), tt.expectErr) { + t.Errorf("expected contain err: %v, but got err: %v", tt.expectErr, err) } - } else if !strings.Contains(err.Error(), tt.expectErr) { - t.Errorf("expected contain err: %v, but got err: %v", tt.expectErr, err) } }) } @@ -181,11 +185,10 @@ func TestFetchConfigFromFileOrCluster(t *testing.T) { func createConfigMapWithCfg(cfgToCreate *kubeadmapi.InitConfiguration, client clientset.Interface) error { cfgYaml, err := MarshalKubeadmConfigObject(cfgToCreate) if err != nil { - fmt.Println("err", err.Error()) return err } - err = apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{ + return apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: kubeadmconstants.InitConfigurationConfigMap, Namespace: metav1.NamespaceSystem, @@ -194,8 +197,4 @@ func createConfigMapWithCfg(cfgToCreate *kubeadmapi.InitConfiguration, client cl kubeadmconstants.InitConfigurationConfigMapKey: string(cfgYaml), }, }) - if err != nil { - return err - } - return nil } diff --git a/cmd/kubeadm/app/util/config/common.go b/cmd/kubeadm/app/util/config/common.go index 10e33d39a0470..067449d4ce911 100644 --- a/cmd/kubeadm/app/util/config/common.go +++ b/cmd/kubeadm/app/util/config/common.go @@ -54,11 +54,13 @@ func AnyConfigFileAndDefaultsToInternal(cfgPath string) (runtime.Object, error) return nil, fmt.Errorf("didn't recognize types with GroupVersionKind: %v", gvks) } -// MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a InitConfiguration, some extra logic is run +// MarshalKubeadmConfigObject marshals an Object registered in the kubeadm scheme. If the object is a InitConfiguration or ClusterConfiguration, some extra logic is run func MarshalKubeadmConfigObject(obj runtime.Object) ([]byte, error) { switch internalcfg := obj.(type) { case *kubeadmapi.InitConfiguration: return MarshalInitConfigurationToBytes(internalcfg, kubeadmapiv1alpha3.SchemeGroupVersion) + case *kubeadmapi.ClusterConfiguration: + return MarshalClusterConfigurationToBytes(internalcfg, kubeadmapiv1alpha3.SchemeGroupVersion) default: return kubeadmutil.MarshalToYamlForCodecs(obj, kubeadmapiv1alpha3.SchemeGroupVersion, kubeadmscheme.Codecs) } @@ -108,7 +110,7 @@ func DetectUnsupportedVersion(b []byte) error { // NormalizeKubernetesVersion resolves version labels, sets alternative // image registry if requested for CI builds, and validates minimal // version that kubeadm SetInitDynamicDefaultssupports. -func NormalizeKubernetesVersion(cfg *kubeadmapi.InitConfiguration) error { +func NormalizeKubernetesVersion(cfg *kubeadmapi.ClusterConfiguration) error { // Requested version is automatic CI build, thus use KubernetesCI Image Repository for core images if kubeadmutil.KubernetesIsCIVersion(cfg.KubernetesVersion) { cfg.CIImageRepository = constants.DefaultCIImageRepository diff --git a/cmd/kubeadm/app/util/config/common_test.go b/cmd/kubeadm/app/util/config/common_test.go index 1a980da798465..ed1f4359a29c7 100644 --- a/cmd/kubeadm/app/util/config/common_test.go +++ b/cmd/kubeadm/app/util/config/common_test.go @@ -204,7 +204,9 @@ func TestLowercaseSANs(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { cfg := &kubeadmapiv1alpha3.InitConfiguration{ - APIServerCertSANs: test.in, + ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + APIServerCertSANs: test.in, + }, } LowercaseSANs(cfg.APIServerCertSANs) diff --git a/cmd/kubeadm/app/util/config/masterconfig.go b/cmd/kubeadm/app/util/config/masterconfig.go index b6d57fc503270..229e80bf3a364 100644 --- a/cmd/kubeadm/app/util/config/masterconfig.go +++ b/cmd/kubeadm/app/util/config/masterconfig.go @@ -43,36 +43,6 @@ import ( // SetInitDynamicDefaults checks and sets configuration values for the InitConfiguration object func SetInitDynamicDefaults(cfg *kubeadmapi.InitConfiguration) error { - - // Default all the embedded ComponentConfig structs - componentconfigs.Known.Default(cfg) - - // validate cfg.API.AdvertiseAddress. - addressIP := net.ParseIP(cfg.API.AdvertiseAddress) - if addressIP == nil && cfg.API.AdvertiseAddress != "" { - return fmt.Errorf("couldn't use \"%s\" as \"apiserver-advertise-address\", must be ipv4 or ipv6 address", cfg.API.AdvertiseAddress) - } - // Choose the right address for the API Server to advertise. If the advertise address is localhost or 0.0.0.0, the default interface's IP address is used - // This is the same logic as the API Server uses - ip, err := netutil.ChooseBindAddress(addressIP) - if err != nil { - return err - } - cfg.API.AdvertiseAddress = ip.String() - ip = net.ParseIP(cfg.API.AdvertiseAddress) - if ip.To4() != nil { - cfg.ComponentConfigs.KubeProxy.BindAddress = kubeadmapiv1alpha3.DefaultProxyBindAddressv4 - } else { - cfg.ComponentConfigs.KubeProxy.BindAddress = kubeadmapiv1alpha3.DefaultProxyBindAddressv6 - } - // Resolve possible version labels and validate version string - if err := NormalizeKubernetesVersion(cfg); err != nil { - return err - } - - // Downcase SANs. Some domain names (like ELBs) have capitals in them. - LowercaseSANs(cfg.APIServerCertSANs) - // Populate the .Token field with a random value if unset // We do this at this layer, and not the API defaulting layer // because of possible security concerns, and more practically @@ -104,6 +74,40 @@ func SetInitDynamicDefaults(cfg *kubeadmapi.InitConfiguration) error { cfg.NodeRegistration.Taints = []v1.Taint{kubeadmconstants.MasterTaint} } + // Do all the defaulting for the nested ClusterConfiguration as well + return SetClusterDynamicDefaults(&cfg.ClusterConfiguration) +} + +// SetClusterDynamicDefaults checks and sets configuration values for the InitConfiguration object +func SetClusterDynamicDefaults(cfg *kubeadmapi.ClusterConfiguration) error { + // Default all the embedded ComponentConfig structs + componentconfigs.Known.Default(cfg) + + // validate cfg.API.AdvertiseAddress. + addressIP := net.ParseIP(cfg.API.AdvertiseAddress) + if addressIP == nil && cfg.API.AdvertiseAddress != "" { + return fmt.Errorf("couldn't use \"%s\" as \"apiserver-advertise-address\", must be ipv4 or ipv6 address", cfg.API.AdvertiseAddress) + } + // Choose the right address for the API Server to advertise. If the advertise address is localhost or 0.0.0.0, the default interface's IP address is used + // This is the same logic as the API Server uses + ip, err := netutil.ChooseBindAddress(addressIP) + if err != nil { + return err + } + cfg.API.AdvertiseAddress = ip.String() + ip = net.ParseIP(cfg.API.AdvertiseAddress) + if ip.To4() != nil { + cfg.ComponentConfigs.KubeProxy.BindAddress = kubeadmapiv1alpha3.DefaultProxyBindAddressv4 + } else { + cfg.ComponentConfigs.KubeProxy.BindAddress = kubeadmapiv1alpha3.DefaultProxyBindAddressv6 + } + // Resolve possible version labels and validate version string + if err := NormalizeKubernetesVersion(cfg); err != nil { + return err + } + + // Downcase SANs. Some domain names (like ELBs) have capitals in them. + LowercaseSANs(cfg.APIServerCertSANs) return nil } @@ -124,24 +128,35 @@ func ConfigFileAndDefaultsToInternalConfig(cfgPath string, defaultversionedcfg * if err != nil { return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err) } - return BytesToInternalConfig(b) + internalcfg, err = BytesToInternalConfig(b) + if err != nil { + return nil, err + } + } else { + // 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) } - // 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) - - return defaultAndValidate(internalcfg) + // Applies dynamic defaults to settings not provided with flags + if err := SetInitDynamicDefaults(internalcfg); err != nil { + return nil, err + } + // Validates cfg (flags/configs + defaults + dynamic defaults) + if err := validation.ValidateInitConfiguration(internalcfg).ToAggregate(); err != nil { + return nil, err + } + return internalcfg, nil } // BytesToInternalConfig converts a byte slice to an internal, defaulted and validated configuration object. // The byte slice may contain one or many different YAML documents. These YAML documents are parsed one-by-one // and well-known ComponentConfig GroupVersionKinds are stored inside of the internal InitConfiguration struct func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) { - internalcfg := &kubeadmapi.InitConfiguration{} - decodedObjs := map[componentconfigs.RegistrationKind]runtime.Object{} - masterConfigFound := false + var initcfg *kubeadmapi.InitConfiguration + var clustercfg *kubeadmapi.ClusterConfiguration + decodedComponentConfigObjects := map[componentconfigs.RegistrationKind]runtime.Object{} if err := DetectUnsupportedVersion(b); err != nil { return nil, err @@ -162,30 +177,57 @@ func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) { if err != nil { return nil, err } - decodedObjs[regKind] = obj + decodedComponentConfigObjects[regKind] = obj continue } if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvk) { - if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), fileContent, internalcfg); err != nil { + // Set initcfg to an empty struct value the deserializer will populate + initcfg = &kubeadmapi.InitConfiguration{} + // Decode the bytes into the internal struct. Under the hood, the bytes will be unmarshalled into the + // right external version, defaulted, and converted into the internal version. + if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), fileContent, initcfg); err != nil { + return nil, err + } + continue + } + if kubeadmutil.GroupVersionKindsHasClusterConfiguration(gvk) { + // Set clustercfg to an empty struct value the deserializer will populate + clustercfg = &kubeadmapi.ClusterConfiguration{} + // Decode the bytes into the internal struct. Under the hood, the bytes will be unmarshalled into the + // right external version, defaulted, and converted into the internal version. + if err := runtime.DecodeInto(kubeadmscheme.Codecs.UniversalDecoder(), fileContent, clustercfg); err != nil { return nil, err } - masterConfigFound = true continue } fmt.Printf("[config] WARNING: Ignored YAML document with GroupVersionKind %v\n", gvk) } - // Just as an extra safety check, don't proceed if a InitConfiguration object wasn't found - if !masterConfigFound { - return nil, fmt.Errorf("no InitConfiguration kind was found in the YAML file") + + // Enforce that InitConfiguration and/or ClusterConfiguration has to exist among the YAML documents + if initcfg == nil && clustercfg == nil { + return nil, fmt.Errorf("no InitConfiguration or ClusterConfiguration kind was found in the YAML file") + } + + // If InitConfiguration wasn't given, default it by creating an external struct instance, default it and convert into the internal type + if initcfg == nil { + extinitcfg := &kubeadmapiv1alpha3.InitConfiguration{} + kubeadmscheme.Scheme.Default(extinitcfg) + // Set initcfg to an empty struct value the deserializer will populate + initcfg = &kubeadmapi.InitConfiguration{} + kubeadmscheme.Scheme.Convert(extinitcfg, initcfg, nil) + } + // If ClusterConfiguration was given, populate it in the InitConfiguration struct + if clustercfg != nil { + initcfg.ClusterConfiguration = *clustercfg } - // Save the loaded ComponentConfig objects in the internalcfg object - for kind, obj := range decodedObjs { + // Save the loaded ComponentConfig objects in the initcfg object + for kind, obj := range decodedComponentConfigObjects { registration, found := componentconfigs.Known[kind] if found { - if ok := registration.SetToInternalConfig(obj, internalcfg); !ok { + if ok := registration.SetToInternalConfig(obj, &initcfg.ClusterConfiguration); !ok { return nil, fmt.Errorf("couldn't save componentconfig value for kind %q", string(kind)) } } else { @@ -193,26 +235,12 @@ func BytesToInternalConfig(b []byte) (*kubeadmapi.InitConfiguration, error) { fmt.Printf("[config] WARNING: Decoded a kind that couldn't be saved to the internal configuration: %q\n", string(kind)) } } - - return defaultAndValidate(internalcfg) -} - -func defaultAndValidate(cfg *kubeadmapi.InitConfiguration) (*kubeadmapi.InitConfiguration, error) { - // Applies dynamic defaults to settings not provided with flags - if err := SetInitDynamicDefaults(cfg); err != nil { - return nil, err - } - // Validates cfg (flags/configs + defaults + dynamic defaults) - if err := validation.ValidateInitConfiguration(cfg).ToAggregate(); err != nil { - return nil, err - } - - return cfg, nil + return initcfg, nil } -func defaultedInternalConfig() *kubeadmapi.InitConfiguration { - externalcfg := &kubeadmapiv1alpha3.InitConfiguration{} - internalcfg := &kubeadmapi.InitConfiguration{} +func defaultedInternalConfig() *kubeadmapi.ClusterConfiguration { + externalcfg := &kubeadmapiv1alpha3.ClusterConfiguration{} + internalcfg := &kubeadmapi.ClusterConfiguration{} kubeadmscheme.Scheme.Default(externalcfg) kubeadmscheme.Scheme.Convert(externalcfg, internalcfg, nil) @@ -223,41 +251,57 @@ func defaultedInternalConfig() *kubeadmapi.InitConfiguration { } // MarshalInitConfigurationToBytes marshals the internal InitConfiguration object to bytes. It writes the embedded -// ComponentConfiguration objects out as separate YAML documents +// ClusterConfiguration object with ComponentConfigs out as separate YAML documents func MarshalInitConfigurationToBytes(cfg *kubeadmapi.InitConfiguration, gv schema.GroupVersion) ([]byte, error) { - masterbytes, err := kubeadmutil.MarshalToYamlForCodecs(cfg, gv, kubeadmscheme.Codecs) + initbytes, err := kubeadmutil.MarshalToYamlForCodecs(cfg, gv, kubeadmscheme.Codecs) if err != nil { return []byte{}, err } - allFiles := [][]byte{masterbytes} - componentConfigContent := map[string][]byte{} + allFiles := [][]byte{initbytes} - // If the specified groupversion is targeting the internal type, don't print the extra componentconfig YAML documents + // Exception: If the specified groupversion is targeting the internal type, don't print embedded ClusterConfiguration contents + // This is mostly used for unit testing. In a real scenario the internal version of the API is never marshalled as-is. if gv.Version != runtime.APIVersionInternal { + clusterbytes, err := MarshalClusterConfigurationToBytes(&cfg.ClusterConfiguration, gv) + if err != nil { + return []byte{}, err + } + allFiles = append(allFiles, clusterbytes) + } + return bytes.Join(allFiles, []byte(kubeadmconstants.YAMLDocumentSeparator)), nil +} - defaultedcfg := defaultedInternalConfig() +// MarshalClusterConfigurationToBytes marshals the internal ClusterConfiguration object to bytes. It writes the embedded +// ComponentConfiguration objects out as separate YAML documents +func MarshalClusterConfigurationToBytes(clustercfg *kubeadmapi.ClusterConfiguration, gv schema.GroupVersion) ([]byte, error) { + clusterbytes, err := kubeadmutil.MarshalToYamlForCodecs(clustercfg, gv, kubeadmscheme.Codecs) + if err != nil { + return []byte{}, err + } + allFiles := [][]byte{clusterbytes} + componentConfigContent := map[string][]byte{} + defaultedcfg := defaultedInternalConfig() - for kind, registration := range componentconfigs.Known { - // If the ComponentConfig struct for the current registration is nil, skip it when marshalling - realobj, ok := registration.GetFromInternalConfig(cfg) - if !ok { - continue - } + for kind, registration := range componentconfigs.Known { + // If the ComponentConfig struct for the current registration is nil, skip it when marshalling + realobj, ok := registration.GetFromInternalConfig(clustercfg) + if !ok { + continue + } - defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg) - // Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference - if !ok { - return []byte{}, fmt.Errorf("couldn't create a default componentconfig object") - } + defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg) + // Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference + if !ok { + return []byte{}, fmt.Errorf("couldn't create a default componentconfig object") + } - // If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it - if !reflect.DeepEqual(realobj, defaultedobj) { - contentBytes, err := registration.Marshal(realobj) - if err != nil { - return []byte{}, err - } - componentConfigContent[string(kind)] = contentBytes + // If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it + if !reflect.DeepEqual(realobj, defaultedobj) { + contentBytes, err := registration.Marshal(realobj) + if err != nil { + return []byte{}, err } + componentConfigContent[string(kind)] = contentBytes } } diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml index 0c6205071821d..c1f9d77e8f1e8 100644 --- a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml +++ b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml @@ -1,3 +1,20 @@ +apiVersion: kubeadm.k8s.io/v1alpha3 +bootstrapTokens: +- groups: + - system:bootstrappers:kubeadm:default-node-token + token: s73ybu.6tw6wnqgp5z0wb77 + ttl: 24h0m0s + usages: + - signing + - authentication +kind: InitConfiguration +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: master-1 + taints: + - effect: NoSchedule + key: node-role.kubernetes.io/master +--- api: advertiseAddress: 192.168.2.2 bindPort: 6443 @@ -9,14 +26,6 @@ auditPolicy: logDir: /var/log/kubernetes/audit logMaxAge: 2 path: "" -bootstrapTokens: -- groups: - - system:bootstrappers:kubeadm:default-node-token - token: s73ybu.6tw6wnqgp5z0wb77 - ttl: 24h0m0s - usages: - - signing - - authentication certificatesDir: /etc/kubernetes/pki clusterName: kubernetes etcd: @@ -24,18 +33,12 @@ etcd: dataDir: /var/lib/etcd image: "" imageRepository: k8s.gcr.io -kind: InitConfiguration +kind: ClusterConfiguration kubernetesVersion: v1.10.2 networking: dnsDomain: cluster.local podSubnet: "" serviceSubnet: 10.96.0.0/12 -nodeRegistration: - criSocket: /var/run/dockershim.sock - name: master-1 - taints: - - effect: NoSchedule - key: node-role.kubernetes.io/master unifiedControlPlaneImage: "" --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 diff --git a/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml b/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml index 8633b69072949..4eb86dd7d7820 100644 --- a/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml +++ b/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml @@ -1,12 +1,4 @@ -api: - advertiseAddress: 192.168.2.2 - bindPort: 6443 - controlPlaneEndpoint: "" apiVersion: kubeadm.k8s.io/v1alpha3 -auditPolicy: - logDir: /var/log/kubernetes/audit - logMaxAge: 2 - path: "" bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token @@ -15,6 +7,23 @@ bootstrapTokens: usages: - signing - authentication +kind: InitConfiguration +nodeRegistration: + criSocket: /var/run/criruntime.sock + name: master-1 + taints: + - effect: NoSchedule + key: node-role.kubernetes.io/master +--- +api: + advertiseAddress: 192.168.2.2 + bindPort: 6443 + controlPlaneEndpoint: "" +apiVersion: kubeadm.k8s.io/v1alpha3 +auditPolicy: + logDir: /var/log/kubernetes/audit + logMaxAge: 2 + path: "" certificatesDir: /var/lib/kubernetes/pki clusterName: kubernetes etcd: @@ -22,18 +31,12 @@ etcd: dataDir: /var/lib/etcd image: "" imageRepository: my-company.com -kind: InitConfiguration +kind: ClusterConfiguration kubernetesVersion: v1.10.2 networking: dnsDomain: cluster.global podSubnet: 10.148.0.0/16 serviceSubnet: 10.196.0.0/12 -nodeRegistration: - criSocket: /var/run/criruntime.sock - name: master-1 - taints: - - effect: NoSchedule - key: node-role.kubernetes.io/master unifiedControlPlaneImage: "" --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 diff --git a/cmd/kubeadm/app/util/marshal.go b/cmd/kubeadm/app/util/marshal.go index 19998df65e2d0..a22f62ba62ce8 100644 --- a/cmd/kubeadm/app/util/marshal.go +++ b/cmd/kubeadm/app/util/marshal.go @@ -147,6 +147,11 @@ func GroupVersionKindsHasKind(gvks []schema.GroupVersionKind, kind string) bool return false } +// GroupVersionKindsHasClusterConfiguration returns whether the following gvk slice contains a ClusterConfiguration object +func GroupVersionKindsHasClusterConfiguration(gvks ...schema.GroupVersionKind) bool { + return GroupVersionKindsHasKind(gvks, constants.ClusterConfigurationKind) +} + // GroupVersionKindsHasInitConfiguration returns whether the following gvk slice contains a InitConfiguration object func GroupVersionKindsHasInitConfiguration(gvks ...schema.GroupVersionKind) bool { // Finding a MasterConfiguration kind is also okay, as it will decode and convert into an InitConfiguration struct eventually diff --git a/cmd/kubeadm/app/util/marshal_test.go b/cmd/kubeadm/app/util/marshal_test.go index 4da9e14295d36..0fa756b787818 100644 --- a/cmd/kubeadm/app/util/marshal_test.go +++ b/cmd/kubeadm/app/util/marshal_test.go @@ -111,26 +111,21 @@ func TestMarshalUnmarshalYaml(t *testing.T) { func TestMarshalUnmarshalToYamlForCodecs(t *testing.T) { cfg := &kubeadmapiv1alpha3.InitConfiguration{ TypeMeta: metav1.TypeMeta{ - Kind: "InitConfiguration", + Kind: constants.InitConfigurationKind, APIVersion: kubeadmapiv1alpha3.SchemeGroupVersion.String(), }, - API: kubeadmapiv1alpha3.API{ - AdvertiseAddress: "10.100.0.1", - BindPort: 4332, - }, NodeRegistration: kubeadmapiv1alpha3.NodeRegistrationOptions{ Name: "testNode", CRISocket: "/var/run/cri.sock", }, - Networking: kubeadmapiv1alpha3.Networking{ - ServiceSubnet: "10.100.0.0/24", - PodSubnet: "10.100.1.0/24", - }, BootstrapTokens: []kubeadmapiv1alpha3.BootstrapToken{ { Token: &kubeadmapiv1alpha3.BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, }, }, + // NOTE: Using MarshalToYamlForCodecs and UnmarshalFromYamlForCodecs for ClusterConfiguration fields here won't work + // by design. This is because we have a `json:"-"` annotation in order to avoid struct duplication. See the comment + // at the kubeadmapiv1alpha3.InitConfiguration definition. } kubeadmapiv1alpha3.SetDefaults_InitConfiguration(cfg) diff --git a/cmd/kubeadm/app/util/staticpod/utils_test.go b/cmd/kubeadm/app/util/staticpod/utils_test.go index 7200def0ea2cd..e6673271bc843 100644 --- a/cmd/kubeadm/app/util/staticpod/utils_test.go +++ b/cmd/kubeadm/app/util/staticpod/utils_test.go @@ -46,7 +46,7 @@ func TestComponentResources(t *testing.T) { func TestComponentProbe(t *testing.T) { var tests = []struct { name string - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration component string port int path string @@ -55,7 +55,7 @@ func TestComponentProbe(t *testing.T) { }{ { name: "default apiserver advertise address with http", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{ AdvertiseAddress: "", }, @@ -68,7 +68,7 @@ func TestComponentProbe(t *testing.T) { }, { name: "default apiserver advertise address with http", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{ AdvertiseAddress: "1.2.3.4", }, @@ -84,7 +84,7 @@ func TestComponentProbe(t *testing.T) { }, { name: "default apiserver advertise address with https", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{ AdvertiseAddress: "", }, @@ -97,7 +97,7 @@ func TestComponentProbe(t *testing.T) { }, { name: "valid ipv4 apiserver advertise address with http", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{ AdvertiseAddress: "1.2.3.4", }, @@ -110,7 +110,7 @@ func TestComponentProbe(t *testing.T) { }, { name: "valid ipv6 apiserver advertise address with http", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ API: kubeadmapi.API{ AdvertiseAddress: "2001:db8::1", }, @@ -123,7 +123,7 @@ func TestComponentProbe(t *testing.T) { }, { name: "valid IPv4 controller-manager probe", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ ControllerManagerExtraArgs: map[string]string{"address": "1.2.3.4"}, }, component: kubeadmconstants.KubeControllerManager, @@ -134,7 +134,7 @@ func TestComponentProbe(t *testing.T) { }, { name: "valid IPv6 controller-manager probe", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ ControllerManagerExtraArgs: map[string]string{"address": "2001:db8::1"}, }, component: kubeadmconstants.KubeControllerManager, @@ -145,7 +145,7 @@ func TestComponentProbe(t *testing.T) { }, { name: "valid IPv4 scheduler probe", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ SchedulerExtraArgs: map[string]string{"address": "1.2.3.4"}, }, component: kubeadmconstants.KubeScheduler, @@ -156,7 +156,7 @@ func TestComponentProbe(t *testing.T) { }, { name: "valid IPv6 scheduler probe", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ SchedulerExtraArgs: map[string]string{"address": "2001:db8::1"}, }, component: kubeadmconstants.KubeScheduler, @@ -167,7 +167,11 @@ func TestComponentProbe(t *testing.T) { }, } for _, rt := range tests { - actual := ComponentProbe(rt.cfg, rt.component, rt.port, rt.path, rt.scheme) + // TODO: Make ComponentProbe accept a ClusterConfiguration object instead of InitConfiguration + initcfg := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: *rt.cfg, + } + actual := ComponentProbe(initcfg, rt.component, rt.port, rt.path, rt.scheme) if actual.Handler.HTTPGet.Host != rt.expected { t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s", rt.name, rt.expected, @@ -194,7 +198,7 @@ func TestComponentProbe(t *testing.T) { func TestEtcdProbe(t *testing.T) { var tests = []struct { name string - cfg *kubeadmapi.InitConfiguration + cfg *kubeadmapi.ClusterConfiguration component string port int certsDir string @@ -205,7 +209,7 @@ func TestEtcdProbe(t *testing.T) { }{ { name: "valid etcd probe using listen-client-urls IPv4 addresses", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ ExtraArgs: map[string]string{ @@ -223,7 +227,7 @@ func TestEtcdProbe(t *testing.T) { }, { name: "valid etcd probe using listen-client-urls unspecified IPv6 address", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ ExtraArgs: map[string]string{ @@ -241,7 +245,7 @@ func TestEtcdProbe(t *testing.T) { }, { name: "valid etcd probe using listen-client-urls unspecified IPv6 address 2", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ ExtraArgs: map[string]string{ @@ -259,7 +263,7 @@ func TestEtcdProbe(t *testing.T) { }, { name: "valid etcd probe using listen-client-urls unspecified IPv6 address 3", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ ExtraArgs: map[string]string{ @@ -277,7 +281,7 @@ func TestEtcdProbe(t *testing.T) { }, { name: "valid etcd probe using listen-client-urls unspecified IPv4 address", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ ExtraArgs: map[string]string{ @@ -295,7 +299,7 @@ func TestEtcdProbe(t *testing.T) { }, { name: "valid etcd probe using listen-client-urls IPv6 addresses", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ ExtraArgs: map[string]string{ @@ -313,7 +317,7 @@ func TestEtcdProbe(t *testing.T) { }, { name: "valid IPv4 etcd probe using hostname for listen-client-urls", - cfg: &kubeadmapi.InitConfiguration{ + cfg: &kubeadmapi.ClusterConfiguration{ Etcd: kubeadmapi.Etcd{ Local: &kubeadmapi.LocalEtcd{ ExtraArgs: map[string]string{ @@ -331,7 +335,11 @@ func TestEtcdProbe(t *testing.T) { }, } for _, rt := range tests { - actual := EtcdProbe(rt.cfg, rt.component, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key) + // TODO: Make EtcdProbe accept a ClusterConfiguration object instead of InitConfiguration + initcfg := &kubeadmapi.InitConfiguration{ + ClusterConfiguration: *rt.cfg, + } + actual := EtcdProbe(initcfg, rt.component, rt.port, rt.certsDir, rt.cacert, rt.cert, rt.key) if actual.Handler.Exec.Command[2] != rt.expected { t.Errorf("%s test case failed:\n\texpected: %s\n\t actual: %s", rt.name, rt.expected, diff --git a/cmd/kubeadm/test/util.go b/cmd/kubeadm/test/util.go index c6487a025639f..1ab6a3a0edc48 100644 --- a/cmd/kubeadm/test/util.go +++ b/cmd/kubeadm/test/util.go @@ -55,12 +55,15 @@ func SetupInitConfigurationFile(t *testing.T, tmpdir string, cfg *kubeadmapi.Ini cfgTemplate := template.Must(template.New("init").Parse(dedent.Dedent(` apiVersion: kubeadm.k8s.io/v1alpha3 kind: InitConfiguration + nodeRegistration: + name: {{.NodeRegistration.Name}} + --- + apiVersion: kubeadm.k8s.io/v1alpha3 + kind: ClusterConfiguration certificatesDir: {{.CertificatesDir}} api: advertiseAddress: {{.API.AdvertiseAddress}} bindPort: {{.API.BindPort}} - nodeRegistration: - name: {{.NodeRegistration.Name}} kubernetesVersion: v1.10.0 `))) From 0fde05ac53dfd04a0217c9203fe39e41ce099b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20K=C3=A4ldstr=C3=B6m?= Date: Fri, 10 Aug 2018 21:45:00 +0300 Subject: [PATCH 2/2] update some stuff --- .../app/apis/kubeadm/v1alpha2/conversion.go | 28 ---- .../v1alpha2/zz_generated.conversion.go | 70 +++------ .../v1alpha3/zz_generated.conversion.go | 142 +++++++++++------- .../kubeadm/v1alpha3/zz_generated.deepcopy.go | 130 +++++++++------- .../kubeadm/v1alpha3/zz_generated.defaults.go | 6 + .../app/apis/kubeadm/zz_generated.deepcopy.go | 132 +++++++++------- cmd/kubeadm/app/images/images_test.go | 74 ++++++--- cmd/kubeadm/app/util/config/masterconfig.go | 1 + 8 files changed, 320 insertions(+), 263 deletions(-) diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go index bd48348752628..ade16575723fe 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/conversion.go @@ -132,31 +132,3 @@ func Convert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(in *kubeadm return nil } -/* - if err := Convert_v1alpha2_API_To_kubeadm_API(&in.API, &out.ClusterConfiguration.API, s); err != nil { - return err - } - if err := Convert_v1alpha2_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.ClusterConfiguration.Etcd, s); err != nil { - return err - } - if err := Convert_v1alpha2_Networking_To_kubeadm_Networking(&in.Networking, &out.ClusterConfiguration.Networking, s); err != nil { - return err - } - out.ClusterConfiguration.KubernetesVersion = in.KubernetesVersion - out.ClusterConfiguration.APIServerExtraArgs = in.APIServerExtraArgs - out.ClusterConfiguration.ControllerManagerExtraArgs = in.ControllerManagerExtraArgs - out.ClusterConfiguration.SchedulerExtraArgs = in.SchedulerExtraArgs - out.ClusterConfiguration.APIServerExtraVolumes = in.APIServerExtraVolumes - out.ClusterConfiguration.ControllerManagerExtraVolumes = in.ControllerManagerExtraVolumes - out.ClusterConfiguration.SchedulerExtraVolumes = in.SchedulerExtraVolumes - out.ClusterConfiguration.APIServerCertSANs = in.APIServerCertSANs - out.ClusterConfiguration.CertificatesDir = in.CertificatesDir - out.ClusterConfiguration.ImageRepository = in.ImageRepository - out.ClusterConfiguration.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage - if err := Convert_v1alpha2_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.ClusterConfiguration.AuditPolicyConfiguration, s); err != nil { - return err - } - out.ClusterConfiguration.FeatureGates = in.FeatureGates - out.ClusterConfiguration.ClusterName = in.ClusterName - -*/ \ No newline at end of file diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go index 11a7c9dd21b64..f374a21feb5fb 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha2/zz_generated.conversion.go @@ -351,68 +351,34 @@ func autoConvert_v1alpha2_InitConfiguration_To_kubeadm_InitConfiguration(in *Ini if err := Convert_v1alpha2_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err } - if err := Convert_v1alpha2_API_To_kubeadm_API(&in.API, &out.API, s); err != nil { - return err - } + // WARNING: in.API requires manual conversion: does not exist in peer-type // WARNING: in.KubeProxy requires manual conversion: does not exist in peer-type - if err := Convert_v1alpha2_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil { - return err - } + // WARNING: in.Etcd requires manual conversion: does not exist in peer-type // WARNING: in.KubeletConfiguration requires manual conversion: does not exist in peer-type - if err := Convert_v1alpha2_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil { - return err - } - out.KubernetesVersion = in.KubernetesVersion - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) - out.CertificatesDir = in.CertificatesDir - out.ImageRepository = in.ImageRepository - out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage - if err := Convert_v1alpha2_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { - return err - } - out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) - out.ClusterName = in.ClusterName + // WARNING: in.Networking requires manual conversion: does not exist in peer-type + // WARNING: in.KubernetesVersion requires manual conversion: does not exist in peer-type + // WARNING: in.APIServerExtraArgs requires manual conversion: does not exist in peer-type + // WARNING: in.ControllerManagerExtraArgs requires manual conversion: does not exist in peer-type + // WARNING: in.SchedulerExtraArgs requires manual conversion: does not exist in peer-type + // WARNING: in.APIServerExtraVolumes requires manual conversion: does not exist in peer-type + // WARNING: in.ControllerManagerExtraVolumes requires manual conversion: does not exist in peer-type + // WARNING: in.SchedulerExtraVolumes requires manual conversion: does not exist in peer-type + // WARNING: in.APIServerCertSANs requires manual conversion: does not exist in peer-type + // WARNING: in.CertificatesDir requires manual conversion: does not exist in peer-type + // WARNING: in.ImageRepository requires manual conversion: does not exist in peer-type + // WARNING: in.UnifiedControlPlaneImage requires manual conversion: does not exist in peer-type + // WARNING: in.AuditPolicyConfiguration requires manual conversion: does not exist in peer-type + // WARNING: in.FeatureGates requires manual conversion: does not exist in peer-type + // WARNING: in.ClusterName requires manual conversion: does not exist in peer-type return nil } func autoConvert_kubeadm_InitConfiguration_To_v1alpha2_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error { + // 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_v1alpha2_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err } - // INFO: in.ComponentConfigs opted out of conversion generation - if err := Convert_kubeadm_API_To_v1alpha2_API(&in.API, &out.API, s); err != nil { - return err - } - if err := Convert_kubeadm_Etcd_To_v1alpha2_Etcd(&in.Etcd, &out.Etcd, s); err != nil { - return err - } - if err := Convert_kubeadm_Networking_To_v1alpha2_Networking(&in.Networking, &out.Networking, s); err != nil { - return err - } - out.KubernetesVersion = in.KubernetesVersion - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) - out.CertificatesDir = in.CertificatesDir - out.ImageRepository = in.ImageRepository - // INFO: in.CIImageRepository opted out of conversion generation - out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage - if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha2_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { - return err - } - out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) - out.ClusterName = in.ClusterName return nil } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go index ecadb313e7f59..a5ca999b13724 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.conversion.go @@ -77,6 +77,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*ClusterConfiguration)(nil), (*kubeadm.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(a.(*ClusterConfiguration), b.(*kubeadm.ClusterConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*kubeadm.ClusterConfiguration)(nil), (*ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(a.(*kubeadm.ClusterConfiguration), b.(*ClusterConfiguration), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*Etcd)(nil), (*kubeadm.Etcd)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha3_Etcd_To_kubeadm_Etcd(a.(*Etcd), b.(*kubeadm.Etcd), scope) }); err != nil { @@ -157,8 +167,8 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*InitConfiguration)(nil), (*kubeadm.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(a.(*InitConfiguration), b.(*kubeadm.InitConfiguration), scope) + if err := s.AddConversionFunc((*ClusterConfiguration)(nil), (*kubeadm.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(a.(*ClusterConfiguration), b.(*kubeadm.ClusterConfiguration), scope) }); err != nil { return err } @@ -265,6 +275,71 @@ func Convert_kubeadm_BootstrapTokenString_To_v1alpha3_BootstrapTokenString(in *k return autoConvert_kubeadm_BootstrapTokenString_To_v1alpha3_BootstrapTokenString(in, out, s) } +func autoConvert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *ClusterConfiguration, out *kubeadm.ClusterConfiguration, s conversion.Scope) error { + if err := Convert_v1alpha3_API_To_kubeadm_API(&in.API, &out.API, s); err != nil { + return err + } + if err := Convert_v1alpha3_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil { + return err + } + if err := Convert_v1alpha3_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil { + return err + } + out.KubernetesVersion = in.KubernetesVersion + out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) + out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) + out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) + out.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) + out.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) + out.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) + out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + out.CertificatesDir = in.CertificatesDir + out.ImageRepository = in.ImageRepository + out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage + if err := Convert_v1alpha3_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { + return err + } + out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) + out.ClusterName = in.ClusterName + return nil +} + +func autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *kubeadm.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error { + // INFO: in.ComponentConfigs opted out of conversion generation + if err := Convert_kubeadm_API_To_v1alpha3_API(&in.API, &out.API, s); err != nil { + return err + } + if err := Convert_kubeadm_Etcd_To_v1alpha3_Etcd(&in.Etcd, &out.Etcd, s); err != nil { + return err + } + if err := Convert_kubeadm_Networking_To_v1alpha3_Networking(&in.Networking, &out.Networking, s); err != nil { + return err + } + out.KubernetesVersion = in.KubernetesVersion + out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) + out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) + out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) + out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) + out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) + out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) + out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) + out.CertificatesDir = in.CertificatesDir + out.ImageRepository = in.ImageRepository + // INFO: in.CIImageRepository opted out of conversion generation + out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage + if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha3_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { + return err + } + out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) + out.ClusterName = in.ClusterName + return nil +} + +// Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration is an autogenerated conversion function. +func Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *kubeadm.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error { + return autoConvert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in, out, s) +} + func autoConvert_v1alpha3_Etcd_To_kubeadm_Etcd(in *Etcd, out *kubeadm.Etcd, s conversion.Scope) error { out.Local = (*kubeadm.LocalEtcd)(unsafe.Pointer(in.Local)) out.External = (*kubeadm.ExternalEtcd)(unsafe.Pointer(in.External)) @@ -342,70 +417,29 @@ func Convert_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *kubeadm.HostPat } func autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { - out.BootstrapTokens = *(*[]kubeadm.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) - if err := Convert_v1alpha3_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { - return err - } - if err := Convert_v1alpha3_API_To_kubeadm_API(&in.API, &out.API, s); err != nil { - return err - } - if err := Convert_v1alpha3_Etcd_To_kubeadm_Etcd(&in.Etcd, &out.Etcd, s); err != nil { + if err := Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil { return err } - if err := Convert_v1alpha3_Networking_To_kubeadm_Networking(&in.Networking, &out.Networking, s); err != nil { - return err - } - out.KubernetesVersion = in.KubernetesVersion - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]kubeadm.HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) - out.CertificatesDir = in.CertificatesDir - out.ImageRepository = in.ImageRepository - out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage - if err := Convert_v1alpha3_AuditPolicyConfiguration_To_kubeadm_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { + out.BootstrapTokens = *(*[]kubeadm.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) + if err := Convert_v1alpha3_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err } - out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) - out.ClusterName = in.ClusterName return nil } +// Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration is an autogenerated conversion function. +func Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s) +} + func autoConvert_kubeadm_InitConfiguration_To_v1alpha3_InitConfiguration(in *kubeadm.InitConfiguration, out *InitConfiguration, s conversion.Scope) error { - out.BootstrapTokens = *(*[]BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) - if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha3_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { - return err - } - // INFO: in.ComponentConfigs opted out of conversion generation - if err := Convert_kubeadm_API_To_v1alpha3_API(&in.API, &out.API, s); err != nil { + if err := Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(&in.ClusterConfiguration, &out.ClusterConfiguration, s); err != nil { return err } - if err := Convert_kubeadm_Etcd_To_v1alpha3_Etcd(&in.Etcd, &out.Etcd, s); err != nil { - return err - } - if err := Convert_kubeadm_Networking_To_v1alpha3_Networking(&in.Networking, &out.Networking, s); err != nil { - return err - } - out.KubernetesVersion = in.KubernetesVersion - out.APIServerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.APIServerExtraArgs)) - out.ControllerManagerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ControllerManagerExtraArgs)) - out.SchedulerExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.SchedulerExtraArgs)) - out.APIServerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.APIServerExtraVolumes)) - out.ControllerManagerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ControllerManagerExtraVolumes)) - out.SchedulerExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.SchedulerExtraVolumes)) - out.APIServerCertSANs = *(*[]string)(unsafe.Pointer(&in.APIServerCertSANs)) - out.CertificatesDir = in.CertificatesDir - out.ImageRepository = in.ImageRepository - // INFO: in.CIImageRepository opted out of conversion generation - out.UnifiedControlPlaneImage = in.UnifiedControlPlaneImage - if err := Convert_kubeadm_AuditPolicyConfiguration_To_v1alpha3_AuditPolicyConfiguration(&in.AuditPolicyConfiguration, &out.AuditPolicyConfiguration, s); err != nil { + out.BootstrapTokens = *(*[]BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) + if err := Convert_kubeadm_NodeRegistrationOptions_To_v1alpha3_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { return err } - out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) - out.ClusterName = in.ClusterName return nil } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.deepcopy.go index 1a4d6c7c14d26..b179a3ea28b11 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.deepcopy.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.deepcopy.go @@ -119,6 +119,83 @@ func (in *BootstrapTokenString) DeepCopy() *BootstrapTokenString { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + out.API = in.API + in.Etcd.DeepCopyInto(&out.Etcd) + out.Networking = in.Networking + if in.APIServerExtraArgs != nil { + in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ControllerManagerExtraArgs != nil { + in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.SchedulerExtraArgs != nil { + in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.APIServerExtraVolumes != nil { + in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } + if in.ControllerManagerExtraVolumes != nil { + in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } + if in.SchedulerExtraVolumes != nil { + in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } + if in.APIServerCertSANs != nil { + in, out := &in.APIServerCertSANs, &out.APIServerCertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration) + if in.FeatureGates != nil { + in, out := &in.FeatureGates, &out.FeatureGates + *out = make(map[string]bool, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterConfiguration. +func (in *ClusterConfiguration) DeepCopy() *ClusterConfiguration { + if in == nil { + return nil + } + out := new(ClusterConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Etcd) DeepCopyInto(out *Etcd) { *out = *in @@ -186,6 +263,7 @@ func (in *HostPathMount) DeepCopy() *HostPathMount { 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)) @@ -194,58 +272,6 @@ func (in *InitConfiguration) DeepCopyInto(out *InitConfiguration) { } } in.NodeRegistration.DeepCopyInto(&out.NodeRegistration) - out.API = in.API - in.Etcd.DeepCopyInto(&out.Etcd) - out.Networking = in.Networking - if in.APIServerExtraArgs != nil { - in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.ControllerManagerExtraArgs != nil { - in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.SchedulerExtraArgs != nil { - in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.APIServerExtraVolumes != nil { - in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.ControllerManagerExtraVolumes != nil { - in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.SchedulerExtraVolumes != nil { - in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.APIServerCertSANs != nil { - in, out := &in.APIServerCertSANs, &out.APIServerCertSANs - *out = make([]string, len(*in)) - copy(*out, *in) - } - in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration) - if in.FeatureGates != nil { - in, out := &in.FeatureGates, &out.FeatureGates - *out = make(map[string]bool, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } return } diff --git a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.defaults.go b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.defaults.go index e614395b6c32d..6d0492f1f6066 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.defaults.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1alpha3/zz_generated.defaults.go @@ -28,13 +28,19 @@ import ( // Public to allow building arbitrary schemes. // All generated defaulters are covering - they call all nested defaulters. func RegisterDefaults(scheme *runtime.Scheme) error { + scheme.AddTypeDefaultingFunc(&ClusterConfiguration{}, func(obj interface{}) { SetObjectDefaults_ClusterConfiguration(obj.(*ClusterConfiguration)) }) scheme.AddTypeDefaultingFunc(&InitConfiguration{}, func(obj interface{}) { SetObjectDefaults_InitConfiguration(obj.(*InitConfiguration)) }) scheme.AddTypeDefaultingFunc(&JoinConfiguration{}, func(obj interface{}) { SetObjectDefaults_JoinConfiguration(obj.(*JoinConfiguration)) }) return nil } +func SetObjectDefaults_ClusterConfiguration(in *ClusterConfiguration) { + SetDefaults_ClusterConfiguration(in) +} + 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/apis/kubeadm/zz_generated.deepcopy.go b/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go index 0cd56658ca2f3..c5e80de8b5cf4 100644 --- a/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go +++ b/cmd/kubeadm/app/apis/kubeadm/zz_generated.deepcopy.go @@ -121,6 +121,84 @@ func (in *BootstrapTokenString) DeepCopy() *BootstrapTokenString { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ComponentConfigs.DeepCopyInto(&out.ComponentConfigs) + out.API = in.API + in.Etcd.DeepCopyInto(&out.Etcd) + out.Networking = in.Networking + if in.APIServerExtraArgs != nil { + in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ControllerManagerExtraArgs != nil { + in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.SchedulerExtraArgs != nil { + in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.APIServerExtraVolumes != nil { + in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } + if in.ControllerManagerExtraVolumes != nil { + in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } + if in.SchedulerExtraVolumes != nil { + in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } + if in.APIServerCertSANs != nil { + in, out := &in.APIServerCertSANs, &out.APIServerCertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration) + if in.FeatureGates != nil { + in, out := &in.FeatureGates, &out.FeatureGates + *out = make(map[string]bool, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterConfiguration. +func (in *ClusterConfiguration) DeepCopy() *ClusterConfiguration { + if in == nil { + return nil + } + out := new(ClusterConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ComponentConfigs) DeepCopyInto(out *ComponentConfigs) { *out = *in @@ -214,6 +292,7 @@ func (in *HostPathMount) DeepCopy() *HostPathMount { 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)) @@ -222,59 +301,6 @@ func (in *InitConfiguration) DeepCopyInto(out *InitConfiguration) { } } in.NodeRegistration.DeepCopyInto(&out.NodeRegistration) - in.ComponentConfigs.DeepCopyInto(&out.ComponentConfigs) - out.API = in.API - in.Etcd.DeepCopyInto(&out.Etcd) - out.Networking = in.Networking - if in.APIServerExtraArgs != nil { - in, out := &in.APIServerExtraArgs, &out.APIServerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.ControllerManagerExtraArgs != nil { - in, out := &in.ControllerManagerExtraArgs, &out.ControllerManagerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.SchedulerExtraArgs != nil { - in, out := &in.SchedulerExtraArgs, &out.SchedulerExtraArgs - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.APIServerExtraVolumes != nil { - in, out := &in.APIServerExtraVolumes, &out.APIServerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.ControllerManagerExtraVolumes != nil { - in, out := &in.ControllerManagerExtraVolumes, &out.ControllerManagerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.SchedulerExtraVolumes != nil { - in, out := &in.SchedulerExtraVolumes, &out.SchedulerExtraVolumes - *out = make([]HostPathMount, len(*in)) - copy(*out, *in) - } - if in.APIServerCertSANs != nil { - in, out := &in.APIServerCertSANs, &out.APIServerCertSANs - *out = make([]string, len(*in)) - copy(*out, *in) - } - in.AuditPolicyConfiguration.DeepCopyInto(&out.AuditPolicyConfiguration) - if in.FeatureGates != nil { - in, out := &in.FeatureGates, &out.FeatureGates - *out = make(map[string]bool, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } return } diff --git a/cmd/kubeadm/app/images/images_test.go b/cmd/kubeadm/app/images/images_test.go index 3475629d5e25a..e1806044e55af 100644 --- a/cmd/kubeadm/app/images/images_test.go +++ b/cmd/kubeadm/app/images/images_test.go @@ -54,31 +54,39 @@ func TestGetKubeControlPlaneImage(t *testing.T) { { expected: "override", cfg: &kubeadmapi.InitConfiguration{ - UnifiedControlPlaneImage: "override", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + UnifiedControlPlaneImage: "override", + }, }, }, { image: constants.KubeAPIServer, expected: GetGenericArchImage(gcrPrefix, "kube-apiserver", expected), cfg: &kubeadmapi.InitConfiguration{ - ImageRepository: gcrPrefix, - KubernetesVersion: testversion, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + ImageRepository: gcrPrefix, + KubernetesVersion: testversion, + }, }, }, { image: constants.KubeControllerManager, expected: GetGenericArchImage(gcrPrefix, "kube-controller-manager", expected), cfg: &kubeadmapi.InitConfiguration{ - ImageRepository: gcrPrefix, - KubernetesVersion: testversion, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + ImageRepository: gcrPrefix, + KubernetesVersion: testversion, + }, }, }, { image: constants.KubeScheduler, expected: GetGenericArchImage(gcrPrefix, "kube-scheduler", expected), cfg: &kubeadmapi.InitConfiguration{ - ImageRepository: gcrPrefix, - KubernetesVersion: testversion, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + ImageRepository: gcrPrefix, + KubernetesVersion: testversion, + }, }, }, } @@ -102,9 +110,11 @@ func TestGetEtcdImage(t *testing.T) { { expected: "override", cfg: &kubeadmapi.InitConfiguration{ - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{ - Image: "override", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{ + Image: "override", + }, }, }, }, @@ -112,8 +122,10 @@ func TestGetEtcdImage(t *testing.T) { { expected: GetGenericArchImage(gcrPrefix, "etcd", constants.DefaultEtcdVersion), cfg: &kubeadmapi.InitConfiguration{ - ImageRepository: gcrPrefix, - KubernetesVersion: testversion, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + ImageRepository: gcrPrefix, + KubernetesVersion: testversion, + }, }, }, } @@ -138,22 +150,28 @@ func TestGetAllImages(t *testing.T) { { name: "defined CIImageRepository", cfg: &kubeadmapi.InitConfiguration{ - CIImageRepository: "test.repo", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + CIImageRepository: "test.repo", + }, }, expect: "test.repo", }, { name: "undefined CIImagerRepository should contain the default image prefix", cfg: &kubeadmapi.InitConfiguration{ - ImageRepository: "real.repo", + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + ImageRepository: "real.repo", + }, }, expect: "real.repo", }, { name: "test that etcd is returned when it is not external", cfg: &kubeadmapi.InitConfiguration{ - Etcd: kubeadmapi.Etcd{ - Local: &kubeadmapi.LocalEtcd{}, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + Etcd: kubeadmapi.Etcd{ + Local: &kubeadmapi.LocalEtcd{}, + }, }, }, expect: constants.Etcd, @@ -161,8 +179,10 @@ func TestGetAllImages(t *testing.T) { { name: "CoreDNS image is returned", cfg: &kubeadmapi.InitConfiguration{ - FeatureGates: map[string]bool{ - "CoreDNS": true, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + FeatureGates: map[string]bool{ + "CoreDNS": true, + }, }, }, expect: constants.CoreDNS, @@ -170,8 +190,10 @@ func TestGetAllImages(t *testing.T) { { name: "main kube-dns image is returned", cfg: &kubeadmapi.InitConfiguration{ - FeatureGates: map[string]bool{ - "CoreDNS": false, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + FeatureGates: map[string]bool{ + "CoreDNS": false, + }, }, }, expect: "k8s-dns-kube-dns", @@ -179,8 +201,10 @@ func TestGetAllImages(t *testing.T) { { name: "kube-dns sidecar image is returned", cfg: &kubeadmapi.InitConfiguration{ - FeatureGates: map[string]bool{ - "CoreDNS": false, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + FeatureGates: map[string]bool{ + "CoreDNS": false, + }, }, }, expect: "k8s-dns-sidecar", @@ -188,8 +212,10 @@ func TestGetAllImages(t *testing.T) { { name: "kube-dns dnsmasq-nanny image is returned", cfg: &kubeadmapi.InitConfiguration{ - FeatureGates: map[string]bool{ - "CoreDNS": false, + ClusterConfiguration: kubeadmapi.ClusterConfiguration{ + FeatureGates: map[string]bool{ + "CoreDNS": false, + }, }, }, expect: "k8s-dns-dnsmasq-nanny", diff --git a/cmd/kubeadm/app/util/config/masterconfig.go b/cmd/kubeadm/app/util/config/masterconfig.go index 229e80bf3a364..23ad28be10421 100644 --- a/cmd/kubeadm/app/util/config/masterconfig.go +++ b/cmd/kubeadm/app/util/config/masterconfig.go @@ -64,6 +64,7 @@ func SetInitDynamicDefaults(cfg *kubeadmapi.InitConfiguration) error { cfg.BootstrapTokens[i].Token = token } + var err error cfg.NodeRegistration.Name, err = nodeutil.GetHostname(cfg.NodeRegistration.Name) if err != nil { return err