mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 03:03:59 +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:
commit
1c32c3bd9f
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user