From d00d6310fc905fd902f4611fec7cd25c0b56e89b Mon Sep 17 00:00:00 2001 From: Amol Deodhar Date: Tue, 27 Feb 2024 23:06:59 -0500 Subject: [PATCH] Add deleteBucket --- cloud/scope/object_storage_bucket.go | 9 +++ cloud/services/object_storage_buckets.go | 9 +++ ...re_v1alpha1_linodeobjectstoragebucket.yaml | 13 ++++- .../linodeobjectstoragebucket_controller.go | 55 ++++++++++++++++++- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/cloud/scope/object_storage_bucket.go b/cloud/scope/object_storage_bucket.go index a4a4cd9a1..8d82c964f 100644 --- a/cloud/scope/object_storage_bucket.go +++ b/cloud/scope/object_storage_bucket.go @@ -90,6 +90,15 @@ func (s *ObjectStorageBucketScope) AddFinalizer(ctx context.Context) error { return nil } +// RemoveFinalizer removes a finalizer immediately patches the +// object to avoid any race conditions. +func (s *ObjectStorageBucketScope) RemoveFinalizer(ctx context.Context) error { + if controllerutil.RemoveFinalizer(s.Object, infrav1alpha1.GroupVersion.String()) { + return s.Close(ctx) + } + return nil +} + // CreateAccessKeySecret creates a Secret containing keys created for accessing the bucket. func (s *ObjectStorageBucketScope) CreateAccessKeySecret(ctx context.Context, keys [2]linodego.ObjectStorageKey, secretName string) error { var err error diff --git a/cloud/services/object_storage_buckets.go b/cloud/services/object_storage_buckets.go index 607efdf39..5854d55cb 100644 --- a/cloud/services/object_storage_buckets.go +++ b/cloud/services/object_storage_buckets.go @@ -55,6 +55,15 @@ func CreateObjectStorageBucket(ctx context.Context, bucketScope *scope.ObjectSto return bucket, nil } +func DeleteObjectStorageBucket(ctx context.Context, bucketScope *scope.ObjectStorageBucketScope, logger logr.Logger) error { + // Delete the OBJ bucket. + if err := bucketScope.LinodeClient.DeleteObjectStorageBucket(ctx, bucketScope.Object.Spec.Cluster, bucketScope.Object.Spec.Label); err != nil { + return fmt.Errorf("delete object storage bucket: %w", err) + } + + return nil +} + func CreateObjectStorageKeys(ctx context.Context, bucketScope *scope.ObjectStorageBucketScope, logger logr.Logger) ([2]linodego.ObjectStorageKey, error) { var newKeys [2]linodego.ObjectStorageKey var existingKeys []linodego.ObjectStorageKey diff --git a/config/samples/infrastructure_v1alpha1_linodeobjectstoragebucket.yaml b/config/samples/infrastructure_v1alpha1_linodeobjectstoragebucket.yaml index c2fe1ffc1..ca32b98b7 100644 --- a/config/samples/infrastructure_v1alpha1_linodeobjectstoragebucket.yaml +++ b/config/samples/infrastructure_v1alpha1_linodeobjectstoragebucket.yaml @@ -1,3 +1,4 @@ +--- apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 kind: LinodeObjectStorageBucket metadata: @@ -9,7 +10,15 @@ metadata: app.kubernetes.io/created-by: cluster-api-provider-linode name: linodeobjectstoragebucket-sample spec: - apiKeySecretRef: + credentialsRef: name: api-key-secret - key: field-name-in-secret + namespace: default keyGeneration: 0 + cluster: us-ord-1 +--- +apiVersion: v1 +kind: Secret +metadata: + name: api-key-secret +stringData: + apiToken: "changeme" diff --git a/controller/linodeobjectstoragebucket_controller.go b/controller/linodeobjectstoragebucket_controller.go index 7b7d251d7..dd7067dfc 100644 --- a/controller/linodeobjectstoragebucket_controller.go +++ b/controller/linodeobjectstoragebucket_controller.go @@ -18,12 +18,14 @@ package controller import ( "context" + "errors" "fmt" "time" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/runtime" @@ -40,6 +42,7 @@ import ( "github.com/linode/cluster-api-provider-linode/cloud/services" "github.com/linode/cluster-api-provider-linode/util" "github.com/linode/cluster-api-provider-linode/util/reconciler" + "github.com/linode/linodego" ) // LinodeObjectStorageBucketReconciler reconciles a LinodeObjectStorageBucket object @@ -156,7 +159,17 @@ func (r *LinodeObjectStorageBucketReconciler) reconcileCreate(ctx context.Contex bucketScope.Object.Spec.Label = util.RenderObjectLabel(bucketScope.Object.UID) } - bucket, err := services.CreateObjectStorageBucket(ctx, bucketScope, logger) + bucket := &linodego.ObjectStorageBucket{} + + exists, err := r.bucketExists(ctx, logger, bucketScope) + if !exists { + bucket, err = services.CreateObjectStorageBucket(ctx, bucketScope, logger) + if err != nil { + r.setFailure(bucketScope, err) + + return err + } + } if err != nil { r.setFailure(bucketScope, err) @@ -191,11 +204,47 @@ func (r *LinodeObjectStorageBucketReconciler) reconcileCreate(ctx context.Contex } func (r *LinodeObjectStorageBucketReconciler) reconcileUpdate(ctx context.Context, logger logr.Logger, bucketScope *scope.ObjectStorageBucketScope) error { - panic("unimplemented") + return nil } func (r *LinodeObjectStorageBucketReconciler) reconcileDelete(ctx context.Context, logger logr.Logger, bucketScope *scope.ObjectStorageBucketScope) error { - panic("unimplemented") + name := types.NamespacedName{Namespace: bucketScope.Object.Namespace, Name: bucketScope.Object.Name} + bucket := &infrav1alpha1.LinodeObjectStorageBucket{} + if err := r.Client.Get(ctx, name, bucket); err != nil { + if apierrors.IsNotFound(err); err != nil { + logger.Error(err, "Failed to fetch bucket") + return err + } + return nil + } + + // Delete the OBJ bucket. + if err := services.DeleteObjectStorageBucket(ctx, bucketScope, logger); err != nil { + return fmt.Errorf("delete object storage bucket: %w", err) + } + + // Remove the finalizer. + // This will allow the ObjectStorageBucket object to be deleted. + if err := bucketScope.RemoveFinalizer(ctx); err != nil { + return nil + } + + return nil +} + +// bucketExists indicates whether or not an Object Storage Bucket exists. +// It uses the Linode API. +func (r *LinodeObjectStorageBucketReconciler) bucketExists(ctx context.Context, logger logr.Logger, bucketScope *scope.ObjectStorageBucketScope) (bool, error) { + if bucketScope.Object == nil { + return false, errors.New("nil bucket") + } + + _, err := bucketScope.LinodeClient.GetObjectStorageBucket(ctx, bucketScope.Object.Spec.Cluster, bucketScope.Object.ObjectMeta.Name) + if err != nil { + return false, fmt.Errorf("get object storage bucket: %w", err) + } + + return true, nil } // SetupWithManager sets up the controller with the Manager.