diff --git a/packages/system/objectstorage-controller/Makefile b/packages/system/objectstorage-controller/Makefile index 66c9e2d9..b947ce36 100644 --- a/packages/system/objectstorage-controller/Makefile +++ b/packages/system/objectstorage-controller/Makefile @@ -1,11 +1,29 @@ -export NAME=cosi-controller +export NAME=objectstorage-controller export NAMESPACE=cozy-$(NAME) +include ../../../scripts/common-envs.mk include ../../../scripts/package.mk update: rm -rf templates - mkdir templates - kubectl kustomize github.com/kubernetes-sigs/container-object-storage-interface-api > templates/crds.yaml - kubectl kustomize github.com/kubernetes-sigs/container-object-storage-interface-controller > templates/controller.yaml - sed -i 's/namespace: default/namespace: {{ .Release.Namespace }}/g' templates/controller.yaml + mkdir -p templates + kubectl kustomize github.com/kubernetes-sigs/container-object-storage-interface > templates/controller.yaml + sed -i 's/namespace: container-object-storage-system/namespace: {{ .Release.Namespace }}/g' templates/controller.yaml + sed -i 's|image:.*|image: {{ .Values.objectstorage.controller.image }}|' templates/controller.yaml + +image: image-controller image-sidecar +image-controller image-sidecar: + $(eval TARGET := $(subst image-,,$@)) + $(eval VALUES_FILE := $(if $(filter sidecar,$(TARGET)),../seaweedfs/values.yaml,values.yaml)) + $(eval YAML_PATH := $(if $(filter sidecar,$(TARGET)),.seaweedfs.cosi.sidecar.image,.objectstorage.controller.image)) + docker buildx build images/objectstorage \ + --target $(TARGET) \ + --tag $(REGISTRY)/objectstorage-$(TARGET):$(call settag,$(TAG)) \ + --cache-from type=registry,ref=$(REGISTRY)/objectstorage-$(TARGET):latest \ + --cache-to type=inline \ + --metadata-file images/$(TARGET).json \ + --push=$(PUSH) --provenance=false --load=$(LOAD) \ + --label "org.opencontainers.image.source=https://github.com/cozystack/cozystack" + IMAGE="$(REGISTRY)/objectstorage-$(TARGET):$(call settag,$(TAG))@$$(yq e '."containerimage.digest"' images/$(TARGET).json -r)" && \ + yq -i '$(YAML_PATH) = strenv(IMAGE)' $(VALUES_FILE) + rm -f images/$(TARGET).json diff --git a/packages/system/objectstorage-controller/images/objectstorage/Dockerfile b/packages/system/objectstorage-controller/images/objectstorage/Dockerfile new file mode 100644 index 00000000..01dafe83 --- /dev/null +++ b/packages/system/objectstorage-controller/images/objectstorage/Dockerfile @@ -0,0 +1,34 @@ +# syntax=docker/dockerfile:1.2 + +FROM alpine AS source +ARG COMMIT_REF=c2f6e651eb58880627ccddafe0d84fb36e03a780 +RUN apk add --no-cache curl tar git +WORKDIR /src + +RUN curl -sSL https://github.com/kubernetes-sigs/container-object-storage-interface/archive/${COMMIT_REF}.tar.gz \ + | tar -xz --strip-components=1 + +COPY patches /patches +RUN git apply /patches/*.diff + +FROM --platform=$BUILDPLATFORM docker.io/golang:1.24 AS builder +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /go/src/cosi + +COPY --from=source /src/go.mod /src/go.sum /src ./ +RUN go mod download + +RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /build/controller ./controller/cmd \ + && CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /build/sidecar ./sidecar/cmd + +FROM gcr.io/distroless/static:nonroot AS controller +COPY --from=builder /build/controller /controller +USER 65532:65532 +ENTRYPOINT ["/controller"] + +FROM gcr.io/distroless/static:nonroot AS sidecar +COPY --from=builder /build/sidecar /sidecar +USER 65532:65532 +ENTRYPOINT ["/sidecar"] diff --git a/packages/system/objectstorage-controller/images/objectstorage/patches/89-reconciliation.diff b/packages/system/objectstorage-controller/images/objectstorage/patches/89-reconciliation.diff new file mode 100644 index 00000000..8a3f11ab --- /dev/null +++ b/packages/system/objectstorage-controller/images/objectstorage/patches/89-reconciliation.diff @@ -0,0 +1,398 @@ +diff --git a/controller/pkg/bucketclaim/bucketclaim.go b/controller/pkg/bucketclaim/bucketclaim.go +index 2f4d565e..8ad7baed 100644 +--- a/controller/pkg/bucketclaim/bucketclaim.go ++++ b/controller/pkg/bucketclaim/bucketclaim.go +@@ -32,6 +32,10 @@ func NewBucketClaimListener() *BucketClaimListener { + + // Add creates a bucket in response to a bucketClaim + func (b *BucketClaimListener) Add(ctx context.Context, bucketClaim *v1alpha1.BucketClaim) error { ++ if !bucketClaim.GetDeletionTimestamp().IsZero() { ++ return b.handleDeletion(ctx, bucketClaim) ++ } ++ + klog.V(3).InfoS("Add BucketClaim", + "name", bucketClaim.ObjectMeta.Name, + "ns", bucketClaim.ObjectMeta.Namespace, +@@ -76,18 +80,11 @@ func (b *BucketClaimListener) Update(ctx context.Context, old, new *v1alpha1.Buc + bucketClaim := new.DeepCopy() + + if !new.GetDeletionTimestamp().IsZero() { +- if controllerutil.ContainsFinalizer(bucketClaim, util.BucketClaimFinalizer) { +- bucketName := bucketClaim.Status.BucketName +- err := b.buckets().Delete(ctx, bucketName, metav1.DeleteOptions{}) +- if err != nil { +- klog.V(3).ErrorS(err, "Error deleting bucket", +- "bucket", bucketName, +- "bucketClaim", bucketClaim.ObjectMeta.Name) +- return b.recordError(bucketClaim, v1.EventTypeWarning, v1alpha1.FailedDeleteBucket, err) +- } +- +- klog.V(5).Infof("Successfully deleted bucket: %s from bucketClaim: %s", bucketName, bucketClaim.ObjectMeta.Name) +- } ++ return b.handleDeletion(ctx, bucketClaim) ++ } ++ ++ if err := b.Add(ctx, bucketClaim); err != nil { ++ return err + } + + klog.V(3).InfoS("Update BucketClaim success", +@@ -96,6 +93,27 @@ func (b *BucketClaimListener) Update(ctx context.Context, old, new *v1alpha1.Buc + return nil + } + ++// handleDeletion processes the deletion of a bucketClaim. ++func (b *BucketClaimListener) handleDeletion(ctx context.Context, bucketClaim *v1alpha1.BucketClaim) error { ++ if !controllerutil.ContainsFinalizer(bucketClaim, util.BucketClaimFinalizer) { ++ return nil ++ } ++ ++ bucketName := bucketClaim.Status.BucketName ++ if bucketName != "" { ++ if err := b.buckets().Delete(ctx, bucketName, metav1.DeleteOptions{}); err != nil && !kubeerrors.IsNotFound(err) { ++ klog.V(3).ErrorS(err, "Error deleting bucket", ++ "bucket", bucketName, ++ "bucketClaim", bucketClaim.ObjectMeta.Name) ++ return b.recordError(bucketClaim, v1.EventTypeWarning, v1alpha1.FailedDeleteBucket, err) ++ } ++ klog.V(5).Infof("Successfully requested deletion of bucket: %s for bucketClaim: %s", ++ bucketName, bucketClaim.ObjectMeta.Name) ++ } ++ ++ return nil ++} ++ + // Delete processes a bucket for which bucket request is deleted + func (b *BucketClaimListener) Delete(ctx context.Context, bucketClaim *v1alpha1.BucketClaim) error { + klog.V(3).InfoS("Delete BucketClaim", +diff --git a/controller/pkg/bucketclaim/bucketclaim_test.go b/controller/pkg/bucketclaim/bucketclaim_test.go +index 284185b6..e2e2d3d2 100644 +--- a/controller/pkg/bucketclaim/bucketclaim_test.go ++++ b/controller/pkg/bucketclaim/bucketclaim_test.go +@@ -323,3 +323,32 @@ func TestRecordEvents(t *testing.T) { + func newEvent(eventType, reason, message string) string { + return fmt.Sprintf("%s %s %s", eventType, reason, message) + } ++ ++// Claim already marked for deletion must not create a bucket ++func TestAddDeletedBucketClaim(t *testing.T) { ++ ctx, cancel := context.WithCancel(context.Background()) ++ defer cancel() ++ ++ client := fakebucketclientset.NewSimpleClientset() ++ kubeClient := fakekubeclientset.NewSimpleClientset() ++ eventRecorder := record.NewFakeRecorder(3) ++ ++ listener := NewBucketClaimListener() ++ listener.InitializeKubeClient(kubeClient) ++ listener.InitializeBucketClient(client) ++ listener.InitializeEventRecorder(eventRecorder) ++ ++ _, _ = util.CreateBucketClass(ctx, client, &goldClass) ++ ++ claimToDelete := bucketClaim1.DeepCopy() ++ now := metav1.Now() ++ claimToDelete.ObjectMeta.DeletionTimestamp = &now ++ ++ if err := listener.Add(ctx, claimToDelete); err != nil { ++ t.Fatalf("Add returned error for deleted claim: %v", err) ++ } ++ ++ if bl := util.GetBuckets(ctx, client, 0); len(bl.Items) != 0 { ++ t.Fatalf("expected 0 buckets, got %d", len(bl.Items)) ++ } ++} +diff --git a/sidecar/pkg/bucket/bucket_controller.go b/sidecar/pkg/bucket/bucket_controller.go +index a934d0c5..bf8b5311 100644 +--- a/sidecar/pkg/bucket/bucket_controller.go ++++ b/sidecar/pkg/bucket/bucket_controller.go +@@ -68,6 +68,10 @@ func (b *BucketListener) Add(ctx context.Context, inputBucket *v1alpha1.Bucket) + + var err error + ++ if !bucket.GetDeletionTimestamp().IsZero() { ++ return b.handleDeletion(ctx, bucket) ++ } ++ + klog.V(3).InfoS("Add Bucket", + "name", bucket.ObjectMeta.Name) + +@@ -212,55 +216,60 @@ func (b *BucketListener) Update(ctx context.Context, old, new *v1alpha1.Bucket) + var err error + + if !bucket.GetDeletionTimestamp().IsZero() { +- if controllerutil.ContainsFinalizer(bucket, consts.BABucketFinalizer) { +- bucketClaimNs := bucket.Spec.BucketClaim.Namespace +- bucketClaimName := bucket.Spec.BucketClaim.Name +- bucketAccessList, err := b.bucketAccesses(bucketClaimNs).List(ctx, metav1.ListOptions{}) +- if err != nil { +- klog.V(3).ErrorS(err, "Error fetching BucketAccessList", +- "bucket", bucket.ObjectMeta.Name) +- return err +- } +- +- for _, bucketAccess := range bucketAccessList.Items { +- if strings.EqualFold(bucketAccess.Spec.BucketClaimName, bucketClaimName) { +- err = b.bucketAccesses(bucketClaimNs).Delete(ctx, bucketAccess.Name, metav1.DeleteOptions{}) +- if err != nil { +- klog.V(3).ErrorS(err, "Error deleting BucketAccess", +- "name", bucketAccess.Name, +- "bucket", bucket.ObjectMeta.Name) +- return err +- } +- } +- } ++ return b.handleDeletion(ctx, bucket) ++ } + +- klog.V(5).Infof("Successfully deleted dependent bucketAccess of bucket:%s", bucket.ObjectMeta.Name) ++ if err = b.Add(ctx, bucket); err != nil { ++ return err ++ } + +- controllerutil.RemoveFinalizer(bucket, consts.BABucketFinalizer) +- klog.V(5).Infof("Successfully removed finalizer: %s of bucket: %s", consts.BABucketFinalizer, bucket.ObjectMeta.Name) +- } ++ klog.V(3).InfoS("Update Bucket success", ++ "name", bucket.ObjectMeta.Name, ++ "ns", bucket.ObjectMeta.Namespace) ++ return nil ++} + +- if controllerutil.ContainsFinalizer(bucket, consts.BucketFinalizer) { +- err = b.deleteBucketOp(ctx, bucket) +- if err != nil { +- return b.recordError(bucket, v1.EventTypeWarning, v1alpha1.FailedDeleteBucket, err) +- } ++func (b *BucketListener) handleDeletion(ctx context.Context, bucket *v1alpha1.Bucket) error { ++ var err error + +- controllerutil.RemoveFinalizer(bucket, consts.BucketFinalizer) +- klog.V(5).Infof("Successfully removed finalizer: %s of bucket: %s", consts.BucketFinalizer, bucket.ObjectMeta.Name) +- } ++ if controllerutil.ContainsFinalizer(bucket, consts.BABucketFinalizer) { ++ bucketClaimNs := bucket.Spec.BucketClaim.Namespace ++ bucketClaimName := bucket.Spec.BucketClaim.Name + +- _, err = b.buckets().Update(ctx, bucket, metav1.UpdateOptions{}) ++ bucketAccessList, err := b.bucketAccesses(bucketClaimNs).List(ctx, metav1.ListOptions{}) + if err != nil { +- klog.V(3).ErrorS(err, "Error updating bucket after removing finalizers", ++ klog.V(3).ErrorS(err, "Error fetching BucketAccessList", + "bucket", bucket.ObjectMeta.Name) + return err + } ++ ++ for _, ba := range bucketAccessList.Items { ++ if strings.EqualFold(ba.Spec.BucketClaimName, bucketClaimName) { ++ if err = b.bucketAccesses(bucketClaimNs).Delete(ctx, ba.Name, metav1.DeleteOptions{}); err != nil { ++ klog.V(3).ErrorS(err, "Error deleting BucketAccess", ++ "name", ba.Name, ++ "bucket", bucket.ObjectMeta.Name) ++ return err ++ } ++ } ++ } ++ ++ controllerutil.RemoveFinalizer(bucket, consts.BABucketFinalizer) ++ } ++ ++ if controllerutil.ContainsFinalizer(bucket, consts.BucketFinalizer) { ++ if err = b.deleteBucketOp(ctx, bucket); err != nil { ++ return b.recordError(bucket, v1.EventTypeWarning, v1alpha1.FailedDeleteBucket, err) ++ } ++ controllerutil.RemoveFinalizer(bucket, consts.BucketFinalizer) ++ } ++ ++ if _, err = b.buckets().Update(ctx, bucket, metav1.UpdateOptions{}); err != nil { ++ klog.V(3).ErrorS(err, "Error updating bucket after removing finalizers", ++ "bucket", bucket.ObjectMeta.Name) ++ return err + } + +- klog.V(3).InfoS("Update Bucket success", +- "name", bucket.ObjectMeta.Name, +- "ns", bucket.ObjectMeta.Namespace) + return nil + } + +diff --git a/sidecar/pkg/bucket/bucket_controller_test.go b/sidecar/pkg/bucket/bucket_controller_test.go +index 9be6cc4a..ae63464e 100644 +--- a/sidecar/pkg/bucket/bucket_controller_test.go ++++ b/sidecar/pkg/bucket/bucket_controller_test.go +@@ -310,3 +310,43 @@ func TestRecordEvents(t *testing.T) { + func newEvent(eventType, reason, message string) string { + return fmt.Sprintf("%s %s %s", eventType, reason, message) + } ++ ++// TestAddDeletedBucket tests that the Add method does not call the driver ++func TestAddDeletedBucket(t *testing.T) { ++ driver := "driver1" ++ ++ mpc := struct{ fakespec.FakeProvisionerClient }{} ++ mpc.FakeDriverDeleteBucket = func( ++ _ context.Context, ++ _ *cosi.DriverDeleteBucketRequest, ++ _ ...grpc.CallOption, ++ ) (*cosi.DriverDeleteBucketResponse, error) { ++ t.Fatalf("driver should NOT be called from Add when object has DeletionTimestamp") ++ return nil, nil ++ } ++ ++ now := metav1.Now() ++ b := v1alpha1.Bucket{ ++ ObjectMeta: metav1.ObjectMeta{ ++ Name: "testbucket", ++ DeletionTimestamp: &now, ++ ResourceVersion: "1", ++ }, ++ Spec: v1alpha1.BucketSpec{ ++ DriverName: driver, ++ BucketClassName: "ignored", ++ }, ++ } ++ ++ client := fakebucketclientset.NewSimpleClientset(&b) ++ ++ bl := BucketListener{ ++ driverName: driver, ++ provisionerClient: &mpc, ++ } ++ bl.InitializeBucketClient(client) ++ ++ if err := bl.Add(context.TODO(), &b); err != nil { ++ t.Fatalf("Add returned error for deleted bucket: %v", err) ++ } ++} +diff --git a/sidecar/pkg/bucketaccess/bucketaccess_controller.go b/sidecar/pkg/bucketaccess/bucketaccess_controller.go +index c6d0ed07..dd18202f 100644 +--- a/sidecar/pkg/bucketaccess/bucketaccess_controller.go ++++ b/sidecar/pkg/bucketaccess/bucketaccess_controller.go +@@ -68,6 +68,12 @@ func NewBucketAccessListener(driverName string, client cosi.ProvisionerClient) * + func (bal *BucketAccessListener) Add(ctx context.Context, inputBucketAccess *v1alpha1.BucketAccess) error { + bucketAccess := inputBucketAccess.DeepCopy() + ++ if !bucketAccess.GetDeletionTimestamp().IsZero() { ++ klog.V(3).InfoS("BucketAccess has deletion timestamp, handling deletion", ++ "name", bucketAccess.ObjectMeta.Name) ++ return bal.deleteBucketAccessOp(ctx, bucketAccess) ++ } ++ + if bucketAccess.Status.AccessGranted && bucketAccess.Status.AccountID != "" { + klog.V(3).InfoS("BucketAccess already exists", bucketAccess.ObjectMeta.Name) + return nil +@@ -310,10 +316,13 @@ func (bal *BucketAccessListener) Update(ctx context.Context, old, new *v1alpha1. + + bucketAccess := new.DeepCopy() + if !bucketAccess.GetDeletionTimestamp().IsZero() { +- err := bal.deleteBucketAccessOp(ctx, bucketAccess) +- if err != nil { ++ if err := bal.deleteBucketAccessOp(ctx, bucketAccess); err != nil { + return bal.recordError(bucketAccess, v1.EventTypeWarning, v1alpha1.FailedRevokeAccess, err) + } ++ } else { ++ if err := bal.Add(ctx, bucketAccess); err != nil { ++ return bal.recordError(bucketAccess, v1.EventTypeWarning, v1alpha1.FailedGrantAccess, err) ++ } + } + + klog.V(3).InfoS("Update BucketAccess success", +diff --git a/sidecar/pkg/bucketaccess/bucketaccess_controller_test.go b/sidecar/pkg/bucketaccess/bucketaccess_controller_test.go +index 2371c81e..d8da44a2 100644 +--- a/sidecar/pkg/bucketaccess/bucketaccess_controller_test.go ++++ b/sidecar/pkg/bucketaccess/bucketaccess_controller_test.go +@@ -502,3 +502,94 @@ func TestRecordEvents(t *testing.T) { + func newEvent(eventType, reason, message string) string { + return fmt.Sprintf("%s %s %s", eventType, reason, message) + } ++ ++// TestAddDeletedBucketAccess tests that a deleted BucketAccess does not ++// trigger a call to the driver to grant access, and that no secrets are created. ++func TestAddDeletedBucketAccess(t *testing.T) { ++ driver := "driver" ++ baName := "bucketaccess-deleted" ++ ns := "testns" ++ ++ mpc := struct{ fakespec.FakeProvisionerClient }{} ++ mpc.FakeDriverGrantBucketAccess = func( ++ _ context.Context, ++ _ *cosi.DriverGrantBucketAccessRequest, ++ _ ...grpc.CallOption, ++ ) (*cosi.DriverGrantBucketAccessResponse, error) { ++ t.Fatalf("driver Grant should NOT be called on deleted BA") ++ return nil, nil ++ } ++ mpc.FakeDriverRevokeBucketAccess = func( ++ _ context.Context, ++ _ *cosi.DriverRevokeBucketAccessRequest, ++ _ ...grpc.CallOption, ++ ) (*cosi.DriverRevokeBucketAccessResponse, error) { ++ return &cosi.DriverRevokeBucketAccessResponse{}, nil ++ } ++ ++ // minimal stub objects just to satisfy look-ups inside delete-path ++ bac := &v1alpha1.BucketAccessClass{ ++ ObjectMeta: metav1.ObjectMeta{Name: "bac"}, ++ DriverName: driver, ++ } ++ claim := &v1alpha1.BucketClaim{ ++ ObjectMeta: metav1.ObjectMeta{Name: "claim", Namespace: ns}, ++ Status: v1alpha1.BucketClaimStatus{ ++ BucketReady: true, ++ BucketName: "bucket", ++ }, ++ } ++ bucket := &v1alpha1.Bucket{ ++ ObjectMeta: metav1.ObjectMeta{Name: "bucket"}, ++ Status: v1alpha1.BucketStatus{ ++ BucketReady: true, ++ BucketID: "id", ++ }, ++ } ++ ++ now := metav1.Now() ++ ba := &v1alpha1.BucketAccess{ ++ ObjectMeta: metav1.ObjectMeta{ ++ Name: baName, ++ Namespace: ns, ++ DeletionTimestamp: &now, ++ Finalizers: []string{consts.BAFinalizer}, ++ }, ++ Spec: v1alpha1.BucketAccessSpec{ ++ BucketClaimName: claim.Name, ++ BucketAccessClassName: bac.Name, ++ CredentialsSecretName: "creds", ++ }, ++ Status: v1alpha1.BucketAccessStatus{ ++ AccountID: "acc", ++ AccessGranted: true, ++ }, ++ } ++ ++ secret := &v1.Secret{ ++ ObjectMeta: metav1.ObjectMeta{ ++ Name: "creds", ++ Namespace: ns, ++ Finalizers: []string{consts.SecretFinalizer}, ++ }, ++ StringData: map[string]string{"dummy": "val"}, ++ } ++ ++ client := fakebucketclientset.NewSimpleClientset(bac, claim, bucket, ba) ++ kubeClient := fakekubeclientset.NewSimpleClientset(secret) ++ ++ bal := BucketAccessListener{ ++ driverName: driver, ++ provisionerClient: &mpc, ++ bucketClient: client, ++ kubeClient: kubeClient, ++ } ++ ++ if err := bal.Add(context.TODO(), ba); err != nil { ++ t.Fatalf("Add returned error for deleted BucketAccess: %v", err) ++ } ++ ++ if _, err := bal.secrets(ns).Get(context.TODO(), "creds", metav1.GetOptions{}); !kubeerrors.IsNotFound(err) { ++ t.Fatalf("secret was not cleaned up, err=%v", err) ++ } ++} diff --git a/packages/system/objectstorage-controller/images/objectstorage/patches/90-bucket-name.diff b/packages/system/objectstorage-controller/images/objectstorage/patches/90-bucket-name.diff new file mode 100644 index 00000000..de2d2c6b --- /dev/null +++ b/packages/system/objectstorage-controller/images/objectstorage/patches/90-bucket-name.diff @@ -0,0 +1,13 @@ +diff --git a/controller/pkg/bucketclaim/bucketclaim.go b/controller/pkg/bucketclaim/bucketclaim.go +index 2f4d565e..2addcee8 100644 +--- a/controller/pkg/bucketclaim/bucketclaim.go ++++ b/controller/pkg/bucketclaim/bucketclaim.go +@@ -165,7 +165,7 @@ func (b *BucketClaimListener) provisionBucketClaimOperation(ctx context.Context, + return b.recordError(inputBucketClaim, v1.EventTypeWarning, v1alpha1.FailedCreateBucket, err) + } + +- bucketName = bucketClassName + string(bucketClaim.ObjectMeta.UID) ++ bucketName = fmt.Sprintf("bucket-%s", bucketClaim.ObjectMeta.UID) + + // create bucket + bucket := &v1alpha1.Bucket{} diff --git a/packages/system/objectstorage-controller/templates/controller.yaml b/packages/system/objectstorage-controller/templates/controller.yaml index 197c1f4f..b51b05ea 100644 --- a/packages/system/objectstorage-controller/templates/controller.yaml +++ b/packages/system/objectstorage-controller/templates/controller.yaml @@ -1,22 +1,507 @@ apiVersion: v1 +kind: Namespace +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: container-object-storage-interface-controller + app.kubernetes.io/part-of: container-object-storage-interface + name: container-object-storage-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + controller-gen.kubebuilder.io/version: v0.17.3 + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api + name: bucketaccessclasses.objectstorage.k8s.io +spec: + group: objectstorage.k8s.io + names: + kind: BucketAccessClass + listKind: BucketAccessClassList + plural: bucketaccessclasses + singular: bucketaccessclass + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + authenticationType: + description: |- + AuthenticationType denotes the style of authentication + It can be one of + Key - access, secret tokens based authentication + IAM - implicit authentication of pods to the OSP based on service account mappings + type: string + driverName: + description: |- + DriverName is the name of driver associated with + this BucketAccess + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + parameters: + additionalProperties: + type: string + description: |- + Parameters is an opaque map for passing in configuration to a driver + for granting access to a bucket + type: object + required: + - authenticationType + - driverName + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + controller-gen.kubebuilder.io/version: v0.17.3 + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api + name: bucketaccesses.objectstorage.k8s.io +spec: + group: objectstorage.k8s.io + names: + kind: BucketAccess + listKind: BucketAccessList + plural: bucketaccesses + singular: bucketaccess + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + bucketAccessClassName: + description: BucketAccessClassName is the name of the BucketAccessClass + type: string + bucketClaimName: + description: BucketClaimName is the name of the BucketClaim. + type: string + credentialsSecretName: + description: |- + CredentialsSecretName is the name of the secret that COSI should populate + with the credentials. If a secret by this name already exists, then it is + assumed that credentials have already been generated. It is not overridden. + This secret is deleted when the BucketAccess is delted. + type: string + protocol: + description: |- + Protocol is the name of the Protocol + that this access credential is supposed to support + If left empty, it will choose the protocol supported + by the bucket. If the bucket supports multiple protocols, + the end protocol is determined by the driver. + type: string + serviceAccountName: + description: |- + ServiceAccountName is the name of the serviceAccount that COSI will map + to the OSP service account when IAM styled authentication is specified + type: string + required: + - bucketAccessClassName + - bucketClaimName + - credentialsSecretName + type: object + status: + properties: + accessGranted: + description: AccessGranted indicates the successful grant of privileges + to access the bucket + type: boolean + accountID: + description: |- + AccountID is the unique ID for the account in the OSP. It will be populated + by the COSI sidecar once access has been successfully granted. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + controller-gen.kubebuilder.io/version: v0.17.3 + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api + name: bucketclaims.objectstorage.k8s.io +spec: + group: objectstorage.k8s.io + names: + kind: BucketClaim + listKind: BucketClaimList + plural: bucketclaims + singular: bucketclaim + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + bucketClassName: + description: Name of the BucketClass + type: string + existingBucketName: + description: |- + Name of a bucket object that was manually + created to import a bucket created outside of COSI + If unspecified, then a new Bucket will be dynamically provisioned + type: string + protocols: + description: |- + Protocols are the set of data API this bucket is required to support. + The possible values for protocol are: + - S3: Indicates Amazon S3 protocol + - Azure: Indicates Microsoft Azure BlobStore protocol + - GCS: Indicates Google Cloud Storage protocol + items: + type: string + type: array + required: + - protocols + type: object + status: + properties: + bucketName: + description: |- + BucketName is the name of the provisioned Bucket in response + to this BucketClaim. It is generated and set by the COSI controller + before making the creation request to the OSP backend. + type: string + bucketReady: + description: |- + BucketReady indicates that the bucket is ready for consumpotion + by workloads + type: boolean + required: + - bucketReady + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + controller-gen.kubebuilder.io/version: v0.17.3 + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api + name: bucketclasses.objectstorage.k8s.io +spec: + group: objectstorage.k8s.io + names: + kind: BucketClass + listKind: BucketClassList + plural: bucketclasses + singular: bucketclass + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + deletionPolicy: + default: Retain + description: |- + DeletionPolicy is used to specify how COSI should handle deletion of this + bucket. There are 2 possible values: + - Retain: Indicates that the bucket should not be deleted from the OSP + - Delete: Indicates that the bucket should be deleted from the OSP + once all the workloads accessing this bucket are done + type: string + driverName: + description: DriverName is the name of driver associated with this bucket + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + parameters: + additionalProperties: + type: string + description: |- + Parameters is an opaque map for passing in configuration to a driver + for creating the bucket + type: object + required: + - deletionPolicy + - driverName + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + controller-gen.kubebuilder.io/version: v0.17.3 + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api + name: buckets.objectstorage.k8s.io +spec: + group: objectstorage.k8s.io + names: + kind: Bucket + listKind: BucketList + plural: buckets + singular: bucket + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + bucketClaim: + description: |- + Name of the BucketClaim that resulted in the creation of this Bucket + In case the Bucket object was created manually, then this should refer + to the BucketClaim with which this Bucket should be bound + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + bucketClassName: + description: Name of the BucketClass specified in the BucketRequest + type: string + deletionPolicy: + default: Retain + description: |- + DeletionPolicy is used to specify how COSI should handle deletion of this + bucket. There are 2 possible values: + - Retain: Indicates that the bucket should not be deleted from the OSP (default) + - Delete: Indicates that the bucket should be deleted from the OSP + once all the workloads accessing this bucket are done + type: string + driverName: + description: DriverName is the name of driver associated with this + bucket + type: string + existingBucketID: + description: |- + ExistingBucketID is the unique id of the bucket in the OSP. This field should be + used to specify a bucket that has been created outside of COSI. + This field will be empty when the Bucket is dynamically provisioned by COSI. + type: string + parameters: + additionalProperties: + type: string + type: object + protocols: + description: |- + Protocols are the set of data APIs this bucket is expected to support. + The possible values for protocol are: + - S3: Indicates Amazon S3 protocol + - Azure: Indicates Microsoft Azure BlobStore protocol + - GCS: Indicates Google Cloud Storage protocol + items: + type: string + type: array + required: + - bucketClaim + - bucketClassName + - driverName + - protocols + type: object + status: + properties: + bucketID: + description: |- + BucketID is the unique id of the bucket in the OSP. This field will be + populated by COSI. + type: string + bucketReady: + description: |- + BucketReady is a boolean condition to reflect the successful creation + of a bucket. + type: boolean + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 kind: ServiceAccount metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api labels: app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: container-object-storage-interface-controller app.kubernetes.io/part-of: container-object-storage-interface - app.kubernetes.io/version: main - name: objectstorage-controller-sa + name: container-object-storage-controller-sa + namespace: {{ .Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api labels: app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: container-object-storage-interface-controller app.kubernetes.io/part-of: container-object-storage-interface app.kubernetes.io/version: main - name: objectstorage-controller + name: container-object-storage-controller namespace: {{ .Release.Namespace }} rules: - apiGroups: @@ -34,13 +519,17 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api labels: app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: container-object-storage-interface-controller app.kubernetes.io/part-of: container-object-storage-interface - app.kubernetes.io/version: main - name: objectstorage-controller-role - namespace: {{ .Release.Namespace }} + name: container-object-storage-controller-role rules: - apiGroups: - objectstorage.k8s.io @@ -95,74 +584,94 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api labels: app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: container-object-storage-interface-controller app.kubernetes.io/part-of: container-object-storage-interface app.kubernetes.io/version: main - name: objectstorage-controller + name: container-object-storage-controller namespace: {{ .Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: objectstorage-controller + name: container-object-storage-controller subjects: - kind: ServiceAccount - name: objectstorage-controller-sa + name: container-object-storage-controller-sa namespace: {{ .Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api labels: app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: container-object-storage-interface-controller app.kubernetes.io/part-of: container-object-storage-interface app.kubernetes.io/version: main - name: objectstorage-controller - namespace: {{ .Release.Namespace }} + name: container-object-storage-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: objectstorage-controller-role + name: container-object-storage-controller-role subjects: - kind: ServiceAccount - name: objectstorage-controller-sa + name: container-object-storage-controller-sa namespace: {{ .Release.Namespace }} --- apiVersion: apps/v1 kind: Deployment metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api labels: + app: container-object-storage-interface-controller app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: container-object-storage-interface-controller app.kubernetes.io/part-of: container-object-storage-interface - app.kubernetes.io/version: main - name: objectstorage-controller + name: container-object-storage-controller + namespace: {{ .Release.Namespace }} spec: replicas: 1 selector: matchLabels: - app.kubernetes.io/component: controller - app.kubernetes.io/name: container-object-storage-interface-controller - app.kubernetes.io/part-of: container-object-storage-interface - app.kubernetes.io/version: main + app: container-object-storage-interface-controller strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support + objectstorage.k8s.io/authors: Kubernetes Authors + objectstorage.k8s.io/license: Apache V2 + objectstorage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api labels: + app: container-object-storage-interface-controller app.kubernetes.io/component: controller + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/name: container-object-storage-interface-controller app.kubernetes.io/part-of: container-object-storage-interface - app.kubernetes.io/version: main spec: containers: - args: - --v=5 - image: gcr.io/k8s-staging-sig-storage/objectstorage-controller:v20221027-v0.1.1-8-g300019f - imagePullPolicy: Always + image: {{ .Values.objectstorage.controller.image }} name: objectstorage-controller - serviceAccountName: objectstorage-controller-sa + serviceAccountName: container-object-storage-controller-sa diff --git a/packages/system/objectstorage-controller/templates/crds.yaml b/packages/system/objectstorage-controller/templates/crds.yaml deleted file mode 100644 index 49dbc484..00000000 --- a/packages/system/objectstorage-controller/templates/crds.yaml +++ /dev/null @@ -1,413 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support - controller-gen.kubebuilder.io/version: (devel) - cosi.storage.k8s.io/authors: Kubernetes Authors - cosi.storage.k8s.io/license: Apache V2 - cosi.storage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api - creationTimestamp: null - name: bucketaccessclasses.objectstorage.k8s.io -spec: - group: objectstorage.k8s.io - names: - kind: BucketAccessClass - listKind: BucketAccessClassList - plural: bucketaccessclasses - singular: bucketaccessclass - scope: Cluster - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - authenticationType: - description: AuthenticationType denotes the style of authentication It - can be one of Key - access, secret tokens based authentication IAM - - implicit authentication of pods to the OSP based on service account - mappings - type: string - driverName: - description: DriverName is the name of driver associated with this BucketAccess - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - parameters: - additionalProperties: - type: string - description: Parameters is an opaque map for passing in configuration - to a driver for granting access to a bucket - type: object - required: - - authenticationType - - driverName - type: object - served: true - storage: true ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support - controller-gen.kubebuilder.io/version: (devel) - cosi.storage.k8s.io/authors: Kubernetes Authors - cosi.storage.k8s.io/license: Apache V2 - cosi.storage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api - creationTimestamp: null - name: bucketaccesses.objectstorage.k8s.io -spec: - group: objectstorage.k8s.io - names: - kind: BucketAccess - listKind: BucketAccessList - plural: bucketaccesses - singular: bucketaccess - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - properties: - bucketAccessClassName: - description: BucketAccessClassName is the name of the BucketAccessClass - type: string - bucketClaimName: - description: BucketClaimName is the name of the BucketClaim. - type: string - credentialsSecretName: - description: CredentialsSecretName is the name of the secret that - COSI should populate with the credentials. If a secret by this name - already exists, then it is assumed that credentials have already - been generated. It is not overridden. This secret is deleted when - the BucketAccess is delted. - type: string - protocol: - description: Protocol is the name of the Protocol that this access - credential is supposed to support If left empty, it will choose - the protocol supported by the bucket. If the bucket supports multiple - protocols, the end protocol is determined by the driver. - type: string - serviceAccountName: - description: ServiceAccountName is the name of the serviceAccount - that COSI will map to the OSP service account when IAM styled authentication - is specified - type: string - required: - - bucketAccessClassName - - bucketClaimName - - credentialsSecretName - type: object - status: - properties: - accessGranted: - description: AccessGranted indicates the successful grant of privileges - to access the bucket - type: boolean - accountID: - description: AccountID is the unique ID for the account in the OSP. - It will be populated by the COSI sidecar once access has been successfully - granted. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support - controller-gen.kubebuilder.io/version: (devel) - cosi.storage.k8s.io/authors: Kubernetes Authors - cosi.storage.k8s.io/license: Apache V2 - cosi.storage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api - creationTimestamp: null - name: bucketclaims.objectstorage.k8s.io -spec: - group: objectstorage.k8s.io - names: - kind: BucketClaim - listKind: BucketClaimList - plural: bucketclaims - singular: bucketclaim - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - properties: - bucketClassName: - description: Name of the BucketClass - type: string - existingBucketName: - description: Name of a bucket object that was manually created to - import a bucket created outside of COSI If unspecified, then a new - Bucket will be dynamically provisioned - type: string - protocols: - description: 'Protocols are the set of data API this bucket is required - to support. The possible values for protocol are: - S3: Indicates - Amazon S3 protocol - Azure: Indicates Microsoft Azure BlobStore - protocol - GCS: Indicates Google Cloud Storage protocol' - items: - type: string - type: array - required: - - protocols - type: object - status: - properties: - bucketName: - description: BucketName is the name of the provisioned Bucket in response - to this BucketClaim. It is generated and set by the COSI controller - before making the creation request to the OSP backend. - type: string - bucketReady: - description: BucketReady indicates that the bucket is ready for consumpotion - by workloads - type: boolean - required: - - bucketReady - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support - controller-gen.kubebuilder.io/version: (devel) - cosi.storage.k8s.io/authors: Kubernetes Authors - cosi.storage.k8s.io/license: Apache V2 - cosi.storage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api - creationTimestamp: null - name: bucketclasses.objectstorage.k8s.io -spec: - group: objectstorage.k8s.io - names: - kind: BucketClass - listKind: BucketClassList - plural: bucketclasses - singular: bucketclass - scope: Cluster - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - deletionPolicy: - default: Retain - description: 'DeletionPolicy is used to specify how COSI should handle - deletion of this bucket. There are 2 possible values: - Retain: Indicates - that the bucket should not be deleted from the OSP - Delete: Indicates - that the bucket should be deleted from the OSP once all the workloads - accessing this bucket are done' - type: string - driverName: - description: DriverName is the name of driver associated with this bucket - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - parameters: - additionalProperties: - type: string - description: Parameters is an opaque map for passing in configuration - to a driver for creating the bucket - type: object - required: - - deletionPolicy - - driverName - type: object - served: true - storage: true ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support - controller-gen.kubebuilder.io/version: (devel) - cosi.storage.k8s.io/authors: Kubernetes Authors - cosi.storage.k8s.io/license: Apache V2 - cosi.storage.k8s.io/support: https://github.com/kubernetes-sigs/container-object-storage-api - creationTimestamp: null - name: buckets.objectstorage.k8s.io -spec: - group: objectstorage.k8s.io - names: - kind: Bucket - listKind: BucketList - plural: buckets - singular: bucket - scope: Cluster - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - properties: - bucketClaim: - description: Name of the BucketClaim that resulted in the creation - of this Bucket In case the Bucket object was created manually, then - this should refer to the BucketClaim with which this Bucket should - be bound - properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: 'If referring to a piece of an object instead of - an entire object, this string should contain a valid JSON/Go - field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container within - a pod, this would take on a value like: "spec.containers{name}" - (where "name" refers to the name of the container that triggered - the event) or if no container name is specified "spec.containers[2]" - (container with index 2 in this pod). This syntax is chosen - only to have some well-defined way of referencing a part of - an object. TODO: this design is not final and this field is - subject to change in the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference - is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' - type: string - type: object - x-kubernetes-map-type: atomic - bucketClassName: - description: Name of the BucketClass specified in the BucketRequest - type: string - deletionPolicy: - default: Retain - description: 'DeletionPolicy is used to specify how COSI should handle - deletion of this bucket. There are 2 possible values: - Retain: - Indicates that the bucket should not be deleted from the OSP (default) - - Delete: Indicates that the bucket should be deleted from the OSP - once all the workloads accessing this bucket are done' - type: string - driverName: - description: DriverName is the name of driver associated with this - bucket - type: string - existingBucketID: - description: ExistingBucketID is the unique id of the bucket in the - OSP. This field should be used to specify a bucket that has been - created outside of COSI. This field will be empty when the Bucket - is dynamically provisioned by COSI. - type: string - parameters: - additionalProperties: - type: string - type: object - protocols: - description: 'Protocols are the set of data APIs this bucket is expected - to support. The possible values for protocol are: - S3: Indicates - Amazon S3 protocol - Azure: Indicates Microsoft Azure BlobStore - protocol - GCS: Indicates Google Cloud Storage protocol' - items: - type: string - type: array - required: - - bucketClaim - - bucketClassName - - driverName - - protocols - type: object - status: - properties: - bucketID: - description: BucketID is the unique id of the bucket in the OSP. This - field will be populated by COSI. - type: string - bucketReady: - description: BucketReady is a boolean condition to reflect the successful - creation of a bucket. - type: boolean - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/packages/system/objectstorage-controller/values.yaml b/packages/system/objectstorage-controller/values.yaml new file mode 100644 index 00000000..0a649151 --- /dev/null +++ b/packages/system/objectstorage-controller/values.yaml @@ -0,0 +1,3 @@ +objectstorage: + controller: + image: "ghcr.io/cozystack/cozystack/objectstorage-controller:latest@sha256:173067339794fbf94534132eec5968b5fb6718037b77aefa00fd70b7413a8d4c"