Skip to content

Commit 321ec39

Browse files
authored
Merge pull request kubernetes-sigs#4443 from fabriziopandini/use-cluster-API-owned-kubeadm-types-in-KCP
🌱 Make KCP using embedded kubeadm types while manipulating the kubeadm-config ConfigMap
2 parents 6c8b2dc + 5c19ea1 commit 321ec39

19 files changed

+973
-2002
lines changed

bootstrap/kubeadm/controllers/kubeadmconfig_controller.go

+21-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strconv"
2323
"time"
2424

25+
"github.com/blang/semver"
2526
"github.com/go-logr/logr"
2627
"github.com/pkg/errors"
2728
corev1 "k8s.io/api/core/v1"
@@ -367,6 +368,10 @@ func (r *KubeadmConfigReconciler) handleClusterNotInitialized(ctx context.Contex
367368
// should not handle special cases.
368369

369370
kubernetesVersion := scope.ConfigOwner.KubernetesVersion()
371+
parsedVersion, err := semver.ParseTolerant(kubernetesVersion)
372+
if err != nil {
373+
return ctrl.Result{}, errors.Wrapf(err, "failed to parse kubernetes version %q", kubernetesVersion)
374+
}
370375

371376
if scope.Config.Spec.InitConfiguration == nil {
372377
scope.Config.Spec.InitConfiguration = &bootstrapv1.InitConfiguration{
@@ -376,7 +381,7 @@ func (r *KubeadmConfigReconciler) handleClusterNotInitialized(ctx context.Contex
376381
},
377382
}
378383
}
379-
initdata, err := kubeadmtypes.MarshalInitConfigurationForVersion(scope.Config.Spec.InitConfiguration, kubernetesVersion)
384+
initdata, err := kubeadmtypes.MarshalInitConfigurationForVersion(scope.Config.Spec.InitConfiguration, parsedVersion)
380385
if err != nil {
381386
scope.Error(err, "Failed to marshal init configuration")
382387
return ctrl.Result{}, err
@@ -394,7 +399,7 @@ func (r *KubeadmConfigReconciler) handleClusterNotInitialized(ctx context.Contex
394399
// injects into config.ClusterConfiguration values from top level object
395400
r.reconcileTopLevelObjectSettings(ctx, scope.Cluster, machine, scope.Config)
396401

397-
clusterdata, err := kubeadmtypes.MarshalClusterConfigurationForVersion(scope.Config.Spec.ClusterConfiguration, kubernetesVersion)
402+
clusterdata, err := kubeadmtypes.MarshalClusterConfigurationForVersion(scope.Config.Spec.ClusterConfiguration, parsedVersion)
398403
if err != nil {
399404
scope.Error(err, "Failed to marshal cluster configuration")
400405
return ctrl.Result{}, err
@@ -476,7 +481,13 @@ func (r *KubeadmConfigReconciler) joinWorker(ctx context.Context, scope *Scope)
476481
return res, nil
477482
}
478483

479-
joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, scope.ConfigOwner.KubernetesVersion())
484+
kubernetesVersion := scope.ConfigOwner.KubernetesVersion()
485+
parsedVersion, err := semver.ParseTolerant(kubernetesVersion)
486+
if err != nil {
487+
return ctrl.Result{}, errors.Wrapf(err, "failed to parse kubernetes version %q", kubernetesVersion)
488+
}
489+
490+
joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, parsedVersion)
480491
if err != nil {
481492
scope.Error(err, "Failed to marshal join configuration")
482493
return ctrl.Result{}, err
@@ -557,7 +568,13 @@ func (r *KubeadmConfigReconciler) joinControlplane(ctx context.Context, scope *S
557568
return res, nil
558569
}
559570

560-
joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, scope.ConfigOwner.KubernetesVersion())
571+
kubernetesVersion := scope.ConfigOwner.KubernetesVersion()
572+
parsedVersion, err := semver.ParseTolerant(kubernetesVersion)
573+
if err != nil {
574+
return ctrl.Result{}, errors.Wrapf(err, "failed to parse kubernetes version %q", kubernetesVersion)
575+
}
576+
577+
joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, parsedVersion)
561578
if err != nil {
562579
scope.Error(err, "Failed to marshal join configuration")
563580
return ctrl.Result{}, err

bootstrap/kubeadm/types/utils.go

+12-16
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ limitations under the License.
1717
package utils
1818

1919
import (
20+
"github.com/blang/semver"
2021
"github.com/pkg/errors"
2122
runtime "k8s.io/apimachinery/pkg/runtime"
2223
"k8s.io/apimachinery/pkg/runtime/schema"
2324
"k8s.io/apimachinery/pkg/runtime/serializer"
24-
versionutil "k8s.io/apimachinery/pkg/util/version"
2525
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4"
2626
"sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta1"
2727
"sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta2"
@@ -30,6 +30,9 @@ import (
3030
)
3131

3232
var (
33+
v1beta1KubeadmVersion = semver.MustParse("1.13.0")
34+
v1beta2KubeadmVersion = semver.MustParse("1.15.0")
35+
3336
clusterConfigurationVersionTypeMap = map[schema.GroupVersion]conversion.Convertible{
3437
v1beta2.GroupVersion: &v1beta2.ClusterConfiguration{},
3538
v1beta1.GroupVersion: &v1beta1.ClusterConfiguration{},
@@ -51,18 +54,11 @@ var (
5154
}
5255
)
5356

54-
func KubeVersionToKubeadmAPIGroupVersion(version string) (schema.GroupVersion, error) {
55-
if version == "" {
56-
return schema.GroupVersion{}, errors.New("version cannot be empty")
57-
}
58-
semVersion, err := versionutil.ParseSemantic(version)
59-
if err != nil {
60-
return schema.GroupVersion{}, errors.Wrap(err, "error parsing the Kubernetes version")
61-
}
57+
func KubeVersionToKubeadmAPIGroupVersion(version semver.Version) (schema.GroupVersion, error) {
6258
switch {
63-
case semVersion.LessThan(versionutil.MustParseSemantic("v1.13.0")):
59+
case version.LT(v1beta1KubeadmVersion):
6460
return schema.GroupVersion{}, errors.New("the bootstrap provider for kubeadm doesn't support Kubernetes version lower than v1.13.0")
65-
case semVersion.LessThan(versionutil.MustParseSemantic("v1.15.0")):
61+
case version.LT(v1beta2KubeadmVersion):
6662
// NOTE: All the Kubernetes version >= v1.13 and < v1.15 should use the kubeadm API version v1beta1
6763
return v1beta1.GroupVersion, nil
6864
default:
@@ -79,32 +75,32 @@ func KubeVersionToKubeadmAPIGroupVersion(version string) (schema.GroupVersion, e
7975
// MarshalClusterConfigurationForVersion converts a Cluster API ClusterConfiguration type to the kubeadm API type
8076
// for the given Kubernetes Version.
8177
// NOTE: This assumes Kubernetes Version equals to kubeadm version.
82-
func MarshalClusterConfigurationForVersion(obj *bootstrapv1.ClusterConfiguration, version string) (string, error) {
78+
func MarshalClusterConfigurationForVersion(obj *bootstrapv1.ClusterConfiguration, version semver.Version) (string, error) {
8379
return marshalForVersion(obj, version, clusterConfigurationVersionTypeMap)
8480
}
8581

8682
// MarshalClusterStatusForVersion converts a Cluster API ClusterStatus type to the kubeadm API type
8783
// for the given Kubernetes Version.
8884
// NOTE: This assumes Kubernetes Version equals to kubeadm version.
89-
func MarshalClusterStatusForVersion(obj *bootstrapv1.ClusterStatus, version string) (string, error) {
85+
func MarshalClusterStatusForVersion(obj *bootstrapv1.ClusterStatus, version semver.Version) (string, error) {
9086
return marshalForVersion(obj, version, clusterStatusVersionTypeMap)
9187
}
9288

9389
// MarshalInitConfigurationForVersion converts a Cluster API InitConfiguration type to the kubeadm API type
9490
// for the given Kubernetes Version.
9591
// NOTE: This assumes Kubernetes Version equals to kubeadm version.
96-
func MarshalInitConfigurationForVersion(obj *bootstrapv1.InitConfiguration, version string) (string, error) {
92+
func MarshalInitConfigurationForVersion(obj *bootstrapv1.InitConfiguration, version semver.Version) (string, error) {
9793
return marshalForVersion(obj, version, initConfigurationVersionTypeMap)
9894
}
9995

10096
// MarshalJoinConfigurationForVersion converts a Cluster API JoinConfiguration type to the kubeadm API type
10197
// for the given Kubernetes Version.
10298
// NOTE: This assumes Kubernetes Version equals to kubeadm version.
103-
func MarshalJoinConfigurationForVersion(obj *bootstrapv1.JoinConfiguration, version string) (string, error) {
99+
func MarshalJoinConfigurationForVersion(obj *bootstrapv1.JoinConfiguration, version semver.Version) (string, error) {
104100
return marshalForVersion(obj, version, joinConfigurationVersionTypeMap)
105101
}
106102

107-
func marshalForVersion(obj conversion.Hub, version string, kubeadmObjVersionTypeMap map[schema.GroupVersion]conversion.Convertible) (string, error) {
103+
func marshalForVersion(obj conversion.Hub, version semver.Version, kubeadmObjVersionTypeMap map[schema.GroupVersion]conversion.Convertible) (string, error) {
108104
kubeadmAPIGroupVersion, err := KubeVersionToKubeadmAPIGroupVersion(version)
109105
if err != nil {
110106
return "", err

bootstrap/kubeadm/types/utils_test.go

+37-36
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package utils
1818

1919
import (
20+
"github.com/blang/semver"
2021
"github.com/google/go-cmp/cmp"
2122
. "github.com/onsi/gomega"
2223
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -29,7 +30,7 @@ import (
2930

3031
func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) {
3132
type args struct {
32-
k8sVersion string
33+
version semver.Version
3334
}
3435
tests := []struct {
3536
name string
@@ -40,47 +41,47 @@ func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) {
4041
{
4142
name: "fails when kubernetes version is too old",
4243
args: args{
43-
k8sVersion: "v1.12.0",
44+
version: semver.MustParse("1.12.0"),
4445
},
4546
want: schema.GroupVersion{},
4647
wantErr: true,
4748
},
4849
{
4950
name: "pass with minimum kubernetes version for kubeadm API v1beta1",
5051
args: args{
51-
k8sVersion: "v1.13.0",
52+
version: semver.MustParse("1.13.0"),
5253
},
5354
want: v1beta1.GroupVersion,
5455
wantErr: false,
5556
},
5657
{
5758
name: "pass with kubernetes version for kubeadm API v1beta1",
5859
args: args{
59-
k8sVersion: "v1.14.99",
60+
version: semver.MustParse("1.14.99"),
6061
},
6162
want: v1beta1.GroupVersion,
6263
wantErr: false,
6364
},
6465
{
6566
name: "pass with minimum kubernetes version for kubeadm API v1beta2",
6667
args: args{
67-
k8sVersion: "v1.15.0",
68+
version: semver.MustParse("1.15.0"),
6869
},
6970
want: v1beta2.GroupVersion,
7071
wantErr: false,
7172
},
7273
{
7374
name: "pass with kubernetes version for kubeadm API v1beta2",
7475
args: args{
75-
k8sVersion: "v1.20.99",
76+
version: semver.MustParse("1.20.99"),
7677
},
7778
want: v1beta2.GroupVersion,
7879
wantErr: false,
7980
},
8081
{
8182
name: "pass with future kubernetes version",
8283
args: args{
83-
k8sVersion: "v99.99.99",
84+
version: semver.MustParse("99.99.99"),
8485
},
8586
want: v1beta2.GroupVersion,
8687
wantErr: false,
@@ -90,7 +91,7 @@ func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) {
9091
t.Run(tt.name, func(t *testing.T) {
9192
g := NewWithT(t)
9293

93-
got, err := KubeVersionToKubeadmAPIGroupVersion(tt.args.k8sVersion)
94+
got, err := KubeVersionToKubeadmAPIGroupVersion(tt.args.version)
9495
if tt.wantErr {
9596
g.Expect(err).To(HaveOccurred())
9697
return
@@ -103,8 +104,8 @@ func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) {
103104

104105
func TestMarshalClusterConfigurationForVersion(t *testing.T) {
105106
type args struct {
106-
capiObj *bootstrapv1.ClusterConfiguration
107-
k8sVersion string
107+
capiObj *bootstrapv1.ClusterConfiguration
108+
version semver.Version
108109
}
109110
tests := []struct {
110111
name string
@@ -115,8 +116,8 @@ func TestMarshalClusterConfigurationForVersion(t *testing.T) {
115116
{
116117
name: "Generates a v1beta1 kubeadm configuration",
117118
args: args{
118-
capiObj: &bootstrapv1.ClusterConfiguration{},
119-
k8sVersion: "v1.14.9",
119+
capiObj: &bootstrapv1.ClusterConfiguration{},
120+
version: semver.MustParse("1.14.9"),
120121
},
121122
want: "apiServer: {}\n" +
122123
"apiVersion: kubeadm.k8s.io/v1beta1\n" + "" +
@@ -131,8 +132,8 @@ func TestMarshalClusterConfigurationForVersion(t *testing.T) {
131132
{
132133
name: "Generates a v1beta2 kubeadm configuration",
133134
args: args{
134-
capiObj: &bootstrapv1.ClusterConfiguration{},
135-
k8sVersion: "v1.15.0",
135+
capiObj: &bootstrapv1.ClusterConfiguration{},
136+
version: semver.MustParse("1.15.0"),
136137
},
137138
want: "apiServer: {}\n" +
138139
"apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
@@ -149,7 +150,7 @@ func TestMarshalClusterConfigurationForVersion(t *testing.T) {
149150
t.Run(tt.name, func(t *testing.T) {
150151
g := NewWithT(t)
151152

152-
got, err := MarshalClusterConfigurationForVersion(tt.args.capiObj, tt.args.k8sVersion)
153+
got, err := MarshalClusterConfigurationForVersion(tt.args.capiObj, tt.args.version)
153154
if tt.wantErr {
154155
g.Expect(err).To(HaveOccurred())
155156
return
@@ -162,8 +163,8 @@ func TestMarshalClusterConfigurationForVersion(t *testing.T) {
162163

163164
func TestMarshalClusterStatusForVersion(t *testing.T) {
164165
type args struct {
165-
capiObj *bootstrapv1.ClusterStatus
166-
k8sVersion string
166+
capiObj *bootstrapv1.ClusterStatus
167+
version semver.Version
167168
}
168169
tests := []struct {
169170
name string
@@ -174,8 +175,8 @@ func TestMarshalClusterStatusForVersion(t *testing.T) {
174175
{
175176
name: "Generates a v1beta1 kubeadm status",
176177
args: args{
177-
capiObj: &bootstrapv1.ClusterStatus{},
178-
k8sVersion: "v1.14.9",
178+
capiObj: &bootstrapv1.ClusterStatus{},
179+
version: semver.MustParse("1.14.9"),
179180
},
180181
want: "apiEndpoints: null\n" +
181182
"apiVersion: kubeadm.k8s.io/v1beta1\n" + "" +
@@ -185,8 +186,8 @@ func TestMarshalClusterStatusForVersion(t *testing.T) {
185186
{
186187
name: "Generates a v1beta2 kubeadm status",
187188
args: args{
188-
capiObj: &bootstrapv1.ClusterStatus{},
189-
k8sVersion: "v1.15.0",
189+
capiObj: &bootstrapv1.ClusterStatus{},
190+
version: semver.MustParse("1.15.0"),
190191
},
191192
want: "apiEndpoints: null\n" +
192193
"apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
@@ -198,7 +199,7 @@ func TestMarshalClusterStatusForVersion(t *testing.T) {
198199
t.Run(tt.name, func(t *testing.T) {
199200
g := NewWithT(t)
200201

201-
got, err := MarshalClusterStatusForVersion(tt.args.capiObj, tt.args.k8sVersion)
202+
got, err := MarshalClusterStatusForVersion(tt.args.capiObj, tt.args.version)
202203
if tt.wantErr {
203204
g.Expect(err).To(HaveOccurred())
204205
return
@@ -211,8 +212,8 @@ func TestMarshalClusterStatusForVersion(t *testing.T) {
211212

212213
func TestMarshalInitConfigurationForVersion(t *testing.T) {
213214
type args struct {
214-
capiObj *bootstrapv1.InitConfiguration
215-
k8sVersion string
215+
capiObj *bootstrapv1.InitConfiguration
216+
version semver.Version
216217
}
217218
tests := []struct {
218219
name string
@@ -223,8 +224,8 @@ func TestMarshalInitConfigurationForVersion(t *testing.T) {
223224
{
224225
name: "Generates a v1beta1 kubeadm configuration",
225226
args: args{
226-
capiObj: &bootstrapv1.InitConfiguration{},
227-
k8sVersion: "v1.14.9",
227+
capiObj: &bootstrapv1.InitConfiguration{},
228+
version: semver.MustParse("1.14.9"),
228229
},
229230
want: "apiVersion: kubeadm.k8s.io/v1beta1\n" +
230231
"kind: InitConfiguration\n" +
@@ -237,8 +238,8 @@ func TestMarshalInitConfigurationForVersion(t *testing.T) {
237238
{
238239
name: "Generates a v1beta2 kubeadm configuration",
239240
args: args{
240-
capiObj: &bootstrapv1.InitConfiguration{},
241-
k8sVersion: "v1.15.0",
241+
capiObj: &bootstrapv1.InitConfiguration{},
242+
version: semver.MustParse("1.15.0"),
242243
},
243244
want: "apiVersion: kubeadm.k8s.io/v1beta2\n" +
244245
"kind: InitConfiguration\n" +
@@ -251,7 +252,7 @@ func TestMarshalInitConfigurationForVersion(t *testing.T) {
251252
t.Run(tt.name, func(t *testing.T) {
252253
g := NewWithT(t)
253254

254-
got, err := MarshalInitConfigurationForVersion(tt.args.capiObj, tt.args.k8sVersion)
255+
got, err := MarshalInitConfigurationForVersion(tt.args.capiObj, tt.args.version)
255256
if tt.wantErr {
256257
g.Expect(err).To(HaveOccurred())
257258
return
@@ -264,8 +265,8 @@ func TestMarshalInitConfigurationForVersion(t *testing.T) {
264265

265266
func TestMarshalJoinConfigurationForVersion(t *testing.T) {
266267
type args struct {
267-
capiObj *bootstrapv1.JoinConfiguration
268-
k8sVersion string
268+
capiObj *bootstrapv1.JoinConfiguration
269+
version semver.Version
269270
}
270271
tests := []struct {
271272
name string
@@ -276,8 +277,8 @@ func TestMarshalJoinConfigurationForVersion(t *testing.T) {
276277
{
277278
name: "Generates a v1beta1 kubeadm configuration",
278279
args: args{
279-
capiObj: &bootstrapv1.JoinConfiguration{},
280-
k8sVersion: "v1.14.9",
280+
capiObj: &bootstrapv1.JoinConfiguration{},
281+
version: semver.MustParse("1.14.9"),
281282
},
282283
want: "apiVersion: kubeadm.k8s.io/v1beta1\n" + "" +
283284
"discovery: {}\n" +
@@ -288,8 +289,8 @@ func TestMarshalJoinConfigurationForVersion(t *testing.T) {
288289
{
289290
name: "Generates a v1beta2 kubeadm configuration",
290291
args: args{
291-
capiObj: &bootstrapv1.JoinConfiguration{},
292-
k8sVersion: "v1.15.0",
292+
capiObj: &bootstrapv1.JoinConfiguration{},
293+
version: semver.MustParse("1.15.0"),
293294
},
294295
want: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
295296
"discovery: {}\n" +
@@ -302,7 +303,7 @@ func TestMarshalJoinConfigurationForVersion(t *testing.T) {
302303
t.Run(tt.name, func(t *testing.T) {
303304
g := NewWithT(t)
304305

305-
got, err := MarshalJoinConfigurationForVersion(tt.args.capiObj, tt.args.k8sVersion)
306+
got, err := MarshalJoinConfigurationForVersion(tt.args.capiObj, tt.args.version)
306307
if tt.wantErr {
307308
g.Expect(err).To(HaveOccurred())
308309
return

0 commit comments

Comments
 (0)