diff --git a/.gitignore b/.gitignore index c5f9775..faa1c3e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ travis.yml release-tools bin +vendor/ +.idea/ \ No newline at end of file diff --git a/go.mod b/go.mod index 65a358a..48c3e48 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,6 @@ require ( k8s.io/client-go v0.19.4 k8s.io/klog/v2 v2.4.0 k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd // indirect - sigs.k8s.io/container-object-storage-interface-api v0.0.0-20210315005104-5e1814a6aedd + sigs.k8s.io/container-object-storage-interface-api v0.0.0-20210330175159-2cdabb1a5dc7 sigs.k8s.io/controller-tools v0.4.1 ) diff --git a/go.sum b/go.sum index 824260f..563f80e 100644 --- a/go.sum +++ b/go.sum @@ -200,6 +200,7 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= @@ -221,6 +222,7 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -269,6 +271,7 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -687,6 +690,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= @@ -714,6 +718,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -778,10 +783,10 @@ k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQbTRyDlZPJX2SUPEqvnB+j7AJjtlox7PEwigU0= -sigs.k8s.io/container-object-storage-interface-api v0.0.0-20210315005104-5e1814a6aedd h1:29yp8kNmIAvmVrk49H+CWBa7Yf4fipVLcTyong15tbs= -sigs.k8s.io/container-object-storage-interface-api v0.0.0-20210315005104-5e1814a6aedd/go.mod h1:yMgeGQDROJIdY1jymECN2ptefmQ4+e3EQB/S8gyIE0o= -sigs.k8s.io/container-object-storage-interface-spec v0.0.0-20210224211525-dfa3af562c18 h1:TIx7kV6/3ZSQ5BETBx1QG1Va28zv1LZAvqRjs28n8ss= -sigs.k8s.io/container-object-storage-interface-spec v0.0.0-20210224211525-dfa3af562c18/go.mod h1:kafkL5l/lTUrZXhVi/9p1GzpEE/ts29BkWkL3Ao33WU= +sigs.k8s.io/container-object-storage-interface-api v0.0.0-20210330175159-2cdabb1a5dc7 h1:M2ZMhWdq9Az8TFj8G6ZffFUpR4XG7Qy8h8ZGsZhi9Xg= +sigs.k8s.io/container-object-storage-interface-api v0.0.0-20210330175159-2cdabb1a5dc7/go.mod h1:5n4lNKN4uOMW2NTqJ9r8qRAiqh5dZRZB7CNOkFihLfM= +sigs.k8s.io/container-object-storage-interface-spec v0.0.0-20210329232956-3bbacbbc9c19 h1:LrLrBCBqO7O/VjJtTrDSj3/f7hLSQaCIouLZFnHGxFg= +sigs.k8s.io/container-object-storage-interface-spec v0.0.0-20210329232956-3bbacbbc9c19/go.mod h1:kafkL5l/lTUrZXhVi/9p1GzpEE/ts29BkWkL3Ao33WU= sigs.k8s.io/controller-runtime v0.6.3 h1:SBbr+inLPEKhvlJtrvDcwIpm+uhDvp63Bl72xYJtoOE= sigs.k8s.io/controller-runtime v0.6.3/go.mod h1:WlZNXcM0++oyaQt4B7C2lEE5JYRs8vJUzRP4N4JpdAY= sigs.k8s.io/controller-tools v0.4.1 h1:VkuV0MxlRPmRu5iTgBZU4UxUX2LiR99n3sdQGRxZF4w= diff --git a/pkg/bucketaccessrequest/bucketaccessrequest.go b/pkg/bucketaccessrequest/bucketaccessrequest.go index ac668fe..f667fb0 100644 --- a/pkg/bucketaccessrequest/bucketaccessrequest.go +++ b/pkg/bucketaccessrequest/bucketaccessrequest.go @@ -7,6 +7,7 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubeclientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/util/retry" "github.com/kubernetes-sigs/container-object-storage-interface-controller/pkg/util" "sigs.k8s.io/container-object-storage-interface-api/apis/objectstorage.k8s.io/v1alpha1" @@ -78,7 +79,7 @@ func (b *bucketAccessRequestListener) provisionBucketAccess(ctx context.Context, name := string(bucketAccessRequest.GetUID()) - if bucketAccessRequest.Spec.BucketAccessName != "" { + if bucketAccessRequest.Status.BucketAccessName != "" { return util.ErrBucketAccessAlreadyExists } @@ -101,7 +102,7 @@ func (b *bucketAccessRequestListener) provisionBucketAccess(ctx context.Context, return err } - if bucketRequest.Spec.BucketInstanceName == "" { + if bucketRequest.Status.BucketName == "" || !bucketRequest.Status.BucketAvailable { return util.ErrWaitForBucketProvisioning } @@ -117,7 +118,8 @@ func (b *bucketAccessRequestListener) provisionBucketAccess(ctx context.Context, bucketaccess := &v1alpha1.BucketAccess{} bucketaccess.Name = name - bucketaccess.Spec.BucketInstanceName = bucketRequest.Spec.BucketInstanceName + bucketaccess.Spec.BucketName = bucketRequest.Status.BucketName + bucketaccess.Spec.BucketAccessRequest = &v1.ObjectReference{ Name: bucketAccessRequest.Name, Namespace: bucketAccessRequest.Namespace, @@ -134,7 +136,7 @@ func (b *bucketAccessRequestListener) provisionBucketAccess(ctx context.Context, return err } // bucketaccess.Spec.Principal - set by the driver - bucketaccess.Spec.Provisioner = bucketAccessClass.Provisioner + bucketaccess.Spec.Parameters = util.CopySS(bucketAccessClass.Parameters) bucketaccess, err = baClient.Create(context.Background(), bucketaccess, metav1.CreateOptions{}) @@ -142,8 +144,15 @@ func (b *bucketAccessRequestListener) provisionBucketAccess(ctx context.Context, return err } - bucketAccessRequest.Spec.BucketAccessName = bucketaccess.Name - _, err = barClient(bucketAccessRequest.Namespace).Update(ctx, bucketAccessRequest, metav1.UpdateOptions{}) + err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + bucketAccessRequest.Status.BucketAccessName = bucketaccess.Name + bucketAccessRequest.Status.AccessGranted = true + _, err := barClient(bucketAccessRequest.Namespace).UpdateStatus(ctx, bucketAccessRequest, metav1.UpdateOptions{}) + if err != nil { + return err + } + return nil + }) if err != nil { return err } diff --git a/pkg/bucketaccessrequest/bucketaccessrequest_test.go b/pkg/bucketaccessrequest/bucketaccessrequest_test.go index 212041b..9a7b05d 100644 --- a/pkg/bucketaccessrequest/bucketaccessrequest_test.go +++ b/pkg/bucketaccessrequest/bucketaccessrequest_test.go @@ -55,7 +55,6 @@ var goldAccessClass = types.BucketAccessClass{ ObjectMeta: metav1.ObjectMeta{ Name: "classaccessgold", }, - Provisioner: "provisioner1", PolicyActionsConfigMap: &v1.ObjectReference{Name: "testconfigmap", Namespace: "default"}, Parameters: classGoldAccessParameters, } @@ -71,9 +70,12 @@ var bucketRequest1 = types.BucketRequest{ UID: "br-12345", }, Spec: types.BucketRequestSpec{ - BucketPrefix: "cosi", - BucketClassName: "classgold", - BucketInstanceName: "cosi1234567890", + BucketPrefix: "cosi", + BucketClassName: "classgold", + }, + Status: types.BucketRequestStatus{ + BucketName: "cosi1234567890", + BucketAvailable: true, }, } diff --git a/pkg/bucketrequest/bucketrequest.go b/pkg/bucketrequest/bucketrequest.go index 6c3c364..a9ccb77 100644 --- a/pkg/bucketrequest/bucketrequest.go +++ b/pkg/bucketrequest/bucketrequest.go @@ -6,6 +6,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" "github.com/kubernetes-sigs/container-object-storage-interface-controller/pkg/util" kubeclientset "k8s.io/client-go/kubernetes" @@ -100,7 +101,7 @@ func (b *bucketRequestListener) provisionBucketRequestOperation(ctx context.Cont } name = name + string(bucketRequest.GetUID()) - if bucketRequest.Spec.BucketInstanceName != "" { + if bucketRequest.Status.BucketName != "" { return util.ErrBucketAlreadyExists } @@ -108,10 +109,10 @@ func (b *bucketRequestListener) provisionBucketRequestOperation(ctx context.Cont bucket := &v1alpha1.Bucket{} bucket.Name = name + bucket.Spec.BucketID = name bucket.Spec.Provisioner = bucketClass.Provisioner - bucket.Spec.RetentionPolicy = bucketClass.RetentionPolicy - bucket.Spec.AnonymousAccessMode = bucketClass.AnonymousAccessMode bucket.Spec.BucketClassName = bucketClass.Name + bucket.Spec.DeletionPolicy = bucketClass.DeletionPolicy bucket.Spec.BucketRequest = &v1.ObjectReference{ Name: bucketRequest.Name, Namespace: bucketRequest.Namespace, @@ -127,11 +128,19 @@ func (b *bucketRequestListener) provisionBucketRequestOperation(ctx context.Cont return err } - bucketRequest.Spec.BucketInstanceName = bucket.Name - _, err = b.BucketRequests(bucketRequest.Namespace).Update(ctx, bucketRequest, metav1.UpdateOptions{}) + err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + bucketRequest.Status.BucketName = bucket.Name + bucketRequest.Status.BucketAvailable = true + _, err := b.BucketRequests(bucketRequest.Namespace).UpdateStatus(ctx, bucketRequest, metav1.UpdateOptions{}) + if err != nil { + return err + } + return nil + }) if err != nil { return err } + klog.Infof("Finished creating Bucket %v", bucket.Name) return nil } @@ -147,7 +156,7 @@ func (b *bucketRequestListener) getBucketClass(bucketRequest *v1alpha1.BucketReq // cloneTheBucket clones a bucket to a different namespace when a BR is for brownfield. func (b *bucketRequestListener) cloneTheBucket(bucketRequest *v1alpha1.BucketRequest) error { - klog.InfoS("Cloning Bucket", "name", bucketRequest.Spec.BucketInstanceName) + klog.InfoS("Cloning Bucket", "name", bucketRequest.Status.BucketName) return util.ErrNotImplemented } diff --git a/pkg/bucketrequest/bucketrequest_test.go b/pkg/bucketrequest/bucketrequest_test.go index 342bb3a..c07fea2 100644 --- a/pkg/bucketrequest/bucketrequest_test.go +++ b/pkg/bucketrequest/bucketrequest_test.go @@ -26,9 +26,16 @@ var goldClass = types.BucketClass{ ObjectMeta: metav1.ObjectMeta{ Name: "classgold", }, - AllowedNamespaces: []string{"default", "cosins"}, - Parameters: classGoldParameters, - Protocol: types.Protocol{Name: "s3"}, + AllowedNamespaces: []string{"default", "cosins"}, + Parameters: classGoldParameters, + Protocol: types.Protocol{ + S3: &types.S3Protocol{ + Endpoint: "endpoint", + BucketName: "cosibucket", + Region: "us-east-1", + SignatureVersion: "S3V4", + }, + }, IsDefaultBucketClass: false, } diff --git a/pkg/util/util.go b/pkg/util/util.go index a3a4e1f..1d14d35 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -165,7 +165,7 @@ func GetBuckets(ctx context.Context, client bucketclientset.Interface, numExpect // This is used by bucket request unit tests func ValidateBucket(bucket types.Bucket, bucketrequest types.BucketRequest, bucketclass types.BucketClass) bool { if strings.HasPrefix(bucket.Name, bucketrequest.Spec.BucketPrefix) && - bucketrequest.Spec.BucketInstanceName == bucket.Name && + bucketrequest.Status.BucketName == bucket.Name && bucket.Spec.BucketClassName == bucketrequest.Spec.BucketClassName && bucket.Spec.BucketRequest.Name == bucketrequest.Name && bucket.Spec.BucketRequest.Namespace == bucketrequest.Namespace && @@ -173,8 +173,7 @@ func ValidateBucket(bucket types.Bucket, bucketrequest types.BucketRequest, buck bucket.Spec.BucketClassName == bucketclass.Name && reflect.DeepEqual(bucket.Spec.Parameters, bucketclass.Parameters) && bucket.Spec.Provisioner == bucketclass.Provisioner && - bucket.Spec.RetentionPolicy == bucketclass.RetentionPolicy && - bucket.Spec.AnonymousAccessMode == bucketclass.AnonymousAccessMode { + bucket.Spec.DeletionPolicy == bucketclass.DeletionPolicy { return true } return false @@ -202,12 +201,11 @@ func GetBucketAccesses(ctx context.Context, client bucketclientset.Interface, nu // Validates the content of the bucket access against bucket access request and backet access class // This is used by bucket access request unit tests func ValidateBucketAccess(bucketaccess types.BucketAccess, bucketaccessrequest types.BucketAccessRequest, bucketaccessclass types.BucketAccessClass) bool { - if bucketaccess.Spec.BucketInstanceName != "" && - bucketaccessrequest.Spec.BucketAccessName == bucketaccess.Name && + if bucketaccess.Spec.BucketName != "" && + bucketaccessrequest.Status.BucketAccessName == bucketaccess.Name && bucketaccess.Spec.BucketAccessRequest.UID == bucketaccessrequest.UID && bucketaccess.Spec.ServiceAccount.Name == bucketaccessrequest.Spec.ServiceAccountName && - bucketaccess.Spec.PolicyActionsConfigMapData != "" && - bucketaccess.Spec.Provisioner == bucketaccessclass.Provisioner { + bucketaccess.Spec.PolicyActionsConfigMapData != "" { return true } return false diff --git a/resources/deployment.yaml b/resources/deployment.yaml index c48e748..452ec01 100644 --- a/resources/deployment.yaml +++ b/resources/deployment.yaml @@ -31,6 +31,7 @@ spec: serviceAccountName: objectstorage-controller-sa containers: - name: objectstorage-controller - image: quay.io/containerobjectstorage/objectstorage-controller:latest + image: quay.io/containerobjectstorage/objectstorage-controller:canary + imagePullPolicy: Always args: - "--v=5" diff --git a/resources/rbac.yaml b/resources/rbac.yaml index 9b554c3..1005c35 100644 --- a/resources/rbac.yaml +++ b/resources/rbac.yaml @@ -11,7 +11,7 @@ metadata: app.kubernetes.io/name: container-object-storage-interface-controller rules: - apiGroups: ["objectstorage.k8s.io"] - resources: ["bucketrequests", "bucketaccessrequests"] + resources: ["bucketrequests", "bucketaccessrequests", "bucketrequests/status", "bucketaccessrequests/status"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["objectstorage.k8s.io"] resources: ["buckets", "bucketaccesses"]