9da206dc7c
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.
122 lines
2.8 KiB
YAML
122 lines
2.8 KiB
YAML
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
labels:
|
|
app: some-app
|
|
plugin1: some-value
|
|
plugin2: some-value
|
|
plugin3: some-value
|
|
plugin4: some-value
|
|
name: some-name
|
|
namespace: default
|
|
ownerReferences:
|
|
- apiVersion: apps/v1
|
|
blockOwnerDeletion: true
|
|
controller: true
|
|
kind: ReplicaSet
|
|
name: some-name
|
|
uid: 0a9d2b9e-779e-11e7-b422-42010a8001be
|
|
spec:
|
|
containers:
|
|
- args:
|
|
- one
|
|
- two
|
|
- three
|
|
- four
|
|
- five
|
|
- six
|
|
- seven
|
|
- eight
|
|
- nine
|
|
env:
|
|
- name: VAR_3
|
|
valueFrom:
|
|
secretKeyRef:
|
|
key: some-other-key
|
|
name: some-oher-name
|
|
- name: VAR_2
|
|
valueFrom:
|
|
secretKeyRef:
|
|
key: other-key
|
|
name: other-name
|
|
- name: VAR_1
|
|
valueFrom:
|
|
secretKeyRef:
|
|
key: some-key
|
|
name: some-name
|
|
image: some-image-name
|
|
imagePullPolicy: IfNotPresent
|
|
name: some-name
|
|
resources:
|
|
requests:
|
|
cpu: '0'
|
|
terminationMessagePath: /dev/termination-log
|
|
terminationMessagePolicy: File
|
|
volumeMounts:
|
|
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
|
|
name: default-token-hu5jz
|
|
readOnly: true
|
|
dnsPolicy: ClusterFirst
|
|
nodeName: node-name
|
|
priority: 0
|
|
restartPolicy: Always
|
|
schedulerName: default-scheduler
|
|
securityContext: {}
|
|
serviceAccount: default
|
|
serviceAccountName: default
|
|
terminationGracePeriodSeconds: 30
|
|
tolerations:
|
|
- effect: NoExecute
|
|
key: node.kubernetes.io/not-ready
|
|
operator: Exists
|
|
tolerationSeconds: 300
|
|
- effect: NoExecute
|
|
key: node.kubernetes.io/unreachable
|
|
operator: Exists
|
|
tolerationSeconds: 300
|
|
volumes:
|
|
- name: default-token-hu5jz
|
|
secret:
|
|
defaultMode: 420
|
|
secretName: default-token-hu5jz
|
|
status:
|
|
conditions:
|
|
- lastProbeTime: null
|
|
lastTransitionTime: '2019-07-08T09:31:18Z'
|
|
status: 'True'
|
|
type: Initialized
|
|
- lastProbeTime: null
|
|
lastTransitionTime: '2019-07-08T09:41:59Z'
|
|
status: 'True'
|
|
type: Ready
|
|
- lastProbeTime: null
|
|
lastTransitionTime: null
|
|
status: 'True'
|
|
type: ContainersReady
|
|
- lastProbeTime: null
|
|
lastTransitionTime: '2019-07-08T09:31:18Z'
|
|
status: 'True'
|
|
type: PodScheduled
|
|
containerStatuses:
|
|
- containerID: docker://885e82a1ed0b7356541bb410a0126921ac42439607c09875cd8097dd5d7b5376
|
|
image: some-image-name
|
|
imageID: docker-pullable://some-image-id
|
|
lastState:
|
|
terminated:
|
|
containerID: docker://d57290f9e00fad626b20d2dd87a3cf69bbc22edae07985374f86a8b2b4e39565
|
|
exitCode: 255
|
|
finishedAt: '2019-07-08T09:39:09Z'
|
|
reason: Error
|
|
startedAt: '2019-07-08T09:38:54Z'
|
|
name: name
|
|
ready: true
|
|
restartCount: 6
|
|
state:
|
|
running:
|
|
startedAt: '2019-07-08T09:41:59Z'
|
|
hostIP: 10.0.0.1
|
|
phase: Running
|
|
podIP: 10.0.0.1
|
|
qosClass: BestEffort
|
|
startTime: '2019-07-08T09:31:18Z'
|