diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer_test.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer_test.go index 7a876d384f..76014a56ff 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer_test.go +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer_test.go @@ -16,11 +16,6 @@ limitations under the License. package fuzzer -// 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" diff --git a/cmd/kubeadm/app/cmd/upgrade/common_test.go b/cmd/kubeadm/app/cmd/upgrade/common_test.go index 47199c1b99..0554623eba 100644 --- a/cmd/kubeadm/app/cmd/upgrade/common_test.go +++ b/cmd/kubeadm/app/cmd/upgrade/common_test.go @@ -43,7 +43,7 @@ func TestPrintConfiguration(t *testing.T) { }, }, expectedBytes: []byte(`[upgrade/config] Configuration used: - apiVersion: kubeadm.k8s.io/v1alpha3 + apiVersion: kubeadm.k8s.io/v1beta1 auditPolicy: logDir: "" path: "" @@ -76,7 +76,7 @@ func TestPrintConfiguration(t *testing.T) { }, }, expectedBytes: []byte(`[upgrade/config] Configuration used: - apiVersion: kubeadm.k8s.io/v1alpha3 + apiVersion: kubeadm.k8s.io/v1beta1 auditPolicy: logDir: "" path: "" diff --git a/cmd/kubeadm/app/phases/upgrade/staticpods_test.go b/cmd/kubeadm/app/phases/upgrade/staticpods_test.go index ea58b28f23..7a01ba6c8d 100644 --- a/cmd/kubeadm/app/phases/upgrade/staticpods_test.go +++ b/cmd/kubeadm/app/phases/upgrade/staticpods_test.go @@ -49,13 +49,13 @@ const ( waitForPodsWithLabel = "wait-for-pods-with-label" testConfiguration = ` -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration nodeRegistration: name: foo criSocket: "" --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration api: advertiseAddress: 1.2.3.4 diff --git a/cmd/kubeadm/app/util/config/cluster_test.go b/cmd/kubeadm/app/util/config/cluster_test.go index b5d2a25aa9..ba8c7841c9 100644 --- a/cmd/kubeadm/app/util/config/cluster_test.go +++ b/cmd/kubeadm/app/util/config/cluster_test.go @@ -38,6 +38,27 @@ var k8sVersionString = "v1.12.0" var k8sVersion = version.MustParseGeneric(k8sVersionString) var nodeName = "mynode" var cfgFiles = map[string][]byte{ + "InitConfiguration_v1beta1": []byte(` +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +`), + "ClusterConfiguration_v1beta1": []byte(` +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterConfiguration +kubernetesVersion: ` + k8sVersionString + ` +`), + "ClusterStatus_v1beta1": []byte(` +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterStatus +apiEndpoints: + ` + nodeName + `: + advertiseAddress: 1.2.3.4 + bindPort: 1234 +`), + "ClusterStatus_v1beta1_Without_APIEndpoints": []byte(` +apiVersion: kubeadm.k8s.io/v1beta1 +kind: ClusterStatus +`), "InitConfiguration_v1alpha3": []byte(` apiVersion: kubeadm.k8s.io/v1alpha3 kind: InitConfiguration @@ -163,7 +184,23 @@ func TestLoadInitConfigurationFromFile(t *testing.T) { name string fileContents []byte }{ - // TODO: implemen v1beta1 tests after introducing v1beta1 + { + name: "v1beta1.partial1", + fileContents: cfgFiles["InitConfiguration_v1beta1"], + }, + { + name: "v1beta1.partial2", + fileContents: cfgFiles["ClusterConfiguration_v1beta1"], + }, + { + name: "v1beta1.full", + fileContents: bytes.Join([][]byte{ + cfgFiles["InitConfiguration_v1beta1"], + cfgFiles["ClusterConfiguration_v1beta1"], + cfgFiles["Kube-proxy_componentconfig"], + cfgFiles["Kubelet_componentconfig"], + }, []byte(kubeadmconstants.YAMLDocumentSeparator)), + }, { name: "v1alpha3.partial1", fileContents: cfgFiles["InitConfiguration_v1alpha3"], @@ -364,7 +401,34 @@ func TestGetAPIEndpoint(t *testing.T) { expectedError bool }{ { - name: "valid", + name: "valid v1beta1", + configMap: fakeConfigMap{ + name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. + data: map[string]string{ + kubeadmconstants.ClusterStatusConfigMapKey: string(cfgFiles["ClusterStatus_v1beta1"]), + }, + }, + }, + { + name: "invalid v1beta1 - No ClusterStatus in kubeadm-config ConfigMap", + configMap: fakeConfigMap{ + name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. + data: map[string]string{}, + }, + expectedError: true, + }, + { + name: "invalid v1beta1 - ClusterStatus without APIEndopoints", + configMap: fakeConfigMap{ + name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. + data: map[string]string{ + kubeadmconstants.ClusterStatusConfigMapKey: string(cfgFiles["ClusterStatus_v1beta1_Without_APIEndpoints"]), + }, + }, + expectedError: true, + }, + { + name: "valid v1alpha3", configMap: fakeConfigMap{ name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. data: map[string]string{ @@ -373,7 +437,7 @@ func TestGetAPIEndpoint(t *testing.T) { }, }, { - name: "invalid - No CLusterStatus in kubeadm-config ConfigMap", + name: "invalid v1alpha3 - No ClusterStatus in kubeadm-config ConfigMap", configMap: fakeConfigMap{ name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. data: map[string]string{}, @@ -381,7 +445,7 @@ func TestGetAPIEndpoint(t *testing.T) { expectedError: true, }, { - name: "invalid - CLusterStatus without APIEndopoints", + name: "invalid v1alpha3 - ClusterStatus without APIEndopoints", configMap: fakeConfigMap{ name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. data: map[string]string{ @@ -517,7 +581,7 @@ func TestGetInitConfigurationFromCluster(t *testing.T) { expectedError: true, }, { - name: "invalid - No CLusterConfiguration in kubeadm-config ConfigMap", + name: "invalid - No ClusterConfiguration in kubeadm-config ConfigMap", configMaps: []fakeConfigMap{ { name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. @@ -527,7 +591,67 @@ func TestGetInitConfigurationFromCluster(t *testing.T) { expectedError: true, }, { - name: "valid - new control plane == false", // InitConfiguration composed with data from different places, with also node specific information from ClusterStatus and node + name: "valid v1beta1 - new control plane == false", // InitConfiguration composed with data from different places, with also node specific information from ClusterStatus and node + configMaps: []fakeConfigMap{ + { + name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. + data: map[string]string{ + kubeadmconstants.ClusterConfigurationConfigMapKey: string(cfgFiles["ClusterConfiguration_v1beta1"]), + kubeadmconstants.ClusterStatusConfigMapKey: string(cfgFiles["ClusterStatus_v1beta1"]), + }, + }, + { + name: kubeadmconstants.KubeProxyConfigMap, // Kube-proxy component config from corresponding ConfigMap. + data: map[string]string{ + kubeadmconstants.KubeProxyConfigMapKey: string(cfgFiles["Kube-proxy_componentconfig"]), + }, + }, + { + name: kubeadmconstants.GetKubeletConfigMapName(k8sVersion), // Kubelet component config from corresponding ConfigMap. + data: map[string]string{ + kubeadmconstants.KubeletBaseConfigurationConfigMapKey: string(cfgFiles["Kubelet_componentconfig"]), + }, + }, + }, + fileContents: kubeletConfFiles["configWithEmbeddedCert"], + node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeName, + Annotations: map[string]string{ + kubeadmconstants.AnnotationKubeadmCRISocket: "myCRIsocket", + }, + }, + Spec: v1.NodeSpec{ + Taints: []v1.Taint{kubeadmconstants.MasterTaint}, + }, + }, + }, + { + name: "valid v1beta1 - new control plane == true", // InitConfiguration composed with data from different places, without node specific information + configMaps: []fakeConfigMap{ + { + name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. + data: map[string]string{ + kubeadmconstants.ClusterConfigurationConfigMapKey: string(cfgFiles["ClusterConfiguration_v1beta1"]), + }, + }, + { + name: kubeadmconstants.KubeProxyConfigMap, // Kube-proxy component config from corresponding ConfigMap. + data: map[string]string{ + kubeadmconstants.KubeProxyConfigMapKey: string(cfgFiles["Kube-proxy_componentconfig"]), + }, + }, + { + name: kubeadmconstants.GetKubeletConfigMapName(k8sVersion), // Kubelet component config from corresponding ConfigMap. + data: map[string]string{ + kubeadmconstants.KubeletBaseConfigurationConfigMapKey: string(cfgFiles["Kubelet_componentconfig"]), + }, + }, + }, + newControlPlane: true, + }, + { + name: "valid v1alpha3 - new control plane == false", // InitConfiguration composed with data from different places, with also node specific information from ClusterStatus and node configMaps: []fakeConfigMap{ { name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. @@ -563,7 +687,7 @@ func TestGetInitConfigurationFromCluster(t *testing.T) { }, }, { - name: "valid - new control plane == true", // InitConfiguration composed with data from different places, without node specific information + name: "valid v1alpha3 - new control plane == true", // InitConfiguration composed with data from different places, without node specific information configMaps: []fakeConfigMap{ { name: kubeadmconstants.KubeadmConfigConfigMap, // ClusterConfiguration from kubeadm-config. diff --git a/cmd/kubeadm/app/util/config/common_test.go b/cmd/kubeadm/app/util/config/common_test.go index ce671391a9..bc4ecf6093 100644 --- a/cmd/kubeadm/app/util/config/common_test.go +++ b/cmd/kubeadm/app/util/config/common_test.go @@ -20,7 +20,7 @@ import ( "bytes" "testing" - kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3" + kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" "k8s.io/kubernetes/cmd/kubeadm/app/constants" ) @@ -48,6 +48,14 @@ kind: InitConfiguration "Join_v1alpha3": []byte(` apiVersion: kubeadm.k8s.io/v1alpha3 kind: JoinConfiguration +`), + "Init_v1beta1": []byte(` +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +`), + "Join_v1beta1": []byte(` +apiVersion: kubeadm.k8s.io/v1beta1 +kind: JoinConfiguration `), "NoKind": []byte(` apiVersion: baz.k8s.io/v1 @@ -100,15 +108,43 @@ func TestDetectUnsupportedVersion(t *testing.T) { fileContents: files["Join_v1alpha3"], }, { - name: "DuplicateInit", + name: "Init_v1beta1", + fileContents: files["Init_v1beta1"], + }, + { + name: "Join_v1beta1", + fileContents: files["Join_v1beta1"], + }, + { + name: "DuplicateInit v1alpha3", fileContents: bytes.Join([][]byte{files["Init_v1alpha3"], files["Init_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), expectedErr: true, }, { - name: "DuplicateJoin", + name: "DuplicateInit v1beta1", + fileContents: bytes.Join([][]byte{files["Init_v1beta1"], files["Init_v1beta1"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "DuplicateInit v1beta1 and v1alpha3", + fileContents: bytes.Join([][]byte{files["Init_v1beta1"], files["Init_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "DuplicateJoin v1alpha3", fileContents: bytes.Join([][]byte{files["Join_v1alpha3"], files["Join_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), expectedErr: true, }, + { + name: "DuplicateJoin v1beta1", + fileContents: bytes.Join([][]byte{files["Join_v1beta1"], files["Join_v1beta1"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "DuplicateJoin v1beta1 and v1alpha3", + fileContents: bytes.Join([][]byte{files["Join_v1beta1"], files["Join_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, { name: "NoKind", fileContents: files["NoKind"], @@ -120,14 +156,31 @@ func TestDetectUnsupportedVersion(t *testing.T) { expectedErr: true, }, { - name: "v1alpha1InMultiple", - fileContents: bytes.Join([][]byte{files["Foo"], files["Master_v1alpha1"]}, []byte(constants.YAMLDocumentSeparator)), + name: "Ignore other Kind", + fileContents: bytes.Join([][]byte{files["Foo"], files["Master_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), + }, + { + name: "Ignore other Kind", + fileContents: bytes.Join([][]byte{files["Foo"], files["Master_v1beta1"]}, []byte(constants.YAMLDocumentSeparator)), + }, + { + name: "MustNotMixInitJoin v1alpha3", + fileContents: bytes.Join([][]byte{files["Init_v1alpha3"], files["Join_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), expectedErr: true, }, - // TODO: implement mustnotMix v1alpha3 v1beta1 after introducing v1beta1 { - name: "MustNotMixInitJoin", - fileContents: bytes.Join([][]byte{files["Init_v1alpha3"], files["Join_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), + name: "MustNotMixInitJoin v1alpha3 - v1beta1", + fileContents: bytes.Join([][]byte{files["Init_v1alpha3"], files["Join_v1beta1"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "MustNotMixInitJoin v1beta1 - v1alpha3", + fileContents: bytes.Join([][]byte{files["Init_v1beta1"], files["Join_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "MustNotMixInitJoin v1beta1", + fileContents: bytes.Join([][]byte{files["Init_v1beta1"], files["Join_v1beta1"]}, []byte(constants.YAMLDocumentSeparator)), expectedErr: true, }, } @@ -171,8 +224,8 @@ func TestLowercaseSANs(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - cfg := &kubeadmapiv1alpha3.InitConfiguration{ - ClusterConfiguration: kubeadmapiv1alpha3.ClusterConfiguration{ + cfg := &kubeadmapiv1beta1.InitConfiguration{ + ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{ APIServerCertSANs: test.in, }, } diff --git a/cmd/kubeadm/app/util/config/masterconfig_test.go b/cmd/kubeadm/app/util/config/masterconfig_test.go index de57d4b1e9..307d2f1e60 100644 --- a/cmd/kubeadm/app/util/config/masterconfig_test.go +++ b/cmd/kubeadm/app/util/config/masterconfig_test.go @@ -26,16 +26,16 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3" + kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" ) const ( - master_v1alpha3YAML = "testdata/conversion/master/v1alpha3.yaml" - //TODO master_v1beta1YAML = "testdata/conversion/master/v1beta1.yaml" after introducing v1beta1 - master_internalYAML = "testdata/conversion/master/internal.yaml" - //TODO master_incompleteYAML = "testdata/defaulting/master/incomplete.yaml" (using v1alpha3) after introducing v1beta1 - master_defaultedYAML = "testdata/defaulting/master/defaulted.yaml" - master_invalidYAML = "testdata/validation/invalid_mastercfg.yaml" + master_v1alpha3YAML = "testdata/conversion/master/v1alpha3.yaml" + master_v1beta1YAML = "testdata/conversion/master/v1beta1.yaml" + master_internalYAML = "testdata/conversion/master/internal.yaml" + master_incompleteYAML = "testdata/defaulting/master/incomplete.yaml" + master_defaultedYAML = "testdata/defaulting/master/defaulted.yaml" + master_invalidYAML = "testdata/validation/invalid_mastercfg.yaml" ) func diff(expected, actual []byte) string { @@ -65,17 +65,32 @@ func TestConfigFileAndDefaultsToInternalConfig(t *testing.T) { out: master_internalYAML, groupVersion: kubeadm.SchemeGroupVersion, }, - // TODO: implement v1beta1 <-> internal after introducing v1beta1 - // TODO: implement v1alpha3 -> internal -> v1beta1 after introducing v1beta1 - { // v1alpha3 -> internal -> v1alpha3 - name: "v1alpha3Tov1alpha3", + { // v1beta1 -> internal + name: "v1beta1ToInternal", + in: master_v1beta1YAML, + out: master_internalYAML, + groupVersion: kubeadm.SchemeGroupVersion, + }, + { // v1alpha3 -> internal -> v1beta1 + name: "v1alpha3Tov1beta1", in: master_v1alpha3YAML, - out: master_v1alpha3YAML, - groupVersion: kubeadmapiv1alpha3.SchemeGroupVersion, + out: master_v1beta1YAML, + groupVersion: kubeadmapiv1beta1.SchemeGroupVersion, + }, + { // v1beta1 -> internal -> v1beta1 + name: "v1beta1Tov1beta1", + in: master_v1beta1YAML, + out: master_v1beta1YAML, + groupVersion: kubeadmapiv1beta1.SchemeGroupVersion, }, // These tests are reading one file that has only a subset of the fields populated, loading it using ConfigFileAndDefaultsToInternalConfig, // and then marshals the internal object to the expected groupVersion - // TODO: implement v1alpha3 -> default -> validate -> v1beta1 -> v1alpha3 after introducing v1beta1 + { // v1beta1 -> default -> validate -> internal -> v1beta1 + name: "incompleteYAMLToDefaultedv1beta1", + in: master_incompleteYAML, + out: master_defaultedYAML, + groupVersion: kubeadmapiv1beta1.SchemeGroupVersion, + }, { // v1alpha3 -> validation should fail name: "invalidYAMLShouldFail", in: master_invalidYAML, @@ -86,7 +101,7 @@ func TestConfigFileAndDefaultsToInternalConfig(t *testing.T) { for _, rt := range tests { t.Run(rt.name, func(t2 *testing.T) { - internalcfg, err := ConfigFileAndDefaultsToInternalConfig(rt.in, &kubeadmapiv1alpha3.InitConfiguration{}) + internalcfg, err := ConfigFileAndDefaultsToInternalConfig(rt.in, &kubeadmapiv1beta1.InitConfiguration{}) if err != nil { if rt.expectedErr { return diff --git a/cmd/kubeadm/app/util/config/nodeconfig_test.go b/cmd/kubeadm/app/util/config/nodeconfig_test.go index c93882f148..065a294785 100644 --- a/cmd/kubeadm/app/util/config/nodeconfig_test.go +++ b/cmd/kubeadm/app/util/config/nodeconfig_test.go @@ -24,17 +24,17 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" - kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3" + kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" ) const ( - node_v1alpha3YAML = "testdata/conversion/node/v1alpha3.yaml" - //TODO node_v1beta1YAML = "testdata/conversion/node/v1beta1.yaml" after introducing v1beta1 - node_internalYAML = "testdata/conversion/node/internal.yaml" - //TODO node_incompleteYAML = "testdata/defaulting/node/incomplete.yaml" (using v1alpha3) after introducing v1beta1 - node_defaultedYAML = "testdata/defaulting/node/defaulted.yaml" - node_invalidYAML = "testdata/validation/invalid_nodecfg.yaml" + node_v1alpha3YAML = "testdata/conversion/node/v1alpha3.yaml" + node_v1beta1YAML = "testdata/conversion/node/v1beta1.yaml" + node_internalYAML = "testdata/conversion/node/internal.yaml" + node_incompleteYAML = "testdata/defaulting/node/incomplete.yaml" + node_defaultedYAML = "testdata/defaulting/node/defaulted.yaml" + node_invalidYAML = "testdata/validation/invalid_nodecfg.yaml" ) func TestNodeConfigFileAndDefaultsToInternalConfig(t *testing.T) { @@ -51,17 +51,32 @@ func TestNodeConfigFileAndDefaultsToInternalConfig(t *testing.T) { out: node_internalYAML, groupVersion: kubeadm.SchemeGroupVersion, }, - // TODO: implement v1beta1 <-> internal after introducing v1beta1 - // TODO: implement v1alpha3 -> internal -> v1beta1 after introducing v1beta1 - { // v1alpha3 -> internal -> v1alpha3 - name: "v1alpha3Tov1alpha3", + { // v1beta1 -> internal + name: "v1beta1ToInternal", + in: node_v1beta1YAML, + out: node_internalYAML, + groupVersion: kubeadm.SchemeGroupVersion, + }, + { // v1alpha3 -> internal -> v1beta1 + name: "v1alpha3Tov1beta1", in: node_v1alpha3YAML, - out: node_v1alpha3YAML, - groupVersion: kubeadmapiv1alpha3.SchemeGroupVersion, + out: node_v1beta1YAML, + groupVersion: kubeadmapiv1beta1.SchemeGroupVersion, + }, + { // v1beta1 -> internal -> v1beta1 + name: "v1beta1Tov1beta1", + in: node_v1beta1YAML, + out: node_v1beta1YAML, + groupVersion: kubeadmapiv1beta1.SchemeGroupVersion, }, // These tests are reading one file that has only a subset of the fields populated, loading it using NodeConfigFileAndDefaultsToInternalConfig, // and then marshals the internal object to the expected groupVersion - // TODO: implement v1alpha3 -> default -> validate -> v1beta1 -> v1alpha3 after introducing v1beta1 + { // v1beta1 -> default -> validate -> internal -> v1beta1 + name: "incompleteYAMLToDefaultedv1beta1", + in: node_incompleteYAML, + out: node_defaultedYAML, + groupVersion: kubeadmapiv1beta1.SchemeGroupVersion, + }, { // v1alpha3 -> validation should fail name: "invalidYAMLShouldFail", in: node_invalidYAML, @@ -72,7 +87,7 @@ func TestNodeConfigFileAndDefaultsToInternalConfig(t *testing.T) { for _, rt := range tests { t.Run(rt.name, func(t2 *testing.T) { - internalcfg, err := NodeConfigFileAndDefaultsToInternalConfig(rt.in, &kubeadmapiv1alpha3.JoinConfiguration{}) + internalcfg, err := NodeConfigFileAndDefaultsToInternalConfig(rt.in, &kubeadmapiv1beta1.JoinConfiguration{}) if err != nil { if rt.expectedErr { return diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/master/v1beta1.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1beta1.yaml new file mode 100644 index 0000000000..7f7106fede --- /dev/null +++ b/cmd/kubeadm/app/util/config/testdata/conversion/master/v1beta1.yaml @@ -0,0 +1,156 @@ +apiEndpoint: + advertiseAddress: 192.168.2.2 + bindPort: 6443 +apiVersion: kubeadm.k8s.io/v1beta1 +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 +--- +apiServerExtraArgs: + authorization-mode: Node,RBAC,Webhook +apiVersion: kubeadm.k8s.io/v1beta1 +auditPolicy: + logDir: /var/log/kubernetes/audit + logMaxAge: 2 + path: "" +certificatesDir: /etc/kubernetes/pki +clusterName: kubernetes +controlPlaneEndpoint: "" +etcd: + local: + dataDir: /var/lib/etcd + image: "" +imageRepository: k8s.gcr.io +kind: ClusterConfiguration +kubernetesVersion: v1.11.2 +networking: + dnsDomain: cluster.local + podSubnet: "" + serviceSubnet: 10.96.0.0/12 +unifiedControlPlaneImage: "" +--- +apiVersion: kubeproxy.config.k8s.io/v1alpha1 +bindAddress: 0.0.0.0 +clientConnection: + acceptContentTypes: "" + burst: 10 + contentType: application/vnd.kubernetes.protobuf + kubeconfig: /var/lib/kube-proxy/kubeconfig.conf + qps: 5 +clusterCIDR: "" +configSyncPeriod: 15m0s +conntrack: + max: null + maxPerCore: 32768 + min: 131072 + tcpCloseWaitTimeout: 1h0m0s + tcpEstablishedTimeout: 24h0m0s +enableProfiling: false +featureGates: + ServiceNodeExclusion: true + SupportIPVSProxyMode: true +healthzBindAddress: 0.0.0.0:10256 +hostnameOverride: "" +iptables: + masqueradeAll: false + masqueradeBit: 14 + minSyncPeriod: 0s + syncPeriod: 30s +ipvs: + excludeCIDRs: null + minSyncPeriod: 0s + scheduler: "" + syncPeriod: 30s +kind: KubeProxyConfiguration +metricsBindAddress: 127.0.0.1:10249 +mode: iptables +nodePortAddresses: null +oomScoreAdj: -999 +portRange: "" +resourceContainer: /kube-proxy +udpIdleTimeout: 250ms +--- +address: 1.2.3.4 +apiVersion: kubelet.config.k8s.io/v1beta1 +authentication: + anonymous: + enabled: false + webhook: + cacheTTL: 2m0s + enabled: true + x509: + clientCAFile: /etc/kubernetes/pki/ca.crt +authorization: + mode: Webhook + webhook: + cacheAuthorizedTTL: 5m0s + cacheUnauthorizedTTL: 30s +cgroupDriver: cgroupfs +cgroupsPerQOS: true +clusterDNS: +- 10.96.0.10 +clusterDomain: cluster.local +configMapAndSecretChangeDetectionStrategy: Watch +containerLogMaxFiles: 5 +containerLogMaxSize: 10Mi +contentType: application/vnd.kubernetes.protobuf +cpuCFSQuota: true +cpuCFSQuotaPeriod: 0s +cpuManagerPolicy: none +cpuManagerReconcilePeriod: 10s +enableControllerAttachDetach: true +enableDebuggingHandlers: true +enforceNodeAllocatable: +- pods +eventBurst: 10 +eventRecordQPS: 5 +evictionHard: + imagefs.available: 15% + memory.available: 100Mi + nodefs.available: 10% + nodefs.inodesFree: 5% +evictionPressureTransitionPeriod: 5m0s +failSwapOn: true +fileCheckFrequency: 20s +hairpinMode: promiscuous-bridge +healthzBindAddress: 127.0.0.1 +healthzPort: 10248 +httpCheckFrequency: 20s +imageGCHighThresholdPercent: 85 +imageGCLowThresholdPercent: 80 +imageMinimumGCAge: 2m0s +iptablesDropBit: 15 +iptablesMasqueradeBit: 14 +kind: KubeletConfiguration +kubeAPIBurst: 10 +kubeAPIQPS: 5 +makeIPTablesUtilChains: true +maxOpenFiles: 1000000 +maxPods: 110 +nodeLeaseDurationSeconds: 40 +nodeStatusUpdateFrequency: 10s +oomScoreAdj: -999 +podPidsLimit: -1 +port: 10250 +registryBurst: 10 +registryPullQPS: 5 +resolvConf: /etc/resolv.conf +rotateCertificates: true +runtimeRequestTimeout: 2m0s +serializeImagePulls: true +staticPodPath: /etc/kubernetes/manifests +streamingConnectionIdleTimeout: 4h0m0s +syncFrequency: 1m0s +volumeStatsAggPeriod: 1m0s diff --git a/cmd/kubeadm/app/util/config/testdata/conversion/node/v1beta1.yaml b/cmd/kubeadm/app/util/config/testdata/conversion/node/v1beta1.yaml new file mode 100644 index 0000000000..a55a6640dd --- /dev/null +++ b/cmd/kubeadm/app/util/config/testdata/conversion/node/v1beta1.yaml @@ -0,0 +1,18 @@ +apiEndpoint: + advertiseAddress: 192.168.2.2 + bindPort: 6443 +apiVersion: kubeadm.k8s.io/v1beta1 +caCertPath: /etc/kubernetes/pki/ca.crt +clusterName: kubernetes +discoveryFile: "" +discoveryTimeout: 5m0s +discoveryToken: abcdef.0123456789abcdef +discoveryTokenAPIServers: +- kube-apiserver:6443 +discoveryTokenUnsafeSkipCAVerification: true +kind: JoinConfiguration +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: master-1 +tlsBootstrapToken: abcdef.0123456789abcdef +token: abcdef.0123456789abcdef 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 78242aa276..d9ff908f36 100644 --- a/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml +++ b/cmd/kubeadm/app/util/config/testdata/defaulting/master/defaulted.yaml @@ -1,7 +1,7 @@ apiEndpoint: advertiseAddress: 192.168.2.2 bindPort: 6443 -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token @@ -18,7 +18,7 @@ nodeRegistration: - effect: NoSchedule key: node-role.kubernetes.io/master --- -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 auditPolicy: logDir: /var/log/kubernetes/audit logMaxAge: 2 @@ -32,7 +32,7 @@ etcd: image: "" imageRepository: my-company.com kind: ClusterConfiguration -kubernetesVersion: v1.11.2 +kubernetesVersion: v1.12.0 networking: dnsDomain: cluster.global podSubnet: 10.148.0.0/16 diff --git a/cmd/kubeadm/app/util/config/testdata/defaulting/master/incomplete.yaml b/cmd/kubeadm/app/util/config/testdata/defaulting/master/incomplete.yaml new file mode 100644 index 0000000000..d402a1bfe1 --- /dev/null +++ b/cmd/kubeadm/app/util/config/testdata/defaulting/master/incomplete.yaml @@ -0,0 +1,19 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration +apiEndpoint: + advertiseAddress: 192.168.2.2 +bootstrapTokens: +- token: s73ybu.6tw6wnqgp5z0wb77 +nodeRegistration: + criSocket: /var/run/criruntime.sock + name: master-1 +--- +apiVersion: kubeadm.k8s.io/v1beta1 +certificatesDir: /var/lib/kubernetes/pki +imageRepository: my-company.com +kind: ClusterConfiguration +kubernetesVersion: v1.12.0 +networking: + dnsDomain: cluster.global + podSubnet: 10.148.0.0/16 + serviceSubnet: 10.196.0.0/12 \ No newline at end of file diff --git a/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml b/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml index 34cd44ab86..040180381e 100644 --- a/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml +++ b/cmd/kubeadm/app/util/config/testdata/defaulting/node/defaulted.yaml @@ -1,7 +1,7 @@ apiEndpoint: advertiseAddress: 192.168.2.2 bindPort: 6443 -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 caCertPath: /etc/kubernetes/pki/ca.crt clusterName: kubernetes discoveryFile: "" diff --git a/cmd/kubeadm/app/util/config/testdata/defaulting/node/incomplete.yaml b/cmd/kubeadm/app/util/config/testdata/defaulting/node/incomplete.yaml new file mode 100644 index 0000000000..e335a18a52 --- /dev/null +++ b/cmd/kubeadm/app/util/config/testdata/defaulting/node/incomplete.yaml @@ -0,0 +1,13 @@ +apiEndpoint: + advertiseAddress: 192.168.2.2 +apiVersion: kubeadm.k8s.io/v1alpha3 +discoveryToken: abcdef.0123456789abcdef +discoveryTokenAPIServers: +- kube-apiserver:6443 +discoveryTokenUnsafeSkipCAVerification: true +kind: JoinConfiguration +nodeRegistration: + criSocket: /var/run/dockershim.sock + name: thegopher +tlsBootstrapToken: abcdef.0123456789abcdef +token: abcdef.0123456789abcdef diff --git a/cmd/kubeadm/app/util/config/testdata/validation/invalid_mastercfg.yaml b/cmd/kubeadm/app/util/config/testdata/validation/invalid_mastercfg.yaml index 5579fd38d8..34924a75ac 100644 --- a/cmd/kubeadm/app/util/config/testdata/validation/invalid_mastercfg.yaml +++ b/cmd/kubeadm/app/util/config/testdata/validation/invalid_mastercfg.yaml @@ -1,4 +1,4 @@ -apiVersion: kubeadm.k8s.io/v1alpha3 +apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration networking: dnsDomain: INVALID-DOMAIN-!!!! diff --git a/cmd/kubeadm/app/util/config/testdata/validation/invalid_nodecfg.yaml b/cmd/kubeadm/app/util/config/testdata/validation/invalid_nodecfg.yaml index 34498e8952..c839a276e1 100644 --- a/cmd/kubeadm/app/util/config/testdata/validation/invalid_nodecfg.yaml +++ b/cmd/kubeadm/app/util/config/testdata/validation/invalid_nodecfg.yaml @@ -1,7 +1,5 @@ -apiVersion: kubeadm.k8s.io/v1alpha2 +apiVersion: kubeadm.k8s.io/v1beta1 kind: NodeConfiguration apiEndpoint: advertiseAddress: INVALID-ADDRESS-!!!! bindPort: 6443 -apiVersion: kubeadm.k8s.io/v1alpha3 -kind: JoinConfiguration diff --git a/cmd/kubeadm/app/util/marshal.go b/cmd/kubeadm/app/util/marshal.go index 6e95dcc715..5f74d4b8dd 100644 --- a/cmd/kubeadm/app/util/marshal.go +++ b/cmd/kubeadm/app/util/marshal.go @@ -154,8 +154,6 @@ func GroupVersionKindsHasClusterConfiguration(gvks ...schema.GroupVersionKind) b // 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 - // TODO: When we remove support for the v1alpha2 API, remove support for MasterConfiguration return GroupVersionKindsHasKind(gvks, constants.InitConfigurationKind) } diff --git a/cmd/kubeadm/test/cmd/init_test.go b/cmd/kubeadm/test/cmd/init_test.go index f8dcf3c84e..a4dfe55c43 100644 --- a/cmd/kubeadm/test/cmd/init_test.go +++ b/cmd/kubeadm/test/cmd/init_test.go @@ -153,12 +153,21 @@ func TestCmdInitConfig(t *testing.T) { args: "--config=testdata/init/v1alpha3.yaml", expected: true, }, - // TODO: implement v1beta1 tests after introducing v1beta1 { - name: "don't allow mixed arguments", + name: "can load v1beta1 config", + args: "--config=testdata/init/v1beta1.yaml", + expected: true, + }, + { + name: "don't allow mixed arguments v1alpha3", args: "--kubernetes-version=1.11.0 --config=testdata/init/v1alpha3.yaml", expected: false, }, + { + name: "don't allow mixed arguments v1beta1", + args: "--kubernetes-version=1.11.0 --config=testdata/init/v1beta1.yaml", + expected: false, + }, } for _, rt := range initTest { diff --git a/cmd/kubeadm/test/cmd/testdata/init/v1beta1.yaml b/cmd/kubeadm/test/cmd/testdata/init/v1beta1.yaml new file mode 100644 index 0000000000..79a70e48bb --- /dev/null +++ b/cmd/kubeadm/test/cmd/testdata/init/v1beta1.yaml @@ -0,0 +1,2 @@ +apiVersion: kubeadm.k8s.io/v1beta1 +kind: InitConfiguration diff --git a/cmd/kubeadm/test/util.go b/cmd/kubeadm/test/util.go index 07bc630766..1a2b73c06a 100644 --- a/cmd/kubeadm/test/util.go +++ b/cmd/kubeadm/test/util.go @@ -26,7 +26,7 @@ import ( "github.com/renstrom/dedent" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3" + kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" @@ -55,7 +55,7 @@ func SetupInitConfigurationFile(t *testing.T, tmpdir string, cfg *kubeadmapi.Ini } cfgTemplate := template.Must(template.New("init").Parse(dedent.Dedent(` - apiVersion: kubeadm.k8s.io/v1alpha3 + apiVersion: kubeadm.k8s.io/v1beta1 kind: InitConfiguration apiEndpoint: advertiseAddress: {{.APIEndpoint.AdvertiseAddress}} @@ -63,7 +63,7 @@ func SetupInitConfigurationFile(t *testing.T, tmpdir string, cfg *kubeadmapi.Ini nodeRegistration: name: {{.NodeRegistration.Name}} --- - apiVersion: kubeadm.k8s.io/v1alpha3 + apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration certificatesDir: {{.CertificatesDir}} kubernetesVersion: v1.11.0 @@ -145,7 +145,7 @@ func AssertFileExists(t *testing.T, dirName string, fileNames ...string) { // GetDefaultInternalConfig returns a defaulted kubeadmapi.InitConfiguration func GetDefaultInternalConfig(t *testing.T) *kubeadmapi.InitConfiguration { - internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig("", &kubeadmapiv1alpha3.InitConfiguration{}) + internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig("", &kubeadmapiv1beta1.InitConfiguration{}) if err != nil { t.Fatalf("unexpected error getting default config: %v", err) } diff --git a/hack/.golint_failures b/hack/.golint_failures index 5e7c6c776f..a97755c20a 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -7,6 +7,7 @@ cmd/kube-controller-manager/app cmd/kube-proxy/app cmd/kubeadm/app cmd/kubeadm/app/apis/kubeadm/v1alpha3 +cmd/kubeadm/app/apis/kubeadm/v1beta1 cmd/kubeadm/app/util/config cmd/kubeadm/app/util/system cmd/kubelet/app