Skip to content

Commit 51ab638

Browse files
⚠️ Align KubeadmConfig to kubeadm v1beta4 types (#12282)
* Align extraArg type * Align ImagePullPolicy type * Add timeouts, move existing timeouts * Documentation * fix linter * fix E2E main * fix E2E * Revert test extension to v1beta1 * Address comments * More feedback
1 parent 4642e14 commit 51ab638

File tree

66 files changed

+4532
-1590
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+4532
-1590
lines changed

api/bootstrap/kubeadm/v1beta1/conversion.go

Lines changed: 172 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,162 @@ limitations under the License.
1717
package v1beta1
1818

1919
import (
20+
"reflect"
21+
2022
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2123
apimachineryconversion "k8s.io/apimachinery/pkg/conversion"
2224
"sigs.k8s.io/controller-runtime/pkg/conversion"
2325

2426
bootstrapv1 "sigs.k8s.io/cluster-api/api/bootstrap/kubeadm/v1beta2"
2527
clusterv1beta1 "sigs.k8s.io/cluster-api/api/core/v1beta1"
2628
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
29+
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
2730
)
2831

2932
func (src *KubeadmConfig) ConvertTo(dstRaw conversion.Hub) error {
3033
dst := dstRaw.(*bootstrapv1.KubeadmConfig)
34+
if err := Convert_v1beta1_KubeadmConfig_To_v1beta2_KubeadmConfig(src, dst, nil); err != nil {
35+
return err
36+
}
3137

32-
return Convert_v1beta1_KubeadmConfig_To_v1beta2_KubeadmConfig(src, dst, nil)
38+
// Manually restore data.
39+
restored := &bootstrapv1.KubeadmConfig{}
40+
ok, err := utilconversion.UnmarshalData(src, restored)
41+
if err != nil {
42+
return err
43+
}
44+
if ok {
45+
RestoreKubeadmConfigSpec(&restored.Spec, &dst.Spec)
46+
}
47+
// Override restored data with timeouts values already existing in v1beta1 but in other structs.
48+
src.Spec.ConvertTo(&dst.Spec)
49+
return nil
50+
}
51+
52+
func RestoreKubeadmConfigSpec(restored *bootstrapv1.KubeadmConfigSpec, dst *bootstrapv1.KubeadmConfigSpec) {
53+
// Restore fields added in v1beta2
54+
if restored.InitConfiguration != nil && restored.InitConfiguration.Timeouts != nil {
55+
if dst.InitConfiguration == nil {
56+
dst.InitConfiguration = &bootstrapv1.InitConfiguration{}
57+
}
58+
dst.InitConfiguration.Timeouts = restored.InitConfiguration.Timeouts
59+
}
60+
if restored.JoinConfiguration != nil && restored.JoinConfiguration.Timeouts != nil {
61+
if dst.JoinConfiguration == nil {
62+
dst.JoinConfiguration = &bootstrapv1.JoinConfiguration{}
63+
}
64+
dst.JoinConfiguration.Timeouts = restored.JoinConfiguration.Timeouts
65+
}
66+
}
67+
68+
func (src *KubeadmConfigSpec) ConvertTo(dst *bootstrapv1.KubeadmConfigSpec) {
69+
// Override with timeouts values already existing in v1beta1.
70+
var initControlPlaneComponentHealthCheckSeconds *int32
71+
if src.ClusterConfiguration != nil && src.ClusterConfiguration.APIServer.TimeoutForControlPlane != nil {
72+
if dst.InitConfiguration == nil {
73+
dst.InitConfiguration = &bootstrapv1.InitConfiguration{}
74+
}
75+
if dst.InitConfiguration.Timeouts == nil {
76+
dst.InitConfiguration.Timeouts = &bootstrapv1.Timeouts{}
77+
}
78+
dst.InitConfiguration.Timeouts.ControlPlaneComponentHealthCheckSeconds = bootstrapv1.ConvertToSeconds(src.ClusterConfiguration.APIServer.TimeoutForControlPlane)
79+
initControlPlaneComponentHealthCheckSeconds = dst.InitConfiguration.Timeouts.ControlPlaneComponentHealthCheckSeconds
80+
}
81+
if (src.JoinConfiguration != nil && src.JoinConfiguration.Discovery.Timeout != nil) || initControlPlaneComponentHealthCheckSeconds != nil {
82+
if dst.JoinConfiguration == nil {
83+
dst.JoinConfiguration = &bootstrapv1.JoinConfiguration{}
84+
}
85+
if dst.JoinConfiguration.Timeouts == nil {
86+
dst.JoinConfiguration.Timeouts = &bootstrapv1.Timeouts{}
87+
}
88+
dst.JoinConfiguration.Timeouts.ControlPlaneComponentHealthCheckSeconds = initControlPlaneComponentHealthCheckSeconds
89+
if src.JoinConfiguration != nil && src.JoinConfiguration.Discovery.Timeout != nil {
90+
dst.JoinConfiguration.Timeouts.TLSBootstrapSeconds = bootstrapv1.ConvertToSeconds(src.JoinConfiguration.Discovery.Timeout)
91+
}
92+
}
93+
94+
if reflect.DeepEqual(dst.ClusterConfiguration, &bootstrapv1.ClusterConfiguration{}) {
95+
dst.ClusterConfiguration = nil
96+
}
3397
}
3498

3599
func (dst *KubeadmConfig) ConvertFrom(srcRaw conversion.Hub) error {
36100
src := srcRaw.(*bootstrapv1.KubeadmConfig)
101+
if err := Convert_v1beta2_KubeadmConfig_To_v1beta1_KubeadmConfig(src, dst, nil); err != nil {
102+
return err
103+
}
104+
105+
// Convert timeouts moved from one struct to another.
106+
dst.Spec.ConvertFrom(&src.Spec)
37107

38-
return Convert_v1beta2_KubeadmConfig_To_v1beta1_KubeadmConfig(src, dst, nil)
108+
// Preserve Hub data on down-conversion except for metadata.
109+
return utilconversion.MarshalData(src, dst)
110+
}
111+
112+
func (dst *KubeadmConfigSpec) ConvertFrom(src *bootstrapv1.KubeadmConfigSpec) {
113+
// Convert timeouts moved from one struct to another.
114+
if src.InitConfiguration != nil && src.InitConfiguration.Timeouts != nil && src.InitConfiguration.Timeouts.ControlPlaneComponentHealthCheckSeconds != nil {
115+
if dst.ClusterConfiguration == nil {
116+
dst.ClusterConfiguration = &ClusterConfiguration{}
117+
}
118+
dst.ClusterConfiguration.APIServer.TimeoutForControlPlane = bootstrapv1.ConvertFromSeconds(src.InitConfiguration.Timeouts.ControlPlaneComponentHealthCheckSeconds)
119+
}
120+
if reflect.DeepEqual(dst.InitConfiguration, &InitConfiguration{}) {
121+
dst.InitConfiguration = nil
122+
}
123+
if src.JoinConfiguration != nil && src.JoinConfiguration.Timeouts != nil && src.JoinConfiguration.Timeouts.TLSBootstrapSeconds != nil {
124+
if dst.JoinConfiguration == nil {
125+
dst.JoinConfiguration = &JoinConfiguration{}
126+
}
127+
dst.JoinConfiguration.Discovery.Timeout = bootstrapv1.ConvertFromSeconds(src.JoinConfiguration.Timeouts.TLSBootstrapSeconds)
128+
}
129+
if reflect.DeepEqual(dst.JoinConfiguration, &JoinConfiguration{}) {
130+
dst.JoinConfiguration = nil
131+
}
39132
}
40133

41134
func (src *KubeadmConfigTemplate) ConvertTo(dstRaw conversion.Hub) error {
42135
dst := dstRaw.(*bootstrapv1.KubeadmConfigTemplate)
136+
if err := Convert_v1beta1_KubeadmConfigTemplate_To_v1beta2_KubeadmConfigTemplate(src, dst, nil); err != nil {
137+
return err
138+
}
139+
140+
// Manually restore data.
141+
restored := &bootstrapv1.KubeadmConfigTemplate{}
142+
ok, err := utilconversion.UnmarshalData(src, restored)
143+
if err != nil {
144+
return err
145+
}
146+
if ok {
147+
RestoreKubeadmConfigSpec(&restored.Spec.Template.Spec, &dst.Spec.Template.Spec)
148+
}
43149

44-
return Convert_v1beta1_KubeadmConfigTemplate_To_v1beta2_KubeadmConfigTemplate(src, dst, nil)
150+
// Override restored data with timeouts values already existing in v1beta1 but in other structs.
151+
src.Spec.Template.Spec.ConvertTo(&dst.Spec.Template.Spec)
152+
return nil
45153
}
46154

47155
func (dst *KubeadmConfigTemplate) ConvertFrom(srcRaw conversion.Hub) error {
48156
src := srcRaw.(*bootstrapv1.KubeadmConfigTemplate)
157+
if err := Convert_v1beta2_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate(src, dst, nil); err != nil {
158+
return err
159+
}
160+
161+
// Convert timeouts moved from one struct to another.
162+
dst.Spec.Template.Spec.ConvertFrom(&src.Spec.Template.Spec)
163+
164+
// Preserve Hub data on down-conversion except for metadata.
165+
return utilconversion.MarshalData(src, dst)
166+
}
167+
168+
func Convert_v1beta2_InitConfiguration_To_v1beta1_InitConfiguration(in *bootstrapv1.InitConfiguration, out *InitConfiguration, s apimachineryconversion.Scope) error {
169+
// Timeouts requires conversion at an upper level
170+
return autoConvert_v1beta2_InitConfiguration_To_v1beta1_InitConfiguration(in, out, s)
171+
}
49172

50-
return Convert_v1beta2_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate(src, dst, nil)
173+
func Convert_v1beta2_JoinConfiguration_To_v1beta1_JoinConfiguration(in *bootstrapv1.JoinConfiguration, out *JoinConfiguration, s apimachineryconversion.Scope) error {
174+
// Timeouts requires conversion at an upper level
175+
return autoConvert_v1beta2_JoinConfiguration_To_v1beta1_JoinConfiguration(in, out, s)
51176
}
52177

53178
func Convert_v1beta2_KubeadmConfigStatus_To_v1beta1_KubeadmConfigStatus(in *bootstrapv1.KubeadmConfigStatus, out *KubeadmConfigStatus, s apimachineryconversion.Scope) error {
@@ -82,11 +207,54 @@ func Convert_v1beta2_KubeadmConfigStatus_To_v1beta1_KubeadmConfigStatus(in *boot
82207
return nil
83208
}
84209

210+
func Convert_v1beta2_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(in *bootstrapv1.ControlPlaneComponent, out *ControlPlaneComponent, s apimachineryconversion.Scope) error {
211+
// Following fields require a custom conversions.
212+
out.ExtraArgs = bootstrapv1.ConvertFromArgs(in.ExtraArgs)
213+
return autoConvert_v1beta2_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(in, out, s)
214+
}
215+
216+
func Convert_v1beta2_LocalEtcd_To_v1beta1_LocalEtcd(in *bootstrapv1.LocalEtcd, out *LocalEtcd, s apimachineryconversion.Scope) error {
217+
// Following fields require a custom conversions.
218+
out.ExtraArgs = bootstrapv1.ConvertFromArgs(in.ExtraArgs)
219+
return autoConvert_v1beta2_LocalEtcd_To_v1beta1_LocalEtcd(in, out, s)
220+
}
221+
222+
func Convert_v1beta2_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in *bootstrapv1.NodeRegistrationOptions, out *NodeRegistrationOptions, s apimachineryconversion.Scope) error {
223+
// Following fields require a custom conversions.
224+
out.KubeletExtraArgs = bootstrapv1.ConvertFromArgs(in.KubeletExtraArgs)
225+
return autoConvert_v1beta2_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in, out, s)
226+
}
227+
228+
func Convert_v1beta1_APIServer_To_v1beta2_APIServer(in *APIServer, out *bootstrapv1.APIServer, s apimachineryconversion.Scope) error {
229+
// TimeoutForControlPlane has been removed in v1beta2
230+
return autoConvert_v1beta1_APIServer_To_v1beta2_APIServer(in, out, s)
231+
}
232+
233+
func Convert_v1beta1_Discovery_To_v1beta2_Discovery(in *Discovery, out *bootstrapv1.Discovery, s apimachineryconversion.Scope) error {
234+
// Timeout has been removed in v1beta2
235+
return autoConvert_v1beta1_Discovery_To_v1beta2_Discovery(in, out, s)
236+
}
237+
85238
func Convert_v1beta1_KubeadmConfigSpec_To_v1beta2_KubeadmConfigSpec(in *KubeadmConfigSpec, out *bootstrapv1.KubeadmConfigSpec, s apimachineryconversion.Scope) error {
86239
// NOTE: v1beta2 KubeadmConfigSpec does not have UseExperimentalRetryJoin anymore, so it's fine to just lose this field.
87240
return autoConvert_v1beta1_KubeadmConfigSpec_To_v1beta2_KubeadmConfigSpec(in, out, s)
88241
}
89242

243+
func Convert_v1beta1_ControlPlaneComponent_To_v1beta2_ControlPlaneComponent(in *ControlPlaneComponent, out *bootstrapv1.ControlPlaneComponent, s apimachineryconversion.Scope) error {
244+
out.ExtraArgs = bootstrapv1.ConvertToArgs(in.ExtraArgs)
245+
return autoConvert_v1beta1_ControlPlaneComponent_To_v1beta2_ControlPlaneComponent(in, out, s)
246+
}
247+
248+
func Convert_v1beta1_LocalEtcd_To_v1beta2_LocalEtcd(in *LocalEtcd, out *bootstrapv1.LocalEtcd, s apimachineryconversion.Scope) error {
249+
out.ExtraArgs = bootstrapv1.ConvertToArgs(in.ExtraArgs)
250+
return autoConvert_v1beta1_LocalEtcd_To_v1beta2_LocalEtcd(in, out, s)
251+
}
252+
253+
func Convert_v1beta1_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(in *NodeRegistrationOptions, out *bootstrapv1.NodeRegistrationOptions, s apimachineryconversion.Scope) error {
254+
out.KubeletExtraArgs = bootstrapv1.ConvertToArgs(in.KubeletExtraArgs)
255+
return autoConvert_v1beta1_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(in, out, s)
256+
}
257+
90258
func Convert_v1beta1_KubeadmConfigStatus_To_v1beta2_KubeadmConfigStatus(in *KubeadmConfigStatus, out *bootstrapv1.KubeadmConfigStatus, s apimachineryconversion.Scope) error {
91259
if err := autoConvert_v1beta1_KubeadmConfigStatus_To_v1beta2_KubeadmConfigStatus(in, out, s); err != nil {
92260
return err

api/bootstrap/kubeadm/v1beta1/conversion_test.go

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,23 @@ package v1beta1
2121
import (
2222
"reflect"
2323
"testing"
24+
"time"
2425

2526
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
29+
"k8s.io/utils/ptr"
2730
"sigs.k8s.io/randfill"
2831

2932
bootstrapv1 "sigs.k8s.io/cluster-api/api/bootstrap/kubeadm/v1beta2"
3033
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
3134
)
3235

36+
const (
37+
fakeID = "abcdef"
38+
fakeSecret = "abcdef0123456789"
39+
)
40+
3341
// Test is disabled when the race detector is enabled (via "//go:build !race" above) because otherwise the fuzz tests would just time out.
3442

3543
func TestFuzzyConversion(t *testing.T) {
@@ -48,11 +56,37 @@ func TestFuzzyConversion(t *testing.T) {
4856
func KubeadmConfigFuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} {
4957
return []interface{}{
5058
hubKubeadmConfigStatus,
59+
spokeAPIServer,
60+
spokeDiscovery,
5161
spokeKubeadmConfigSpec,
5262
spokeKubeadmConfigStatus,
63+
hubBootstrapTokenString,
64+
spokeBootstrapTokenString,
65+
hubKubeadmConfigSpec,
5366
}
5467
}
5568

69+
func KubeadmConfigTemplateFuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} {
70+
return []interface{}{
71+
spokeAPIServer,
72+
spokeDiscovery,
73+
spokeKubeadmConfigSpec,
74+
spokeBootstrapTokenString,
75+
hubBootstrapTokenString,
76+
hubKubeadmConfigSpec,
77+
}
78+
}
79+
80+
func hubBootstrapTokenString(in *bootstrapv1.BootstrapTokenString, _ randfill.Continue) {
81+
in.ID = fakeID
82+
in.Secret = fakeSecret
83+
}
84+
85+
func spokeBootstrapTokenString(in *BootstrapTokenString, _ randfill.Continue) {
86+
in.ID = fakeID
87+
in.Secret = fakeSecret
88+
}
89+
5690
func hubKubeadmConfigStatus(in *bootstrapv1.KubeadmConfigStatus, c randfill.Continue) {
5791
c.FillNoCustom(in)
5892
// Always create struct with at least one mandatory fields.
@@ -71,13 +105,48 @@ func hubKubeadmConfigStatus(in *bootstrapv1.KubeadmConfigStatus, c randfill.Cont
71105
}
72106
}
73107

108+
func hubKubeadmConfigSpec(in *bootstrapv1.KubeadmConfigSpec, c randfill.Continue) {
109+
c.FillNoCustom(in)
110+
111+
// enforce ControlPlaneComponentHealthCheckSeconds to be equal on init and join configuration
112+
var initControlPlaneComponentHealthCheckSeconds *int32
113+
if in.InitConfiguration != nil && in.InitConfiguration.Timeouts != nil {
114+
initControlPlaneComponentHealthCheckSeconds = in.InitConfiguration.Timeouts.ControlPlaneComponentHealthCheckSeconds
115+
}
116+
if (in.JoinConfiguration != nil && in.JoinConfiguration.Timeouts != nil) || initControlPlaneComponentHealthCheckSeconds != nil {
117+
if in.JoinConfiguration == nil {
118+
in.JoinConfiguration = &bootstrapv1.JoinConfiguration{}
119+
}
120+
if in.JoinConfiguration.Timeouts == nil {
121+
in.JoinConfiguration.Timeouts = &bootstrapv1.Timeouts{}
122+
}
123+
in.JoinConfiguration.Timeouts.ControlPlaneComponentHealthCheckSeconds = initControlPlaneComponentHealthCheckSeconds
124+
}
125+
}
126+
74127
func spokeKubeadmConfigSpec(in *KubeadmConfigSpec, c randfill.Continue) {
75128
c.FillNoCustom(in)
76129

77130
// Drop UseExperimentalRetryJoin as we intentionally don't preserve it.
78131
in.UseExperimentalRetryJoin = false
79132
}
80133

134+
func spokeAPIServer(in *APIServer, c randfill.Continue) {
135+
c.FillNoCustom(in)
136+
137+
if in.TimeoutForControlPlane != nil {
138+
in.TimeoutForControlPlane = ptr.To[metav1.Duration](metav1.Duration{Duration: time.Duration(c.Int31()) * time.Second})
139+
}
140+
}
141+
142+
func spokeDiscovery(in *Discovery, c randfill.Continue) {
143+
c.FillNoCustom(in)
144+
145+
if in.Timeout != nil {
146+
in.Timeout = ptr.To[metav1.Duration](metav1.Duration{Duration: time.Duration(c.Int31()) * time.Second})
147+
}
148+
}
149+
81150
func spokeKubeadmConfigStatus(in *KubeadmConfigStatus, c randfill.Continue) {
82151
c.FillNoCustom(in)
83152
// Drop empty structs with only omit empty fields.
@@ -87,9 +156,3 @@ func spokeKubeadmConfigStatus(in *KubeadmConfigStatus, c randfill.Continue) {
87156
}
88157
}
89158
}
90-
91-
func KubeadmConfigTemplateFuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} {
92-
return []interface{}{
93-
spokeKubeadmConfigSpec,
94-
}
95-
}

0 commit comments

Comments
 (0)