From 6eb4f299881de8f3b8d04a23770b61338c4c438a Mon Sep 17 00:00:00 2001 From: Enxebre Date: Wed, 3 Feb 2021 15:52:15 +0100 Subject: [PATCH] Add support for hostedCluster to delete all nodePools Currently when deleting a hostedCluster it won't delete any owned nodePool causing a race between CAPI deleting the underlying machineSets and the nodePool CR wanting to recreate them. --- .../controllers/hostedcluster_controller.go | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/hypershift-operator/controllers/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster_controller.go index e61fbe64e66..7d8ee54abf4 100644 --- a/hypershift-operator/controllers/hostedcluster_controller.go +++ b/hypershift-operator/controllers/hostedcluster_controller.go @@ -43,10 +43,11 @@ import ( ) const ( - finalizer = "hypershift.openshift.io/finalizer" - pullSecretName = "pull-secret" - sshKeySecretName = "ssh-key" - providerCredsSecretName = "provider-creds" + finalizer = "hypershift.openshift.io/finalizer" + pullSecretName = "pull-secret" + sshKeySecretName = "ssh-key" + providerCredsSecretName = "provider-creds" + clusterNameIndexFieldName = "clusterName" ) // HostedClusterReconciler reconciles a HostedCluster object @@ -286,19 +287,30 @@ func (r *HostedClusterReconciler) Reconcile(ctx context.Context, req ctrl.Reques return ctrl.Result{}, nil } +func (r *HostedClusterReconciler) listNodePools(key, value string) ([]hyperv1.NodePool, error) { + nodePoolList := &hyperv1.NodePoolList{} + if err := r.Client.List( + context.TODO(), + nodePoolList, + client.MatchingFields{key: value}, + ); err != nil { + return nil, fmt.Errorf("failed getting nodePool list: %v", err) + } + return nodePoolList.Items, nil +} + func (r *HostedClusterReconciler) delete(ctx context.Context, req ctrl.Request) error { targetNamespace := req.Name - r.Log.Info("Deleting default nodePool", "name", req.Name) - defaultNodePool := &hyperv1.NodePool{ - ObjectMeta: metav1.ObjectMeta{ - Name: req.Name, - Namespace: req.Namespace, - }, + nodePools, err := r.listNodePools(clusterNameIndexFieldName, req.Name) + if err != nil { + return fmt.Errorf("failed to get nodePools by cluster name for cluster %q: %w", req.Name, err) } - if err := r.Delete(ctx, defaultNodePool); err != nil && !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to delete defaultNodePool: %w", err) + for key := range nodePools { + if err := r.Delete(ctx, &nodePools[key]); err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to delete defaultNodePool: %w", err) + } } r.Log.Info("Deleting cluster", "name", req.Name, "namespace", targetNamespace) @@ -330,6 +342,16 @@ func (r *HostedClusterReconciler) SetupWithManager(mgr ctrl.Manager) error { } r.Infra = &infra + // index nodePool by clusterName + mgr.GetCache().IndexField(context.Background(), &hyperv1.NodePool{}, clusterNameIndexFieldName, + func(object client.Object) []string { + if nodePool, ok := object.(*hyperv1.NodePool); ok { + return []string{nodePool.Spec.ClusterName} + } + return nil + }, + ) + return ctrl.NewControllerManagedBy(mgr). For(&hyperv1.HostedCluster{}). WithEventFilter(predicate.GenerationChangedPredicate{}).