mirror of https://github.com/k3s-io/k3s
Merge pull request #74025 from rosti/deprecated-configs
kubeadm: Don't load deprecated configspull/564/head
commit
8d69dc630b
|
@ -1,3 +1,3 @@
|
|||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
kind: ClusterConfiguration
|
||||
kubernetesVersion: 1.12.0
|
||||
kubernetesVersion: 1.13.0
|
||||
|
|
|
@ -48,20 +48,35 @@ func MarshalKubeadmConfigObject(obj runtime.Object) ([]byte, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// ValidateSupportedVersion checks if a supplied GroupVersion is not on the list of unsupported GVs. If it is, an error is returned.
|
||||
func ValidateSupportedVersion(gv schema.GroupVersion) error {
|
||||
// validateSupportedVersion checks if the supplied GroupVersion is not on the lists of old unsupported or deprecated GVs.
|
||||
// If it is, an error is returned.
|
||||
func validateSupportedVersion(gv schema.GroupVersion, allowDeprecated bool) error {
|
||||
// The support matrix will look something like this now and in the future:
|
||||
// v1.10 and earlier: v1alpha1
|
||||
// v1.11: v1alpha1 read-only, writes only v1alpha2 config
|
||||
// v1.12: v1alpha2 read-only, writes only v1alpha3 config. Warns if the user tries to use v1alpha1
|
||||
// v1.13: v1alpha3 read-only, writes only v1beta1 config. Warns if the user tries to use v1alpha1 or v1alpha2
|
||||
// v1.12: v1alpha2 read-only, writes only v1alpha3 config. Errors if the user tries to use v1alpha1
|
||||
// v1.13: v1alpha3 read-only, writes only v1beta1 config. Errors if the user tries to use v1alpha1 or v1alpha2
|
||||
// v1.14: v1alpha3 convert only, writes only v1beta1 config. Errors if the user tries to use v1alpha1 or v1alpha2
|
||||
oldKnownAPIVersions := map[string]string{
|
||||
"kubeadm.k8s.io/v1alpha1": "v1.11",
|
||||
"kubeadm.k8s.io/v1alpha2": "v1.12",
|
||||
}
|
||||
if useKubeadmVersion := oldKnownAPIVersions[gv.String()]; useKubeadmVersion != "" {
|
||||
|
||||
// Deprecated API versions are supported by us, but can only be used for migration.
|
||||
deprecatedAPIVersions := map[string]struct{}{
|
||||
"kubeadm.k8s.io/v1alpha3": {}, // Can be migrated with kubeadm 1.13+
|
||||
}
|
||||
|
||||
gvString := gv.String()
|
||||
|
||||
if useKubeadmVersion := oldKnownAPIVersions[gvString]; useKubeadmVersion != "" {
|
||||
return errors.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.", gv.String(), useKubeadmVersion)
|
||||
}
|
||||
|
||||
if _, present := deprecatedAPIVersions[gvString]; present && !allowDeprecated {
|
||||
return errors.Errorf("your configuration file uses a deprecated API spec: %q. Please use 'kubeadm config migrate --old-config old.yaml --new-config new.yaml', which will write the new, similar spec using a newer API version.", gv.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -154,7 +169,7 @@ func MigrateOldConfig(oldConfig []byte) ([]byte, error) {
|
|||
|
||||
// Migrate InitConfiguration and ClusterConfiguration if there are any in the config
|
||||
if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvks...) || kubeadmutil.GroupVersionKindsHasClusterConfiguration(gvks...) {
|
||||
o, err := documentMapToInitConfiguration(gvkmap)
|
||||
o, err := documentMapToInitConfiguration(gvkmap, true)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
@ -167,7 +182,7 @@ func MigrateOldConfig(oldConfig []byte) ([]byte, error) {
|
|||
|
||||
// Migrate JoinConfiguration if there is any
|
||||
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
||||
o, err := documentMapToJoinConfiguration(gvkmap)
|
||||
o, err := documentMapToJoinConfiguration(gvkmap, true)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/lithammer/dedent"
|
||||
|
@ -27,12 +28,13 @@ import (
|
|||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
)
|
||||
|
||||
func TestValidateSupportedVersion(t *testing.T) {
|
||||
const KubeadmGroupName = "kubeadm.k8s.io"
|
||||
const KubeadmGroupName = "kubeadm.k8s.io"
|
||||
|
||||
func TestValidateSupportedVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
gv schema.GroupVersion
|
||||
expectedErr bool
|
||||
gv schema.GroupVersion
|
||||
allowDeprecated bool
|
||||
expectedErr bool
|
||||
}{
|
||||
{
|
||||
gv: schema.GroupVersion{
|
||||
|
@ -53,6 +55,14 @@ func TestValidateSupportedVersion(t *testing.T) {
|
|||
Group: KubeadmGroupName,
|
||||
Version: "v1alpha3",
|
||||
},
|
||||
expectedErr: true,
|
||||
},
|
||||
{
|
||||
gv: schema.GroupVersion{
|
||||
Group: KubeadmGroupName,
|
||||
Version: "v1alpha3",
|
||||
},
|
||||
allowDeprecated: true,
|
||||
},
|
||||
{
|
||||
gv: schema.GroupVersion{
|
||||
|
@ -69,8 +79,8 @@ func TestValidateSupportedVersion(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, rt := range tests {
|
||||
t.Run(rt.gv.String(), func(t *testing.T) {
|
||||
err := ValidateSupportedVersion(rt.gv)
|
||||
t.Run(fmt.Sprintf("%s/allowDeprecated:%t", rt.gv, rt.allowDeprecated), func(t *testing.T) {
|
||||
err := validateSupportedVersion(rt.gv, rt.allowDeprecated)
|
||||
if rt.expectedErr && err == nil {
|
||||
t.Error("unexpected success")
|
||||
} else if !rt.expectedErr && err != nil {
|
||||
|
|
|
@ -190,11 +190,7 @@ func LoadInitConfigurationFromFile(cfgPath string) (*kubeadmapi.InitConfiguratio
|
|||
return nil, errors.Wrapf(err, "unable to read config from %q ", cfgPath)
|
||||
}
|
||||
|
||||
internalcfg, err := BytesToInitConfiguration(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return internalcfg, nil
|
||||
return BytesToInitConfiguration(b)
|
||||
}
|
||||
|
||||
// LoadOrDefaultInitConfiguration takes a path to a config file and a versioned configuration that can serve as the default config
|
||||
|
@ -222,18 +218,18 @@ func BytesToInitConfiguration(b []byte) (*kubeadmapi.InitConfiguration, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return documentMapToInitConfiguration(gvkmap)
|
||||
return documentMapToInitConfiguration(gvkmap, false)
|
||||
}
|
||||
|
||||
// documentMapToInitConfiguration converts a map of GVKs and YAML documents to defaulted and validated configuration object.
|
||||
func documentMapToInitConfiguration(gvkmap map[schema.GroupVersionKind][]byte) (*kubeadmapi.InitConfiguration, error) {
|
||||
func documentMapToInitConfiguration(gvkmap map[schema.GroupVersionKind][]byte, allowDeprecated bool) (*kubeadmapi.InitConfiguration, error) {
|
||||
var initcfg *kubeadmapi.InitConfiguration
|
||||
var clustercfg *kubeadmapi.ClusterConfiguration
|
||||
decodedComponentConfigObjects := map[componentconfigs.RegistrationKind]runtime.Object{}
|
||||
|
||||
for gvk, fileContent := range gvkmap {
|
||||
// first, check if this GVK is supported one
|
||||
if err := ValidateSupportedVersion(gvk.GroupVersion()); err != nil {
|
||||
// first, check if this GVK is supported and possibly not deprecated
|
||||
if err := validateSupportedVersion(gvk.GroupVersion(), allowDeprecated); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ func TestLoadInitConfigurationFromFile(t *testing.T) {
|
|||
var tests = []struct {
|
||||
name string
|
||||
fileContents []byte
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "v1beta1.partial1",
|
||||
|
@ -92,10 +93,12 @@ func TestLoadInitConfigurationFromFile(t *testing.T) {
|
|||
{
|
||||
name: "v1alpha3.partial1",
|
||||
fileContents: cfgFiles["InitConfiguration_v1alpha3"],
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "v1alpha3.partial2",
|
||||
fileContents: cfgFiles["ClusterConfiguration_v1alpha3"],
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
name: "v1alpha3.full",
|
||||
|
@ -105,6 +108,7 @@ func TestLoadInitConfigurationFromFile(t *testing.T) {
|
|||
cfgFiles["Kube-proxy_componentconfig"],
|
||||
cfgFiles["Kubelet_componentconfig"],
|
||||
}, []byte(constants.YAMLDocumentSeparator)),
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -118,13 +122,19 @@ func TestLoadInitConfigurationFromFile(t *testing.T) {
|
|||
}
|
||||
|
||||
obj, err := LoadInitConfigurationFromFile(cfgPath)
|
||||
if err != nil {
|
||||
t.Errorf("Error reading file: %v", err)
|
||||
return
|
||||
}
|
||||
if rt.expectErr {
|
||||
if err == nil {
|
||||
t.Error("Unexpected success")
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("Error reading file: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if obj == nil {
|
||||
t.Errorf("Unexpected nil return value")
|
||||
if obj == nil {
|
||||
t.Errorf("Unexpected nil return value")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -150,10 +160,9 @@ func TestInitConfigurationMarshallingFromFile(t *testing.T) {
|
|||
// These tests are reading one file, loading it using LoadInitConfigurationFromFile that all of kubeadm is using for unmarshal of our API types,
|
||||
// and then marshals the internal object to the expected groupVersion
|
||||
{ // v1alpha3 -> internal
|
||||
name: "v1alpha3ToInternal",
|
||||
in: masterV1alpha3YAMLAbstracted,
|
||||
out: masterInternalYAMLAbstracted,
|
||||
groupVersion: kubeadm.SchemeGroupVersion,
|
||||
name: "v1alpha3IsDeprecated",
|
||||
in: masterV1alpha3YAMLAbstracted,
|
||||
expectedErr: true,
|
||||
},
|
||||
{ // v1beta1 -> internal
|
||||
name: "v1beta1ToInternal",
|
||||
|
@ -161,12 +170,6 @@ func TestInitConfigurationMarshallingFromFile(t *testing.T) {
|
|||
out: masterInternalYAMLAbstracted,
|
||||
groupVersion: kubeadm.SchemeGroupVersion,
|
||||
},
|
||||
{ // v1alpha3 -> internal -> v1beta1
|
||||
name: "v1alpha3Tov1beta1",
|
||||
in: masterV1alpha3YAMLAbstracted,
|
||||
out: masterV1beta1YAMLAbstracted,
|
||||
groupVersion: kubeadmapiv1beta1.SchemeGroupVersion,
|
||||
},
|
||||
{ // v1beta1 -> internal -> v1beta1
|
||||
name: "v1beta1Tov1beta1",
|
||||
in: masterV1beta1YAMLAbstracted,
|
||||
|
@ -181,7 +184,7 @@ func TestInitConfigurationMarshallingFromFile(t *testing.T) {
|
|||
out: masterDefaultedYAMLAbstracted,
|
||||
groupVersion: kubeadmapiv1beta1.SchemeGroupVersion,
|
||||
},
|
||||
{ // v1alpha3 -> validation should fail
|
||||
{ // v1beta1 -> validation should fail
|
||||
name: "invalidYAMLShouldFail",
|
||||
in: masterInvalidYAML,
|
||||
expectedErr: true,
|
||||
|
|
|
@ -84,12 +84,12 @@ func LoadJoinConfigurationFromFile(cfgPath string) (*kubeadmapi.JoinConfiguratio
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return documentMapToJoinConfiguration(gvkmap)
|
||||
return documentMapToJoinConfiguration(gvkmap, false)
|
||||
}
|
||||
|
||||
// documentMapToJoinConfiguration takes a map between GVKs and YAML documents (as returned by SplitYAMLDocuments),
|
||||
// finds a JoinConfiguration, decodes it, dynamically defaults it and then validates it prior to return.
|
||||
func documentMapToJoinConfiguration(gvkmap map[schema.GroupVersionKind][]byte) (*kubeadmapi.JoinConfiguration, error) {
|
||||
func documentMapToJoinConfiguration(gvkmap map[schema.GroupVersionKind][]byte, allowDeprecated bool) (*kubeadmapi.JoinConfiguration, error) {
|
||||
joinBytes := []byte{}
|
||||
for gvk, bytes := range gvkmap {
|
||||
// not interested in anything other than JoinConfiguration
|
||||
|
@ -97,8 +97,8 @@ func documentMapToJoinConfiguration(gvkmap map[schema.GroupVersionKind][]byte) (
|
|||
continue
|
||||
}
|
||||
|
||||
// check if this version is supported one
|
||||
if err := ValidateSupportedVersion(gvk.GroupVersion()); err != nil {
|
||||
// check if this version is supported and possibly not deprecated
|
||||
if err := validateSupportedVersion(gvk.GroupVersion(), allowDeprecated); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -46,10 +46,9 @@ func TestLoadJoinConfigurationFromFile(t *testing.T) {
|
|||
// These tests are reading one file, loading it using LoadJoinConfigurationFromFile that all of kubeadm is using for unmarshal of our API types,
|
||||
// and then marshals the internal object to the expected groupVersion
|
||||
{ // v1alpha3 -> internal
|
||||
name: "v1alpha3ToInternal",
|
||||
in: nodeV1alpha3YAML,
|
||||
out: nodeInternalYAML,
|
||||
groupVersion: kubeadm.SchemeGroupVersion,
|
||||
name: "v1alpha3IsDeprecated",
|
||||
in: nodeV1alpha3YAML,
|
||||
expectedErr: true,
|
||||
},
|
||||
{ // v1beta1 -> internal
|
||||
name: "v1beta1ToInternal",
|
||||
|
@ -57,12 +56,6 @@ func TestLoadJoinConfigurationFromFile(t *testing.T) {
|
|||
out: nodeInternalYAML,
|
||||
groupVersion: kubeadm.SchemeGroupVersion,
|
||||
},
|
||||
{ // v1alpha3 -> internal -> v1beta1
|
||||
name: "v1alpha3Tov1beta1",
|
||||
in: nodeV1alpha3YAML,
|
||||
out: nodeV1beta1YAML,
|
||||
groupVersion: kubeadmapiv1beta1.SchemeGroupVersion,
|
||||
},
|
||||
{ // v1beta1 -> internal -> v1beta1
|
||||
name: "v1beta1Tov1beta1",
|
||||
in: nodeV1beta1YAML,
|
||||
|
@ -77,7 +70,7 @@ func TestLoadJoinConfigurationFromFile(t *testing.T) {
|
|||
out: nodeDefaultedYAML,
|
||||
groupVersion: kubeadmapiv1beta1.SchemeGroupVersion,
|
||||
},
|
||||
{ // v1alpha3 -> validation should fail
|
||||
{ // v1beta1 -> validation should fail
|
||||
name: "invalidYAMLShouldFail",
|
||||
in: nodeInvalidYAML,
|
||||
expectedErr: true,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
apiVersion: kubeadm.k8s.io/v1alpha3
|
||||
discoveryToken: abcdef.0123456789abcdef
|
||||
discoveryTokenAPIServers:
|
||||
- kube-apiserver:6443
|
||||
discoveryTokenUnsafeSkipCAVerification: true
|
||||
apiVersion: kubeadm.k8s.io/v1beta1
|
||||
discovery:
|
||||
bootstrapToken:
|
||||
apiServerEndpoint: kube-apiserver:6443
|
||||
token: abcdef.0123456789abcdef
|
||||
unsafeSkipCAVerification: true
|
||||
tlsBootstrapToken: abcdef.0123456789abcdef
|
||||
kind: JoinConfiguration
|
||||
nodeRegistration:
|
||||
criSocket: /var/run/dockershim.sock
|
||||
name: thegopher
|
||||
tlsBootstrapToken: abcdef.0123456789abcdef
|
||||
token: abcdef.0123456789abcdef
|
||||
|
|
|
@ -146,19 +146,19 @@ func TestCmdInitConfig(t *testing.T) {
|
|||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "can't load v1alpha1 config",
|
||||
name: "can't load old v1alpha1 config",
|
||||
args: "--config=testdata/init/v1alpha1.yaml",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "can't load v1alpha2 config",
|
||||
name: "can't load old v1alpha2 config",
|
||||
args: "--config=testdata/init/v1alpha2.yaml",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "can load v1alpha3 config",
|
||||
name: "can't load deprecated v1alpha3 config",
|
||||
args: "--config=testdata/init/v1alpha3.yaml",
|
||||
expected: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "can load v1beta1 config",
|
||||
|
|
Loading…
Reference in New Issue