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:
commit
1c32c3bd9f
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
"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/v1beta3"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Scheme is the runtime.Scheme to which all kubeadm api types are registered.
|
// Scheme is the runtime.Scheme to which all kubeadm api types are registered.
|
||||||
@ -42,5 +43,8 @@ func init() {
|
|||||||
func AddToScheme(scheme *runtime.Scheme) {
|
func AddToScheme(scheme *runtime.Scheme) {
|
||||||
utilruntime.Must(kubeadm.AddToScheme(scheme))
|
utilruntime.Must(kubeadm.AddToScheme(scheme))
|
||||||
utilruntime.Must(v1beta3.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
|
// newCmdConfigMigrate returns cobra.Command for "kubeadm config migrate" command
|
||||||
func newCmdConfigMigrate(out io.Writer) *cobra.Command {
|
func newCmdConfigMigrate(out io.Writer) *cobra.Command {
|
||||||
var oldCfgPath, newCfgPath string
|
var oldCfgPath, newCfgPath string
|
||||||
|
var allowExperimental bool
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "migrate",
|
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",
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
outputBytes, err := configutil.MigrateOldConfig(oldCfgBytes)
|
outputBytes, err := configutil.MigrateOldConfig(oldCfgBytes, allowExperimental)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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(&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().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
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCmdConfigValidate returns cobra.Command for the "kubeadm config validate" command
|
// newCmdConfigValidate returns cobra.Command for the "kubeadm config validate" command
|
||||||
func newCmdConfigValidate(out io.Writer) *cobra.Command {
|
func newCmdConfigValidate(out io.Writer) *cobra.Command {
|
||||||
var cfgPath string
|
var cfgPath string
|
||||||
|
var allowExperimental bool
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "validate",
|
Use: "validate",
|
||||||
@ -300,7 +304,7 @@ func newCmdConfigValidate(out io.Writer) *cobra.Command {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := configutil.ValidateConfig(cfgBytes); err != nil {
|
if err := configutil.ValidateConfig(cfgBytes, allowExperimental); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintln(out, "ok")
|
fmt.Fprintln(out, "ok")
|
||||||
@ -310,6 +314,7 @@ func newCmdConfigValidate(out io.Writer) *cobra.Command {
|
|||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
options.AddConfigFlag(cmd.Flags(), &cfgPath)
|
options.AddConfigFlag(cmd.Flags(), &cfgPath)
|
||||||
|
cmd.Flags().BoolVar(&allowExperimental, options.AllowExperimentalAPI, false, "Allow validation of experimental, unreleased APIs.")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,4 +142,7 @@ const (
|
|||||||
|
|
||||||
// CleanupTmpDir flag indicates whether reset will cleanup the tmp dir
|
// CleanupTmpDir flag indicates whether reset will cleanup the tmp dir
|
||||||
CleanupTmpDir = "cleanup-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"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
||||||
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
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/componentconfigs"
|
||||||
"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"
|
||||||
@ -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.
|
// validateSupportedVersion checks if the supplied GroupVersion is not on the lists of old unsupported or deprecated GVs.
|
||||||
// If it is, an error is returned.
|
// 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:
|
// The support matrix will look something like this now and in the future:
|
||||||
// v1.10 and earlier: v1alpha1
|
// v1.10 and earlier: v1alpha1
|
||||||
// v1.11: v1alpha1 read-only, writes only v1alpha2 config
|
// 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",
|
"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.
|
// Deprecated API versions are supported by us, but can only be used for migration.
|
||||||
deprecatedAPIVersions := map[string]struct{}{}
|
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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +217,7 @@ func validateKnownGVKs(gvks []schema.GroupVersionKind) error {
|
|||||||
|
|
||||||
// Skip legacy known GVs so that they don't return errors.
|
// Skip legacy known GVs so that they don't return errors.
|
||||||
// This makes the function return errors only for GVs that where never known.
|
// 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
|
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).
|
// MigrateOldConfig migrates an old configuration from a byte slice into a new one (returned again as a byte slice).
|
||||||
// Only kubeadm kinds are migrated.
|
// Only kubeadm kinds are migrated.
|
||||||
func MigrateOldConfig(oldConfig []byte) ([]byte, error) {
|
func MigrateOldConfig(oldConfig []byte, allowExperimental bool) ([]byte, error) {
|
||||||
newConfig := [][]byte{}
|
newConfig := [][]byte{}
|
||||||
|
|
||||||
gvkmap, err := kubeadmutil.SplitYAMLDocuments(oldConfig)
|
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
|
// Migrate InitConfiguration and ClusterConfiguration if there are any in the config
|
||||||
if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvks...) || kubeadmutil.GroupVersionKindsHasClusterConfiguration(gvks...) {
|
if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvks...) || kubeadmutil.GroupVersionKindsHasClusterConfiguration(gvks...) {
|
||||||
o, err := documentMapToInitConfiguration(gvkmap, true, true)
|
o, err := documentMapToInitConfiguration(gvkmap, true, allowExperimental, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
@ -261,7 +273,7 @@ func MigrateOldConfig(oldConfig []byte) ([]byte, error) {
|
|||||||
|
|
||||||
// Migrate JoinConfiguration if there is any
|
// Migrate JoinConfiguration if there is any
|
||||||
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
||||||
o, err := documentMapToJoinConfiguration(gvkmap, true, true)
|
o, err := documentMapToJoinConfiguration(gvkmap, true, allowExperimental, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
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
|
// 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) error {
|
func ValidateConfig(oldConfig []byte, allowExperimental bool) error {
|
||||||
gvkmap, err := kubeadmutil.SplitYAMLDocuments(oldConfig)
|
gvkmap, err := kubeadmutil.SplitYAMLDocuments(oldConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -294,14 +306,14 @@ func ValidateConfig(oldConfig []byte) error {
|
|||||||
|
|
||||||
// Validate InitConfiguration and ClusterConfiguration if there are any in the config
|
// Validate InitConfiguration and ClusterConfiguration if there are any in the config
|
||||||
if kubeadmutil.GroupVersionKindsHasInitConfiguration(gvks...) || kubeadmutil.GroupVersionKindsHasClusterConfiguration(gvks...) {
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate JoinConfiguration if there is any
|
// Validate JoinConfiguration if there is any
|
||||||
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
if kubeadmutil.GroupVersionKindsHasJoinConfiguration(gvks...) {
|
||||||
if _, err := documentMapToJoinConfiguration(gvkmap, true, true); err != nil {
|
if _, err := documentMapToJoinConfiguration(gvkmap, true, allowExperimental, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,10 @@ const KubeadmGroupName = "kubeadm.k8s.io"
|
|||||||
|
|
||||||
func TestValidateSupportedVersion(t *testing.T) {
|
func TestValidateSupportedVersion(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
gv schema.GroupVersion
|
gv schema.GroupVersion
|
||||||
allowDeprecated bool
|
allowDeprecated bool
|
||||||
expectedErr bool
|
allowExperimental bool
|
||||||
|
expectedErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
gv: schema.GroupVersion{
|
gv: schema.GroupVersion{
|
||||||
@ -85,11 +86,25 @@ func TestValidateSupportedVersion(t *testing.T) {
|
|||||||
Version: "v1",
|
Version: "v1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
gv: schema.GroupVersion{
|
||||||
|
Group: KubeadmGroupName,
|
||||||
|
Version: "v1beta4",
|
||||||
|
},
|
||||||
|
allowExperimental: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
gv: schema.GroupVersion{
|
||||||
|
Group: KubeadmGroupName,
|
||||||
|
Version: "v1beta4",
|
||||||
|
},
|
||||||
|
expectedErr: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
t.Run(fmt.Sprintf("%s/allowDeprecated:%t", rt.gv, rt.allowDeprecated), func(t *testing.T) {
|
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 {
|
if rt.expectedErr && err == nil {
|
||||||
t.Error("unexpected success")
|
t.Error("unexpected success")
|
||||||
} else if !rt.expectedErr && err != nil {
|
} else if !rt.expectedErr && err != nil {
|
||||||
|
@ -287,17 +287,17 @@ func BytesToInitConfiguration(b []byte) (*kubeadmapi.InitConfiguration, error) {
|
|||||||
return nil, err
|
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.
|
// 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 initcfg *kubeadmapi.InitConfiguration
|
||||||
var clustercfg *kubeadmapi.ClusterConfiguration
|
var clustercfg *kubeadmapi.ClusterConfiguration
|
||||||
|
|
||||||
for gvk, fileContent := range gvkmap {
|
for gvk, fileContent := range gvkmap {
|
||||||
// first, check if this GVK is supported and possibly not deprecated
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,12 +85,12 @@ func LoadJoinConfigurationFromFile(cfgPath string) (*kubeadmapi.JoinConfiguratio
|
|||||||
return nil, err
|
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),
|
// 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.
|
// 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{}
|
joinBytes := []byte{}
|
||||||
for gvk, bytes := range gvkmap {
|
for gvk, bytes := range gvkmap {
|
||||||
// not interested in anything other than JoinConfiguration
|
// 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
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user