From 1dc39f33c5905a85863ff0b2f14dcd08c0567ace Mon Sep 17 00:00:00 2001 From: Amit Sahastrabuddhe Date: Tue, 25 Jun 2024 18:06:56 +0530 Subject: [PATCH] CAPI changes for kubeadm cluster takeover --- api/v1beta1/common_types.go | 3 +++ .../internal/controllers/kubeadmconfig_controller.go | 2 +- controlplane/kubeadm/internal/controllers/controller.go | 4 ++-- controlplane/kubeadm/internal/controllers/helpers.go | 8 ++++++-- internal/controllers/cluster/cluster_controller_phases.go | 5 ++++- util/annotations/helpers.go | 5 +++++ 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/api/v1beta1/common_types.go b/api/v1beta1/common_types.go index 113c4e95f25a..de2fc4115e53 100644 --- a/api/v1beta1/common_types.go +++ b/api/v1beta1/common_types.go @@ -136,6 +136,9 @@ const ( // instead of being a source of truth for eventual consistency. // This annotation can be used to inform MachinePool status during in-progress scaling scenarios. ReplicasManagedByAnnotation = "cluster.x-k8s.io/replicas-managed-by" + + // TakeOverCluster is the label used to mark the nodes that run on takeover-cluster instances. + TakeOverCluster = "cluster.x-k8s.io/takeover-cluster" ) const ( diff --git a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go index d46246b453c6..83e4a3678a60 100644 --- a/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go +++ b/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go @@ -278,7 +278,7 @@ func (r *KubeadmConfigReconciler) Reconcile(ctx context.Context, req ctrl.Reques } // Note: can't use IsFalse here because we need to handle the absence of the condition as well as false. - if !conditions.IsTrue(cluster, clusterv1.ControlPlaneInitializedCondition) { + if !annotations.IsTakeOverCluster(cluster.GetObjectMeta()) && !conditions.IsTrue(cluster, clusterv1.ControlPlaneInitializedCondition) { return r.handleClusterNotInitialized(ctx, scope) } diff --git a/controlplane/kubeadm/internal/controllers/controller.go b/controlplane/kubeadm/internal/controllers/controller.go index 05d69b52b00b..8cf1f3d443b9 100644 --- a/controlplane/kubeadm/internal/controllers/controller.go +++ b/controlplane/kubeadm/internal/controllers/controller.go @@ -399,7 +399,7 @@ func (r *KubeadmControlPlaneReconciler) reconcile(ctx context.Context, cluster * conditions.MarkFalse(controlPlane.KCP, controlplanev1.AvailableCondition, controlplanev1.WaitingForKubeadmInitReason, clusterv1.ConditionSeverityInfo, "") return r.initializeControlPlane(ctx, cluster, kcp, controlPlane) // We are scaling up - case numMachines < desiredReplicas && numMachines > 0: + case numMachines < desiredReplicas && numMachines >= 0: // Create a new Machine w/ join log.Info("Scaling up control plane", "Desired", desiredReplicas, "Existing", numMachines) return r.scaleUpControlPlane(ctx, cluster, kcp, controlPlane) @@ -568,7 +568,7 @@ func (r *KubeadmControlPlaneReconciler) reconcileEtcdMembers(ctx context.Context log := ctrl.LoggerFrom(ctx) // If etcd is not managed by KCP this is a no-op. - if !controlPlane.IsEtcdManaged() { + if annotations.IsTakeOverCluster(controlPlane.Cluster.GetObjectMeta()) || !controlPlane.IsEtcdManaged() { return ctrl.Result{}, nil } diff --git a/controlplane/kubeadm/internal/controllers/helpers.go b/controlplane/kubeadm/internal/controllers/helpers.go index 3355f942409c..46f6eaab0a5d 100644 --- a/controlplane/kubeadm/internal/controllers/helpers.go +++ b/controlplane/kubeadm/internal/controllers/helpers.go @@ -74,8 +74,12 @@ func (r *KubeadmControlPlaneReconciler) reconcileKubeconfig(ctx context.Context, return ctrl.Result{}, errors.Wrap(err, "failed to retrieve kubeconfig Secret") } - if err := r.adoptKubeconfigSecret(ctx, cluster, configSecret, kcp); err != nil { - return ctrl.Result{}, err + // Check if the kubeconfig secret was created by v1alpha2 controllers, and thus it has the Cluster as the owner instead of KCP; + // If yes, adopt it. + if util.IsOwnedByObject(configSecret, cluster) && !util.IsControlledBy(configSecret, kcp) { + if err := r.adoptKubeconfigSecret(ctx, cluster, configSecret, kcp); err != nil { + return ctrl.Result{}, err + } } // only do rotation on owned secrets diff --git a/internal/controllers/cluster/cluster_controller_phases.go b/internal/controllers/cluster/cluster_controller_phases.go index 741a423cb244..1fb739d6e6d0 100644 --- a/internal/controllers/cluster/cluster_controller_phases.go +++ b/internal/controllers/cluster/cluster_controller_phases.go @@ -245,7 +245,10 @@ func (r *Reconciler) reconcileControlPlane(ctx context.Context, cluster *cluster if err != nil { return ctrl.Result{}, err } - if initialized { + + // TODO: PCP-22 set controlPlaneInitializedCondition to true for takeOver cluster + // as CP are already initialized in existing cluster + if annotations.IsTakeOverCluster(cluster.GetObjectMeta()) || initialized { conditions.MarkTrue(cluster, clusterv1.ControlPlaneInitializedCondition) } else { conditions.MarkFalse(cluster, clusterv1.ControlPlaneInitializedCondition, clusterv1.WaitingForControlPlaneProviderInitializedReason, clusterv1.ConditionSeverityInfo, "Waiting for control plane provider to indicate the control plane has been initialized") diff --git a/util/annotations/helpers.go b/util/annotations/helpers.go index 0ec9ef9388ac..072dbd119e1c 100644 --- a/util/annotations/helpers.go +++ b/util/annotations/helpers.go @@ -38,6 +38,11 @@ func IsExternallyManaged(o metav1.Object) bool { return hasAnnotation(o, clusterv1.ManagedByAnnotation) } +// IsTakeOverCluster returns true if the object has the `managed-by` annotation. +func IsTakeOverCluster(o metav1.Object) bool { + return hasAnnotation(o, clusterv1.TakeOverCluster) +} + // HasPaused returns true if the object has the `paused` annotation. func HasPaused(o metav1.Object) bool { return hasAnnotation(o, clusterv1.PausedAnnotation)