Skip to content
This repository was archived by the owner on Dec 3, 2024. It is now read-only.

Commit 459c723

Browse files
authored
Merge pull request #74 from mukhoakash/finalizer_fix
Fix: Add DeleteContext to DriverDeleteBucket and fix delete BucketAccess flow
2 parents 8271dbe + 80ba720 commit 459c723

File tree

5 files changed

+151
-13
lines changed

5 files changed

+151
-13
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require (
1313
k8s.io/client-go v0.24.2
1414
k8s.io/klog/v2 v2.70.1
1515
sigs.k8s.io/container-object-storage-interface-api v0.0.0-20220806044417-5d7517114883
16-
sigs.k8s.io/container-object-storage-interface-spec v0.0.0-20220811182913-3c421cfc2830
16+
sigs.k8s.io/container-object-storage-interface-spec v0.1.1-0.20221006174327-ec782953b8ac
1717
sigs.k8s.io/controller-runtime v0.12.3
1818
)
1919

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
727727
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
728728
sigs.k8s.io/container-object-storage-interface-api v0.0.0-20220806044417-5d7517114883 h1:CtqK7l2m9Atw8L5daJdsXvVgxxvQkRBbJbUz7NiadD8=
729729
sigs.k8s.io/container-object-storage-interface-api v0.0.0-20220806044417-5d7517114883/go.mod h1:YiB+i/UGkzqgODDhRG3u7jkbWkQcoUeLEJ7hwOT/2Qk=
730-
sigs.k8s.io/container-object-storage-interface-spec v0.0.0-20220811182913-3c421cfc2830 h1:o8/7mIJCflt33epl4TZNS/+M5MktS8fQvcNuN8p235k=
731-
sigs.k8s.io/container-object-storage-interface-spec v0.0.0-20220811182913-3c421cfc2830/go.mod h1:SzF/yVSh88TgYdBOAXqhT96XjU8pCQtoeQKxzIOOmWQ=
730+
sigs.k8s.io/container-object-storage-interface-spec v0.1.1-0.20221006174327-ec782953b8ac h1:M1ZBBDJVWw3gDmE+kZZmwQ6+29GbWhG9RMqx9oV0tEs=
731+
sigs.k8s.io/container-object-storage-interface-spec v0.1.1-0.20221006174327-ec782953b8ac/go.mod h1:SzF/yVSh88TgYdBOAXqhT96XjU8pCQtoeQKxzIOOmWQ=
732732
sigs.k8s.io/controller-runtime v0.12.3 h1:FCM8xeY/FI8hoAfh/V4XbbYMY20gElh9yh+A98usMio=
733733
sigs.k8s.io/controller-runtime v0.12.3/go.mod h1:qKsk4WE6zW2Hfj0G4v10EnNB2jMG1C+NTb8h+DwCoU0=
734734
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=

pkg/bucket/bucket_controller.go

+73-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package bucket
1717

1818
import (
1919
"context"
20+
"fmt"
2021
"strings"
2122

2223
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -66,9 +67,13 @@ func (b *BucketListener) Add(ctx context.Context, inputBucket *v1alpha1.Bucket)
6667
var err error
6768

6869
klog.V(3).InfoS("Add Bucket",
69-
"name", bucket.ObjectMeta.Name,
70-
"bucketclass", bucket.Spec.BucketClassName,
71-
)
70+
"name", bucket.ObjectMeta.Name)
71+
72+
if bucket.Spec.BucketClassName == "" {
73+
err = errors.New(fmt.Sprintf("BucketClassName not defined for bucket %s", bucket.ObjectMeta.Name))
74+
klog.V(3).ErrorS(err, "BucketClassName not defined")
75+
return err
76+
}
7277

7378
if !strings.EqualFold(bucket.Spec.DriverName, b.driverName) {
7479
klog.V(5).InfoS("Skipping bucket for driver",
@@ -93,6 +98,24 @@ func (b *BucketListener) Add(ctx context.Context, inputBucket *v1alpha1.Bucket)
9398
if bucket.Spec.ExistingBucketID != "" {
9499
bucketReady = true
95100
bucketID = bucket.Spec.ExistingBucketID
101+
if bucket.Spec.Parameters == nil {
102+
bucketClass, err := b.bucketClasses().Get(ctx, bucket.Spec.BucketClassName, metav1.GetOptions{})
103+
if err != nil {
104+
klog.V(3).ErrorS(err, "Error fetching bucketClass",
105+
"bucketClass", bucket.Spec.BucketClassName,
106+
"bucket", bucket.ObjectMeta.Name)
107+
return err
108+
}
109+
110+
if bucketClass.Parameters != nil {
111+
var param map[string]string
112+
for k, v := range bucketClass.Parameters {
113+
param[k] = v
114+
}
115+
116+
bucket.Spec.Parameters = param
117+
}
118+
}
96119
} else {
97120
req := &cosi.DriverCreateBucketRequest{
98121
Parameters: bucket.Spec.Parameters,
@@ -110,7 +133,7 @@ func (b *BucketListener) Add(ctx context.Context, inputBucket *v1alpha1.Bucket)
110133
}
111134

112135
if rsp == nil {
113-
err = errors.New("DriverCreateBucket returned a nil response")
136+
err = errors.New(fmt.Sprintf("DriverCreateBucket returned a nil response for bucket: %s", bucket.ObjectMeta.Name))
114137
klog.V(3).ErrorS(err, "Internal Error from driver",
115138
"bucket", bucket.ObjectMeta.Name)
116139
return err
@@ -122,7 +145,7 @@ func (b *BucketListener) Add(ctx context.Context, inputBucket *v1alpha1.Bucket)
122145
} else {
123146
klog.V(3).ErrorS(err, "DriverCreateBucket returned an empty bucketID",
124147
"bucket", bucket.ObjectMeta.Name)
125-
err = errors.New("DriverCreateBucket returned an empty bucketID")
148+
err = errors.New(fmt.Sprintf("DriverCreateBucket returned an empty bucketID for bucket: %s", bucket.ObjectMeta.Name))
126149
return err
127150
}
128151

@@ -217,6 +240,16 @@ func (b *BucketListener) Update(ctx context.Context, old, new *v1alpha1.Bucket)
217240
if err != nil {
218241
return err
219242
}
243+
244+
controllerutil.RemoveFinalizer(bucket, consts.BucketFinalizer)
245+
klog.V(5).Infof("Successfully removed finalizer: %s of bucket: %s", consts.BucketFinalizer, bucket.ObjectMeta.Name)
246+
}
247+
248+
_, err = b.buckets().Update(ctx, bucket, metav1.UpdateOptions{})
249+
if err != nil {
250+
klog.V(3).ErrorS(err, "Error updating bucket after removing finalizers",
251+
"bucket", bucket.ObjectMeta.Name)
252+
return err
220253
}
221254
}
222255

@@ -227,14 +260,38 @@ func (b *BucketListener) Update(ctx context.Context, old, new *v1alpha1.Bucket)
227260
}
228261

229262
// Delete attemps to delete a bucket. This function must be idempotent
263+
// Delete function is called when the bucket was not able to add finalizers while creation.
264+
// Hence we will take care of removing the BucketClaim finalizer before deleting the Bucket object.
230265
// Return values
231266
// nil - Bucket successfully deleted
232267
// non-nil err - Internal error [requeue'd with exponential backoff]
233268
func (b *BucketListener) Delete(ctx context.Context, inputBucket *v1alpha1.Bucket) error {
234269
klog.V(3).InfoS("Delete Bucket",
235270
"name", inputBucket.ObjectMeta.Name,
236-
"bucketclass", inputBucket.Spec.BucketClassName,
237-
)
271+
"bucketclass", inputBucket.Spec.BucketClassName)
272+
273+
if inputBucket.Spec.BucketClaim != nil {
274+
ref := inputBucket.Spec.BucketClaim
275+
klog.V(3).Infof("Removing finalizer of bucketClaim: %s before deleting bucket: %s", ref.Name, inputBucket.ObjectMeta.Name)
276+
277+
bucketClaim, err := b.bucketClaims(ref.Namespace).Get(ctx, ref.Name, metav1.GetOptions{})
278+
if err != nil {
279+
klog.V(3).ErrorS(err, "Error getting bucketClaim for removing finalizer",
280+
"bucket", inputBucket.ObjectMeta.Name,
281+
"bucketClaim", ref.Name)
282+
return err
283+
}
284+
285+
if controllerutil.RemoveFinalizer(bucketClaim, consts.BCFinalizer) {
286+
_, err := b.bucketClaims(bucketClaim.ObjectMeta.Namespace).Update(ctx, bucketClaim, metav1.UpdateOptions{})
287+
if err != nil {
288+
klog.V(3).ErrorS(err, "Error removing bucketClaim finalizer",
289+
"bucket", inputBucket.ObjectMeta.Name,
290+
"bucketClaim", bucketClaim.ObjectMeta.Name)
291+
return err
292+
}
293+
}
294+
}
238295

239296
return nil
240297

@@ -270,7 +327,8 @@ func (b *BucketListener) deleteBucketOp(ctx context.Context, bucket *v1alpha1.Bu
270327
// only when the retain policy is set to Delete
271328
if bucket.Spec.DeletionPolicy == v1alpha1.DeletionPolicyDelete {
272329
req := &cosi.DriverDeleteBucketRequest{
273-
BucketId: bucket.Status.BucketID,
330+
BucketId: bucket.Status.BucketID,
331+
DeleteContext: bucket.Spec.Parameters,
274332
}
275333

276334
if _, err := b.provisionerClient.DriverDeleteBucket(ctx, req); err != nil {
@@ -317,6 +375,13 @@ func (b *BucketListener) buckets() bucketapi.BucketInterface {
317375
panic("uninitialized listener")
318376
}
319377

378+
func (b *BucketListener) bucketClasses() bucketapi.BucketClassInterface {
379+
if b.bucketClient != nil {
380+
return b.bucketClient.ObjectstorageV1alpha1().BucketClasses()
381+
}
382+
panic("uninitialized listener")
383+
}
384+
320385
func (b *BucketListener) bucketClaims(namespace string) bucketapi.BucketClaimInterface {
321386
if b.bucketClient != nil {
322387
return b.bucketClient.ObjectstorageV1alpha1().BucketClaims(namespace)

pkg/bucket/bucket_controller_test.go

+35-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package bucket
1717

1818
import (
1919
"context"
20+
"errors"
2021
"reflect"
2122
"testing"
2223

@@ -25,6 +26,7 @@ import (
2526
cosi "sigs.k8s.io/container-object-storage-interface-spec"
2627
fakespec "sigs.k8s.io/container-object-storage-interface-spec/fake"
2728

29+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2830
utilversion "k8s.io/apimachinery/pkg/util/version"
2931
"k8s.io/apimachinery/pkg/version"
3032
fakediscovery "k8s.io/client-go/discovery/fake"
@@ -86,7 +88,8 @@ func TestAddWrongProvisioner(t *testing.T) {
8688

8789
b := v1alpha1.Bucket{
8890
Spec: v1alpha1.BucketSpec{
89-
DriverName: "driver2",
91+
DriverName: "driver2",
92+
BucketClassName: "test-bucket",
9093
},
9194
}
9295
ctx := context.TODO()
@@ -95,3 +98,34 @@ func TestAddWrongProvisioner(t *testing.T) {
9598
t.Errorf("Error returned: %+v", err)
9699
}
97100
}
101+
102+
func TestMissingBucketClassName(t *testing.T) {
103+
driver := "driver1"
104+
mpc := struct{ fakespec.FakeProvisionerClient }{}
105+
mpc.FakeDriverCreateBucket = func(ctx context.Context,
106+
in *cosi.DriverCreateBucketRequest,
107+
opts ...grpc.CallOption) (*cosi.DriverCreateBucketResponse, error) {
108+
t.Errorf("grpc client called")
109+
return nil, nil
110+
}
111+
112+
bl := BucketListener{
113+
driverName: driver,
114+
provisionerClient: &mpc,
115+
}
116+
117+
b := v1alpha1.Bucket{
118+
ObjectMeta: metav1.ObjectMeta{
119+
Name: "testbucket",
120+
},
121+
Spec: v1alpha1.BucketSpec{
122+
DriverName: "driver1",
123+
},
124+
}
125+
ctx := context.TODO()
126+
err := bl.Add(ctx, &b)
127+
expectedErr := errors.New("BucketClassName not defined for bucket testbucket")
128+
if err == nil || err.Error() != expectedErr.Error() {
129+
t.Errorf("Expecter error: %+v \n Returned error: %+v", expectedErr, err)
130+
}
131+
}

pkg/bucketaccess/bucketaccess_controller.go

+40-1
Original file line numberDiff line numberDiff line change
@@ -324,14 +324,44 @@ func (bal *BucketAccessListener) Delete(ctx context.Context, bucketAccess *v1alp
324324
}
325325

326326
func (bal *BucketAccessListener) deleteBucketAccessOp(ctx context.Context, bucketAccess *v1alpha1.BucketAccess) error {
327+
// Fetching bucketClaim and corresponding bucket to get the bucketID
328+
// for performing DriverRevokeBucketAccess request.
329+
bucketClaimName := bucketAccess.Spec.BucketClaimName
330+
bucketClaim, err := bal.bucketClaims(bucketAccess.ObjectMeta.Namespace).Get(ctx, bucketClaimName, metav1.GetOptions{})
331+
if err != nil {
332+
klog.V(3).ErrorS(err, "Failed to fetch bucketClaim", "bucketClaim", bucketClaimName)
333+
return errors.Wrap(err, "Failed to fetch bucketClaim")
334+
}
335+
336+
bucket, err := bal.buckets().Get(ctx, bucketClaim.Status.BucketName, metav1.GetOptions{})
337+
if err != nil {
338+
klog.V(3).ErrorS(err, "Failed to fetch bucket", "bucket", bucketClaim.Status.BucketName)
339+
return errors.Wrap(err, "Failed to fetch bucket")
340+
}
341+
342+
req := &cosi.DriverRevokeBucketAccessRequest{
343+
BucketId: bucket.Status.BucketID,
344+
AccountId: bucketAccess.Status.AccountID,
345+
}
346+
347+
// First we revoke the bucketAccess from the driver
348+
if _, err := bal.provisionerClient.DriverRevokeBucketAccess(ctx, req); err != nil {
349+
klog.V(3).ErrorS(err,
350+
"Failed to revoke bucket access",
351+
"bucketAccess", bucketAccess.ObjectMeta.Name,
352+
"bucketClaim", bucketClaimName,
353+
)
354+
return errors.Wrap(err, "failed to revoke access")
355+
}
356+
327357
credSecretName := bucketAccess.Spec.CredentialsSecretName
328358
secret, err := bal.secrets(bucketAccess.ObjectMeta.Namespace).Get(ctx, credSecretName, metav1.GetOptions{})
329359
if err != nil {
330360
return err
331361
}
332362

333363
if controllerutil.RemoveFinalizer(secret, consts.SecretFinalizer) {
334-
_, err = bal.secrets(bucketAccess.ObjectMeta.Namespace).Update(ctx, secret, metav1.UpdateOptions{})
364+
_, err = bal.secrets(secret.ObjectMeta.Namespace).Update(ctx, secret, metav1.UpdateOptions{})
335365
if err != nil {
336366
klog.V(3).ErrorS(err, "Error removing finalizer from secret",
337367
"secret", secret.ObjectMeta.Name,
@@ -342,6 +372,15 @@ func (bal *BucketAccessListener) deleteBucketAccessOp(ctx context.Context, bucke
342372
klog.V(5).Infof("Successfully removed finalizer from secret: %s, bucketAccess: %s", secret.ObjectMeta.Name, bucketAccess.ObjectMeta.Name)
343373
}
344374

375+
err = bal.secrets(secret.ObjectMeta.Namespace).Delete(ctx, credSecretName, metav1.DeleteOptions{})
376+
if err != nil {
377+
klog.V(3).ErrorS(err, "Error deleting secret",
378+
"secret", secret.ObjectMeta.Name,
379+
"bucketAccess", bucketAccess.ObjectMeta.Name,
380+
"ns", bucketAccess.ObjectMeta.Namespace)
381+
return nil
382+
}
383+
345384
if controllerutil.RemoveFinalizer(bucketAccess, consts.BAFinalizer) {
346385
_, err = bal.bucketAccesses(bucketAccess.ObjectMeta.Namespace).Update(ctx, bucketAccess, metav1.UpdateOptions{})
347386
if err != nil {

0 commit comments

Comments
 (0)