Skip to content
Open
6 changes: 0 additions & 6 deletions docs/deletion.md

This file was deleted.

23 changes: 20 additions & 3 deletions internal/controller/clustertunnel_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package controller
import (
"context"

"github.com/adyanth/cloudflare-operator/internal/k8s"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -143,9 +145,15 @@ func (r *ClusterTunnelReconciler) Reconcile(ctx context.Context, req ctrl.Reques
if err := r.Get(ctx, req.NamespacedName, tunnel); err != nil {
if apierrors.IsNotFound(err) {
// Tunnel object not found, could have been deleted after reconcile request.
// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
// Return and don't requeue
r.log.Info("Tunnel deleted, nothing to do")
// Owned objects are automatically garbage collected.
secretClient, err := k8s.NewSecretClient(r.Client, &r.log)
if err != nil {
return ctrl.Result{}, err
}
err = secretClient.RemoveFinalizer(ctx, r.GetTunnel().GetSpec().Cloudflare.Secret, r.GetTunnel().GetNamespace(), tunnelFinalizer)
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
r.log.Error(err, "unable to fetch Tunnel")
Expand All @@ -156,6 +164,15 @@ func (r *ClusterTunnelReconciler) Reconcile(ctx context.Context, req ctrl.Reques
return ctrl.Result{}, err
}

secretClient, err := k8s.NewSecretClient(r.Client, &r.log)
if err != nil {
return ctrl.Result{}, err
}
err = secretClient.EnsureFinalizer(ctx, r.GetTunnel().GetSpec().Cloudflare.Secret, r.GetTunnel().GetNamespace(), tunnelFinalizer)
if err != nil {
return ctrl.Result{}, err
}

if res, ok, err := setupTunnel(r); !ok {
return res, err
}
Expand Down
23 changes: 20 additions & 3 deletions internal/controller/tunnel_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package controller
import (
"context"

"github.com/adyanth/cloudflare-operator/internal/k8s"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -138,9 +140,15 @@ func (r *TunnelReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
if err := r.Get(ctx, req.NamespacedName, tunnel); err != nil {
if apierrors.IsNotFound(err) {
// Tunnel object not found, could have been deleted after reconcile request.
// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
// Return and don't requeue
r.log.Info("Tunnel deleted, nothing to do")
// Owned objects are automatically garbage collected.
secretClient, err := k8s.NewSecretClient(r.Client, &r.log)
if err != nil {
return ctrl.Result{}, err
}
err = secretClient.RemoveFinalizer(ctx, r.GetTunnel().GetSpec().Cloudflare.Secret, r.GetTunnel().GetNamespace(), tunnelFinalizer)
if err != nil {
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}
r.log.Error(err, "unable to fetch Tunnel")
Expand All @@ -151,6 +159,15 @@ func (r *TunnelReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}

secretClient, err := k8s.NewSecretClient(r.Client, &r.log)
if err != nil {
return ctrl.Result{}, err
}
err = secretClient.EnsureFinalizer(ctx, r.GetTunnel().GetSpec().Cloudflare.Secret, r.GetTunnel().GetNamespace(), tunnelFinalizer)
if err != nil {
return ctrl.Result{}, err
}

if res, ok, err := setupTunnel(r); !ok {
return res, err
}
Expand Down
84 changes: 84 additions & 0 deletions internal/k8s/secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package k8s

import (
"context"
"errors"

"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type SecretClient struct {
k8sClient client.Client
log *logr.Logger
}

func NewSecretClient(k8sClient client.Client, log *logr.Logger) (*SecretClient, error) {
if k8sClient == nil {
return nil, errors.New("k8sClient cannot be nil")
}
if log == nil {
return nil, errors.New("logger cannot be nil")
}
return &SecretClient{
k8sClient: k8sClient,
log: log,
}, nil
}

// EnsureFinalizer idempotently adds the specified finalizer to the specified secret
func (s *SecretClient) EnsureFinalizer(ctx context.Context, secretName, secretNamespace, finalizer string) error {
Comment thread
adyanth marked this conversation as resolved.
Outdated
var secret corev1.Secret
secretKey := client.ObjectKey{
Name: secretName,
Namespace: secretNamespace,
}
if err := s.k8sClient.Get(ctx, secretKey, &secret); err != nil {
return err
}

// if finalizer already exists, we are happy
for _, existingFinalizer := range secret.Finalizers {
if finalizer == existingFinalizer {
return nil
}
}

s.log.WithValues("finalizer", finalizer).Info("creating finalizer")
secret.Finalizers = append(secret.Finalizers, finalizer)
return s.k8sClient.Update(ctx, &secret)
}

// RemoveFinalizer removes the first instance of the finalizer from the given secret
func (s *SecretClient) RemoveFinalizer(ctx context.Context, secretName, secretNamespace, finalizer string) error {
Comment thread
cyclingwithelephants marked this conversation as resolved.
Outdated
var secret corev1.Secret
secretKey := client.ObjectKey{
Name: secretName,
Namespace: secretNamespace,
}
if err := s.k8sClient.Get(ctx, secretKey, &secret); err != nil {
if k8serrors.IsNotFound(err) {
return nil
}
return err
}

s.log.WithValues("finalizer", finalizer).Info("deleting finalizer")
secret.Finalizers = removeString(secret.Finalizers, finalizer)
return s.k8sClient.Update(ctx, &secret)
}

// removeString returns a copy of list with the first (only) occurrence
// of target removed. If target is not present, the original slice is
// returned unchanged.
func removeString(list []string, target string) []string {
for i, v := range list {
if v == target {
// splice out the element at index i
return append(list[:i], list[i+1:]...)
Comment thread
adyanth marked this conversation as resolved.
Outdated
}
}
return list
}
Loading