Files
autobackup-operator/test/crds/ceph.unkin.net_buckets.yaml
T
unkin-agent 9da206dc7c Implement autobackup-operator controllers, tests, CI and packaging
PVCs and CloudNativePG Clusters need S3 buckets and backup schedules
provisioned consistently. This operator watches the
backups.unkin.net/{schedule,destination} annotations on those objects and
provisions everything needed to back them up, with no new CRDs.

- Add a PVC controller that provisions cephrgw ObjectStoreUser/Bucket/BucketAccess,
  auto-generates a restic repo-password Secret and creates a k8up Schedule scoped
  to the PVC via spec.backup.volumes[].persistentVolumeClaim.claimName.
- Add a CNPG Cluster controller that provisions the same bucket stack, idempotently
  patches spec.backup.barmanObjectStore (leaving a user-set destinationPath alone
  with a Warning event) and creates a ScheduledBackup.
- Resolve destinations through a ConfigMap lookup table; requeue until the
  BucketAccess is Ready before creating schedule resources; own-reference created
  resources and retain bucket data by default.
- Add schedule-mapping helpers (k8up 5-field/shortcut pass-through, CNPG 6-field
  seconds-first) and deterministic, length-bounded name derivation.
- Add unit tests (schedule mapping, name derivation, destination resolution) and
  envtest controller tests for both paths, wiring the external CRDs into envtest.
- Add kubebuilder-generated RBAC, a Dockerfile (distroless/nonroot), Woodpecker
  lint/test/build pipelines and a tag-triggered image push to the artifactapi
  docker-internal registry, plus a version-bump Makefile and deploy manifests.
2026-08-14 00:08:37 +10:00

251 lines
11 KiB
YAML

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.17.3
name: buckets.ceph.unkin.net
spec:
group: ceph.unkin.net
names:
kind: Bucket
listKind: BucketList
plural: buckets
shortNames:
- bkt
singular: bucket
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .status.bucketName
name: Bucket
type: string
- jsonPath: .status.owner
name: Owner
type: string
- jsonPath: .status.policyPrincipals
name: Grants
type: integer
- jsonPath: .status.adopted
name: Adopted
type: boolean
- jsonPath: .status.phase
name: Phase
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: Bucket is a Ceph RGW S3 bucket.
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:
description: BucketSpec defines a Ceph RGW (S3) bucket owned by an ObjectStoreUser.
properties:
bucketName:
description: BucketName is the S3 bucket name. Defaults to metadata.name.
Immutable.
type: string
managePolicy:
default: true
description: |-
ManagePolicy controls whether the operator manages the bucket's S3 policy
from BucketAccess grants. When true (the default) the operator reconciles
its own statements while preserving any statements it does not own, so it
is safe to adopt a bucket that already has a policy. Set to false to leave
the bucket policy entirely untouched (BucketAccess grants then have no
effect on this bucket).
type: boolean
objectLock:
description: ObjectLock configures S3 object lock. Enabling it forces
versioning on.
properties:
days:
description: Days is the default retention period in days. Mutually
exclusive with Years.
format: int32
type: integer
enabled:
description: Enabled turns on object lock for the bucket.
type: boolean
mode:
description: Mode is the default retention mode applied to new
objects.
enum:
- GOVERNANCE
- COMPLIANCE
type: string
years:
description: Years is the default retention period in years. Mutually
exclusive with Days.
format: int32
type: integer
required:
- enabled
type: object
ownerRef:
description: |-
OwnerRef names the ObjectStoreUser (in this namespace) that owns the
bucket. The owner always has full control; grant additional principals
with BucketAccess objects.
type: string
placementTarget:
description: PlacementTarget optionally selects a non-default placement
target/pool.
type: string
purgeOnDelete:
description: |-
PurgeOnDelete deletes the bucket together with all objects it contains
when the Bucket resource is removed. Dangerous; defaults to false.
type: boolean
quota:
description: Quota optionally applies a bucket-level quota.
properties:
enabled:
default: true
description: |-
Enabled turns the quota on. When false the other fields are ignored and
the quota is disabled on the target.
type: boolean
maxObjects:
description: MaxObjects caps the number of objects. Nil or negative
means unlimited.
format: int64
type: integer
maxSizeBytes:
description: MaxSizeBytes caps the total size in bytes. Nil or
negative means unlimited.
format: int64
type: integer
type: object
retainOnDelete:
description: |-
RetainOnDelete keeps the RGW bucket (and its objects) when the Bucket
resource is deleted. By default the operator removes the empty bucket;
it never purges objects unless PurgeOnDelete is also set.
type: boolean
tags:
additionalProperties:
type: string
description: Tags are bucket tags (key/value) applied to the bucket.
type: object
versioning:
description: Versioning enables S3 object versioning on the bucket.
type: boolean
zonegroup:
description: Zonegroup optionally pins the bucket to a specific RGW
zonegroup.
type: string
required:
- ownerRef
type: object
status:
description: BucketStatus reports observed bucket state.
properties:
adopted:
description: |-
Adopted reports that the RGW bucket already existed when the operator
first reconciled this resource (it was taken over, not created).
type: boolean
bucketID:
description: BucketID is the RGW internal bucket instance id.
type: string
bucketName:
description: BucketName is the provisioned S3 bucket name.
type: string
conditions:
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
observedGeneration:
format: int64
type: integer
owner:
description: Owner is the RGW uid that owns the bucket.
type: string
phase:
description: Phase is a coarse lifecycle summary (Pending/Ready/Error).
type: string
policyPrincipals:
description: |-
PolicyPrincipals is the number of extra principals granted via
BucketAccess and reflected in the bucket policy.
format: int32
type: integer
type: object
type: object
served: true
storage: true
subresources:
status: {}