kubernetes/cmd/kubeadm/app/util/config/joinconfiguration_test.go
Rostislav M. Georgiev f64baf755e kubeadm: Don't load deprecated configs
Currently kubeadm supports a couple of configuration versions - v1alpha3 and
v1beta1. The former is deprecated, but still supported.

To discourage users from using it and to speedup conversion to newer versions,
we disable the loading of deprecated configurations by all kubeadm
sub-commands, but "kubeadm config migrate".

v1alpha3 is still present and supported at source level, but cannot be used
directly with kubeadm and some of its internal APIs.

The added benefit to this is, that users won't need to lookup for an old
kubeadm binary after upgrade, just because they were stuck with a deprecated
config version for too long.

To achieve this, the following was done:

- ValidateSupportedVersion now has an allowDeprecated boolean parameter, that
  controls if the function should return an error upon detecting deprecated
  config version. Currently the only deprecated version is v1alpha3.

- ValidateSupportedVersion is made package private, because it's not used
  outside of the package anyway.

- BytesToInitConfiguration and LoadJoinConfigurationFromFile are modified to
  disallow loading of deprecated kubeadm config versions. An error message,
  that points users to kubeadm config migrate is returned.

- MigrateOldConfig is still allowed to load deprecated kubeadm config versions.

- A bunch of tests were fixed to not expect success if v1alpha3 config is
  supplied.

Signed-off-by: Rostislav M. Georgiev <rostislavg@vmware.com>
2019-02-19 12:27:39 +02:00

108 lines
3.5 KiB
Go

/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package config
import (
"bytes"
"io/ioutil"
"testing"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
)
const (
nodeV1alpha3YAML = "testdata/conversion/node/v1alpha3.yaml"
nodeV1beta1YAML = "testdata/conversion/node/v1beta1.yaml"
nodeInternalYAML = "testdata/conversion/node/internal.yaml"
nodeIncompleteYAML = "testdata/defaulting/node/incomplete.yaml"
nodeDefaultedYAML = "testdata/defaulting/node/defaulted.yaml"
nodeInvalidYAML = "testdata/validation/invalid_nodecfg.yaml"
)
func TestLoadJoinConfigurationFromFile(t *testing.T) {
var tests = []struct {
name, in, out string
groupVersion schema.GroupVersion
expectedErr bool
}{
// 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: "v1alpha3IsDeprecated",
in: nodeV1alpha3YAML,
expectedErr: true,
},
{ // v1beta1 -> internal
name: "v1beta1ToInternal",
in: nodeV1beta1YAML,
out: nodeInternalYAML,
groupVersion: kubeadm.SchemeGroupVersion,
},
{ // v1beta1 -> internal -> v1beta1
name: "v1beta1Tov1beta1",
in: nodeV1beta1YAML,
out: nodeV1beta1YAML,
groupVersion: kubeadmapiv1beta1.SchemeGroupVersion,
},
// These tests are reading one file that has only a subset of the fields populated, loading it using LoadJoinConfigurationFromFile,
// and then marshals the internal object to the expected groupVersion
{ // v1beta1 -> default -> validate -> internal -> v1beta1
name: "incompleteYAMLToDefaultedv1beta1",
in: nodeIncompleteYAML,
out: nodeDefaultedYAML,
groupVersion: kubeadmapiv1beta1.SchemeGroupVersion,
},
{ // v1beta1 -> validation should fail
name: "invalidYAMLShouldFail",
in: nodeInvalidYAML,
expectedErr: true,
},
}
for _, rt := range tests {
t.Run(rt.name, func(t2 *testing.T) {
internalcfg, err := LoadJoinConfigurationFromFile(rt.in)
if err != nil {
if rt.expectedErr {
return
}
t2.Fatalf("couldn't unmarshal test data: %v", err)
}
actual, err := kubeadmutil.MarshalToYamlForCodecs(internalcfg, rt.groupVersion, scheme.Codecs)
if err != nil {
t2.Fatalf("couldn't marshal internal object: %v", err)
}
expected, err := ioutil.ReadFile(rt.out)
if err != nil {
t2.Fatalf("couldn't read test data: %v", err)
}
if !bytes.Equal(expected, actual) {
t2.Errorf("the expected and actual output differs.\n\tin: %s\n\tout: %s\n\tgroupversion: %s\n\tdiff: \n%s\n",
rt.in, rt.out, rt.groupVersion.String(), diff(expected, actual))
}
})
}
}