From 2f967850ec15cbef1481008e2d50a9be7f116aa4 Mon Sep 17 00:00:00 2001 From: Stefan Bueringer Date: Fri, 9 Jul 2021 10:21:32 +0200 Subject: [PATCH] support NodeRegistrationOptions.IgnorePreflightErrors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Büringer buringerst@vmware.com --- bootstrap/kubeadm/api/v1alpha3/conversion.go | 99 +++++++++++++++- .../kubeadm/api/v1alpha3/conversion_test.go | 24 ++++ .../api/v1alpha3/zz_generated.conversion.go | 60 +++++++++- .../kubeadm/api/v1alpha4/kubeadm_types.go | 4 + .../api/v1alpha4/zz_generated.deepcopy.go | 5 + ...strap.cluster.x-k8s.io_kubeadmconfigs.yaml | 12 ++ ...uster.x-k8s.io_kubeadmconfigtemplates.yaml | 14 +++ bootstrap/kubeadm/types/utils_test.go | 106 +++++++++++++++++- bootstrap/kubeadm/types/v1beta1/conversion.go | 6 + .../kubeadm/types/v1beta1/conversion_test.go | 10 ++ .../types/v1beta1/zz_generated.conversion.go | 8 +- bootstrap/kubeadm/types/v1beta2/conversion.go | 5 - .../kubeadm/types/v1beta2/conversion_test.go | 8 -- bootstrap/kubeadm/types/v1beta2/types.go | 10 +- .../types/v1beta2/zz_generated.conversion.go | 18 ++- .../types/v1beta3/zz_generated.conversion.go | 3 +- .../kubeadm/api/v1alpha3/conversion.go | 15 +++ ...cluster.x-k8s.io_kubeadmcontrolplanes.yaml | 14 +++ ...x-k8s.io_kubeadmcontrolplanetemplates.yaml | 14 +++ 19 files changed, 395 insertions(+), 40 deletions(-) diff --git a/bootstrap/kubeadm/api/v1alpha3/conversion.go b/bootstrap/kubeadm/api/v1alpha3/conversion.go index abac455f51df..028ec4d74a58 100644 --- a/bootstrap/kubeadm/api/v1alpha3/conversion.go +++ b/bootstrap/kubeadm/api/v1alpha3/conversion.go @@ -20,19 +20,55 @@ import ( apiconversion "k8s.io/apimachinery/pkg/conversion" kubeadmbootstrapv1alpha4 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4" kubeadmbootstrapv1beta1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" "sigs.k8s.io/controller-runtime/pkg/conversion" ) // ConvertTo converts this KubeadmConfig to the Hub version (v1alpha4). func (src *KubeadmConfig) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*kubeadmbootstrapv1alpha4.KubeadmConfig) - return Convert_v1alpha3_KubeadmConfig_To_v1alpha4_KubeadmConfig(src, dst, nil) + + if err := Convert_v1alpha3_KubeadmConfig_To_v1alpha4_KubeadmConfig(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &kubeadmbootstrapv1alpha4.KubeadmConfig{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + if restored.Spec.JoinConfiguration != nil && restored.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.JoinConfiguration == nil { + dst.Spec.JoinConfiguration = &kubeadmbootstrapv1alpha4.JoinConfiguration{} + } + dst.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors + } + + if restored.Spec.InitConfiguration != nil && restored.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.InitConfiguration == nil { + dst.Spec.InitConfiguration = &kubeadmbootstrapv1alpha4.InitConfiguration{} + } + dst.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors + } + + return nil } // ConvertFrom converts from the KubeadmConfig Hub version (v1alpha4) to this version. func (dst *KubeadmConfig) ConvertFrom(srcRaw conversion.Hub) error { src := srcRaw.(*kubeadmbootstrapv1alpha4.KubeadmConfig) - return Convert_v1alpha4_KubeadmConfig_To_v1alpha3_KubeadmConfig(src, dst, nil) + + if err := Convert_v1alpha4_KubeadmConfig_To_v1alpha3_KubeadmConfig(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil } // ConvertTo converts this KubeadmConfigList to the Hub version (v1alpha4). @@ -50,13 +86,48 @@ func (dst *KubeadmConfigList) ConvertFrom(srcRaw conversion.Hub) error { // ConvertTo converts this KubeadmConfigTemplate to the Hub version (v1alpha4). func (src *KubeadmConfigTemplate) ConvertTo(dstRaw conversion.Hub) error { dst := dstRaw.(*kubeadmbootstrapv1alpha4.KubeadmConfigTemplate) - return Convert_v1alpha3_KubeadmConfigTemplate_To_v1alpha4_KubeadmConfigTemplate(src, dst, nil) + + if err := Convert_v1alpha3_KubeadmConfigTemplate_To_v1alpha4_KubeadmConfigTemplate(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &kubeadmbootstrapv1alpha4.KubeadmConfigTemplate{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + if restored.Spec.Template.Spec.JoinConfiguration != nil && restored.Spec.Template.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.Template.Spec.JoinConfiguration == nil { + dst.Spec.Template.Spec.JoinConfiguration = &kubeadmbootstrapv1alpha4.JoinConfiguration{} + } + dst.Spec.Template.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.Template.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors + } + + if restored.Spec.Template.Spec.InitConfiguration != nil && restored.Spec.Template.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.Template.Spec.InitConfiguration == nil { + dst.Spec.Template.Spec.InitConfiguration = &kubeadmbootstrapv1alpha4.InitConfiguration{} + } + dst.Spec.Template.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.Template.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors + } + + return nil } // ConvertFrom converts from the KubeadmConfigTemplate Hub version (v1alpha4) to this version. func (dst *KubeadmConfigTemplate) ConvertFrom(srcRaw conversion.Hub) error { src := srcRaw.(*kubeadmbootstrapv1alpha4.KubeadmConfigTemplate) - return Convert_v1alpha4_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate(src, dst, nil) + + if err := Convert_v1alpha4_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil } // ConvertTo converts this KubeadmConfigTemplateList to the Hub version (v1alpha3). @@ -90,3 +161,23 @@ func Convert_v1beta1_ClusterConfiguration_To_v1alpha4_ClusterConfiguration(in *k // ClusterConfiguration.UseHyperKubeImage was removed in kubeadm v1alpha4 API return kubeadmbootstrapv1beta1.Convert_v1beta1_ClusterConfiguration_To_v1alpha4_ClusterConfiguration(in, out, s) } + +func Convert_v1alpha4_InitConfiguration_To_v1beta1_InitConfiguration(in *kubeadmbootstrapv1alpha4.InitConfiguration, out *kubeadmbootstrapv1beta1.InitConfiguration, s apiconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return kubeadmbootstrapv1beta1.Convert_v1alpha4_InitConfiguration_To_v1beta1_InitConfiguration(in, out, s) +} + +func Convert_v1beta1_InitConfiguration_To_v1alpha4_InitConfiguration(in *kubeadmbootstrapv1beta1.InitConfiguration, out *kubeadmbootstrapv1alpha4.InitConfiguration, s apiconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return kubeadmbootstrapv1beta1.Convert_v1beta1_InitConfiguration_To_v1alpha4_InitConfiguration(in, out, s) +} + +func Convert_v1alpha4_JoinConfiguration_To_v1beta1_JoinConfiguration(in *kubeadmbootstrapv1alpha4.JoinConfiguration, out *kubeadmbootstrapv1beta1.JoinConfiguration, s apiconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return kubeadmbootstrapv1beta1.Convert_v1alpha4_JoinConfiguration_To_v1beta1_JoinConfiguration(in, out, s) +} + +func Convert_v1beta1_JoinConfiguration_To_v1alpha4_JoinConfiguration(in *kubeadmbootstrapv1beta1.JoinConfiguration, out *kubeadmbootstrapv1alpha4.JoinConfiguration, s apiconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return kubeadmbootstrapv1beta1.Convert_v1beta1_JoinConfiguration_To_v1alpha4_JoinConfiguration(in, out, s) +} diff --git a/bootstrap/kubeadm/api/v1alpha3/conversion_test.go b/bootstrap/kubeadm/api/v1alpha3/conversion_test.go index e5b0de2b61b9..e416231bf42b 100644 --- a/bootstrap/kubeadm/api/v1alpha3/conversion_test.go +++ b/bootstrap/kubeadm/api/v1alpha3/conversion_test.go @@ -23,7 +23,9 @@ import ( "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4" + kubeadmbootstrapv1alpha4 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4" "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta1" + kubeadmv1beta1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta1" utilconversion "sigs.k8s.io/cluster-api/util/conversion" ) @@ -45,6 +47,18 @@ func fuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { KubeadmConfigStatusFuzzer, dnsFuzzer, clusterConfigurationFuzzer, + // This custom functions are needed when ConvertTo/ConvertFrom functions + // uses the json package to unmarshal the bootstrap token string. + // + // The Kubeadm BootstrapTokenString type ships with a custom + // json string representation, in particular it supplies a customized + // UnmarshalJSON function that can return an error if the string + // isn't in the correct form. + // + // This function effectively disables any fuzzing for the token by setting + // the values for ID and Secret to working alphanumeric values. + kubeadmBootstrapTokenStringFuzzerV1beta1, + kubeadmBootstrapTokenStringFuzzerV1Alpha4, } } @@ -68,3 +82,13 @@ func clusterConfigurationFuzzer(obj *v1beta1.ClusterConfiguration, c fuzz.Contin // ClusterConfiguration.UseHyperKubeImage has been removed in v1alpha4, so setting it to false in order to avoid v1beta1 --> v1alpha4 --> v1beta1 round trip errors. obj.UseHyperKubeImage = false } + +func kubeadmBootstrapTokenStringFuzzerV1beta1(in *kubeadmv1beta1.BootstrapTokenString, c fuzz.Continue) { + in.ID = "abcdef" + in.Secret = "abcdef0123456789" +} + +func kubeadmBootstrapTokenStringFuzzerV1Alpha4(in *kubeadmbootstrapv1alpha4.BootstrapTokenString, c fuzz.Continue) { + in.ID = "abcdef" + in.Secret = "abcdef0123456789" +} diff --git a/bootstrap/kubeadm/api/v1alpha3/zz_generated.conversion.go b/bootstrap/kubeadm/api/v1alpha3/zz_generated.conversion.go index a08738c0f55e..b20aa66189ce 100644 --- a/bootstrap/kubeadm/api/v1alpha3/zz_generated.conversion.go +++ b/bootstrap/kubeadm/api/v1alpha3/zz_generated.conversion.go @@ -203,11 +203,31 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*v1alpha4.InitConfiguration)(nil), (*v1beta1.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha4_InitConfiguration_To_v1beta1_InitConfiguration(a.(*v1alpha4.InitConfiguration), b.(*v1beta1.InitConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1alpha4.JoinConfiguration)(nil), (*v1beta1.JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha4_JoinConfiguration_To_v1beta1_JoinConfiguration(a.(*v1alpha4.JoinConfiguration), b.(*v1beta1.JoinConfiguration), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*v1beta1.ClusterConfiguration)(nil), (*v1alpha4.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_ClusterConfiguration_To_v1alpha4_ClusterConfiguration(a.(*v1beta1.ClusterConfiguration), b.(*v1alpha4.ClusterConfiguration), scope) }); err != nil { return err } + if err := s.AddConversionFunc((*v1beta1.InitConfiguration)(nil), (*v1alpha4.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_InitConfiguration_To_v1alpha4_InitConfiguration(a.(*v1beta1.InitConfiguration), b.(*v1alpha4.InitConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.JoinConfiguration)(nil), (*v1alpha4.JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_JoinConfiguration_To_v1alpha4_JoinConfiguration(a.(*v1beta1.JoinConfiguration), b.(*v1alpha4.JoinConfiguration), scope) + }); err != nil { + return err + } return nil } @@ -403,8 +423,24 @@ func autoConvert_v1alpha3_KubeadmConfigSpec_To_v1alpha4_KubeadmConfigSpec(in *Ku } else { out.ClusterConfiguration = nil } - out.InitConfiguration = (*v1alpha4.InitConfiguration)(unsafe.Pointer(in.InitConfiguration)) - out.JoinConfiguration = (*v1alpha4.JoinConfiguration)(unsafe.Pointer(in.JoinConfiguration)) + if in.InitConfiguration != nil { + in, out := &in.InitConfiguration, &out.InitConfiguration + *out = new(v1alpha4.InitConfiguration) + if err := Convert_v1beta1_InitConfiguration_To_v1alpha4_InitConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.InitConfiguration = nil + } + if in.JoinConfiguration != nil { + in, out := &in.JoinConfiguration, &out.JoinConfiguration + *out = new(v1alpha4.JoinConfiguration) + if err := Convert_v1beta1_JoinConfiguration_To_v1alpha4_JoinConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.JoinConfiguration = nil + } out.Files = *(*[]v1alpha4.File)(unsafe.Pointer(&in.Files)) out.DiskSetup = (*v1alpha4.DiskSetup)(unsafe.Pointer(in.DiskSetup)) out.Mounts = *(*[]v1alpha4.MountPoints)(unsafe.Pointer(&in.Mounts)) @@ -433,8 +469,24 @@ func autoConvert_v1alpha4_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec(in *v1 } else { out.ClusterConfiguration = nil } - out.InitConfiguration = (*v1beta1.InitConfiguration)(unsafe.Pointer(in.InitConfiguration)) - out.JoinConfiguration = (*v1beta1.JoinConfiguration)(unsafe.Pointer(in.JoinConfiguration)) + if in.InitConfiguration != nil { + in, out := &in.InitConfiguration, &out.InitConfiguration + *out = new(v1beta1.InitConfiguration) + if err := Convert_v1alpha4_InitConfiguration_To_v1beta1_InitConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.InitConfiguration = nil + } + if in.JoinConfiguration != nil { + in, out := &in.JoinConfiguration, &out.JoinConfiguration + *out = new(v1beta1.JoinConfiguration) + if err := Convert_v1alpha4_JoinConfiguration_To_v1beta1_JoinConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.JoinConfiguration = nil + } out.Files = *(*[]File)(unsafe.Pointer(&in.Files)) out.DiskSetup = (*DiskSetup)(unsafe.Pointer(in.DiskSetup)) out.Mounts = *(*[]MountPoints)(unsafe.Pointer(&in.Mounts)) diff --git a/bootstrap/kubeadm/api/v1alpha4/kubeadm_types.go b/bootstrap/kubeadm/api/v1alpha4/kubeadm_types.go index ef5d79dd3189..b6f9224ff4ab 100644 --- a/bootstrap/kubeadm/api/v1alpha4/kubeadm_types.go +++ b/bootstrap/kubeadm/api/v1alpha4/kubeadm_types.go @@ -225,6 +225,10 @@ type NodeRegistrationOptions struct { // Flags have higher priority when parsing. These values are local and specific to the node kubeadm is executing on. // +optional KubeletExtraArgs map[string]string `json:"kubeletExtraArgs,omitempty"` + + // IgnorePreflightErrors provides a slice of pre-flight errors to be ignored when the current node is registered. + // +optional + IgnorePreflightErrors []string `json:"ignorePreflightErrors,omitempty"` } // Networking contains elements describing cluster's networking configuration. diff --git a/bootstrap/kubeadm/api/v1alpha4/zz_generated.deepcopy.go b/bootstrap/kubeadm/api/v1alpha4/zz_generated.deepcopy.go index 45dbe6aa933c..d331cf8baff5 100644 --- a/bootstrap/kubeadm/api/v1alpha4/zz_generated.deepcopy.go +++ b/bootstrap/kubeadm/api/v1alpha4/zz_generated.deepcopy.go @@ -918,6 +918,11 @@ func (in *NodeRegistrationOptions) DeepCopyInto(out *NodeRegistrationOptions) { (*out)[key] = val } } + if in.IgnorePreflightErrors != nil { + in, out := &in.IgnorePreflightErrors, &out.IgnorePreflightErrors + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeRegistrationOptions. diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml index 535a005e353f..d1f353010627 100644 --- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml +++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml @@ -1571,6 +1571,12 @@ spec: info. This information will be annotated to the Node API object, for later re-use type: string + ignorePreflightErrors: + description: IgnorePreflightErrors provides a slice of pre-flight + errors to be ignored when the current node is registered. + items: + type: string + type: array kubeletExtraArgs: additionalProperties: type: string @@ -1747,6 +1753,12 @@ spec: info. This information will be annotated to the Node API object, for later re-use type: string + ignorePreflightErrors: + description: IgnorePreflightErrors provides a slice of pre-flight + errors to be ignored when the current node is registered. + items: + type: string + type: array kubeletExtraArgs: additionalProperties: type: string diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml index 45808f99e5a4..ccf3db1a658a 100644 --- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml +++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml @@ -1599,6 +1599,13 @@ spec: runtime info. This information will be annotated to the Node API object, for later re-use type: string + ignorePreflightErrors: + description: IgnorePreflightErrors provides a slice + of pre-flight errors to be ignored when the current + node is registered. + items: + type: string + type: array kubeletExtraArgs: additionalProperties: type: string @@ -1786,6 +1793,13 @@ spec: runtime info. This information will be annotated to the Node API object, for later re-use type: string + ignorePreflightErrors: + description: IgnorePreflightErrors provides a slice + of pre-flight errors to be ignored when the current + node is registered. + items: + type: string + type: array kubeletExtraArgs: additionalProperties: type: string diff --git a/bootstrap/kubeadm/types/utils_test.go b/bootstrap/kubeadm/types/utils_test.go index f8ec5933d182..aec57ed083a9 100644 --- a/bootstrap/kubeadm/types/utils_test.go +++ b/bootstrap/kubeadm/types/utils_test.go @@ -162,6 +162,22 @@ func TestMarshalClusterConfigurationForVersion(t *testing.T) { "scheduler: {}\n", wantErr: false, }, + { + name: "Generates a v1beta3 kubeadm configuration", + args: args{ + capiObj: &bootstrapv1.ClusterConfiguration{}, + version: semver.MustParse("1.22.0"), + }, + want: "apiServer: {}\n" + + "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + + "controllerManager: {}\n" + + "dns: {}\n" + + "etcd: {}\n" + + "kind: ClusterConfiguration\n" + + "networking: {}\n" + + "scheduler: {}\n", + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -211,6 +227,14 @@ func TestMarshalClusterStatusForVersion(t *testing.T) { "kind: ClusterStatus\n", wantErr: false, }, + { + name: "Fails generating a v1beta3 kubeadm status", + args: args{ + capiObj: &bootstrapv1.ClusterStatus{}, + version: semver.MustParse("1.22.0"), + }, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -255,13 +279,38 @@ func TestMarshalInitConfigurationForVersion(t *testing.T) { { name: "Generates a v1beta2 kubeadm configuration", args: args{ - capiObj: &bootstrapv1.InitConfiguration{}, + capiObj: &bootstrapv1.InitConfiguration{ + NodeRegistration: bootstrapv1.NodeRegistrationOptions{ + IgnorePreflightErrors: []string{"some-preflight-check"}, + }, + }, version: semver.MustParse("1.15.0"), }, want: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "kind: InitConfiguration\n" + "localAPIEndpoint: {}\n" + - "nodeRegistration: {}\n", + "nodeRegistration:\n" + + " ignorePreflightErrors:\n" + + " - some-preflight-check\n", + wantErr: false, + }, + { + name: "Generates a v1beta3 kubeadm configuration", + args: args{ + capiObj: &bootstrapv1.InitConfiguration{ + NodeRegistration: bootstrapv1.NodeRegistrationOptions{ + IgnorePreflightErrors: []string{"some-preflight-check"}, + }, + }, + version: semver.MustParse("1.22.0"), + }, + want: "apiVersion: kubeadm.k8s.io/v1beta3\n" + + "kind: InitConfiguration\n" + + "localAPIEndpoint: {}\n" + + "nodeRegistration:\n" + + " ignorePreflightErrors:\n" + + " - some-preflight-check\n" + + " taints: null\n", wantErr: false, }, } @@ -306,13 +355,38 @@ func TestMarshalJoinConfigurationForVersion(t *testing.T) { { name: "Generates a v1beta2 kubeadm configuration", args: args{ - capiObj: &bootstrapv1.JoinConfiguration{}, + capiObj: &bootstrapv1.JoinConfiguration{ + NodeRegistration: bootstrapv1.NodeRegistrationOptions{ + IgnorePreflightErrors: []string{"some-preflight-check"}, + }, + }, version: semver.MustParse("1.15.0"), }, want: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" + "discovery: {}\n" + "kind: JoinConfiguration\n" + - "nodeRegistration: {}\n", + "nodeRegistration:\n" + + " ignorePreflightErrors:\n" + + " - some-preflight-check\n", + wantErr: false, + }, + { + name: "Generates a v1beta3 kubeadm configuration", + args: args{ + capiObj: &bootstrapv1.JoinConfiguration{ + NodeRegistration: bootstrapv1.NodeRegistrationOptions{ + IgnorePreflightErrors: []string{"some-preflight-check"}, + }, + }, + version: semver.MustParse("1.22.0"), + }, + want: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + + "discovery: {}\n" + + "kind: JoinConfiguration\n" + + "nodeRegistration:\n" + + " ignorePreflightErrors:\n" + + " - some-preflight-check\n" + + " taints: null\n", wantErr: false, }, } @@ -371,6 +445,21 @@ func TestUnmarshalClusterConfiguration(t *testing.T) { want: &bootstrapv1.ClusterConfiguration{}, wantErr: false, }, + { + name: "Parses a v1beta3 kubeadm configuration", + args: args{ + yaml: "apiServer: {}\n" + + "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + + "controllerManager: {}\n" + + "dns: {}\n" + + "etcd: {}\n" + + "kind: ClusterConfiguration\n" + + "networking: {}\n" + + "scheduler: {}\n", + }, + want: &bootstrapv1.ClusterConfiguration{}, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -417,6 +506,15 @@ func TestUnmarshalClusterStatus(t *testing.T) { want: &bootstrapv1.ClusterStatus{}, wantErr: false, }, + { + name: "Fails parsing a v1beta3 kubeadm configuration", + args: args{ + yaml: "apiEndpoints: null\n" + + "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" + + "kind: ClusterStatus\n", + }, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/bootstrap/kubeadm/types/v1beta1/conversion.go b/bootstrap/kubeadm/types/v1beta1/conversion.go index 83f40c7369c8..83a186703b39 100644 --- a/bootstrap/kubeadm/types/v1beta1/conversion.go +++ b/bootstrap/kubeadm/types/v1beta1/conversion.go @@ -19,6 +19,7 @@ package v1beta1 import ( apimachineryconversion "k8s.io/apimachinery/pkg/conversion" bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4" + v1alpha4 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4" "sigs.k8s.io/controller-runtime/pkg/conversion" ) @@ -79,3 +80,8 @@ func Convert_v1beta1_ClusterConfiguration_To_v1alpha4_ClusterConfiguration(in *C // ClusterConfiguration.UseHyperKubeImage was removed in kubeadm v1alpha4 API return autoConvert_v1beta1_ClusterConfiguration_To_v1alpha4_ClusterConfiguration(in, out, s) } + +func Convert_v1alpha4_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in *v1alpha4.NodeRegistrationOptions, out *NodeRegistrationOptions, s apimachineryconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return autoConvert_v1alpha4_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in, out, s) +} diff --git a/bootstrap/kubeadm/types/v1beta1/conversion_test.go b/bootstrap/kubeadm/types/v1beta1/conversion_test.go index f4ec090ec779..8302224b6ec5 100644 --- a/bootstrap/kubeadm/types/v1beta1/conversion_test.go +++ b/bootstrap/kubeadm/types/v1beta1/conversion_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4" + kubeadmbootstrapv1alpha4 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4" utilconversion "sigs.k8s.io/cluster-api/util/conversion" ) @@ -61,6 +62,7 @@ func fuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { return []interface{}{ dnsFuzzer, clusterConfigurationFuzzer, + kubeadmNodeRegistrationOptionsFuzzer, } } @@ -77,3 +79,11 @@ func clusterConfigurationFuzzer(obj *ClusterConfiguration, c fuzz.Continue) { // ClusterConfiguration.UseHyperKubeImage has been removed in v1alpha4, so setting it to false in order to avoid v1beta1 --> v1alpha4 --> v1beta1 round trip errors. obj.UseHyperKubeImage = false } + +func kubeadmNodeRegistrationOptionsFuzzer(obj *kubeadmbootstrapv1alpha4.NodeRegistrationOptions, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API, so setting it to nil in order to avoid + // v1alpha4 --> v1beta1 -> v1alpha4 round trip errors. + obj.IgnorePreflightErrors = nil +} diff --git a/bootstrap/kubeadm/types/v1beta1/zz_generated.conversion.go b/bootstrap/kubeadm/types/v1beta1/zz_generated.conversion.go index a842e40c6f0d..18104e8ad5af 100644 --- a/bootstrap/kubeadm/types/v1beta1/zz_generated.conversion.go +++ b/bootstrap/kubeadm/types/v1beta1/zz_generated.conversion.go @@ -232,7 +232,7 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*v1alpha4.NodeRegistrationOptions)(nil), (*NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + if err := s.AddConversionFunc((*v1alpha4.NodeRegistrationOptions)(nil), (*NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(a.(*v1alpha4.NodeRegistrationOptions), b.(*NodeRegistrationOptions), scope) }); err != nil { return err @@ -810,10 +810,6 @@ func autoConvert_v1alpha4_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOpt out.CRISocket = in.CRISocket out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) + // WARNING: in.IgnorePreflightErrors requires manual conversion: does not exist in peer-type return nil } - -// Convert_v1alpha4_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions is an autogenerated conversion function. -func Convert_v1alpha4_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in *v1alpha4.NodeRegistrationOptions, out *NodeRegistrationOptions, s conversion.Scope) error { - return autoConvert_v1alpha4_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in, out, s) -} diff --git a/bootstrap/kubeadm/types/v1beta2/conversion.go b/bootstrap/kubeadm/types/v1beta2/conversion.go index 3251f8a9852e..966a7b708247 100644 --- a/bootstrap/kubeadm/types/v1beta2/conversion.go +++ b/bootstrap/kubeadm/types/v1beta2/conversion.go @@ -75,11 +75,6 @@ func Convert_v1beta2_InitConfiguration_To_v1alpha4_InitConfiguration(in *InitCon return autoConvert_v1beta2_InitConfiguration_To_v1alpha4_InitConfiguration(in, out, s) } -func Convert_v1beta2_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOptions(in *NodeRegistrationOptions, out *bootstrapv1.NodeRegistrationOptions, s apimachineryconversion.Scope) error { - // NodeRegistrationOptions.IgnorePreflightErrors exists in v1beta2 types but not in bootstrapv1.NodeRegistrationOptions (Cluster API does not support it for now). Ignoring when converting. - return autoConvert_v1beta2_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOptions(in, out, s) -} - func Convert_v1beta2_JoinControlPlane_To_v1alpha4_JoinControlPlane(in *JoinControlPlane, out *bootstrapv1.JoinControlPlane, s apimachineryconversion.Scope) error { // JoinControlPlane.CertificateKey exists in v1beta2 types but not in bootstrapv1.JoinControlPlane (Cluster API does not uses automatic copy certs). Ignoring when converting. return autoConvert_v1beta2_JoinControlPlane_To_v1alpha4_JoinControlPlane(in, out, s) diff --git a/bootstrap/kubeadm/types/v1beta2/conversion_test.go b/bootstrap/kubeadm/types/v1beta2/conversion_test.go index acfaea4ea81e..82e99e8264db 100644 --- a/bootstrap/kubeadm/types/v1beta2/conversion_test.go +++ b/bootstrap/kubeadm/types/v1beta2/conversion_test.go @@ -60,7 +60,6 @@ func TestFuzzyConversion(t *testing.T) { func fuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { return []interface{}{ - nodeRegistrationOptionsFuzzer, initConfigurationFuzzer, joinControlPlanesFuzzer, dnsFuzzer, @@ -68,13 +67,6 @@ func fuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { } } -func nodeRegistrationOptionsFuzzer(obj *NodeRegistrationOptions, c fuzz.Continue) { - c.FuzzNoCustom(obj) - - // NodeRegistrationOptions.IgnorePreflightErrors does not exists in v1alpha4, so setting it to nil in order to avoid v1beta2 --> v1alpha4 --> v1beta2 round trip errors. - obj.IgnorePreflightErrors = nil -} - func joinControlPlanesFuzzer(obj *JoinControlPlane, c fuzz.Continue) { c.FuzzNoCustom(obj) diff --git a/bootstrap/kubeadm/types/v1beta2/types.go b/bootstrap/kubeadm/types/v1beta2/types.go index 0adba068052e..58490deee74a 100644 --- a/bootstrap/kubeadm/types/v1beta2/types.go +++ b/bootstrap/kubeadm/types/v1beta2/types.go @@ -141,6 +141,8 @@ type ClusterConfiguration struct { // ControlPlaneComponent holds settings common to control plane component of the cluster. type ControlPlaneComponent struct { // ExtraArgs is an extra set of flags to pass to the control plane component. + // A key in this map is the flag name as it appears on the + // command line except without leading dash(es). // TODO: This is temporary and ideally we would like to switch all components to // use ComponentConfig + ConfigMaps. ExtraArgs map[string]string `json:"extraArgs,omitempty"` @@ -232,13 +234,15 @@ type NodeRegistrationOptions struct { // Taints specifies the taints the Node API object should be registered with. If this field is unset, i.e. nil, in the `kubeadm init` process // it will be defaulted to []corev1.Taint{'node-role.kubernetes.io/master=""'}. If you don't want to taint your control-plane node, set this field to an - // empty slice, i.e. `taints: {}` in the YAML file. This field is solely used for Node registration. + // empty slice, i.e. `taints: []` in the YAML file. This field is solely used for Node registration. // +optional Taints []corev1.Taint `json:"taints,omitempty"` // KubeletExtraArgs passes through extra arguments to the kubelet. The arguments here are passed to the kubelet command line via the environment file // kubeadm writes at runtime for the kubelet to source. This overrides the generic base-level configuration in the kubelet-config-1.X ConfigMap // Flags have higher priority when parsing. These values are local and specific to the node kubeadm is executing on. + // A key in this map is the flag name as it appears on the + // command line except without leading dash(es). // +optional KubeletExtraArgs map[string]string `json:"kubeletExtraArgs,omitempty"` @@ -310,6 +314,8 @@ type LocalEtcd struct { // ExtraArgs are extra arguments provided to the etcd binary // when run inside a static pod. + // A key in this map is the flag name as it appears on the + // command line except without leading dash(es). ExtraArgs map[string]string `json:"extraArgs,omitempty"` // ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert. @@ -411,7 +417,7 @@ type BootstrapTokenDiscovery struct { // pinning, which can be unsafe. Each hash is specified as ":", // where the only currently supported type is "sha256". This is a hex-encoded // SHA-256 hash of the Subject Public Key Info (SPKI) object in DER-encoded - // ASN.1. These hashes can be calculated using, for example, OpenSSL: + // ASN.1. These hashes can be calculated using, for example, OpenSSL. CACertHashes []string `json:"caCertHashes,omitempty"` // UnsafeSkipCAVerification allows token-based discovery diff --git a/bootstrap/kubeadm/types/v1beta2/zz_generated.conversion.go b/bootstrap/kubeadm/types/v1beta2/zz_generated.conversion.go index 5071358ab2a6..91f87e6a52e7 100644 --- a/bootstrap/kubeadm/types/v1beta2/zz_generated.conversion.go +++ b/bootstrap/kubeadm/types/v1beta2/zz_generated.conversion.go @@ -217,6 +217,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*NodeRegistrationOptions)(nil), (*v1alpha4.NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOptions(a.(*NodeRegistrationOptions), b.(*v1alpha4.NodeRegistrationOptions), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*v1alpha4.NodeRegistrationOptions)(nil), (*NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha4_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(a.(*v1alpha4.NodeRegistrationOptions), b.(*NodeRegistrationOptions), scope) }); err != nil { @@ -242,11 +247,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddConversionFunc((*NodeRegistrationOptions)(nil), (*v1alpha4.NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1beta2_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOptions(a.(*NodeRegistrationOptions), b.(*v1alpha4.NodeRegistrationOptions), scope) - }); err != nil { - return err - } return nil } @@ -805,15 +805,21 @@ func autoConvert_v1beta2_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOpt out.CRISocket = in.CRISocket out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) - // WARNING: in.IgnorePreflightErrors requires manual conversion: does not exist in peer-type + out.IgnorePreflightErrors = *(*[]string)(unsafe.Pointer(&in.IgnorePreflightErrors)) return nil } +// Convert_v1beta2_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOptions is an autogenerated conversion function. +func Convert_v1beta2_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOptions(in *NodeRegistrationOptions, out *v1alpha4.NodeRegistrationOptions, s conversion.Scope) error { + return autoConvert_v1beta2_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOptions(in, out, s) +} + func autoConvert_v1alpha4_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(in *v1alpha4.NodeRegistrationOptions, out *NodeRegistrationOptions, s conversion.Scope) error { out.Name = in.Name out.CRISocket = in.CRISocket out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) + out.IgnorePreflightErrors = *(*[]string)(unsafe.Pointer(&in.IgnorePreflightErrors)) return nil } diff --git a/bootstrap/kubeadm/types/v1beta3/zz_generated.conversion.go b/bootstrap/kubeadm/types/v1beta3/zz_generated.conversion.go index 1c2b6362fea7..610fe377a435 100644 --- a/bootstrap/kubeadm/types/v1beta3/zz_generated.conversion.go +++ b/bootstrap/kubeadm/types/v1beta3/zz_generated.conversion.go @@ -780,7 +780,7 @@ func autoConvert_v1beta3_NodeRegistrationOptions_To_v1alpha4_NodeRegistrationOpt out.CRISocket = in.CRISocket out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) - // WARNING: in.IgnorePreflightErrors requires manual conversion: does not exist in peer-type + out.IgnorePreflightErrors = *(*[]string)(unsafe.Pointer(&in.IgnorePreflightErrors)) return nil } @@ -789,6 +789,7 @@ func autoConvert_v1alpha4_NodeRegistrationOptions_To_v1beta3_NodeRegistrationOpt out.CRISocket = in.CRISocket out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) + out.IgnorePreflightErrors = *(*[]string)(unsafe.Pointer(&in.IgnorePreflightErrors)) return nil } diff --git a/controlplane/kubeadm/api/v1alpha3/conversion.go b/controlplane/kubeadm/api/v1alpha3/conversion.go index b84c440d4a0d..f03b48c173ce 100644 --- a/controlplane/kubeadm/api/v1alpha3/conversion.go +++ b/controlplane/kubeadm/api/v1alpha3/conversion.go @@ -18,6 +18,7 @@ package v1alpha3 import ( apiconversion "k8s.io/apimachinery/pkg/conversion" + kubeadmbootstrapv1alpha4 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4" "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha4" utilconversion "sigs.k8s.io/cluster-api/util/conversion" "sigs.k8s.io/controller-runtime/pkg/conversion" @@ -39,6 +40,20 @@ func (src *KubeadmControlPlane) ConvertTo(destRaw conversion.Hub) error { dest.Spec.RolloutStrategy = restored.Spec.RolloutStrategy dest.Spec.MachineTemplate.ObjectMeta = restored.Spec.MachineTemplate.ObjectMeta + if restored.Spec.KubeadmConfigSpec.JoinConfiguration != nil && restored.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dest.Spec.KubeadmConfigSpec.JoinConfiguration == nil { + dest.Spec.KubeadmConfigSpec.JoinConfiguration = &kubeadmbootstrapv1alpha4.JoinConfiguration{} + } + dest.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors + } + + if restored.Spec.KubeadmConfigSpec.InitConfiguration != nil && restored.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dest.Spec.KubeadmConfigSpec.InitConfiguration == nil { + dest.Spec.KubeadmConfigSpec.InitConfiguration = &kubeadmbootstrapv1alpha4.InitConfiguration{} + } + dest.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.IgnorePreflightErrors + } + return nil } diff --git a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml index 2d5819d43454..4b2059c3e252 100644 --- a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml +++ b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml @@ -1785,6 +1785,13 @@ spec: info. This information will be annotated to the Node API object, for later re-use type: string + ignorePreflightErrors: + description: IgnorePreflightErrors provides a slice of + pre-flight errors to be ignored when the current node + is registered. + items: + type: string + type: array kubeletExtraArgs: additionalProperties: type: string @@ -1967,6 +1974,13 @@ spec: info. This information will be annotated to the Node API object, for later re-use type: string + ignorePreflightErrors: + description: IgnorePreflightErrors provides a slice of + pre-flight errors to be ignored when the current node + is registered. + items: + type: string + type: array kubeletExtraArgs: additionalProperties: type: string diff --git a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml index e8d9533b0004..6fbfa2d37d5c 100644 --- a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml +++ b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanetemplates.yaml @@ -653,6 +653,13 @@ spec: runtime info. This information will be annotated to the Node API object, for later re-use type: string + ignorePreflightErrors: + description: IgnorePreflightErrors provides a + slice of pre-flight errors to be ignored when + the current node is registered. + items: + type: string + type: array kubeletExtraArgs: additionalProperties: type: string @@ -849,6 +856,13 @@ spec: runtime info. This information will be annotated to the Node API object, for later re-use type: string + ignorePreflightErrors: + description: IgnorePreflightErrors provides a + slice of pre-flight errors to be ignored when + the current node is registered. + items: + type: string + type: array kubeletExtraArgs: additionalProperties: type: string