Skip to content

Commit

Permalink
Merge pull request #4443 from fabriziopandini/use-cluster-API-owned-k…
Browse files Browse the repository at this point in the history
…ubeadm-types-in-KCP

🌱 Make KCP using embedded kubeadm types while manipulating the kubeadm-config ConfigMap
  • Loading branch information
k8s-ci-robot authored May 11, 2021
2 parents 6c8b2dc + 5c19ea1 commit 321ec39
Show file tree
Hide file tree
Showing 19 changed files with 973 additions and 2,002 deletions.
25 changes: 21 additions & 4 deletions bootstrap/kubeadm/controllers/kubeadmconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"strconv"
"time"

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

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

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

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

joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, scope.ConfigOwner.KubernetesVersion())
kubernetesVersion := scope.ConfigOwner.KubernetesVersion()
parsedVersion, err := semver.ParseTolerant(kubernetesVersion)
if err != nil {
return ctrl.Result{}, errors.Wrapf(err, "failed to parse kubernetes version %q", kubernetesVersion)
}

joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, parsedVersion)
if err != nil {
scope.Error(err, "Failed to marshal join configuration")
return ctrl.Result{}, err
Expand Down Expand Up @@ -557,7 +568,13 @@ func (r *KubeadmConfigReconciler) joinControlplane(ctx context.Context, scope *S
return res, nil
}

joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, scope.ConfigOwner.KubernetesVersion())
kubernetesVersion := scope.ConfigOwner.KubernetesVersion()
parsedVersion, err := semver.ParseTolerant(kubernetesVersion)
if err != nil {
return ctrl.Result{}, errors.Wrapf(err, "failed to parse kubernetes version %q", kubernetesVersion)
}

joinData, err := kubeadmtypes.MarshalJoinConfigurationForVersion(scope.Config.Spec.JoinConfiguration, parsedVersion)
if err != nil {
scope.Error(err, "Failed to marshal join configuration")
return ctrl.Result{}, err
Expand Down
28 changes: 12 additions & 16 deletions bootstrap/kubeadm/types/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ limitations under the License.
package utils

import (
"github.com/blang/semver"
"github.com/pkg/errors"
runtime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
versionutil "k8s.io/apimachinery/pkg/util/version"
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4"
"sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta1"
"sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta2"
Expand All @@ -30,6 +30,9 @@ import (
)

var (
v1beta1KubeadmVersion = semver.MustParse("1.13.0")
v1beta2KubeadmVersion = semver.MustParse("1.15.0")

clusterConfigurationVersionTypeMap = map[schema.GroupVersion]conversion.Convertible{
v1beta2.GroupVersion: &v1beta2.ClusterConfiguration{},
v1beta1.GroupVersion: &v1beta1.ClusterConfiguration{},
Expand All @@ -51,18 +54,11 @@ var (
}
)

func KubeVersionToKubeadmAPIGroupVersion(version string) (schema.GroupVersion, error) {
if version == "" {
return schema.GroupVersion{}, errors.New("version cannot be empty")
}
semVersion, err := versionutil.ParseSemantic(version)
if err != nil {
return schema.GroupVersion{}, errors.Wrap(err, "error parsing the Kubernetes version")
}
func KubeVersionToKubeadmAPIGroupVersion(version semver.Version) (schema.GroupVersion, error) {
switch {
case semVersion.LessThan(versionutil.MustParseSemantic("v1.13.0")):
case version.LT(v1beta1KubeadmVersion):
return schema.GroupVersion{}, errors.New("the bootstrap provider for kubeadm doesn't support Kubernetes version lower than v1.13.0")
case semVersion.LessThan(versionutil.MustParseSemantic("v1.15.0")):
case version.LT(v1beta2KubeadmVersion):
// NOTE: All the Kubernetes version >= v1.13 and < v1.15 should use the kubeadm API version v1beta1
return v1beta1.GroupVersion, nil
default:
Expand All @@ -79,32 +75,32 @@ func KubeVersionToKubeadmAPIGroupVersion(version string) (schema.GroupVersion, e
// MarshalClusterConfigurationForVersion converts a Cluster API ClusterConfiguration type to the kubeadm API type
// for the given Kubernetes Version.
// NOTE: This assumes Kubernetes Version equals to kubeadm version.
func MarshalClusterConfigurationForVersion(obj *bootstrapv1.ClusterConfiguration, version string) (string, error) {
func MarshalClusterConfigurationForVersion(obj *bootstrapv1.ClusterConfiguration, version semver.Version) (string, error) {
return marshalForVersion(obj, version, clusterConfigurationVersionTypeMap)
}

// MarshalClusterStatusForVersion converts a Cluster API ClusterStatus type to the kubeadm API type
// for the given Kubernetes Version.
// NOTE: This assumes Kubernetes Version equals to kubeadm version.
func MarshalClusterStatusForVersion(obj *bootstrapv1.ClusterStatus, version string) (string, error) {
func MarshalClusterStatusForVersion(obj *bootstrapv1.ClusterStatus, version semver.Version) (string, error) {
return marshalForVersion(obj, version, clusterStatusVersionTypeMap)
}

// MarshalInitConfigurationForVersion converts a Cluster API InitConfiguration type to the kubeadm API type
// for the given Kubernetes Version.
// NOTE: This assumes Kubernetes Version equals to kubeadm version.
func MarshalInitConfigurationForVersion(obj *bootstrapv1.InitConfiguration, version string) (string, error) {
func MarshalInitConfigurationForVersion(obj *bootstrapv1.InitConfiguration, version semver.Version) (string, error) {
return marshalForVersion(obj, version, initConfigurationVersionTypeMap)
}

// MarshalJoinConfigurationForVersion converts a Cluster API JoinConfiguration type to the kubeadm API type
// for the given Kubernetes Version.
// NOTE: This assumes Kubernetes Version equals to kubeadm version.
func MarshalJoinConfigurationForVersion(obj *bootstrapv1.JoinConfiguration, version string) (string, error) {
func MarshalJoinConfigurationForVersion(obj *bootstrapv1.JoinConfiguration, version semver.Version) (string, error) {
return marshalForVersion(obj, version, joinConfigurationVersionTypeMap)
}

func marshalForVersion(obj conversion.Hub, version string, kubeadmObjVersionTypeMap map[schema.GroupVersion]conversion.Convertible) (string, error) {
func marshalForVersion(obj conversion.Hub, version semver.Version, kubeadmObjVersionTypeMap map[schema.GroupVersion]conversion.Convertible) (string, error) {
kubeadmAPIGroupVersion, err := KubeVersionToKubeadmAPIGroupVersion(version)
if err != nil {
return "", err
Expand Down
73 changes: 37 additions & 36 deletions bootstrap/kubeadm/types/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package utils

import (
"github.com/blang/semver"
"github.com/google/go-cmp/cmp"
. "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand All @@ -29,7 +30,7 @@ import (

func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) {
type args struct {
k8sVersion string
version semver.Version
}
tests := []struct {
name string
Expand All @@ -40,47 +41,47 @@ func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) {
{
name: "fails when kubernetes version is too old",
args: args{
k8sVersion: "v1.12.0",
version: semver.MustParse("1.12.0"),
},
want: schema.GroupVersion{},
wantErr: true,
},
{
name: "pass with minimum kubernetes version for kubeadm API v1beta1",
args: args{
k8sVersion: "v1.13.0",
version: semver.MustParse("1.13.0"),
},
want: v1beta1.GroupVersion,
wantErr: false,
},
{
name: "pass with kubernetes version for kubeadm API v1beta1",
args: args{
k8sVersion: "v1.14.99",
version: semver.MustParse("1.14.99"),
},
want: v1beta1.GroupVersion,
wantErr: false,
},
{
name: "pass with minimum kubernetes version for kubeadm API v1beta2",
args: args{
k8sVersion: "v1.15.0",
version: semver.MustParse("1.15.0"),
},
want: v1beta2.GroupVersion,
wantErr: false,
},
{
name: "pass with kubernetes version for kubeadm API v1beta2",
args: args{
k8sVersion: "v1.20.99",
version: semver.MustParse("1.20.99"),
},
want: v1beta2.GroupVersion,
wantErr: false,
},
{
name: "pass with future kubernetes version",
args: args{
k8sVersion: "v99.99.99",
version: semver.MustParse("99.99.99"),
},
want: v1beta2.GroupVersion,
wantErr: false,
Expand All @@ -90,7 +91,7 @@ func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

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

func TestMarshalClusterConfigurationForVersion(t *testing.T) {
type args struct {
capiObj *bootstrapv1.ClusterConfiguration
k8sVersion string
capiObj *bootstrapv1.ClusterConfiguration
version semver.Version
}
tests := []struct {
name string
Expand All @@ -115,8 +116,8 @@ func TestMarshalClusterConfigurationForVersion(t *testing.T) {
{
name: "Generates a v1beta1 kubeadm configuration",
args: args{
capiObj: &bootstrapv1.ClusterConfiguration{},
k8sVersion: "v1.14.9",
capiObj: &bootstrapv1.ClusterConfiguration{},
version: semver.MustParse("1.14.9"),
},
want: "apiServer: {}\n" +
"apiVersion: kubeadm.k8s.io/v1beta1\n" + "" +
Expand All @@ -131,8 +132,8 @@ func TestMarshalClusterConfigurationForVersion(t *testing.T) {
{
name: "Generates a v1beta2 kubeadm configuration",
args: args{
capiObj: &bootstrapv1.ClusterConfiguration{},
k8sVersion: "v1.15.0",
capiObj: &bootstrapv1.ClusterConfiguration{},
version: semver.MustParse("1.15.0"),
},
want: "apiServer: {}\n" +
"apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
Expand All @@ -149,7 +150,7 @@ func TestMarshalClusterConfigurationForVersion(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

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

func TestMarshalClusterStatusForVersion(t *testing.T) {
type args struct {
capiObj *bootstrapv1.ClusterStatus
k8sVersion string
capiObj *bootstrapv1.ClusterStatus
version semver.Version
}
tests := []struct {
name string
Expand All @@ -174,8 +175,8 @@ func TestMarshalClusterStatusForVersion(t *testing.T) {
{
name: "Generates a v1beta1 kubeadm status",
args: args{
capiObj: &bootstrapv1.ClusterStatus{},
k8sVersion: "v1.14.9",
capiObj: &bootstrapv1.ClusterStatus{},
version: semver.MustParse("1.14.9"),
},
want: "apiEndpoints: null\n" +
"apiVersion: kubeadm.k8s.io/v1beta1\n" + "" +
Expand All @@ -185,8 +186,8 @@ func TestMarshalClusterStatusForVersion(t *testing.T) {
{
name: "Generates a v1beta2 kubeadm status",
args: args{
capiObj: &bootstrapv1.ClusterStatus{},
k8sVersion: "v1.15.0",
capiObj: &bootstrapv1.ClusterStatus{},
version: semver.MustParse("1.15.0"),
},
want: "apiEndpoints: null\n" +
"apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
Expand All @@ -198,7 +199,7 @@ func TestMarshalClusterStatusForVersion(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

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

func TestMarshalInitConfigurationForVersion(t *testing.T) {
type args struct {
capiObj *bootstrapv1.InitConfiguration
k8sVersion string
capiObj *bootstrapv1.InitConfiguration
version semver.Version
}
tests := []struct {
name string
Expand All @@ -223,8 +224,8 @@ func TestMarshalInitConfigurationForVersion(t *testing.T) {
{
name: "Generates a v1beta1 kubeadm configuration",
args: args{
capiObj: &bootstrapv1.InitConfiguration{},
k8sVersion: "v1.14.9",
capiObj: &bootstrapv1.InitConfiguration{},
version: semver.MustParse("1.14.9"),
},
want: "apiVersion: kubeadm.k8s.io/v1beta1\n" +
"kind: InitConfiguration\n" +
Expand All @@ -237,8 +238,8 @@ func TestMarshalInitConfigurationForVersion(t *testing.T) {
{
name: "Generates a v1beta2 kubeadm configuration",
args: args{
capiObj: &bootstrapv1.InitConfiguration{},
k8sVersion: "v1.15.0",
capiObj: &bootstrapv1.InitConfiguration{},
version: semver.MustParse("1.15.0"),
},
want: "apiVersion: kubeadm.k8s.io/v1beta2\n" +
"kind: InitConfiguration\n" +
Expand All @@ -251,7 +252,7 @@ func TestMarshalInitConfigurationForVersion(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

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

func TestMarshalJoinConfigurationForVersion(t *testing.T) {
type args struct {
capiObj *bootstrapv1.JoinConfiguration
k8sVersion string
capiObj *bootstrapv1.JoinConfiguration
version semver.Version
}
tests := []struct {
name string
Expand All @@ -276,8 +277,8 @@ func TestMarshalJoinConfigurationForVersion(t *testing.T) {
{
name: "Generates a v1beta1 kubeadm configuration",
args: args{
capiObj: &bootstrapv1.JoinConfiguration{},
k8sVersion: "v1.14.9",
capiObj: &bootstrapv1.JoinConfiguration{},
version: semver.MustParse("1.14.9"),
},
want: "apiVersion: kubeadm.k8s.io/v1beta1\n" + "" +
"discovery: {}\n" +
Expand All @@ -288,8 +289,8 @@ func TestMarshalJoinConfigurationForVersion(t *testing.T) {
{
name: "Generates a v1beta2 kubeadm configuration",
args: args{
capiObj: &bootstrapv1.JoinConfiguration{},
k8sVersion: "v1.15.0",
capiObj: &bootstrapv1.JoinConfiguration{},
version: semver.MustParse("1.15.0"),
},
want: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
"discovery: {}\n" +
Expand All @@ -302,7 +303,7 @@ func TestMarshalJoinConfigurationForVersion(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

got, err := MarshalJoinConfigurationForVersion(tt.args.capiObj, tt.args.k8sVersion)
got, err := MarshalJoinConfigurationForVersion(tt.args.capiObj, tt.args.version)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
return
Expand Down
Loading

0 comments on commit 321ec39

Please sign in to comment.