Skip to content

Commit 3c4948d

Browse files
authored
🐛 set finalizer later in unified mode; unblock hub delete when init failed (#81)
* fix: set finalizer later when in unified mode Signed-off-by: Artur Shad Nik <[email protected]> * chore: bump fcc to 0.1.4 Signed-off-by: Artur Shad Nik <[email protected]> * chore: set labels on clusterissuer Signed-off-by: Artur Shad Nik <[email protected]> * test: error on missing CRD Signed-off-by: Artur Shad Nik <[email protected]> * test: update assertion Signed-off-by: Artur Shad Nik <[email protected]> --------- Signed-off-by: Artur Shad Nik <[email protected]>
1 parent 704faa7 commit 3c4948d

File tree

10 files changed

+61
-38
lines changed

10 files changed

+61
-38
lines changed

fleetconfig-controller/api/v1alpha1/webhook_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ var _ = BeforeSuite(func() {
8383
filepath.Join(root, "charts", "fleetconfig-controller", "crds"),
8484
filepath.Join(root, "config", "crds"),
8585
},
86-
ErrorIfCRDPathMissing: false,
86+
ErrorIfCRDPathMissing: true,
8787
WebhookInstallOptions: envtest.WebhookInstallOptions{
8888
Paths: []string{filepath.Join("..", "..", "config", "webhook")},
8989
},

fleetconfig-controller/charts/fleetconfig-controller/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Resource specifications for all klusterlet-managed containers.
158158
| `replicas` | fleetconfig-controller replica count | `1` |
159159
| `imageRegistry` | Image registry | `""` |
160160
| `image.repository` | Image repository | `quay.io/open-cluster-management/fleetconfig-controller` |
161-
| `image.tag` | Image tag | `v0.1.3` |
161+
| `image.tag` | Image tag | `v0.1.4` |
162162
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
163163
| `imagePullSecrets` | Image pull secrets | `[]` |
164164
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |

fleetconfig-controller/charts/fleetconfig-controller/templates/clusterissuer.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ apiVersion: cert-manager.io/v1
44
kind: ClusterIssuer
55
metadata:
66
name: fleetconfig-controller
7+
labels:
8+
{{ include "chart.labels" . | nindent 4 }}
79
annotations:
810
{{ include "chart.annotations" . | nindent 4 }}
911
spec:

fleetconfig-controller/charts/fleetconfig-controller/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ imageRegistry: ""
294294
## @param image.pullPolicy Image pull policy
295295
image:
296296
repository: quay.io/open-cluster-management/fleetconfig-controller
297-
tag: v0.1.3
297+
tag: v0.1.4
298298
pullPolicy: IfNotPresent
299299

300300
## @param imagePullSecrets Image pull secrets

fleetconfig-controller/devspace.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ pipelines:
4949
run_dependencies --all
5050
build_images fleetconfig-controller-dev
5151
create_deployments cert-manager
52-
kubectl apply -f ./hack/dev/cluster-issuer.yaml
5352
create_deployments fleetconfig-controller-dev
5453
start_dev fleetconfig-controller-dev-hub
5554
deploy: |-
@@ -62,7 +61,6 @@ pipelines:
6261
deploy-local: |-
6362
run_pipelines load-local
6463
create_deployments cert-manager
65-
kubectl apply -f ./hack/dev/cluster-issuer.yaml
6664
create_deployments fleetconfig-controller-local
6765
debug: |-
6866
run_dependencies --all

fleetconfig-controller/internal/controller/v1beta1/hub_controller.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,22 @@ func (r *HubReconciler) cleanHub(ctx context.Context, hub *v1beta1.Hub, hubKubec
221221

222222
logger.Info("All Spokes have been deleted, proceeding with Hub cleanup")
223223

224+
operatorC, err := common.OperatorClient(hubKubeconfig)
225+
if err != nil {
226+
return true, fmt.Errorf("failed to create operator client for cleanup: %w", err)
227+
}
228+
_, err = operatorC.OperatorV1().ClusterManagers().Get(ctx, "cluster-manager", metav1.GetOptions{})
229+
if err != nil {
230+
if kerrs.IsNotFound(err) {
231+
logger.Info("ClusterManager not found; skip cleanup.", "hub", hub.Name)
232+
hub.Finalizers = slices.DeleteFunc(hub.Finalizers, func(s string) bool {
233+
return s == v1beta1.HubCleanupFinalizer
234+
})
235+
return false, nil
236+
}
237+
return true, fmt.Errorf("failed to get ClusterManager: %w", err)
238+
}
239+
224240
addonC, err := common.AddOnClient(hubKubeconfig)
225241
if err != nil {
226242
return true, fmt.Errorf("failed to create addon client for cleanup: %w", err)

fleetconfig-controller/internal/controller/v1beta1/spoke_controller.go

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -97,38 +97,38 @@ func (r *SpokeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
9797
spoke.Status.Phase = v1beta1.Unhealthy
9898
}
9999

100-
switch r.InstanceType {
101-
case v1beta1.InstanceTypeManager:
102-
if !slices.Contains(spoke.Finalizers, v1beta1.HubCleanupFinalizer) {
103-
setDefaults(ctx, spoke, hubMeta)
104-
spoke.Finalizers = append(
105-
spoke.Finalizers,
106-
v1beta1.HubCleanupPreflightFinalizer, // removed by the hub to signal to the spoke that preflight is completed
107-
v1beta1.HubCleanupFinalizer, // removed by the hub after post-unjoin cleanup is finished
108-
)
109-
if spoke.IsHubAsSpoke() {
110-
spoke.Finalizers = append(spoke.Finalizers, v1beta1.SpokeCleanupFinalizer)
100+
if spoke.DeletionTimestamp.IsZero() {
101+
switch r.InstanceType {
102+
case v1beta1.InstanceTypeManager:
103+
if !slices.Contains(spoke.Finalizers, v1beta1.HubCleanupFinalizer) {
104+
setDefaults(ctx, spoke, hubMeta)
105+
spoke.Finalizers = append(
106+
spoke.Finalizers,
107+
v1beta1.HubCleanupPreflightFinalizer, // removed by the hub to signal to the spoke that preflight is completed
108+
v1beta1.HubCleanupFinalizer, // removed by the hub after post-unjoin cleanup is finished
109+
)
110+
return ret(ctx, ctrl.Result{RequeueAfter: spokeRequeuePreJoin}, nil)
111111
}
112-
return ret(ctx, ctrl.Result{RequeueAfter: spokeRequeuePreJoin}, nil)
113-
}
114-
case v1beta1.InstanceTypeUnified:
115-
if !slices.Contains(spoke.Finalizers, v1beta1.HubCleanupFinalizer) {
116-
setDefaults(ctx, spoke, hubMeta)
117-
spoke.Finalizers = append(
118-
spoke.Finalizers,
119-
v1beta1.HubCleanupPreflightFinalizer, // removed by the hub to signal to the spoke that preflight is completed
120-
v1beta1.SpokeCleanupFinalizer, // removed by the hub after successful unjoin
121-
v1beta1.HubCleanupFinalizer, // removed by the hub after post-unjoin cleanup is finished
122-
)
123-
}
124-
case v1beta1.InstanceTypeAgent:
125-
if !slices.Contains(spoke.Finalizers, v1beta1.SpokeCleanupFinalizer) && spoke.DeletionTimestamp.IsZero() {
126-
spoke.Finalizers = append(spoke.Finalizers, v1beta1.SpokeCleanupFinalizer) // removed by the spoke to signal to the hub that unjoin succeeded
127-
return ret(ctx, ctrl.Result{RequeueAfter: spokeRequeuePreJoin}, nil)
112+
case v1beta1.InstanceTypeUnified:
113+
if !slices.Contains(spoke.Finalizers, v1beta1.HubCleanupFinalizer) {
114+
setDefaults(ctx, spoke, hubMeta)
115+
spoke.Finalizers = append(
116+
spoke.Finalizers,
117+
v1beta1.HubCleanupPreflightFinalizer, // removed by the hub to signal to the spoke that preflight is completed
118+
v1beta1.HubCleanupFinalizer, // removed by the hub after post-unjoin cleanup is finished
119+
)
120+
// SpokeCleanupFinalizer is added later after successful join
121+
return ret(ctx, ctrl.Result{RequeueAfter: spokeRequeuePreJoin}, nil)
122+
}
123+
case v1beta1.InstanceTypeAgent:
124+
if !slices.Contains(spoke.Finalizers, v1beta1.SpokeCleanupFinalizer) {
125+
spoke.Finalizers = append(spoke.Finalizers, v1beta1.SpokeCleanupFinalizer) // removed by the spoke to signal to the hub that unjoin succeeded
126+
return ret(ctx, ctrl.Result{RequeueAfter: spokeRequeuePreJoin}, nil)
127+
}
128+
default:
129+
// this is guarded against when the manager is initialized. should never reach this point
130+
panic(fmt.Sprintf("unknown instance type %s. Must be one of %v", r.InstanceType, v1beta1.SupportedInstanceTypes))
128131
}
129-
default:
130-
// this is guarded against when the manager is initialized. should never reach this point
131-
panic(fmt.Sprintf("unknown instance type %s. Must be one of %v", r.InstanceType, v1beta1.SupportedInstanceTypes))
132132
}
133133

134134
// Handle deletion logic with finalizer

fleetconfig-controller/internal/controller/v1beta1/spoke_controller_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ var _ = Describe("Spoke Controller", Ordered, func() {
116116

117117
By("Verifying the Spoke's finalizer")
118118
Expect(k8sClient.Get(ctx, spokeNN, spoke)).To(Succeed())
119-
Expect(spoke.Finalizers).To(ContainElement(v1beta1.SpokeCleanupFinalizer),
119+
Expect(spoke.Finalizers).To(ContainElement(v1beta1.HubCleanupFinalizer),
120120
"Spoke %s wasn't given a finalizer", spokeNN.Name)
121121
})
122122

fleetconfig-controller/internal/controller/v1beta1/spoke_handler.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,12 @@ func (r *SpokeReconciler) doHubWork(ctx context.Context, spoke *v1beta1.Spoke, h
254254
}
255255
}
256256

257+
// Add SpokeCleanupFinalizer now that join succeeded and there's something to clean up
258+
if r.InstanceType != v1beta1.InstanceTypeAgent && !slices.Contains(spoke.Finalizers, v1beta1.SpokeCleanupFinalizer) {
259+
spoke.Finalizers = append(spoke.Finalizers, v1beta1.SpokeCleanupFinalizer)
260+
logger.V(1).Info("Added SpokeCleanupFinalizer after successful join")
261+
}
262+
257263
// TODO - handle this via `klusterlet upgrade` once https://github.com/open-cluster-management-io/ocm/issues/1210 is resolved
258264
if managedCluster != nil {
259265
klusterletValuesAnnotations := map[string]string{}
@@ -686,6 +692,7 @@ func (r *SpokeReconciler) waitForAgentAddonDeleted(ctx context.Context, spoke *v
686692
// doSpokeCleanup handles all the required cleanup of a spoke cluster when deregistering a Spoke
687693
func (r *SpokeReconciler) doSpokeCleanup(ctx context.Context, spoke *v1beta1.Spoke, pivotComplete bool) (bool, error) {
688694
logger := log.FromContext(ctx)
695+
689696
// requeue until preflight is complete by the hub's controller
690697
if slices.Contains(spoke.Finalizers, v1beta1.HubCleanupPreflightFinalizer) {
691698
logger.V(1).Info("Cleanup initiated, waiting for hub to complete preflight")

fleetconfig-controller/internal/webhook/v1beta1/webhook_suite_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ var _ = BeforeSuite(func() {
9090
filepath.Join(root, "charts", "fleetconfig-controller", "crds"),
9191
filepath.Join(root, "config", "crds"),
9292
},
93-
ErrorIfCRDPathMissing: false,
93+
ErrorIfCRDPathMissing: true,
9494

9595
WebhookInstallOptions: envtest.WebhookInstallOptions{
96-
Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")},
96+
Paths: []string{filepath.Join(root, "config", "webhook")},
9797
},
9898
}
9999

0 commit comments

Comments
 (0)