Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/v1alpha1/kamajicontrolplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
capiv1beta2 "sigs.k8s.io/cluster-api/api/core/v1beta2"
)

// ControlPlaneComponent allows the customization for the given component of the control plane.
Expand Down Expand Up @@ -105,7 +105,7 @@ type CoreDNSAddonSpec struct {
type KamajiControlPlaneSpec struct {
KamajiControlPlaneFields `json:",inline"`
// ControlPlaneEndpoint propagates the endpoint the Kubernetes API Server managed by Kamaji is located.
ControlPlaneEndpoint capiv1beta1.APIEndpoint `json:"controlPlaneEndpoint,omitempty"`
ControlPlaneEndpoint capiv1beta2.APIEndpoint `json:"controlPlaneEndpoint,omitempty"`
// Number of desired replicas for the given TenantControlPlane.
// Defaults to 2.
// +kubebuilder:default=2
Expand Down
2 changes: 1 addition & 1 deletion api/v1alpha1/kamajicontrolplanetemplate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta1"

Check failure on line 8 in api/v1alpha1/kamajicontrolplanetemplate_types.go

View workflow job for this annotation

GitHub Actions / lint

SA1019: "sigs.k8s.io/cluster-api/api/core/v1beta1" is deprecated: This package is deprecated and is going to be removed when support for v1beta1 will be dropped. (staticcheck)
)

// KamajiControlPlaneTemplateSpec defines the desired state of KamajiControlPlaneTemplate.
Expand Down
15 changes: 12 additions & 3 deletions config/control-plane-components.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -493,18 +493,19 @@ spec:
type: object
controlPlaneEndpoint:
description: ControlPlaneEndpoint propagates the endpoint the Kubernetes API Server managed by Kamaji is located.
minProperties: 1
properties:
host:
description: host is the hostname on which the API server is serving.
maxLength: 512
minLength: 1
type: string
port:
description: port is the port on which the API server is serving.
format: int32
maximum: 65535
minimum: 1
type: integer
required:
- host
- port
type: object
controllerManager:
description: ControlPlaneComponent allows the customization for the given component of the control plane.
Expand Down Expand Up @@ -14093,6 +14094,14 @@ rules:
- patch
- update
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- list
- watch
- apiGroups:
- cluster.x-k8s.io
resources:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,18 +493,19 @@ spec:
controlPlaneEndpoint:
description: ControlPlaneEndpoint propagates the endpoint the Kubernetes
API Server managed by Kamaji is located.
minProperties: 1
properties:
host:
description: host is the hostname on which the API server is serving.
maxLength: 512
minLength: 1
type: string
port:
description: port is the port on which the API server is serving.
format: int32
maximum: 65535
minimum: 1
type: integer
required:
- host
- port
type: object
controllerManager:
description: ControlPlaneComponent allows the customization for the
Expand Down
8 changes: 8 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ rules:
- patch
- update
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- list
- watch
- apiGroups:
- cluster.x-k8s.io
resources:
Expand Down
21 changes: 11 additions & 10 deletions controllers/kamajicontrolplane_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/util/retry"
"k8s.io/component-base/featuregate"
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
capiv1beta2 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/cluster-api/util/annotations"
conditionsapi "sigs.k8s.io/cluster-api/util/conditions"
"sigs.k8s.io/cluster-api/util/predicates"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
Expand Down Expand Up @@ -80,18 +81,18 @@ func (r *KamajiControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.R
}

// Retrieving the Cluster information
cluster := capiv1beta1.Cluster{}
cluster := capiv1beta2.Cluster{}
cluster.SetName(kcp.GetOwnerReferences()[0].Name)
cluster.SetNamespace(kcp.GetNamespace())

if err = r.client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, &cluster); err != nil {
if errors.IsNotFound(err) {
log.Info("capiv1beta1.Cluster resource may have been deleted, withdrawing reconciliation")
log.Info("capiv1beta2.Cluster resource may have been deleted, withdrawing reconciliation")

return ctrl.Result{}, nil
}

log.Error(err, "unable to get capiv1beta1.Cluster")
log.Error(err, "unable to get capiv1beta2.Cluster")

return ctrl.Result{}, err //nolint:wrapcheck
}
Expand Down Expand Up @@ -199,12 +200,12 @@ func (r *KamajiControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.R
// check that happens latter will never succeed.
if err = r.client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, &cluster); err != nil {
if errors.IsNotFound(err) {
log.Info("capiv1beta1.Cluster resource may have been deleted, withdrawing reconciliation")
log.Info("capiv1beta2.Cluster resource may have been deleted, withdrawing reconciliation")

return ctrl.Result{}, nil
}

log.Error(err, "unable to get capiv1beta1.Cluster")
log.Error(err, "unable to get capiv1beta2.Cluster")

return ctrl.Result{}, err //nolint:wrapcheck
}
Expand All @@ -221,7 +222,7 @@ func (r *KamajiControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.R
})

if err != nil {
log.Error(err, "cannot patch capiv1beta1.Cluster")
log.Error(err, "cannot patch capiv1beta2.Cluster")

return ctrl.Result{}, err
}
Expand All @@ -231,13 +232,13 @@ func (r *KamajiControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.R
// 1. an assigned Control Plane endpoint
// 2. a ready infrastructure
if len(cluster.Spec.ControlPlaneEndpoint.Host) == 0 {
log.Info("capiv1beta1.Cluster Control Plane endpoint still unprocessed, enqueuing back")
log.Info("capiv1beta2.Cluster Control Plane endpoint still unprocessed, enqueuing back")

return ctrl.Result{RequeueAfter: time.Second}, nil
}

if !cluster.Status.InfrastructureReady {
log.Info("capiv1beta1.Cluster infrastructure is not yet ready, enqueuing back")
if conditionsapi.IsFalse(&cluster, capiv1beta2.InfrastructureReadyCondition) {
log.Info("capiv1beta2.Cluster infrastructure is not yet ready, enqueuing back")

return ctrl.Result{RequeueAfter: time.Second}, nil
}
Expand Down
67 changes: 27 additions & 40 deletions controllers/kamajicontrolplane_controller_cluster_patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/util/retry"
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
capiv1beta2 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/cluster-api/controllers/external"
"sigs.k8s.io/cluster-api/util/patch"
"sigs.k8s.io/controller-runtime/pkg/client"

Expand Down Expand Up @@ -60,7 +60,7 @@
return errors.Wrap(scopedErr, "cannot retrieve *v1alpha1.KamajiControlPlane")
}

controlPlane.Spec.ControlPlaneEndpoint = capiv1beta1.APIEndpoint{
controlPlane.Spec.ControlPlaneEndpoint = capiv1beta2.APIEndpoint{
Host: endpoint,
Port: int32(port), //nolint:gosec
}
Expand All @@ -73,10 +73,12 @@
return nil
}

//+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch

//nolint:cyclop
func (r *KamajiControlPlaneReconciler) patchCluster(ctx context.Context, cluster capiv1beta1.Cluster, controlPlane *v1alpha1.KamajiControlPlane, hostPort string) error {
if cluster.Spec.InfrastructureRef == nil {
return errors.New("capiv1beta1.Cluster has no InfrastructureRef")
func (r *KamajiControlPlaneReconciler) patchCluster(ctx context.Context, cluster capiv1beta2.Cluster, controlPlane *v1alpha1.KamajiControlPlane, hostPort string) error {
if !cluster.Spec.InfrastructureRef.IsDefined() {
return errors.New("capiv1beta2.Cluster has no InfrastructureRef")
}

endpoint, port, err := r.controlPlaneEndpoint(controlPlane, hostPort)
Expand Down Expand Up @@ -121,7 +123,7 @@
//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=proxmoxclusters;vsphereclusters;tinkerbellclusters,verbs=get;list;watch
//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=proxmoxclusters;vsphereclusters;tinkerbellclusters,verbs=patch

func (r *KamajiControlPlaneReconciler) checkOrPatchGenericCluster(ctx context.Context, cluster capiv1beta1.Cluster, endpoint string, port int64) error {
func (r *KamajiControlPlaneReconciler) checkOrPatchGenericCluster(ctx context.Context, cluster capiv1beta2.Cluster, endpoint string, port int64) error {
if err := r.checkGenericCluster(ctx, cluster, endpoint, port); err != nil {
if errors.As(err, &UnmanagedControlPlaneAddressError{}) {
return r.patchGenericCluster(ctx, cluster, endpoint, port, false)
Expand All @@ -136,18 +138,13 @@
//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsclusters;azureclusters;hetznerclusters;kubevirtclusters;nutanixclusters;packetclusters;ionoscloudclusters,verbs=patch;get;list;watch
//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=kubevirtclusters/status;nutanixclusters/status;packetclusters/status,verbs=patch

func (r *KamajiControlPlaneReconciler) patchGenericCluster(ctx context.Context, cluster capiv1beta1.Cluster, endpoint string, port int64, patchStatus bool) error {
infraCluster := unstructured.Unstructured{}

infraCluster.SetGroupVersionKind(cluster.Spec.InfrastructureRef.GroupVersionKind())
infraCluster.SetName(cluster.Spec.InfrastructureRef.Name)
infraCluster.SetNamespace(cluster.Spec.InfrastructureRef.Namespace)

if err := r.client.Get(ctx, types.NamespacedName{Name: infraCluster.GetName(), Namespace: infraCluster.GetNamespace()}, &infraCluster); err != nil {
return errors.Wrap(err, fmt.Sprintf("cannot retrieve the %s resource", infraCluster.GetKind()))
func (r *KamajiControlPlaneReconciler) patchGenericCluster(ctx context.Context, cluster capiv1beta2.Cluster, endpoint string, port int64, patchStatus bool) error {
infraCluster, err := external.GetObjectFromContractVersionedRef(ctx, r.client, cluster.Spec.InfrastructureRef, cluster.GetNamespace())
if err != nil {
return errors.Wrap(err, fmt.Sprintf("cannot get infrastructure reference %s", cluster.Spec.InfrastructureRef.Name))

Check failure on line 144 in controllers/kamajicontrolplane_controller_cluster_patch.go

View workflow job for this annotation

GitHub Actions / lint

string-format: fmt.Sprintf can be replaced with string concatenation (perfsprint)
}

patchHelper, err := patch.NewHelper(&infraCluster, r.client)
patchHelper, err := patch.NewHelper(infraCluster, r.client)
if err != nil {
return errors.Wrap(err, "unable to create patch helper")
}
Expand All @@ -165,7 +162,7 @@
}
}

if err = patchHelper.Patch(ctx, &infraCluster); err != nil {
if err = patchHelper.Patch(ctx, infraCluster); err != nil {
return errors.Wrap(err, fmt.Sprintf("cannot perform PATCH update for the %s resource", infraCluster.GetKind()))
}

Expand All @@ -174,15 +171,10 @@

//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=metal3clusters,verbs=get;list;watch

func (r *KamajiControlPlaneReconciler) checkGenericCluster(ctx context.Context, cluster capiv1beta1.Cluster, endpoint string, port int64) error {
gkc := unstructured.Unstructured{}

gkc.SetGroupVersionKind(cluster.Spec.InfrastructureRef.GroupVersionKind())
gkc.SetName(cluster.Spec.InfrastructureRef.Name)
gkc.SetNamespace(cluster.Spec.InfrastructureRef.Namespace)

if err := r.client.Get(ctx, types.NamespacedName{Name: gkc.GetName(), Namespace: gkc.GetNamespace()}, &gkc); err != nil {
return errors.Wrap(err, fmt.Sprintf("cannot retrieve the %s resource", gkc.GetKind()))
func (r *KamajiControlPlaneReconciler) checkGenericCluster(ctx context.Context, cluster capiv1beta2.Cluster, endpoint string, port int64) error {
gkc, err := external.GetObjectFromContractVersionedRef(ctx, r.client, cluster.Spec.InfrastructureRef, cluster.GetNamespace())
if err != nil {
return errors.Wrap(err, fmt.Sprintf("cannot get infrastructure reference %s", cluster.Spec.InfrastructureRef.Name))

Check failure on line 177 in controllers/kamajicontrolplane_controller_cluster_patch.go

View workflow job for this annotation

GitHub Actions / lint

string-format: fmt.Sprintf can be replaced with string concatenation (perfsprint)
}

cpHost, _, err := unstructured.NestedString(gkc.Object, "spec", "controlPlaneEndpoint", "host")
Expand All @@ -204,30 +196,25 @@
}

if cpHost != endpoint {
return fmt.Errorf("the %s cluster has been provisioned with a mismatching host", gkc.GetKind())
return fmt.Errorf("the %s cluster has been provisioned with a mismatching host %s instead of %s", gkc.GetKind(), cpHost, endpoint)
}

if cpPort != port {
return fmt.Errorf("the %s cluster has been provisioned with a mismatching port", gkc.GetKind())
return fmt.Errorf("the %s cluster has been provisioned with a mismatching port %d instead of %d", gkc.GetKind(), cpPort, port)
}

return nil
}

//+kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=openstackclusters,verbs=patch;get;list;watch

func (r *KamajiControlPlaneReconciler) patchOpenStackCluster(ctx context.Context, cluster capiv1beta1.Cluster, endpoint string, port int64) error {
osc := unstructured.Unstructured{}

osc.SetGroupVersionKind(cluster.Spec.InfrastructureRef.GroupVersionKind())
osc.SetName(cluster.Spec.InfrastructureRef.Name)
osc.SetNamespace(cluster.Spec.InfrastructureRef.Namespace)

if err := r.client.Get(ctx, types.NamespacedName{Name: osc.GetName(), Namespace: osc.GetNamespace()}, &osc); err != nil {
return errors.Wrap(err, fmt.Sprintf("cannot retrieve the %s resource", osc.GetKind()))
func (r *KamajiControlPlaneReconciler) patchOpenStackCluster(ctx context.Context, cluster capiv1beta2.Cluster, endpoint string, port int64) error {
osc, err := external.GetObjectFromContractVersionedRef(ctx, r.client, cluster.Spec.InfrastructureRef, cluster.GetNamespace())
if err != nil {
return errors.Wrap(err, fmt.Sprintf("cannot get infrastructure reference %s", cluster.Spec.InfrastructureRef.Name))

Check failure on line 214 in controllers/kamajicontrolplane_controller_cluster_patch.go

View workflow job for this annotation

GitHub Actions / lint

string-format: fmt.Sprintf can be replaced with string concatenation (perfsprint)
}

patchHelper, err := patch.NewHelper(&osc, r.client)
patchHelper, err := patch.NewHelper(osc, r.client)
if err != nil {
return errors.Wrap(err, "unable to create patch helper")
}
Expand All @@ -240,7 +227,7 @@
return errors.Wrap(err, fmt.Sprintf("unable to set unstructured %s spec apiServerPort", osc.GetKind()))
}

if err = patchHelper.Patch(ctx, &osc); err != nil {
if err = patchHelper.Patch(ctx, osc); err != nil {
return errors.Wrap(err, "cannot perform PATCH update for the OpenStackCluster resource")
}

Expand Down
16 changes: 8 additions & 8 deletions controllers/kamajicontrolplane_controller_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/util/retry"
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
capiv1beta2 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
Expand All @@ -24,7 +24,7 @@ var ErrEnqueueBack = errors.New("enqueue back")

//+kubebuilder:rbac:groups="",resources="secrets",verbs=get;list;watch;create;update;patch

func (r *KamajiControlPlaneReconciler) createRequiredResources(ctx context.Context, remoteClient client.Client, cluster capiv1beta1.Cluster, kcp v1alpha1.KamajiControlPlane, tcp *kamajiv1alpha1.TenantControlPlane) error {
func (r *KamajiControlPlaneReconciler) createRequiredResources(ctx context.Context, remoteClient client.Client, cluster capiv1beta2.Cluster, kcp v1alpha1.KamajiControlPlane, tcp *kamajiv1alpha1.TenantControlPlane) error {
log := ctrllog.FromContext(ctx)
// Creating a kubeconfig secret for the workload cluster.
if secretName := tcp.Status.KubeConfig.Admin.SecretName; len(secretName) == 0 {
Expand Down Expand Up @@ -64,7 +64,7 @@ func (r *KamajiControlPlaneReconciler) createRequiredResources(ctx context.Conte
// also in regard to the naming conventions according to the Cluster API contracts about Kubeconfig.
//
// more info: https://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster.html#secrets
func (r *KamajiControlPlaneReconciler) createOrUpdateCertificateAuthority(ctx context.Context, reader client.Client, cluster capiv1beta1.Cluster, kcp v1alpha1.KamajiControlPlane, tcp *kamajiv1alpha1.TenantControlPlane) error {
func (r *KamajiControlPlaneReconciler) createOrUpdateCertificateAuthority(ctx context.Context, reader client.Client, cluster capiv1beta2.Cluster, kcp v1alpha1.KamajiControlPlane, tcp *kamajiv1alpha1.TenantControlPlane) error {
capiCA := &corev1.Secret{}
capiCA.Name = cluster.Name + "-ca"
capiCA.Namespace = cluster.Namespace
Expand Down Expand Up @@ -99,7 +99,7 @@ func (r *KamajiControlPlaneReconciler) createOrUpdateCertificateAuthority(ctx co
labels = map[string]string{}
}

labels[capiv1beta1.ClusterNameLabel] = cluster.Name
labels[capiv1beta2.ClusterNameLabel] = cluster.Name
labels["kamaji.clastix.io/component"] = "capi"
labels["kamaji.clastix.io/secret"] = "ca"
labels["kamaji.clastix.io/cluster"] = cluster.Name
Expand All @@ -111,7 +111,7 @@ func (r *KamajiControlPlaneReconciler) createOrUpdateCertificateAuthority(ctx co
corev1.TLSCertKey: crt,
corev1.TLSPrivateKeyKey: key,
}
capiCA.Type = capiv1beta1.ClusterSecretType
capiCA.Type = capiv1beta2.ClusterSecretType

return controllerutil.SetControllerReference(&kcp, capiCA, r.client.Scheme())
})
Expand All @@ -129,7 +129,7 @@ func (r *KamajiControlPlaneReconciler) createOrUpdateCertificateAuthority(ctx co
// also in regard to the naming conventions according to the Cluster API contracts about kubeconfig.
//
// more info: https://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster.html#secrets
func (r *KamajiControlPlaneReconciler) createOrUpdateKubeconfig(ctx context.Context, reader client.Client, cluster capiv1beta1.Cluster, kcp v1alpha1.KamajiControlPlane, tcp *kamajiv1alpha1.TenantControlPlane) error {
func (r *KamajiControlPlaneReconciler) createOrUpdateKubeconfig(ctx context.Context, reader client.Client, cluster capiv1beta2.Cluster, kcp v1alpha1.KamajiControlPlane, tcp *kamajiv1alpha1.TenantControlPlane) error {
capiAdminKubeconfig := &corev1.Secret{}
capiAdminKubeconfig.Name = cluster.Name + "-kubeconfig"
capiAdminKubeconfig.Namespace = cluster.Namespace
Expand All @@ -149,7 +149,7 @@ func (r *KamajiControlPlaneReconciler) createOrUpdateKubeconfig(ctx context.Cont
labels = map[string]string{}
}

labels[capiv1beta1.ClusterNameLabel] = cluster.Name
labels[capiv1beta2.ClusterNameLabel] = cluster.Name
labels["kamaji.clastix.io/component"] = "capi"
labels["kamaji.clastix.io/secret"] = "kubeconfig"
labels["kamaji.clastix.io/cluster"] = cluster.Name
Expand All @@ -170,7 +170,7 @@ func (r *KamajiControlPlaneReconciler) createOrUpdateKubeconfig(ctx context.Cont
capiAdminKubeconfig.Data = map[string][]byte{
"value": value,
}
capiAdminKubeconfig.Type = capiv1beta1.ClusterSecretType
capiAdminKubeconfig.Type = capiv1beta2.ClusterSecretType

return controllerutil.SetControllerReference(&kcp, capiAdminKubeconfig, r.client.Scheme())
})
Expand Down
Loading
Loading