From 728b30b3f107f541a2578972229e87195d08e8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20K=C3=A4ldstr=C3=B6m?= Date: Mon, 9 Jul 2018 05:16:00 +0300 Subject: [PATCH] kubeadm: Make the kubeadm config kinds mutually exclusive --- cmd/kubeadm/app/util/config/common.go | 15 ++++ cmd/kubeadm/app/util/config/common_test.go | 83 +++++++++++++++++++--- 2 files changed, 89 insertions(+), 9 deletions(-) diff --git a/cmd/kubeadm/app/util/config/common.go b/cmd/kubeadm/app/util/config/common.go index ee842dd6060..10e33d39a04 100644 --- a/cmd/kubeadm/app/util/config/common.go +++ b/cmd/kubeadm/app/util/config/common.go @@ -82,10 +82,25 @@ func DetectUnsupportedVersion(b []byte) error { "kubeadm.k8s.io/v1alpha1": "v1.11", } // If we find an old API version in this gvk list, error out and tell the user why this doesn't work + knownKinds := map[string]bool{} for _, gvk := range gvks { if useKubeadmVersion := oldKnownAPIVersions[gvk.GroupVersion().String()]; len(useKubeadmVersion) != 0 { return fmt.Errorf("your configuration file uses an old API spec: %q. Please use kubeadm %s instead and run 'kubeadm config migrate --old-config old.yaml --new-config new.yaml', which will write the new, similar spec using a newer API version.", gvk.GroupVersion().String(), useKubeadmVersion) } + knownKinds[gvk.Kind] = true + } + // InitConfiguration, MasterConfiguration and NodeConfiguration are mutually exclusive, error if more than one are specified + mutuallyExclusive := []string{constants.InitConfigurationKind, constants.MasterConfigurationKind, constants.JoinConfigurationKind, constants.NodeConfigurationKind} + foundOne := false + for _, kind := range mutuallyExclusive { + if knownKinds[kind] { + if !foundOne { + foundOne = true + continue + } + + return fmt.Errorf("invalid configuration: kinds %v are mutually exclusive", mutuallyExclusive) + } } return nil } diff --git a/cmd/kubeadm/app/util/config/common_test.go b/cmd/kubeadm/app/util/config/common_test.go index 2227a175a8b..1a980da7984 100644 --- a/cmd/kubeadm/app/util/config/common_test.go +++ b/cmd/kubeadm/app/util/config/common_test.go @@ -31,13 +31,21 @@ kind: InitConfiguration `), "Node_v1alpha1": []byte(` apiVersion: kubeadm.k8s.io/v1alpha1 -kind: JoinConfiguration +kind: NodeConfiguration `), - "Master_v1alpha3": []byte(` + "Master_v1alpha2": []byte(` +apiVersion: kubeadm.k8s.io/v1alpha2 +kind: MasterConfiguration +`), + "Node_v1alpha2": []byte(` +apiVersion: kubeadm.k8s.io/v1alpha2 +kind: NodeConfiguration +`), + "Init_v1alpha3": []byte(` apiVersion: kubeadm.k8s.io/v1alpha3 kind: InitConfiguration `), - "Node_v1alpha3": []byte(` + "Join_v1alpha3": []byte(` apiVersion: kubeadm.k8s.io/v1alpha3 kind: JoinConfiguration `), @@ -50,6 +58,10 @@ bar: bar kind: Bar foo: foo bar: bar +`), + "Foo": []byte(` +apiVersion: foo.k8s.io/v1 +kind: Foo `), } @@ -70,16 +82,39 @@ func TestDetectUnsupportedVersion(t *testing.T) { expectedErr: true, }, { - name: "Master_v1alpha3", - fileContents: files["Master_v1alpha3"], + name: "Master_v1alpha2", + fileContents: files["Master_v1alpha2"], }, { - name: "Node_v1alpha3", - fileContents: files["Node_v1alpha3"], + name: "Node_v1alpha2", + fileContents: files["Node_v1alpha2"], + }, + { + name: "Init_v1alpha3", + fileContents: files["Init_v1alpha3"], + }, + { + name: "Join_v1alpha3", + fileContents: files["Join_v1alpha3"], }, { name: "DuplicateMaster", - fileContents: bytes.Join([][]byte{files["Master_v1alpha3"], files["Master_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), + fileContents: bytes.Join([][]byte{files["Master_v1alpha2"], files["Master_v1alpha2"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "DuplicateNode", + fileContents: bytes.Join([][]byte{files["Node_v1alpha2"], files["Node_v1alpha2"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "DuplicateInit", + fileContents: bytes.Join([][]byte{files["Init_v1alpha3"], files["Init_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "DuplicateJoin", + fileContents: bytes.Join([][]byte{files["Join_v1alpha3"], files["Join_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), expectedErr: true, }, { @@ -94,7 +129,37 @@ func TestDetectUnsupportedVersion(t *testing.T) { }, { name: "v1alpha1InMultiple", - fileContents: bytes.Join([][]byte{files["Master_v1alpha3"], files["Master_v1alpha1"]}, []byte(constants.YAMLDocumentSeparator)), + fileContents: bytes.Join([][]byte{files["Foo"], files["Master_v1alpha1"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "MustNotMixMasterNode", + fileContents: bytes.Join([][]byte{files["Master_v1alpha2"], files["Node_v1alpha2"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "MustNotMixMasterJoin", + fileContents: bytes.Join([][]byte{files["Master_v1alpha2"], files["Join_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "MustNotMixJoinNode", + fileContents: bytes.Join([][]byte{files["Join_v1alpha3"], files["Node_v1alpha2"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "MustNotMixInitMaster", + fileContents: bytes.Join([][]byte{files["Init_v1alpha3"], files["Master_v1alpha2"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "MustNotMixInitNode", + fileContents: bytes.Join([][]byte{files["Init_v1alpha3"], files["Node_v1alpha2"]}, []byte(constants.YAMLDocumentSeparator)), + expectedErr: true, + }, + { + name: "MustNotMixInitJoin", + fileContents: bytes.Join([][]byte{files["Init_v1alpha3"], files["Join_v1alpha3"]}, []byte(constants.YAMLDocumentSeparator)), expectedErr: true, }, }