mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 04:27:54 +00:00
Merge pull request #118941 from neolit123/1.28-restore-test-function-for-config-migrate
kubeadm: restore and generalize the TestMigrateOldConfig test
This commit is contained in:
commit
14b08b82e4
@ -38,7 +38,6 @@ import (
|
|||||||
outputapischeme "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/scheme"
|
outputapischeme "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/scheme"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
|
||||||
utilruntime "k8s.io/kubernetes/cmd/kubeadm/app/util/runtime"
|
utilruntime "k8s.io/kubernetes/cmd/kubeadm/app/util/runtime"
|
||||||
)
|
)
|
||||||
@ -52,44 +51,6 @@ var (
|
|||||||
// kubeadm lookup dl.k8s.io to resolve what the latest stable release is
|
// kubeadm lookup dl.k8s.io to resolve what the latest stable release is
|
||||||
dummyKubernetesVersion = constants.MinimumControlPlaneVersion
|
dummyKubernetesVersion = constants.MinimumControlPlaneVersion
|
||||||
dummyKubernetesVersionStr = dummyKubernetesVersion.String()
|
dummyKubernetesVersionStr = dummyKubernetesVersion.String()
|
||||||
|
|
||||||
// predefined configuration contents for migration and validation
|
|
||||||
cfgInvalidSubdomain = []byte(dedent.Dedent(fmt.Sprintf(`
|
|
||||||
apiVersion: %s
|
|
||||||
kind: InitConfiguration
|
|
||||||
nodeRegistration:
|
|
||||||
criSocket: %s
|
|
||||||
name: foo bar # not a valid subdomain
|
|
||||||
`, kubeadmapiv1.SchemeGroupVersion.String(), constants.UnknownCRISocket)))
|
|
||||||
|
|
||||||
cfgUnknownAPI = []byte(dedent.Dedent(fmt.Sprintf(`
|
|
||||||
apiVersion: foo/bar # not a valid GroupVersion
|
|
||||||
kind: zzz # not a valid Kind
|
|
||||||
nodeRegistration:
|
|
||||||
criSocket: %s
|
|
||||||
`, constants.UnknownCRISocket)))
|
|
||||||
|
|
||||||
cfgLegacyAPI = []byte(dedent.Dedent(fmt.Sprintf(`
|
|
||||||
apiVersion: kubeadm.k8s.io/v1beta1 # legacy API
|
|
||||||
kind: InitConfiguration
|
|
||||||
nodeRegistration:
|
|
||||||
criSocket: %s
|
|
||||||
`, constants.UnknownCRISocket)))
|
|
||||||
|
|
||||||
cfgUnknownField = []byte(dedent.Dedent(fmt.Sprintf(`
|
|
||||||
apiVersion: %s
|
|
||||||
kind: InitConfiguration
|
|
||||||
foo: bar
|
|
||||||
nodeRegistration:
|
|
||||||
criSocket: %s
|
|
||||||
`, kubeadmapiv1.SchemeGroupVersion.String(), constants.UnknownCRISocket)))
|
|
||||||
|
|
||||||
cfgValid = []byte(dedent.Dedent(fmt.Sprintf(`
|
|
||||||
apiVersion: %s
|
|
||||||
kind: InitConfiguration
|
|
||||||
nodeRegistration:
|
|
||||||
criSocket: %s
|
|
||||||
`, kubeadmapiv1.SchemeGroupVersion.String(), constants.UnknownCRISocket)))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewCmdConfigImagesList(t *testing.T) {
|
func TestNewCmdConfigImagesList(t *testing.T) {
|
||||||
@ -428,153 +389,6 @@ func TestImagesPull(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMigrate(t *testing.T) {
|
|
||||||
cfgFileInvalidSubdomain, cleanup := tempConfig(t, cfgInvalidSubdomain)
|
|
||||||
defer cleanup()
|
|
||||||
cfgFileUnknownAPI, cleanup := tempConfig(t, cfgUnknownAPI)
|
|
||||||
defer cleanup()
|
|
||||||
cfgFileLegacyAPI, cleanup := tempConfig(t, cfgLegacyAPI)
|
|
||||||
defer cleanup()
|
|
||||||
cfgFileUnknownField, cleanup := tempConfig(t, cfgUnknownField)
|
|
||||||
defer cleanup()
|
|
||||||
cfgFileValid, cleanup := tempConfig(t, cfgValid)
|
|
||||||
defer cleanup()
|
|
||||||
|
|
||||||
testcases := []struct {
|
|
||||||
name string
|
|
||||||
cfg string
|
|
||||||
expectedError bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "invalid subdomain",
|
|
||||||
cfg: cfgFileInvalidSubdomain,
|
|
||||||
expectedError: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "unknown API GVK",
|
|
||||||
cfg: cfgFileUnknownAPI,
|
|
||||||
expectedError: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "legacy API GVK",
|
|
||||||
cfg: cfgFileLegacyAPI,
|
|
||||||
expectedError: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "unknown field",
|
|
||||||
cfg: cfgFileUnknownField,
|
|
||||||
expectedError: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid",
|
|
||||||
cfg: cfgFileValid,
|
|
||||||
expectedError: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testcases {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
var output bytes.Buffer
|
|
||||||
command := newCmdConfigMigrate(&output)
|
|
||||||
if err := command.Flags().Set("old-config", tc.cfg); err != nil {
|
|
||||||
t.Fatalf("failed to set old-config flag")
|
|
||||||
}
|
|
||||||
newConfigPath := filepath.Join(filepath.Dir(tc.cfg), "new-migrated-config")
|
|
||||||
if err := command.Flags().Set("new-config", newConfigPath); err != nil {
|
|
||||||
t.Fatalf("failed to set new-config flag")
|
|
||||||
}
|
|
||||||
err := command.RunE(nil, nil)
|
|
||||||
if (err != nil) != tc.expectedError {
|
|
||||||
t.Fatalf("Expected error from validate command: %v, got: %v, error: %v",
|
|
||||||
tc.expectedError, err != nil, err)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, err := configutil.LoadInitConfigurationFromFile(newConfigPath); err != nil {
|
|
||||||
t.Fatalf("Could not read output back into internal type: %v", err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidate(t *testing.T) {
|
|
||||||
cfgFileInvalidSubdomain, cleanup := tempConfig(t, cfgInvalidSubdomain)
|
|
||||||
defer cleanup()
|
|
||||||
cfgFileUnknownAPI, cleanup := tempConfig(t, cfgUnknownAPI)
|
|
||||||
defer cleanup()
|
|
||||||
cfgFileLegacyAPI, cleanup := tempConfig(t, cfgLegacyAPI)
|
|
||||||
defer cleanup()
|
|
||||||
cfgFileUnknownField, cleanup := tempConfig(t, cfgUnknownField)
|
|
||||||
defer cleanup()
|
|
||||||
cfgFileValid, cleanup := tempConfig(t, cfgValid)
|
|
||||||
defer cleanup()
|
|
||||||
|
|
||||||
testcases := []struct {
|
|
||||||
name string
|
|
||||||
cfg string
|
|
||||||
expectedError bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "invalid subdomain",
|
|
||||||
cfg: cfgFileInvalidSubdomain,
|
|
||||||
expectedError: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "unknown API GVK",
|
|
||||||
cfg: cfgFileUnknownAPI,
|
|
||||||
expectedError: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "legacy API GVK",
|
|
||||||
cfg: cfgFileLegacyAPI,
|
|
||||||
expectedError: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "unknown field",
|
|
||||||
cfg: cfgFileUnknownField,
|
|
||||||
expectedError: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid",
|
|
||||||
cfg: cfgFileValid,
|
|
||||||
expectedError: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testcases {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
var output bytes.Buffer
|
|
||||||
command := newCmdConfigValidate(&output)
|
|
||||||
if err := command.Flags().Set("config", tc.cfg); err != nil {
|
|
||||||
t.Fatalf("Failed to set config flag")
|
|
||||||
}
|
|
||||||
if err := command.RunE(nil, nil); (err != nil) != tc.expectedError {
|
|
||||||
t.Fatalf("Expected error from validate command: %v, got: %v, error: %v",
|
|
||||||
tc.expectedError, err != nil, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the name of the file created and a cleanup callback
|
|
||||||
func tempConfig(t *testing.T, config []byte) (string, func()) {
|
|
||||||
t.Helper()
|
|
||||||
tmpDir, err := os.MkdirTemp("", "kubeadm-migration-test")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unable to create temporary directory: %v", err)
|
|
||||||
}
|
|
||||||
configFilePath := filepath.Join(tmpDir, "test-config-file")
|
|
||||||
if err := os.WriteFile(configFilePath, config, 0644); err != nil {
|
|
||||||
os.RemoveAll(tmpDir)
|
|
||||||
t.Fatalf("Failed writing a config file: %v", err)
|
|
||||||
}
|
|
||||||
return configFilePath, func() {
|
|
||||||
os.RemoveAll(tmpDir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewCmdConfigPrintActionDefaults(t *testing.T) {
|
func TestNewCmdConfigPrintActionDefaults(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -289,8 +289,8 @@ func MigrateOldConfig(oldConfig []byte, allowExperimental bool) ([]byte, error)
|
|||||||
|
|
||||||
// ValidateConfig takes a byte slice containing a kubeadm configuration and performs conversion
|
// ValidateConfig takes a byte slice containing a kubeadm configuration and performs conversion
|
||||||
// to internal types and validation.
|
// to internal types and validation.
|
||||||
func ValidateConfig(oldConfig []byte, allowExperimental bool) error {
|
func ValidateConfig(config []byte, allowExperimental bool) error {
|
||||||
gvkmap, err := kubeadmutil.SplitYAMLDocuments(oldConfig)
|
gvkmap, err := kubeadmutil.SplitYAMLDocuments(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,16 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/lithammer/dedent"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||||
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
kubeadmapiv1old "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
||||||
|
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta4"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const KubeadmGroupName = "kubeadm.k8s.io"
|
const KubeadmGroupName = "kubeadm.k8s.io"
|
||||||
@ -213,209 +216,342 @@ func TestVerifyAPIServerBindAddress(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: re-include TestMigrateOldConfigFromFile once a new API version is added after v1beta3.
|
// NOTE: do not delete this test once an older API is removed and there is only one API left.
|
||||||
// see <link-to-commit-foo> of how this unit test function
|
// Update the inline "gv" and "gvExperimental" variables, to have the GroupVersion String of
|
||||||
// looked before it was removed with the removal of v1beta2.
|
// the API to be tested. If there are no experimental APIs make "gvExperimental" point to
|
||||||
// func TestMigrateOldConfigFromFile(t *testing.T) {
|
// an non-experimental API.
|
||||||
// tests := []struct {
|
func TestMigrateOldConfig(t *testing.T) {
|
||||||
// desc string
|
var (
|
||||||
// oldCfg string
|
gv = kubeadmapiv1old.SchemeGroupVersion.String()
|
||||||
// expectedKinds []string
|
gvExperimental = kubeadmapiv1.SchemeGroupVersion.String()
|
||||||
// expectErr bool
|
)
|
||||||
// }{
|
tests := []struct {
|
||||||
// {
|
name string
|
||||||
// desc: "empty file produces empty result",
|
oldCfg string
|
||||||
// oldCfg: "",
|
expectedKinds []string
|
||||||
// expectErr: false,
|
expectErr bool
|
||||||
// },
|
allowExperimental bool
|
||||||
// {
|
}{
|
||||||
// desc: "bad config produces error",
|
{
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
name: "empty file produces empty result",
|
||||||
// apiVersion: %s
|
oldCfg: "",
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
expectErr: false,
|
||||||
// expectErr: true,
|
},
|
||||||
// },
|
{
|
||||||
// {
|
name: "bad config produces error",
|
||||||
// desc: "InitConfiguration only gets migrated",
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
apiVersion: %s
|
||||||
// apiVersion: %s
|
`, gv)),
|
||||||
// kind: InitConfiguration
|
expectErr: true,
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
},
|
||||||
// expectedKinds: []string{
|
{
|
||||||
// constants.InitConfigurationKind,
|
name: "unknown API produces error",
|
||||||
// constants.ClusterConfigurationKind,
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// },
|
apiVersion: %s
|
||||||
// expectErr: false,
|
kind: Foo
|
||||||
// },
|
`, gv)),
|
||||||
// {
|
expectErr: true,
|
||||||
// desc: "ClusterConfiguration only gets migrated",
|
},
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
{
|
||||||
// apiVersion: %s
|
name: "InitConfiguration only gets migrated",
|
||||||
// kind: ClusterConfiguration
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
apiVersion: %s
|
||||||
// expectedKinds: []string{
|
kind: InitConfiguration
|
||||||
// constants.InitConfigurationKind,
|
`, gv)),
|
||||||
// constants.ClusterConfigurationKind,
|
expectedKinds: []string{
|
||||||
// },
|
constants.InitConfigurationKind,
|
||||||
// expectErr: false,
|
constants.ClusterConfigurationKind,
|
||||||
// },
|
},
|
||||||
// {
|
expectErr: false,
|
||||||
// desc: "JoinConfiguration only gets migrated",
|
},
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
{
|
||||||
// apiVersion: %s
|
name: "ClusterConfiguration only gets migrated",
|
||||||
// kind: JoinConfiguration
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// discovery:
|
apiVersion: %s
|
||||||
// bootstrapToken:
|
kind: ClusterConfiguration
|
||||||
// token: abcdef.0123456789abcdef
|
`, gv)),
|
||||||
// apiServerEndpoint: kube-apiserver:6443
|
expectedKinds: []string{
|
||||||
// unsafeSkipCAVerification: true
|
constants.InitConfigurationKind,
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
constants.ClusterConfigurationKind,
|
||||||
// expectedKinds: []string{
|
},
|
||||||
// constants.JoinConfigurationKind,
|
expectErr: false,
|
||||||
// },
|
},
|
||||||
// expectErr: false,
|
{
|
||||||
// },
|
name: "JoinConfiguration only gets migrated",
|
||||||
// {
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// desc: "Init + Cluster Configurations are migrated",
|
apiVersion: %s
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
kind: JoinConfiguration
|
||||||
// apiVersion: %s
|
discovery:
|
||||||
// kind: InitConfiguration
|
bootstrapToken:
|
||||||
// ---
|
token: abcdef.0123456789abcdef
|
||||||
// apiVersion: %[1]s
|
apiServerEndpoint: kube-apiserver:6443
|
||||||
// kind: ClusterConfiguration
|
unsafeSkipCAVerification: true
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
`, gv)),
|
||||||
// expectedKinds: []string{
|
expectedKinds: []string{
|
||||||
// constants.InitConfigurationKind,
|
constants.JoinConfigurationKind,
|
||||||
// constants.ClusterConfigurationKind,
|
},
|
||||||
// },
|
expectErr: false,
|
||||||
// expectErr: false,
|
},
|
||||||
// },
|
{
|
||||||
// {
|
name: "Init + Cluster Configurations are migrated",
|
||||||
// desc: "Init + Join Configurations are migrated",
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
apiVersion: %s
|
||||||
// apiVersion: %s
|
kind: InitConfiguration
|
||||||
// kind: InitConfiguration
|
---
|
||||||
// ---
|
apiVersion: %[1]s
|
||||||
// apiVersion: %[1]s
|
kind: ClusterConfiguration
|
||||||
// kind: JoinConfiguration
|
`, gv)),
|
||||||
// discovery:
|
expectedKinds: []string{
|
||||||
// bootstrapToken:
|
constants.InitConfigurationKind,
|
||||||
// token: abcdef.0123456789abcdef
|
constants.ClusterConfigurationKind,
|
||||||
// apiServerEndpoint: kube-apiserver:6443
|
},
|
||||||
// unsafeSkipCAVerification: true
|
expectErr: false,
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
},
|
||||||
// expectedKinds: []string{
|
{
|
||||||
// constants.InitConfigurationKind,
|
name: "Init + Join Configurations are migrated",
|
||||||
// constants.ClusterConfigurationKind,
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// constants.JoinConfigurationKind,
|
apiVersion: %s
|
||||||
// },
|
kind: InitConfiguration
|
||||||
// expectErr: false,
|
---
|
||||||
// },
|
apiVersion: %[1]s
|
||||||
// {
|
kind: JoinConfiguration
|
||||||
// desc: "Cluster + Join Configurations are migrated",
|
discovery:
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
bootstrapToken:
|
||||||
// apiVersion: %s
|
token: abcdef.0123456789abcdef
|
||||||
// kind: ClusterConfiguration
|
apiServerEndpoint: kube-apiserver:6443
|
||||||
// ---
|
unsafeSkipCAVerification: true
|
||||||
// apiVersion: %[1]s
|
`, gv)),
|
||||||
// kind: JoinConfiguration
|
expectedKinds: []string{
|
||||||
// discovery:
|
constants.InitConfigurationKind,
|
||||||
// bootstrapToken:
|
constants.ClusterConfigurationKind,
|
||||||
// token: abcdef.0123456789abcdef
|
constants.JoinConfigurationKind,
|
||||||
// apiServerEndpoint: kube-apiserver:6443
|
},
|
||||||
// unsafeSkipCAVerification: true
|
expectErr: false,
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
},
|
||||||
// expectedKinds: []string{
|
{
|
||||||
// constants.InitConfigurationKind,
|
name: "Cluster + Join Configurations are migrated",
|
||||||
// constants.ClusterConfigurationKind,
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// constants.JoinConfigurationKind,
|
apiVersion: %s
|
||||||
// },
|
kind: ClusterConfiguration
|
||||||
// expectErr: false,
|
---
|
||||||
// },
|
apiVersion: %[1]s
|
||||||
// {
|
kind: JoinConfiguration
|
||||||
// desc: "Init + Cluster + Join Configurations are migrated",
|
discovery:
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
bootstrapToken:
|
||||||
// apiVersion: %s
|
token: abcdef.0123456789abcdef
|
||||||
// kind: InitConfiguration
|
apiServerEndpoint: kube-apiserver:6443
|
||||||
// ---
|
unsafeSkipCAVerification: true
|
||||||
// apiVersion: %[1]s
|
`, gv)),
|
||||||
// kind: ClusterConfiguration
|
expectedKinds: []string{
|
||||||
// ---
|
constants.InitConfigurationKind,
|
||||||
// apiVersion: %[1]s
|
constants.ClusterConfigurationKind,
|
||||||
// kind: JoinConfiguration
|
constants.JoinConfigurationKind,
|
||||||
// discovery:
|
},
|
||||||
// bootstrapToken:
|
expectErr: false,
|
||||||
// token: abcdef.0123456789abcdef
|
},
|
||||||
// apiServerEndpoint: kube-apiserver:6443
|
{
|
||||||
// unsafeSkipCAVerification: true
|
name: "Init + Cluster + Join Configurations are migrated",
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// expectedKinds: []string{
|
apiVersion: %s
|
||||||
// constants.InitConfigurationKind,
|
kind: InitConfiguration
|
||||||
// constants.ClusterConfigurationKind,
|
---
|
||||||
// constants.JoinConfigurationKind,
|
apiVersion: %[1]s
|
||||||
// },
|
kind: ClusterConfiguration
|
||||||
// expectErr: false,
|
---
|
||||||
// },
|
apiVersion: %[1]s
|
||||||
// {
|
kind: JoinConfiguration
|
||||||
// desc: "component configs are not migrated",
|
discovery:
|
||||||
// oldCfg: dedent.Dedent(fmt.Sprintf(`
|
bootstrapToken:
|
||||||
// apiVersion: %s
|
token: abcdef.0123456789abcdef
|
||||||
// kind: InitConfiguration
|
apiServerEndpoint: kube-apiserver:6443
|
||||||
// ---
|
unsafeSkipCAVerification: true
|
||||||
// apiVersion: %[1]s
|
`, gv)),
|
||||||
// kind: ClusterConfiguration
|
expectedKinds: []string{
|
||||||
// ---
|
constants.InitConfigurationKind,
|
||||||
// apiVersion: %[1]s
|
constants.ClusterConfigurationKind,
|
||||||
// kind: JoinConfiguration
|
constants.JoinConfigurationKind,
|
||||||
// discovery:
|
},
|
||||||
// bootstrapToken:
|
expectErr: false,
|
||||||
// token: abcdef.0123456789abcdef
|
},
|
||||||
// apiServerEndpoint: kube-apiserver:6443
|
{
|
||||||
// unsafeSkipCAVerification: true
|
name: "component configs are not migrated",
|
||||||
// ---
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
// apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
apiVersion: %s
|
||||||
// kind: KubeProxyConfiguration
|
kind: InitConfiguration
|
||||||
// ---
|
---
|
||||||
// apiVersion: kubelet.config.k8s.io/v1beta1
|
apiVersion: %[1]s
|
||||||
// kind: KubeletConfiguration
|
kind: ClusterConfiguration
|
||||||
// `, kubeadmapiv1old.SchemeGroupVersion.String())),
|
---
|
||||||
// expectedKinds: []string{
|
apiVersion: %[1]s
|
||||||
// constants.InitConfigurationKind,
|
kind: JoinConfiguration
|
||||||
// constants.ClusterConfigurationKind,
|
discovery:
|
||||||
// constants.JoinConfigurationKind,
|
bootstrapToken:
|
||||||
// },
|
token: abcdef.0123456789abcdef
|
||||||
// expectErr: false,
|
apiServerEndpoint: kube-apiserver:6443
|
||||||
// },
|
unsafeSkipCAVerification: true
|
||||||
// }
|
---
|
||||||
|
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||||||
|
kind: KubeProxyConfiguration
|
||||||
|
---
|
||||||
|
apiVersion: kubelet.config.k8s.io/v1beta1
|
||||||
|
kind: KubeletConfiguration
|
||||||
|
`, gv)),
|
||||||
|
expectedKinds: []string{
|
||||||
|
constants.InitConfigurationKind,
|
||||||
|
constants.ClusterConfigurationKind,
|
||||||
|
constants.JoinConfigurationKind,
|
||||||
|
},
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ClusterConfiguration gets migrated from experimental API",
|
||||||
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: %s
|
||||||
|
kind: ClusterConfiguration
|
||||||
|
`, gvExperimental)),
|
||||||
|
expectedKinds: []string{
|
||||||
|
constants.InitConfigurationKind,
|
||||||
|
constants.ClusterConfigurationKind,
|
||||||
|
},
|
||||||
|
allowExperimental: true,
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ClusterConfiguration from experimental API cannot be migrated",
|
||||||
|
oldCfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: %s
|
||||||
|
kind: ClusterConfiguration
|
||||||
|
`, gvExperimental)),
|
||||||
|
allowExperimental: false,
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// for _, test := range tests {
|
for _, test := range tests {
|
||||||
// t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
// b, err := MigrateOldConfig([]byte(test.oldCfg))
|
b, err := MigrateOldConfig([]byte(test.oldCfg), test.allowExperimental)
|
||||||
// if test.expectErr {
|
if test.expectErr {
|
||||||
// if err == nil {
|
if err == nil {
|
||||||
// t.Fatalf("unexpected success:\n%s", b)
|
t.Fatalf("unexpected success:\n%s", b)
|
||||||
// }
|
}
|
||||||
// } else {
|
} else {
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// t.Fatalf("unexpected failure: %v", err)
|
t.Fatalf("unexpected failure: %v", err)
|
||||||
// }
|
}
|
||||||
// gvks, err := kubeadmutil.GroupVersionKindsFromBytes(b)
|
gvks, err := kubeadmutil.GroupVersionKindsFromBytes(b)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// t.Fatalf("unexpected error returned by GroupVersionKindsFromBytes: %v", err)
|
t.Fatalf("unexpected error returned by GroupVersionKindsFromBytes: %v", err)
|
||||||
// }
|
}
|
||||||
// if len(gvks) != len(test.expectedKinds) {
|
if len(gvks) != len(test.expectedKinds) {
|
||||||
// t.Fatalf("length mismatch between resulting gvks and expected kinds:\n\tlen(gvks)=%d\n\tlen(expectedKinds)=%d",
|
t.Fatalf("length mismatch between resulting gvks and expected kinds:\n\tlen(gvks)=%d\n\tlen(expectedKinds)=%d",
|
||||||
// len(gvks), len(test.expectedKinds))
|
len(gvks), len(test.expectedKinds))
|
||||||
// }
|
}
|
||||||
// for _, expectedKind := range test.expectedKinds {
|
for _, expectedKind := range test.expectedKinds {
|
||||||
// if !kubeadmutil.GroupVersionKindsHasKind(gvks, expectedKind) {
|
if !kubeadmutil.GroupVersionKindsHasKind(gvks, expectedKind) {
|
||||||
// t.Fatalf("migration failed to produce config kind: %s", expectedKind)
|
t.Fatalf("migration failed to produce config kind: %s", expectedKind)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
// NOTE: do not delete this test once an older API is removed and there is only one API left.
|
||||||
|
// Update the inline "gv" and "gvExperimental" variables, to have the GroupVersion String of
|
||||||
|
// the API to be tested. If there are no experimental APIs make "gvExperimental" point to
|
||||||
|
// an non-experimental API.
|
||||||
|
func TestValidateConfig(t *testing.T) {
|
||||||
|
var (
|
||||||
|
gv = kubeadmapiv1old.SchemeGroupVersion.String()
|
||||||
|
gvExperimental = kubeadmapiv1.SchemeGroupVersion.String()
|
||||||
|
)
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
cfg string
|
||||||
|
expectedError bool
|
||||||
|
allowExperimental bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "invalid subdomain",
|
||||||
|
cfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: %s
|
||||||
|
kind: InitConfiguration
|
||||||
|
nodeRegistration:
|
||||||
|
criSocket: %s
|
||||||
|
name: foo bar # not a valid subdomain
|
||||||
|
`, gv, constants.UnknownCRISocket)),
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unknown API GVK",
|
||||||
|
cfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: foo/bar # not a valid GroupVersion
|
||||||
|
kind: zzz # not a valid Kind
|
||||||
|
nodeRegistration:
|
||||||
|
criSocket: %s
|
||||||
|
`, constants.UnknownCRISocket)),
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "legacy API GVK",
|
||||||
|
cfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: kubeadm.k8s.io/v1beta1 # legacy API
|
||||||
|
kind: InitConfiguration
|
||||||
|
nodeRegistration:
|
||||||
|
criSocket: %s
|
||||||
|
`, constants.UnknownCRISocket)),
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unknown field",
|
||||||
|
cfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: %s
|
||||||
|
kind: InitConfiguration
|
||||||
|
foo: bar
|
||||||
|
nodeRegistration:
|
||||||
|
criSocket: %s
|
||||||
|
`, gv, constants.UnknownCRISocket)),
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid",
|
||||||
|
cfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: %s
|
||||||
|
kind: InitConfiguration
|
||||||
|
nodeRegistration:
|
||||||
|
criSocket: %s
|
||||||
|
`, gv, constants.UnknownCRISocket)),
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid: experimental API",
|
||||||
|
cfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: %s
|
||||||
|
kind: InitConfiguration
|
||||||
|
`, gvExperimental)),
|
||||||
|
expectedError: false,
|
||||||
|
allowExperimental: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid: experimental API",
|
||||||
|
cfg: dedent.Dedent(fmt.Sprintf(`
|
||||||
|
apiVersion: %s
|
||||||
|
kind: InitConfiguration
|
||||||
|
`, gvExperimental)),
|
||||||
|
expectedError: true,
|
||||||
|
allowExperimental: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
err := ValidateConfig([]byte(test.cfg), test.allowExperimental)
|
||||||
|
if (err != nil) != test.expectedError {
|
||||||
|
t.Fatalf("expected error: %v, got: %v, error: %v", test.expectedError, (err != nil), err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestIsKubeadmPrereleaseVersion(t *testing.T) {
|
func TestIsKubeadmPrereleaseVersion(t *testing.T) {
|
||||||
validVersionInfo := &apimachineryversion.Info{Major: "1", GitVersion: "v1.23.0-alpha.1"}
|
validVersionInfo := &apimachineryversion.Info{Major: "1", GitVersion: "v1.23.0-alpha.1"}
|
||||||
|
Loading…
Reference in New Issue
Block a user