Skip to content

Commit 81a990f

Browse files
authored
Merge pull request #150 from fluxcd/finalizer-checks
2 parents 198eda8 + 546cbdd commit 81a990f

File tree

3 files changed

+76
-60
lines changed

3 files changed

+76
-60
lines changed

config/manager/deployment.yaml

+11-4
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,27 @@ spec:
2828
ports:
2929
- containerPort: 8080
3030
name: http-prom
31+
- containerPort: 9440
32+
name: healthz
33+
protocol: TCP
3134
env:
3235
- name: RUNTIME_NAMESPACE
3336
valueFrom:
3437
fieldRef:
3538
fieldPath: metadata.namespace
36-
livenessProbe:
37-
httpGet:
38-
port: http-prom
39-
path: /metrics
4039
args:
4140
- --watch-all-namespaces
4241
- --log-level=info
4342
- --log-json
4443
- --enable-leader-election
44+
readinessProbe:
45+
httpGet:
46+
path: /readyz
47+
port: healthz
48+
livenessProbe:
49+
httpGet:
50+
path: /healthz
51+
port: healthz
4552
resources:
4653
limits:
4754
cpu: 1000m

controllers/kustomization_controller.go

+40-49
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
"sigs.k8s.io/controller-runtime/pkg/client"
4343
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
4444
"sigs.k8s.io/controller-runtime/pkg/controller"
45+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
4546
"sigs.k8s.io/kustomize/api/filesys"
4647
"sigs.k8s.io/kustomize/api/krusty"
4748
kustypes "sigs.k8s.io/kustomize/api/types"
@@ -83,47 +84,18 @@ func (r *KustomizationReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro
8384

8485
log := r.Log.WithValues("controller", strings.ToLower(kustomizev1.KustomizationKind), "request", req.NamespacedName)
8586

86-
// Examine if the object is under deletion
87-
if kustomization.ObjectMeta.DeletionTimestamp.IsZero() {
88-
// The object is not being deleted, so if it does not have our finalizer,
89-
// then lets add the finalizer and update the object. This is equivalent
90-
// registering our finalizer.
91-
if !containsString(kustomization.ObjectMeta.Finalizers, kustomizev1.KustomizationFinalizer) {
92-
kustomization.ObjectMeta.Finalizers = append(kustomization.ObjectMeta.Finalizers, kustomizev1.KustomizationFinalizer)
93-
if err := r.Update(ctx, &kustomization); err != nil {
94-
log.Error(err, "unable to register finalizer")
95-
return ctrl.Result{}, err
96-
}
87+
// Add our finalizer if it does not exist
88+
if !controllerutil.ContainsFinalizer(&kustomization, kustomizev1.KustomizationFinalizer) {
89+
controllerutil.AddFinalizer(&kustomization, kustomizev1.KustomizationFinalizer)
90+
if err := r.Update(ctx, &kustomization); err != nil {
91+
log.Error(err, "unable to register finalizer")
92+
return ctrl.Result{}, err
9793
}
98-
} else {
99-
// The object is being deleted
100-
if containsString(kustomization.ObjectMeta.Finalizers, kustomizev1.KustomizationFinalizer) {
101-
// Our finalizer is still present, so lets handle garbage collection
102-
if kustomization.Spec.Prune && !kustomization.Spec.Suspend {
103-
// create any necessary kube-clients
104-
client, _, err := r.newKustomizationClient(kustomization)
105-
if err != nil {
106-
err = fmt.Errorf("Failed to build kube client for Kustomization: %w", err)
107-
log.Error(err, "Unable to prune for finalizer")
108-
return ctrl.Result{}, err
109-
}
110-
if err := r.prune(client, kustomization, kustomization.Status.Snapshot, true); err != nil {
111-
r.event(kustomization, kustomization.Status.LastAppliedRevision, events.EventSeverityError, "pruning for deleted resource failed", nil)
112-
// Return the error so we retry the failed garbage collection
113-
return ctrl.Result{}, err
114-
}
115-
}
116-
// Record deleted status
117-
r.recordReadiness(kustomization, true)
94+
}
11895

119-
// Remove our finalizer from the list and update it
120-
kustomization.ObjectMeta.Finalizers = removeString(kustomization.ObjectMeta.Finalizers, kustomizev1.KustomizationFinalizer)
121-
if err := r.Update(ctx, &kustomization); err != nil {
122-
return ctrl.Result{}, err
123-
}
124-
// Stop reconciliation as the object is being deleted
125-
return ctrl.Result{}, nil
126-
}
96+
// Examine if the object is under deletion
97+
if !kustomization.ObjectMeta.DeletionTimestamp.IsZero() {
98+
return r.reconcileDelete(ctx, log, kustomization)
12799
}
128100

129101
if kustomization.Spec.Suspend {
@@ -517,6 +489,35 @@ func (r *KustomizationReconciler) build(kustomization kustomizev1.Kustomization,
517489
return kustomizev1.NewSnapshot(resources, checksum)
518490
}
519491

492+
func (r *KustomizationReconciler) reconcileDelete(ctx context.Context, log logr.Logger, kustomization kustomizev1.Kustomization) (ctrl.Result, error) {
493+
if kustomization.Spec.Prune && !kustomization.Spec.Suspend {
494+
// create any necessary kube-clients
495+
client, _, err := r.newKustomizationClient(kustomization)
496+
if err != nil {
497+
err = fmt.Errorf("failed to build kube client for Kustomization: %w", err)
498+
log.Error(err, "Unable to prune for finalizer")
499+
return ctrl.Result{}, err
500+
}
501+
if err := r.prune(client, kustomization, kustomization.Status.Snapshot, true); err != nil {
502+
r.event(kustomization, kustomization.Status.LastAppliedRevision, events.EventSeverityError, "pruning for deleted resource failed", nil)
503+
// Return the error so we retry the failed garbage collection
504+
return ctrl.Result{}, err
505+
}
506+
}
507+
508+
// Record deleted status
509+
r.recordReadiness(kustomization, true)
510+
511+
// Remove our finalizer from the list and update it
512+
controllerutil.RemoveFinalizer(&kustomization, kustomizev1.KustomizationFinalizer)
513+
if err := r.Update(ctx, &kustomization); err != nil {
514+
return ctrl.Result{}, err
515+
}
516+
517+
// Stop reconciliation as the object is being deleted
518+
return ctrl.Result{}, nil
519+
}
520+
520521
func (r *KustomizationReconciler) validate(kustomization kustomizev1.Kustomization, dirPath string) error {
521522
if kustomization.Spec.Validation == "" {
522523
return nil
@@ -904,13 +905,3 @@ func containsString(slice []string, s string) bool {
904905
}
905906
return false
906907
}
907-
908-
func removeString(slice []string, s string) (result []string) {
909-
for _, item := range slice {
910-
if item == s {
911-
continue
912-
}
913-
result = append(result, item)
914-
}
915-
return
916-
}

main.go

+25-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
2727
"sigs.k8s.io/cli-utils/pkg/kstatus/polling"
2828
ctrl "sigs.k8s.io/controller-runtime"
29+
"sigs.k8s.io/controller-runtime/pkg/healthz"
2930
crtlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
3031

3132
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
@@ -54,6 +55,7 @@ func main() {
5455
var (
5556
metricsAddr string
5657
eventsAddr string
58+
healthAddr string
5759
enableLeaderElection bool
5860
concurrent int
5961
requeueDependency time.Duration
@@ -64,6 +66,7 @@ func main() {
6466

6567
flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
6668
flag.StringVar(&eventsAddr, "events-addr", "", "The address of the events receiver.")
69+
flag.StringVar(&healthAddr, "health-addr", ":9440", "The address the health endpoint binds to.")
6770
flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
6871
"Enable leader election for controller manager. "+
6972
"Enabling this will ensure there is only one active controller manager.")
@@ -96,19 +99,22 @@ func main() {
9699
}
97100

98101
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
99-
Scheme: scheme,
100-
MetricsBindAddress: metricsAddr,
101-
Port: 9443,
102-
LeaderElection: enableLeaderElection,
103-
LeaderElectionID: "7593cc5d.fluxcd.io",
104-
Namespace: watchNamespace,
105-
Logger: ctrl.Log,
102+
Scheme: scheme,
103+
MetricsBindAddress: metricsAddr,
104+
HealthProbeBindAddress: healthAddr,
105+
Port: 9443,
106+
LeaderElection: enableLeaderElection,
107+
LeaderElectionID: "7593cc5d.fluxcd.io",
108+
Namespace: watchNamespace,
109+
Logger: ctrl.Log,
106110
})
107111
if err != nil {
108112
setupLog.Error(err, "unable to start manager")
109113
os.Exit(1)
110114
}
111115

116+
setupChecks(mgr)
117+
112118
if err = (&controllers.GitRepositoryWatcher{
113119
Client: mgr.GetClient(),
114120
Log: ctrl.Log.WithName("controllers").WithName(sourcev1.GitRepositoryKind),
@@ -148,3 +154,15 @@ func main() {
148154
os.Exit(1)
149155
}
150156
}
157+
158+
func setupChecks(mgr ctrl.Manager) {
159+
if err := mgr.AddReadyzCheck("ping", healthz.Ping); err != nil {
160+
setupLog.Error(err, "unable to create ready check")
161+
os.Exit(1)
162+
}
163+
164+
if err := mgr.AddHealthzCheck("ping", healthz.Ping); err != nil {
165+
setupLog.Error(err, "unable to create health check")
166+
os.Exit(1)
167+
}
168+
}

0 commit comments

Comments
 (0)