mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #118866 from neolit123/1.28-add-v1beta4-to-scheme
kubeadm: add v1beta4 to scheme; add --allow-experimental-api flag
This commit is contained in:
		@@ -25,6 +25,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta4"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Scheme is the runtime.Scheme to which all kubeadm api types are registered.
 | 
			
		||||
@@ -42,5 +43,8 @@ func init() {
 | 
			
		||||
func AddToScheme(scheme *runtime.Scheme) {
 | 
			
		||||
	utilruntime.Must(kubeadm.AddToScheme(scheme))
 | 
			
		||||
	utilruntime.Must(v1beta3.AddToScheme(scheme))
 | 
			
		||||
	utilruntime.Must(scheme.SetVersionPriority(v1beta3.SchemeGroupVersion))
 | 
			
		||||
	utilruntime.Must(v1beta4.AddToScheme(scheme))
 | 
			
		||||
	// TODO: https://github.com/kubernetes/kubeadm/issues/2890
 | 
			
		||||
	// make v1beta4 highest priority
 | 
			
		||||
	utilruntime.Must(scheme.SetVersionPriority(v1beta3.SchemeGroupVersion, v1beta4.SchemeGroupVersion))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -225,6 +225,8 @@ func getDefaultNodeConfigBytes() ([]byte, error) {
 | 
			
		||||
// newCmdConfigMigrate returns cobra.Command for "kubeadm config migrate" command
 | 
			
		||||
func newCmdConfigMigrate(out io.Writer) *cobra.Command {
 | 
			
		||||
	var oldCfgPath, newCfgPath string
 | 
			
		||||
	var allowExperimental bool
 | 
			
		||||
 | 
			
		||||
	cmd := &cobra.Command{
 | 
			
		||||
		Use:   "migrate",
 | 
			
		||||
		Short: "Read an older version of the kubeadm configuration API types from a file, and output the similar config object for the newer version",
 | 
			
		||||
@@ -252,7 +254,7 @@ func newCmdConfigMigrate(out io.Writer) *cobra.Command {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			outputBytes, err := configutil.MigrateOldConfig(oldCfgBytes)
 | 
			
		||||
			outputBytes, err := configutil.MigrateOldConfig(oldCfgBytes, allowExperimental)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
@@ -270,12 +272,14 @@ func newCmdConfigMigrate(out io.Writer) *cobra.Command {
 | 
			
		||||
	}
 | 
			
		||||
	cmd.Flags().StringVar(&oldCfgPath, "old-config", "", "Path to the kubeadm config file that is using an old API version and should be converted. This flag is mandatory.")
 | 
			
		||||
	cmd.Flags().StringVar(&newCfgPath, "new-config", "", "Path to the resulting equivalent kubeadm config file using the new API version. Optional, if not specified output will be sent to STDOUT.")
 | 
			
		||||
	cmd.Flags().BoolVar(&allowExperimental, options.AllowExperimentalAPI, false, "Allow migration to experimental, unreleased APIs.")
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// newCmdConfigValidate returns cobra.Command for the "kubeadm config validate" command
 | 
			
		||||
func newCmdConfigValidate(out io.Writer) *cobra.Command {
 | 
			
		||||
	var cfgPath string
 | 
			
		||||
	var allowExperimental bool
 | 
			
		||||
 | 
			
		||||
	cmd := &cobra.Command{
 | 
			
		||||
		Use:   "validate",
 | 
			
		||||
@@ -300,7 +304,7 @@ func newCmdConfigValidate(out io.Writer) *cobra.Command {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if err := configutil.ValidateConfig(cfgBytes); err != nil {
 | 
			
		||||
			if err := configutil.ValidateConfig(cfgBytes, allowExperimental); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			fmt.Fprintln(out, "ok")
 | 
			
		||||
@@ -310,6 +314,7 @@ func newCmdConfigValidate(out io.Writer) *cobra.Command {
 | 
			
		||||
		Args: cobra.NoArgs,
 | 
			
		||||
	}
 | 
			
		||||
	options.AddConfigFlag(cmd.Flags(), &cfgPath)
 | 
			
		||||
	cmd.Flags().BoolVar(&allowExperimental, options.AllowExperimentalAPI, false, "Allow validation of experimental, unreleased APIs.")
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -142,4 +142,7 @@ const (
 | 
			
		||||
 | 
			
		||||
	// CleanupTmpDir flag indicates whether reset will cleanup the tmp dir
 | 
			
		||||
	CleanupTmpDir = "cleanup-tmp-dir"
 | 
			
		||||
 | 
			
		||||
	// AllowExperimentalAPI flag can be used to allow experimental / work in progress APIs
 | 
			
		||||
	AllowExperimentalAPI = "allow-experimental-api"
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@ import (
 | 
			
		||||
	kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
 | 
			
		||||
	kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
 | 
			
		||||
	kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
 | 
			
		||||
	"k8s.io/kubernetes/cmd/kubeadm/app/constants"
 | 
			
		||||
	kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
 | 
			
		||||
@@ -54,7 +55,7 @@ func MarshalKubeadmConfigObject(obj runtime.Object) ([]byte, 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 {
 | 
			
		||||
func validateSupportedVersion(gv schema.GroupVersion, allowDeprecated, allowExperimental 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
 | 
			
		||||
@@ -72,6 +73,13 @@ func validateSupportedVersion(gv schema.GroupVersion, allowDeprecated bool) erro
 | 
			
		||||
		"kubeadm.k8s.io/v1beta2":  "v1.22",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// v1.28: v1beta4 is released as experimental
 | 
			
		||||
	experimentalAPIVersions := map[string]string{
 | 
			
		||||
		// TODO: https://github.com/kubernetes/kubeadm/issues/2890
 | 
			
		||||
		// remove this from experimental once v1beta4 is released
 | 
			
		||||
		"kubeadm.k8s.io/v1beta4": "v1.28",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Deprecated API versions are supported by us, but can only be used for migration.
 | 
			
		||||
	deprecatedAPIVersions := map[string]struct{}{}
 | 
			
		||||
 | 
			
		||||
@@ -85,6 +93,10 @@ func validateSupportedVersion(gv schema.GroupVersion, allowDeprecated bool) erro
 | 
			
		||||
		klog.Warningf("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)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, present := experimentalAPIVersions[gvString]; present && !allowExperimental {
 | 
			
		||||
		return errors.Errorf("experimental API spec: %q is not allowed. You can use the --%s flag if the command supports it.", gv, options.AllowExperimentalAPI)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -205,7 +217,7 @@ func validateKnownGVKs(gvks []schema.GroupVersionKind) error {
 | 
			
		||||
 | 
			
		||||
		// Skip legacy known GVs so that they don't return errors.
 | 
			
		||||
		// This makes the function return errors only for GVs that where never known.
 | 
			
		||||
		if err := validateSupportedVersion(gvk.GroupVersion(), true); err != nil {
 | 
			
		||||
		if err := validateSupportedVersion(gvk.GroupVersion(), true, true); err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -229,7 +241,7 @@ func validateKnownGVKs(gvks []schema.GroupVersionKind) error {
 | 
			
		||||
 | 
			
		||||
// MigrateOldConfig migrates an old configuration from a byte slice into a new one (returned again as a byte slice).
 | 
			
		||||
// Only kubeadm kinds are migrated.
 | 
			
		||||
func MigrateOldConfig(oldConfig []byte) ([]byte, error) {
 | 
			
		||||
func MigrateOldConfig(oldConfig []byte, allowExperimental bool) ([]byte, error) {
 | 
			
		||||
	newConfig := [][]byte{}
 | 
			
		||||
 | 
			
		||||
	gvkmap, err := kubeadmutil.SplitYAMLDocuments(oldConfig)
 | 
			
		||||
@@ -248,7 +260,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, true, true)
 | 
			
		||||
		o, err := documentMapToInitConfiguration(gvkmap, true, allowExperimental, true)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return []byte{}, err
 | 
			
		||||
		}
 | 
			
		||||
@@ -261,7 +273,7 @@ func MigrateOldConfig(oldConfig []byte) ([]byte, error) {
 | 
			
		||||
 | 
			
		||||
	// Migrate JoinConfiguration if there is any
 | 
			
		||||
	if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
 | 
			
		||||
		o, err := documentMapToJoinConfiguration(gvkmap, true, true)
 | 
			
		||||
		o, err := documentMapToJoinConfiguration(gvkmap, true, allowExperimental, true)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return []byte{}, err
 | 
			
		||||
		}
 | 
			
		||||
@@ -277,7 +289,7 @@ func MigrateOldConfig(oldConfig []byte) ([]byte, error) {
 | 
			
		||||
 | 
			
		||||
// ValidateConfig takes a byte slice containing a kubeadm configuration and performs conversion
 | 
			
		||||
// to internal types and validation.
 | 
			
		||||
func ValidateConfig(oldConfig []byte) error {
 | 
			
		||||
func ValidateConfig(oldConfig []byte, allowExperimental bool) error {
 | 
			
		||||
	gvkmap, err := kubeadmutil.SplitYAMLDocuments(oldConfig)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@@ -294,14 +306,14 @@ func ValidateConfig(oldConfig []byte) error {
 | 
			
		||||
 | 
			
		||||
	// Validate InitConfiguration and ClusterConfiguration if there are any in the config
 | 
			
		||||
	if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvks...) || kubeadmutil.GroupVersionKindsHasClusterConfiguration(gvks...) {
 | 
			
		||||
		if _, err := documentMapToInitConfiguration(gvkmap, true, true); err != nil {
 | 
			
		||||
		if _, err := documentMapToInitConfiguration(gvkmap, true, allowExperimental, true); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Validate JoinConfiguration if there is any
 | 
			
		||||
	if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
 | 
			
		||||
		if _, err := documentMapToJoinConfiguration(gvkmap, true, true); err != nil {
 | 
			
		||||
		if _, err := documentMapToJoinConfiguration(gvkmap, true, allowExperimental, true); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -34,9 +34,10 @@ const KubeadmGroupName = "kubeadm.k8s.io"
 | 
			
		||||
 | 
			
		||||
func TestValidateSupportedVersion(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		gv              schema.GroupVersion
 | 
			
		||||
		allowDeprecated bool
 | 
			
		||||
		expectedErr     bool
 | 
			
		||||
		gv                schema.GroupVersion
 | 
			
		||||
		allowDeprecated   bool
 | 
			
		||||
		allowExperimental bool
 | 
			
		||||
		expectedErr       bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			gv: schema.GroupVersion{
 | 
			
		||||
@@ -85,11 +86,25 @@ func TestValidateSupportedVersion(t *testing.T) {
 | 
			
		||||
				Version: "v1",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			gv: schema.GroupVersion{
 | 
			
		||||
				Group:   KubeadmGroupName,
 | 
			
		||||
				Version: "v1beta4",
 | 
			
		||||
			},
 | 
			
		||||
			allowExperimental: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			gv: schema.GroupVersion{
 | 
			
		||||
				Group:   KubeadmGroupName,
 | 
			
		||||
				Version: "v1beta4",
 | 
			
		||||
			},
 | 
			
		||||
			expectedErr: true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, rt := range tests {
 | 
			
		||||
		t.Run(fmt.Sprintf("%s/allowDeprecated:%t", rt.gv, rt.allowDeprecated), func(t *testing.T) {
 | 
			
		||||
			err := validateSupportedVersion(rt.gv, rt.allowDeprecated)
 | 
			
		||||
			err := validateSupportedVersion(rt.gv, rt.allowDeprecated, rt.allowExperimental)
 | 
			
		||||
			if rt.expectedErr && err == nil {
 | 
			
		||||
				t.Error("unexpected success")
 | 
			
		||||
			} else if !rt.expectedErr && err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -287,17 +287,17 @@ func BytesToInitConfiguration(b []byte) (*kubeadmapi.InitConfiguration, error) {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return documentMapToInitConfiguration(gvkmap, false, false)
 | 
			
		||||
	return documentMapToInitConfiguration(gvkmap, false, false, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// documentMapToInitConfiguration converts a map of GVKs and YAML documents to defaulted and validated configuration object.
 | 
			
		||||
func documentMapToInitConfiguration(gvkmap kubeadmapi.DocumentMap, allowDeprecated, strictErrors bool) (*kubeadmapi.InitConfiguration, error) {
 | 
			
		||||
func documentMapToInitConfiguration(gvkmap kubeadmapi.DocumentMap, allowDeprecated, allowExperimental, strictErrors bool) (*kubeadmapi.InitConfiguration, error) {
 | 
			
		||||
	var initcfg *kubeadmapi.InitConfiguration
 | 
			
		||||
	var clustercfg *kubeadmapi.ClusterConfiguration
 | 
			
		||||
 | 
			
		||||
	for gvk, fileContent := range gvkmap {
 | 
			
		||||
		// first, check if this GVK is supported and possibly not deprecated
 | 
			
		||||
		if err := validateSupportedVersion(gvk.GroupVersion(), allowDeprecated); err != nil {
 | 
			
		||||
		if err := validateSupportedVersion(gvk.GroupVersion(), allowDeprecated, allowExperimental); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -85,12 +85,12 @@ func LoadJoinConfigurationFromFile(cfgPath string) (*kubeadmapi.JoinConfiguratio
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return documentMapToJoinConfiguration(gvkmap, false, false)
 | 
			
		||||
	return documentMapToJoinConfiguration(gvkmap, false, false, 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 kubeadmapi.DocumentMap, allowDeprecated, strictErrors bool) (*kubeadmapi.JoinConfiguration, error) {
 | 
			
		||||
func documentMapToJoinConfiguration(gvkmap kubeadmapi.DocumentMap, allowDeprecated, allowExperimental, strictErrors bool) (*kubeadmapi.JoinConfiguration, error) {
 | 
			
		||||
	joinBytes := []byte{}
 | 
			
		||||
	for gvk, bytes := range gvkmap {
 | 
			
		||||
		// not interested in anything other than JoinConfiguration
 | 
			
		||||
@@ -99,7 +99,7 @@ func documentMapToJoinConfiguration(gvkmap kubeadmapi.DocumentMap, allowDeprecat
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// check if this version is supported and possibly not deprecated
 | 
			
		||||
		if err := validateSupportedVersion(gvk.GroupVersion(), allowDeprecated); err != nil {
 | 
			
		||||
		if err := validateSupportedVersion(gvk.GroupVersion(), allowDeprecated, allowExperimental); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user