diff --git a/README.md b/README.md index 7d8fb1c82..12aba0cd5 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@

------ -*PLEASE NOTE*: This project is considered ALPHA quality and should NOT be used for production, as it is currently in active development. Use at your own risk. APIs, configuration file formats, and functionality are all subject to change frequently. That said, please try it out in your development and test environments and let us know if it works. Contributions welcome! Thanks! +*PLEASE NOTE*: This project is considered ALPHA quality and should NOT be used for production, as it is currently in active development. Use at your own risk. APIs, configuration file formats, and functionality are all subject to change frequently. That said, please try it out in your development and test environments and let us know how it works for you. Contributions welcome! Thanks! ------ diff --git a/controller/linodeobjectstoragebucket_controller_test.go b/controller/linodeobjectstoragebucket_controller_test.go index 05ddbdd59..4c6e90285 100644 --- a/controller/linodeobjectstoragebucket_controller_test.go +++ b/controller/linodeobjectstoragebucket_controller_test.go @@ -72,7 +72,7 @@ func mockLinodeClientBuilder(m *mock.MockLinodeObjectStorageClient) scope.Linode } } -var _ = Describe("lifecycle", Label("lifecycle"), func() { +var _ = Describe("lifecycle", Ordered, Label("bucket", "lifecycle"), func() { var mockCtrl *gomock.Controller var reconciler *LinodeObjectStorageBucketReconciler var testLogs *bytes.Buffer @@ -341,7 +341,7 @@ var _ = Describe("lifecycle", Label("lifecycle"), func() { }) }) -var _ = Describe("pre-reconcile", Label("pre-reconcile"), func() { +var _ = Describe("pre-reconcile", Label("bucket", "pre-reconcile"), func() { var obj infrav1.LinodeObjectStorageBucket var mockCtrl *gomock.Controller var reconciler *LinodeObjectStorageBucketReconciler @@ -413,7 +413,7 @@ var _ = Describe("pre-reconcile", Label("pre-reconcile"), func() { }) }) -var _ = Describe("apply", Label("apply"), func() { +var _ = Describe("apply", Label("bucket", "apply"), func() { var obj infrav1.LinodeObjectStorageBucket var mockCtrl *gomock.Controller var testLogs *bytes.Buffer @@ -456,7 +456,7 @@ var _ = Describe("apply", Label("apply"), func() { } }) - It("fails when a finalizer cannot be added", Label("current"), func(ctx SpecContext) { + It("fails when a finalizer cannot be added", func(ctx SpecContext) { mockK8sClient := mock.NewMockk8sClient(mockCtrl) prev := mockK8sClient.EXPECT(). Scheme(). diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index fbf5abe64..2b61f8304 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -11,6 +11,7 @@ - [k3s](./topics/flavors/k3s.md) - [rke2](./topics/flavors/rke2.md) - [Etcd](./topics/etcd.md) + - [Backups](./topics/backups.md) - [Multi-Tenancy](./topics/multi-tenancy.md) - [Development](./developers/development.md) - [Releasing](./developers/releasing.md) diff --git a/docs/src/topics/backups.md b/docs/src/topics/backups.md new file mode 100644 index 000000000..b8ff8df33 --- /dev/null +++ b/docs/src/topics/backups.md @@ -0,0 +1,116 @@ +# Backups + +CAPL supports performing etcd backups by provisioning an Object Storage bucket and access keys. This feature is not enabled by default and can be configured as an addon. + +```admonish warning +Enabling this addon requires enabling Object Storage in the account where the resources will be provisioned. Please refer to the [Pricing](https://www.linode.com/docs/products/storage/object-storage/#pricing) information in Linode's [Object Storage documentation](https://www.linode.com/docs/products/storage/object-storage/). +``` + +## Enabling Backups + +TODO + +## Object Storage + +Additionally, CAPL can be used to provision Object Storage buckets and access keys for general purposes by configuring a `LinodeObjectStorageBucket` resource. + +```admonish warning +Using this feature requires enabling Object Storage in the account where the resources will be provisioned. Please refer to the [Pricing](https://www.linode.com/docs/products/storage/object-storage/#pricing) information in Linode's [Object Storage documentation](https://www.linode.com/docs/products/storage/object-storage/). +``` + +### Bucket Creation + +The following is the minimal required configuration needed to provision an Object Storage bucket and set of access keys. + +```yaml +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 +kind: LinodeObjectStorageBucket +metadata: + name: + namespace: +spec: + cluster: + secretType: Opaque +``` + +Upon creation of the resource, CAPL will provision a bucket in the region specified using the `.metadata.name` as the bucket's label. + +```admonish warning +The bucket label must be unique within the region across all accounts. Otherwise, CAPL will populate the resource status fields with errors to show that the operation failed. +``` + +### Access Keys Creation + +CAPL will also create `read_write` and `read_only` access keys for the bucket and store credentials in a secret in the same namespace where the `LinodeObjectStorageBucket` was created: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: -access-keys + namespace: + ownerReferences: + - apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 + kind: LinodeObjectStorageBucket + name: + controller: true +data: + bucket_name: + access_key_rw: + secret_key_rw: + access_key_ro: + secret_key_ro: +``` + +The access key secret is owned and managed by CAPL during the life of the `LinodeObjectStorageBucket`. + +### Access Keys Rotation + +The following configuration with `keyGeneration` set to a new value (different from `.status.lastKeyGeneration`) will instruct CAPL to rotate the access keys. + +```yaml +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 +kind: LinodeObjectStorageBucket +metadata: + name: + namespace: +spec: + cluster: + secretType: Opaque + keyGeneration: 1 +# status: +# lastKeyGeneration: 0 +``` + +### Bucket Status + +Upon successful provisioning of a bucket and keys, the `LinodeObjectStorageBucket` resource's status will resemble the following: + +```yaml +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 +kind: LinodeObjectStorageBucket +metadata: + name: + namespace: +spec: + cluster: + secretType: Opaque + keyGeneration: 0 +status: + ready: true + conditions: + - type: Ready + status: "True" + lastTransitionTime: + hostname: + creationTime: + lastKeyGeneration: 0 + keySecretName: -access-keys + accessKeyRefs: + - + - +``` + +### Resource Deletion + +When deleting a `LinodeObjectStorageBucket` resource, CAPL will deprovision the access keys and managed secret but retain the underlying bucket to avoid unintended data loss. diff --git a/docs/src/topics/getting-started.md b/docs/src/topics/getting-started.md index a63d5cb49..cdffa150e 100644 --- a/docs/src/topics/getting-started.md +++ b/docs/src/topics/getting-started.md @@ -11,6 +11,7 @@ Make sure to create the token with at least the following read/write permissions - Volumes - VPCs - IPs + - Object Storage ```admonish question title="" For more information please see the diff --git a/docs/src/topics/multi-tenancy.md b/docs/src/topics/multi-tenancy.md index 884d48b30..6609d2b5b 100644 --- a/docs/src/topics/multi-tenancy.md +++ b/docs/src/topics/multi-tenancy.md @@ -51,6 +51,16 @@ spec: credentialsRef: name: linode-credentials ... +--- +# Example: LinodeObjectStorageBucket +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha1 +kind: LinodeObjectStorageBucket +metadata: + name: test-bucket +spec: + credentialsRef: + name: linode-credentials + ... ``` Secrets from other namespaces by additionally specifying an optional