mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +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:
		@@ -38,7 +38,6 @@ import (
 | 
			
		||||
	outputapischeme "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/scheme"
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
 | 
			
		||||
	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"
 | 
			
		||||
	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
 | 
			
		||||
	dummyKubernetesVersion    = constants.MinimumControlPlaneVersion
 | 
			
		||||
	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) {
 | 
			
		||||
@@ -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) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		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
 | 
			
		||||
// to internal types and validation.
 | 
			
		||||
func ValidateConfig(oldConfig []byte, allowExperimental bool) error {
 | 
			
		||||
	gvkmap, err := kubeadmutil.SplitYAMLDocuments(oldConfig)
 | 
			
		||||
func ValidateConfig(config []byte, allowExperimental bool) error {
 | 
			
		||||
	gvkmap, err := kubeadmutil.SplitYAMLDocuments(config)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,13 +21,16 @@ import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/lithammer/dedent"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/util/version"
 | 
			
		||||
	apimachineryversion "k8s.io/apimachinery/pkg/version"
 | 
			
		||||
 | 
			
		||||
	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"
 | 
			
		||||
	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
// see <link-to-commit-foo> of how this unit test function
 | 
			
		||||
// looked before it was removed with the removal of v1beta2.
 | 
			
		||||
// func TestMigrateOldConfigFromFile(t *testing.T) {
 | 
			
		||||
// 	tests := []struct {
 | 
			
		||||
// 		desc          string
 | 
			
		||||
// 		oldCfg        string
 | 
			
		||||
// 		expectedKinds []string
 | 
			
		||||
// 		expectErr     bool
 | 
			
		||||
// 	}{
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc:      "empty file produces empty result",
 | 
			
		||||
// 			oldCfg:    "",
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "bad config produces error",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectErr: true,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "InitConfiguration only gets migrated",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			kind: InitConfiguration
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectedKinds: []string{
 | 
			
		||||
// 				constants.InitConfigurationKind,
 | 
			
		||||
// 				constants.ClusterConfigurationKind,
 | 
			
		||||
// 			},
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "ClusterConfiguration only gets migrated",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			kind: ClusterConfiguration
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectedKinds: []string{
 | 
			
		||||
// 				constants.InitConfigurationKind,
 | 
			
		||||
// 				constants.ClusterConfigurationKind,
 | 
			
		||||
// 			},
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "JoinConfiguration only gets migrated",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			kind: JoinConfiguration
 | 
			
		||||
// 			discovery:
 | 
			
		||||
// 			  bootstrapToken:
 | 
			
		||||
// 			    token: abcdef.0123456789abcdef
 | 
			
		||||
// 			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
// 			    unsafeSkipCAVerification: true
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectedKinds: []string{
 | 
			
		||||
// 				constants.JoinConfigurationKind,
 | 
			
		||||
// 			},
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "Init + Cluster Configurations are migrated",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			kind: InitConfiguration
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: %[1]s
 | 
			
		||||
// 			kind: ClusterConfiguration
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectedKinds: []string{
 | 
			
		||||
// 				constants.InitConfigurationKind,
 | 
			
		||||
// 				constants.ClusterConfigurationKind,
 | 
			
		||||
// 			},
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "Init + Join Configurations are migrated",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			kind: InitConfiguration
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: %[1]s
 | 
			
		||||
// 			kind: JoinConfiguration
 | 
			
		||||
// 			discovery:
 | 
			
		||||
// 			  bootstrapToken:
 | 
			
		||||
// 			    token: abcdef.0123456789abcdef
 | 
			
		||||
// 			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
// 			    unsafeSkipCAVerification: true
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectedKinds: []string{
 | 
			
		||||
// 				constants.InitConfigurationKind,
 | 
			
		||||
// 				constants.ClusterConfigurationKind,
 | 
			
		||||
// 				constants.JoinConfigurationKind,
 | 
			
		||||
// 			},
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "Cluster + Join Configurations are migrated",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			kind: ClusterConfiguration
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: %[1]s
 | 
			
		||||
// 			kind: JoinConfiguration
 | 
			
		||||
// 			discovery:
 | 
			
		||||
// 			  bootstrapToken:
 | 
			
		||||
// 			    token: abcdef.0123456789abcdef
 | 
			
		||||
// 			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
// 			    unsafeSkipCAVerification: true
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectedKinds: []string{
 | 
			
		||||
// 				constants.InitConfigurationKind,
 | 
			
		||||
// 				constants.ClusterConfigurationKind,
 | 
			
		||||
// 				constants.JoinConfigurationKind,
 | 
			
		||||
// 			},
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "Init + Cluster + Join Configurations are migrated",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			kind: InitConfiguration
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: %[1]s
 | 
			
		||||
// 			kind: ClusterConfiguration
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: %[1]s
 | 
			
		||||
// 			kind: JoinConfiguration
 | 
			
		||||
// 			discovery:
 | 
			
		||||
// 			  bootstrapToken:
 | 
			
		||||
// 			    token: abcdef.0123456789abcdef
 | 
			
		||||
// 			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
// 			    unsafeSkipCAVerification: true
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectedKinds: []string{
 | 
			
		||||
// 				constants.InitConfigurationKind,
 | 
			
		||||
// 				constants.ClusterConfigurationKind,
 | 
			
		||||
// 				constants.JoinConfigurationKind,
 | 
			
		||||
// 			},
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 		{
 | 
			
		||||
// 			desc: "component configs are not migrated",
 | 
			
		||||
// 			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
// 			apiVersion: %s
 | 
			
		||||
// 			kind: InitConfiguration
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: %[1]s
 | 
			
		||||
// 			kind: ClusterConfiguration
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: %[1]s
 | 
			
		||||
// 			kind: JoinConfiguration
 | 
			
		||||
// 			discovery:
 | 
			
		||||
// 			  bootstrapToken:
 | 
			
		||||
// 			    token: abcdef.0123456789abcdef
 | 
			
		||||
// 			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
// 			    unsafeSkipCAVerification: true
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: kubeproxy.config.k8s.io/v1alpha1
 | 
			
		||||
// 			kind: KubeProxyConfiguration
 | 
			
		||||
// 			---
 | 
			
		||||
// 			apiVersion: kubelet.config.k8s.io/v1beta1
 | 
			
		||||
// 			kind: KubeletConfiguration
 | 
			
		||||
// 			`, kubeadmapiv1old.SchemeGroupVersion.String())),
 | 
			
		||||
// 			expectedKinds: []string{
 | 
			
		||||
// 				constants.InitConfigurationKind,
 | 
			
		||||
// 				constants.ClusterConfigurationKind,
 | 
			
		||||
// 				constants.JoinConfigurationKind,
 | 
			
		||||
// 			},
 | 
			
		||||
// 			expectErr: false,
 | 
			
		||||
// 		},
 | 
			
		||||
// 	}
 | 
			
		||||
// 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 TestMigrateOldConfig(t *testing.T) {
 | 
			
		||||
	var (
 | 
			
		||||
		gv             = kubeadmapiv1old.SchemeGroupVersion.String()
 | 
			
		||||
		gvExperimental = kubeadmapiv1.SchemeGroupVersion.String()
 | 
			
		||||
	)
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name              string
 | 
			
		||||
		oldCfg            string
 | 
			
		||||
		expectedKinds     []string
 | 
			
		||||
		expectErr         bool
 | 
			
		||||
		allowExperimental bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name:      "empty file produces empty result",
 | 
			
		||||
			oldCfg:    "",
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "bad config produces error",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectErr: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "unknown API produces error",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: Foo
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectErr: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "InitConfiguration only gets migrated",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: InitConfiguration
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectedKinds: []string{
 | 
			
		||||
				constants.InitConfigurationKind,
 | 
			
		||||
				constants.ClusterConfigurationKind,
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "ClusterConfiguration only gets migrated",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: ClusterConfiguration
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectedKinds: []string{
 | 
			
		||||
				constants.InitConfigurationKind,
 | 
			
		||||
				constants.ClusterConfigurationKind,
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "JoinConfiguration only gets migrated",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: JoinConfiguration
 | 
			
		||||
			discovery:
 | 
			
		||||
			  bootstrapToken:
 | 
			
		||||
			    token: abcdef.0123456789abcdef
 | 
			
		||||
			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
			    unsafeSkipCAVerification: true
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectedKinds: []string{
 | 
			
		||||
				constants.JoinConfigurationKind,
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Init + Cluster Configurations are migrated",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: InitConfiguration
 | 
			
		||||
			---
 | 
			
		||||
			apiVersion: %[1]s
 | 
			
		||||
			kind: ClusterConfiguration
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectedKinds: []string{
 | 
			
		||||
				constants.InitConfigurationKind,
 | 
			
		||||
				constants.ClusterConfigurationKind,
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Init + Join Configurations are migrated",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: InitConfiguration
 | 
			
		||||
			---
 | 
			
		||||
			apiVersion: %[1]s
 | 
			
		||||
			kind: JoinConfiguration
 | 
			
		||||
			discovery:
 | 
			
		||||
			  bootstrapToken:
 | 
			
		||||
			    token: abcdef.0123456789abcdef
 | 
			
		||||
			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
			    unsafeSkipCAVerification: true
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectedKinds: []string{
 | 
			
		||||
				constants.InitConfigurationKind,
 | 
			
		||||
				constants.ClusterConfigurationKind,
 | 
			
		||||
				constants.JoinConfigurationKind,
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Cluster + Join Configurations are migrated",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: ClusterConfiguration
 | 
			
		||||
			---
 | 
			
		||||
			apiVersion: %[1]s
 | 
			
		||||
			kind: JoinConfiguration
 | 
			
		||||
			discovery:
 | 
			
		||||
			  bootstrapToken:
 | 
			
		||||
			    token: abcdef.0123456789abcdef
 | 
			
		||||
			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
			    unsafeSkipCAVerification: true
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectedKinds: []string{
 | 
			
		||||
				constants.InitConfigurationKind,
 | 
			
		||||
				constants.ClusterConfigurationKind,
 | 
			
		||||
				constants.JoinConfigurationKind,
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Init + Cluster + Join Configurations are migrated",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: InitConfiguration
 | 
			
		||||
			---
 | 
			
		||||
			apiVersion: %[1]s
 | 
			
		||||
			kind: ClusterConfiguration
 | 
			
		||||
			---
 | 
			
		||||
			apiVersion: %[1]s
 | 
			
		||||
			kind: JoinConfiguration
 | 
			
		||||
			discovery:
 | 
			
		||||
			  bootstrapToken:
 | 
			
		||||
			    token: abcdef.0123456789abcdef
 | 
			
		||||
			    apiServerEndpoint: kube-apiserver:6443
 | 
			
		||||
			    unsafeSkipCAVerification: true
 | 
			
		||||
			`, gv)),
 | 
			
		||||
			expectedKinds: []string{
 | 
			
		||||
				constants.InitConfigurationKind,
 | 
			
		||||
				constants.ClusterConfigurationKind,
 | 
			
		||||
				constants.JoinConfigurationKind,
 | 
			
		||||
			},
 | 
			
		||||
			expectErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "component configs are not migrated",
 | 
			
		||||
			oldCfg: dedent.Dedent(fmt.Sprintf(`
 | 
			
		||||
			apiVersion: %s
 | 
			
		||||
			kind: InitConfiguration
 | 
			
		||||
			---
 | 
			
		||||
			apiVersion: %[1]s
 | 
			
		||||
			kind: ClusterConfiguration
 | 
			
		||||
			---
 | 
			
		||||
			apiVersion: %[1]s
 | 
			
		||||
			kind: JoinConfiguration
 | 
			
		||||
			discovery:
 | 
			
		||||
			  bootstrapToken:
 | 
			
		||||
			    token: abcdef.0123456789abcdef
 | 
			
		||||
			    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 {
 | 
			
		||||
// 		t.Run(test.desc, func(t *testing.T) {
 | 
			
		||||
// 			b, err := MigrateOldConfig([]byte(test.oldCfg))
 | 
			
		||||
// 			if test.expectErr {
 | 
			
		||||
// 				if err == nil {
 | 
			
		||||
// 					t.Fatalf("unexpected success:\n%s", b)
 | 
			
		||||
// 				}
 | 
			
		||||
// 			} else {
 | 
			
		||||
// 				if err != nil {
 | 
			
		||||
// 					t.Fatalf("unexpected failure: %v", err)
 | 
			
		||||
// 				}
 | 
			
		||||
// 				gvks, err := kubeadmutil.GroupVersionKindsFromBytes(b)
 | 
			
		||||
// 				if err != nil {
 | 
			
		||||
// 					t.Fatalf("unexpected error returned by GroupVersionKindsFromBytes: %v", err)
 | 
			
		||||
// 				}
 | 
			
		||||
// 				if len(gvks) != len(test.expectedKinds) {
 | 
			
		||||
// 					t.Fatalf("length mismatch between resulting gvks and expected kinds:\n\tlen(gvks)=%d\n\tlen(expectedKinds)=%d",
 | 
			
		||||
// 						len(gvks), len(test.expectedKinds))
 | 
			
		||||
// 				}
 | 
			
		||||
// 				for _, expectedKind := range test.expectedKinds {
 | 
			
		||||
// 					if !kubeadmutil.GroupVersionKindsHasKind(gvks, expectedKind) {
 | 
			
		||||
// 						t.Fatalf("migration failed to produce config kind: %s", expectedKind)
 | 
			
		||||
// 					}
 | 
			
		||||
// 				}
 | 
			
		||||
// 			}
 | 
			
		||||
// 		})
 | 
			
		||||
// 	}
 | 
			
		||||
// }
 | 
			
		||||
	for _, test := range tests {
 | 
			
		||||
		t.Run(test.name, func(t *testing.T) {
 | 
			
		||||
			b, err := MigrateOldConfig([]byte(test.oldCfg), test.allowExperimental)
 | 
			
		||||
			if test.expectErr {
 | 
			
		||||
				if err == nil {
 | 
			
		||||
					t.Fatalf("unexpected success:\n%s", b)
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					t.Fatalf("unexpected failure: %v", err)
 | 
			
		||||
				}
 | 
			
		||||
				gvks, err := kubeadmutil.GroupVersionKindsFromBytes(b)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					t.Fatalf("unexpected error returned by GroupVersionKindsFromBytes: %v", err)
 | 
			
		||||
				}
 | 
			
		||||
				if len(gvks) != len(test.expectedKinds) {
 | 
			
		||||
					t.Fatalf("length mismatch between resulting gvks and expected kinds:\n\tlen(gvks)=%d\n\tlen(expectedKinds)=%d",
 | 
			
		||||
						len(gvks), len(test.expectedKinds))
 | 
			
		||||
				}
 | 
			
		||||
				for _, expectedKind := range test.expectedKinds {
 | 
			
		||||
					if !kubeadmutil.GroupVersionKindsHasKind(gvks, 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) {
 | 
			
		||||
	validVersionInfo := &apimachineryversion.Info{Major: "1", GitVersion: "v1.23.0-alpha.1"}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user