mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-07-09 19:22:21 +02:00
Compare commits
7 Commits
14f78b6fa6
...
62f2b012aa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62f2b012aa | ||
|
|
3593c18f3f | ||
|
|
e8655233d6 | ||
|
|
12549771f9 | ||
|
|
a8b446faa8 | ||
|
|
27589c0eeb | ||
|
|
6ae101f016 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -44,7 +44,7 @@ jobs:
|
|||||||
- name: Install Dagger
|
- name: Install Dagger
|
||||||
env:
|
env:
|
||||||
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
||||||
DAGGER_VERSION: 0.20.1
|
DAGGER_VERSION: 0.20.4
|
||||||
run: |
|
run: |
|
||||||
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
||||||
- name: Run CI task
|
- name: Run CI task
|
||||||
|
|||||||
2
.github/workflows/release-please.yml
vendored
2
.github/workflows/release-please.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
|||||||
- name: Install Dagger
|
- name: Install Dagger
|
||||||
env:
|
env:
|
||||||
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
||||||
DAGGER_VERSION: 0.20.1
|
DAGGER_VERSION: 0.20.4
|
||||||
run: |
|
run: |
|
||||||
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
||||||
- name: Create image and manifest
|
- name: Create image and manifest
|
||||||
|
|||||||
2
.github/workflows/release-publish.yml
vendored
2
.github/workflows/release-publish.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
|||||||
- name: Install Dagger
|
- name: Install Dagger
|
||||||
env:
|
env:
|
||||||
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
||||||
DAGGER_VERSION: 0.20.1
|
DAGGER_VERSION: 0.20.4
|
||||||
run: |
|
run: |
|
||||||
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
||||||
- name: Create image and manifest
|
- name: Create image and manifest
|
||||||
|
|||||||
27
Taskfile.yml
27
Taskfile.yml
@ -6,6 +6,8 @@ output: prefixed
|
|||||||
|
|
||||||
# Variables that are shared across tasks.
|
# Variables that are shared across tasks.
|
||||||
vars:
|
vars:
|
||||||
|
GO_VERSION:
|
||||||
|
sh: sed -n 's/^toolchain go//p' go.mod
|
||||||
# renovate: datasource=docker depName=kindest/node versioning=semver
|
# renovate: datasource=docker depName=kindest/node versioning=semver
|
||||||
E2E_KUBERNETES_VERSION: v1.35.1
|
E2E_KUBERNETES_VERSION: v1.35.1
|
||||||
E2E_CLUSTER_NAME: barman-cloud-plugin-e2e-{{.E2E_KUBERNETES_VERSION}}
|
E2E_CLUSTER_NAME: barman-cloud-plugin-e2e-{{.E2E_KUBERNETES_VERSION}}
|
||||||
@ -21,7 +23,7 @@ tasks:
|
|||||||
# renovate: datasource=git-refs depName=golangci-lint lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main
|
# renovate: datasource=git-refs depName=golangci-lint lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main
|
||||||
DAGGER_GOLANGCI_LINT_SHA: 5dcc7e4c4cd5ed230046955f42e27f2166545155
|
DAGGER_GOLANGCI_LINT_SHA: 5dcc7e4c4cd5ed230046955f42e27f2166545155
|
||||||
# renovate: datasource=docker depName=golangci/golangci-lint versioning=semver
|
# renovate: datasource=docker depName=golangci/golangci-lint versioning=semver
|
||||||
GOLANGCI_LINT_VERSION: v2.11.2
|
GOLANGCI_LINT_VERSION: v2.11.4
|
||||||
cmds:
|
cmds:
|
||||||
- >
|
- >
|
||||||
GITHUB_REF= dagger -sc "github.com/sagikazarmark/daggerverse/golangci-lint@${DAGGER_GOLANGCI_LINT_SHA}
|
GITHUB_REF= dagger -sc "github.com/sagikazarmark/daggerverse/golangci-lint@${DAGGER_GOLANGCI_LINT_SHA}
|
||||||
@ -128,8 +130,6 @@ tasks:
|
|||||||
go-test:
|
go-test:
|
||||||
desc: Run go test
|
desc: Run go test
|
||||||
env:
|
env:
|
||||||
# renovate: datasource=docker depName=golang versioning=semver
|
|
||||||
GOLANG_IMAGE_VERSION: 1.26.1
|
|
||||||
# renovate: datasource=git-refs depname=kubernetes packageName=https://github.com/kubernetes/kubernetes versioning=semver
|
# renovate: datasource=git-refs depname=kubernetes packageName=https://github.com/kubernetes/kubernetes versioning=semver
|
||||||
K8S_VERSION: 1.31.0
|
K8S_VERSION: 1.31.0
|
||||||
# renovate: datasource=git-refs depName=controller-runtime packageName=https://github.com/kubernetes-sigs/controller-runtime versioning=semver
|
# renovate: datasource=git-refs depName=controller-runtime packageName=https://github.com/kubernetes-sigs/controller-runtime versioning=semver
|
||||||
@ -137,7 +137,7 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- >
|
- >
|
||||||
GITHUB_REF= dagger -s call -m ./dagger/gotest
|
GITHUB_REF= dagger -s call -m ./dagger/gotest
|
||||||
--go-version ${GOLANG_IMAGE_VERSION}
|
--go-version {{.GO_VERSION}}
|
||||||
--kube-version ${K8S_VERSION}
|
--kube-version ${K8S_VERSION}
|
||||||
--setup-envtest-version ${SETUP_ENVTEST_VERSION}
|
--setup-envtest-version ${SETUP_ENVTEST_VERSION}
|
||||||
unit-test --src .
|
unit-test --src .
|
||||||
@ -206,7 +206,7 @@ tasks:
|
|||||||
- start-build-network
|
- start-build-network
|
||||||
vars:
|
vars:
|
||||||
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
||||||
DAGGER_VERSION: 0.20.1
|
DAGGER_VERSION: 0.20.4
|
||||||
DAGGER_ENGINE_IMAGE: registry.dagger.io/engine:v{{ .DAGGER_VERSION }}
|
DAGGER_ENGINE_IMAGE: registry.dagger.io/engine:v{{ .DAGGER_VERSION }}
|
||||||
cmds:
|
cmds:
|
||||||
- >
|
- >
|
||||||
@ -231,7 +231,7 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- >
|
- >
|
||||||
GITHUB_REF= dagger -s call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
GITHUB_REF= dagger -s call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
||||||
build --dir . --file containers/Dockerfile.plugin --platform linux/amd64
|
build --dir . --file containers/Dockerfile.plugin --args GO_VERSION={{.GO_VERSION}} --platform linux/amd64
|
||||||
publish --ref {{ .REGISTRY_NAME }}:{{ .REGISTRY_PORT }}/plugin-barman-cloud --tags testing
|
publish --ref {{ .REGISTRY_NAME }}:{{ .REGISTRY_PORT }}/plugin-barman-cloud --tags testing
|
||||||
|
|
||||||
# We build an image and push it to a local registry.
|
# We build an image and push it to a local registry.
|
||||||
@ -248,7 +248,7 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- >
|
- >
|
||||||
GITHUB_REF= dagger -s call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
GITHUB_REF= dagger -s call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
||||||
build --dir . --file containers/Dockerfile.sidecar --platform linux/amd64
|
build --dir . --file containers/Dockerfile.sidecar --args GO_VERSION={{.GO_VERSION}} --platform linux/amd64
|
||||||
publish --ref {{ .REGISTRY_NAME }}:{{ .REGISTRY_PORT }}/sidecar-barman-cloud --tags testing
|
publish --ref {{ .REGISTRY_NAME }}:{{ .REGISTRY_PORT }}/sidecar-barman-cloud --tags testing
|
||||||
|
|
||||||
build-images:
|
build-images:
|
||||||
@ -305,8 +305,6 @@ tasks:
|
|||||||
- build-images
|
- build-images
|
||||||
- start-kind-cluster
|
- start-kind-cluster
|
||||||
vars:
|
vars:
|
||||||
# renovate: datasource=docker depName=golang versioning=semver
|
|
||||||
GOLANG_IMAGE_VERSION: 1.26.1
|
|
||||||
KUBECONFIG_PATH:
|
KUBECONFIG_PATH:
|
||||||
sh: mktemp -t kubeconfig-XXXXX
|
sh: mktemp -t kubeconfig-XXXXX
|
||||||
env:
|
env:
|
||||||
@ -317,15 +315,12 @@ tasks:
|
|||||||
GITHUB_REF= dagger call -m dagger/e2e/ run
|
GITHUB_REF= dagger call -m dagger/e2e/ run
|
||||||
--source .
|
--source .
|
||||||
--kubeconfig {{.KUBECONFIG_PATH}}
|
--kubeconfig {{.KUBECONFIG_PATH}}
|
||||||
--go-version {{ .GOLANG_IMAGE_VERSION }}
|
--go-version {{.GO_VERSION}}
|
||||||
|
|
||||||
e2e-ephemeral:
|
e2e-ephemeral:
|
||||||
desc: Run e2e tests in an ephemeral k3s cluster
|
desc: Run e2e tests in an ephemeral k3s cluster
|
||||||
deps:
|
deps:
|
||||||
- build-images
|
- build-images
|
||||||
vars:
|
|
||||||
# renovate: datasource=docker depName=golang versioning=semver
|
|
||||||
GOLANG_IMAGE_VERSION: 1.26.1
|
|
||||||
env:
|
env:
|
||||||
_EXPERIMENTAL_DAGGER_RUNNER_HOST: docker-container://{{ .DAGGER_ENGINE_CONTAINER_NAME }}
|
_EXPERIMENTAL_DAGGER_RUNNER_HOST: docker-container://{{ .DAGGER_ENGINE_CONTAINER_NAME }}
|
||||||
cmds:
|
cmds:
|
||||||
@ -334,7 +329,7 @@ tasks:
|
|||||||
--source .
|
--source .
|
||||||
--ca certs/ca.pem
|
--ca certs/ca.pem
|
||||||
--registry {{.REGISTRY_NAME}}:{{.REGISTRY_PORT}}
|
--registry {{.REGISTRY_NAME}}:{{.REGISTRY_PORT}}
|
||||||
--go-version {{ .GOLANG_IMAGE_VERSION }}
|
--go-version {{.GO_VERSION}}
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
desc: Run the CI pipeline
|
desc: Run the CI pipeline
|
||||||
@ -373,12 +368,12 @@ tasks:
|
|||||||
- >
|
- >
|
||||||
dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
||||||
--registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD
|
--registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD
|
||||||
build --dir . --file containers/Dockerfile.plugin --platform linux/amd64 --platform linux/arm64
|
build --dir . --file containers/Dockerfile.plugin --args GO_VERSION={{.GO_VERSION}} --platform linux/amd64 --platform linux/arm64
|
||||||
publish --ref {{.PLUGIN_IMAGE_NAME}} --tags {{.IMAGE_VERSION}}
|
publish --ref {{.PLUGIN_IMAGE_NAME}} --tags {{.IMAGE_VERSION}}
|
||||||
- >
|
- >
|
||||||
dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
dagger call -m github.com/purpleclay/daggerverse/docker@${DAGGER_DOCKER_SHA}
|
||||||
--registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD
|
--registry ghcr.io --username $REGISTRY_USER --password env:REGISTRY_PASSWORD
|
||||||
build --dir . --file containers/Dockerfile.sidecar --platform linux/amd64 --platform linux/arm64
|
build --dir . --file containers/Dockerfile.sidecar --args GO_VERSION={{.GO_VERSION}} --platform linux/amd64 --platform linux/arm64
|
||||||
publish --ref {{.SIDECAR_IMAGE_NAME}} --tags {{.IMAGE_VERSION}}
|
publish --ref {{.SIDECAR_IMAGE_NAME}} --tags {{.IMAGE_VERSION}}
|
||||||
|
|
||||||
controller-gen:
|
controller-gen:
|
||||||
|
|||||||
@ -44,6 +44,7 @@ rules:
|
|||||||
- postgresql.cnpg.io
|
- postgresql.cnpg.io
|
||||||
resources:
|
resources:
|
||||||
- backups
|
- backups
|
||||||
|
- clusters
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
# Build the manager binary
|
# Build the manager binary
|
||||||
FROM --platform=$BUILDPLATFORM golang:1.26.1 AS gobuilder
|
# GO_VERSION must be passed as a build arg (read from go.mod toolchain directive by Taskfile)
|
||||||
|
ARG GO_VERSION
|
||||||
|
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS gobuilder
|
||||||
ARG TARGETOS
|
ARG TARGETOS
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,9 @@
|
|||||||
# Both components are built before going into a distroless container
|
# Both components are built before going into a distroless container
|
||||||
|
|
||||||
# Build the manager binary
|
# Build the manager binary
|
||||||
FROM --platform=$BUILDPLATFORM golang:1.26.1 AS gobuilder
|
# GO_VERSION must be passed as a build arg (read from go.mod toolchain directive by Taskfile)
|
||||||
|
ARG GO_VERSION
|
||||||
|
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} AS gobuilder
|
||||||
ARG TARGETOS
|
ARG TARGETOS
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
barman[azure,cloud,google,snappy,zstandard,lz4]==3.17.0
|
barman[azure,cloud,google,snappy,zstandard,lz4]==3.18.0
|
||||||
setuptools==82.0.1
|
setuptools==82.0.1
|
||||||
zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability
|
zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability
|
||||||
|
|||||||
@ -18,9 +18,9 @@ azure-storage-blob==12.28.0 \
|
|||||||
--hash=sha256:00fb1db28bf6a7b7ecaa48e3b1d5c83bfadacc5a678b77826081304bd87d6461 \
|
--hash=sha256:00fb1db28bf6a7b7ecaa48e3b1d5c83bfadacc5a678b77826081304bd87d6461 \
|
||||||
--hash=sha256:e7d98ea108258d29aa0efbfd591b2e2075fa1722a2fae8699f0b3c9de11eff41
|
--hash=sha256:e7d98ea108258d29aa0efbfd591b2e2075fa1722a2fae8699f0b3c9de11eff41
|
||||||
# via barman
|
# via barman
|
||||||
barman==3.17.0 \
|
barman==3.18.0 \
|
||||||
--hash=sha256:07b033da14e72f103de44261c31bd0c3169bbb2e4de3481c6bb3510e9870d38e \
|
--hash=sha256:8e752ac93d2f3a61e86b8374185209cae477a638ece7e6f540070f36d28d6997 \
|
||||||
--hash=sha256:d6618990a6dbb31af3286d746a278a038534b7e3cc617c2b379ef7ebdeb7ed5a
|
--hash=sha256:ff90c44dafa4107b7574142771cdc2611c4cf1af818d93d3e67440a0c81164b9
|
||||||
# via -r sidecar-requirements.in
|
# via -r sidecar-requirements.in
|
||||||
boto3==1.42.63 \
|
boto3==1.42.63 \
|
||||||
--hash=sha256:cd008cfd0d7ea30f1c5e22daf0998c55b7c6c68cb68eea05110e33fe641173d5 \
|
--hash=sha256:cd008cfd0d7ea30f1c5e22daf0998c55b7c6c68cb68eea05110e33fe641173d5 \
|
||||||
|
|||||||
49
go.mod
49
go.mod
@ -5,23 +5,23 @@ go 1.25.0
|
|||||||
toolchain go1.26.1
|
toolchain go1.26.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cert-manager/cert-manager v1.19.4
|
github.com/cert-manager/cert-manager v1.20.1
|
||||||
github.com/cloudnative-pg/api v1.28.1
|
github.com/cloudnative-pg/api v1.28.1
|
||||||
github.com/cloudnative-pg/barman-cloud v0.5.0
|
github.com/cloudnative-pg/barman-cloud v0.5.0
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.28.1
|
github.com/cloudnative-pg/cloudnative-pg v1.29.0
|
||||||
github.com/cloudnative-pg/cnpg-i v0.3.1
|
github.com/cloudnative-pg/cnpg-i v0.5.0
|
||||||
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
|
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
|
||||||
github.com/cloudnative-pg/machinery v0.3.3
|
github.com/cloudnative-pg/machinery v0.3.3
|
||||||
github.com/onsi/ginkgo/v2 v2.28.1
|
github.com/onsi/ginkgo/v2 v2.28.1
|
||||||
github.com/onsi/gomega v1.39.1
|
github.com/onsi/gomega v1.39.1
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
github.com/spf13/viper v1.21.0
|
github.com/spf13/viper v1.21.0
|
||||||
google.golang.org/grpc v1.79.3
|
google.golang.org/grpc v1.80.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
k8s.io/api v0.35.2
|
k8s.io/api v0.35.3
|
||||||
k8s.io/apiextensions-apiserver v0.35.2
|
k8s.io/apiextensions-apiserver v0.35.3
|
||||||
k8s.io/apimachinery v0.35.2
|
k8s.io/apimachinery v0.35.3
|
||||||
k8s.io/client-go v0.35.2
|
k8s.io/client-go v0.35.3
|
||||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2
|
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2
|
||||||
sigs.k8s.io/controller-runtime v0.23.3
|
sigs.k8s.io/controller-runtime v0.23.3
|
||||||
sigs.k8s.io/kustomize/api v0.21.1
|
sigs.k8s.io/kustomize/api v0.21.1
|
||||||
@ -32,6 +32,7 @@ require (
|
|||||||
cel.dev/expr v0.25.1 // indirect
|
cel.dev/expr v0.25.1 // indirect
|
||||||
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||||
|
github.com/avast/retry-go/v5 v5.0.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||||
@ -74,7 +75,7 @@ require (
|
|||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 // indirect
|
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 // indirect
|
||||||
github.com/lib/pq v1.11.1 // indirect
|
github.com/lib/pq v1.12.0 // indirect
|
||||||
github.com/moby/spdystream v0.5.0 // indirect
|
github.com/moby/spdystream v0.5.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||||
@ -113,29 +114,29 @@ require (
|
|||||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect
|
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect
|
||||||
golang.org/x/mod v0.32.0 // indirect
|
golang.org/x/mod v0.33.0 // indirect
|
||||||
golang.org/x/net v0.49.0 // indirect
|
golang.org/x/net v0.52.0 // indirect
|
||||||
golang.org/x/oauth2 v0.34.0 // indirect
|
golang.org/x/oauth2 v0.35.0 // indirect
|
||||||
golang.org/x/sync v0.19.0 // indirect
|
golang.org/x/sync v0.20.0 // indirect
|
||||||
golang.org/x/sys v0.42.0 // indirect
|
golang.org/x/sys v0.42.0 // indirect
|
||||||
golang.org/x/term v0.39.0 // indirect
|
golang.org/x/term v0.41.0 // indirect
|
||||||
golang.org/x/text v0.33.0 // indirect
|
golang.org/x/text v0.35.0 // indirect
|
||||||
golang.org/x/time v0.14.0 // indirect
|
golang.org/x/time v0.14.0 // indirect
|
||||||
golang.org/x/tools v0.41.0 // indirect
|
golang.org/x/tools v0.42.0 // indirect
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect
|
||||||
google.golang.org/protobuf v1.36.11 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
k8s.io/apiserver v0.35.2 // indirect
|
k8s.io/apiserver v0.35.3 // indirect
|
||||||
k8s.io/component-base v0.35.2 // indirect
|
k8s.io/component-base v0.35.3 // indirect
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
k8s.io/klog/v2 v2.140.0 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // indirect
|
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 // indirect
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 // indirect
|
||||||
sigs.k8s.io/gateway-api v1.4.0 // indirect
|
sigs.k8s.io/gateway-api v1.5.0 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
|
||||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
102
go.sum
102
go.sum
@ -6,24 +6,26 @@ github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYW
|
|||||||
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
|
github.com/avast/retry-go/v5 v5.0.0 h1:kf1Qc2UsTZ4qq8elDymqfbISvkyMuhgRxuJqX2NHP7k=
|
||||||
|
github.com/avast/retry-go/v5 v5.0.0/go.mod h1://d+usmKWio1agtZfS1H/ltTqwtIfBnRq9zEwjc3eH8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||||
github.com/cert-manager/cert-manager v1.19.4 h1:7lOkSYj+nJNjgGFfAznQzPpOfWX+1Kgz6xUXwTa/K5k=
|
github.com/cert-manager/cert-manager v1.20.1 h1:99ExHJu5TPp1V92AvvE4oY6BkOSyJiWLxxMkbqbdGaY=
|
||||||
github.com/cert-manager/cert-manager v1.19.4/go.mod h1:9uBnn3IK9NxjjuXmQDYhwOwFUU5BtGVB1g/voPvvcVw=
|
github.com/cert-manager/cert-manager v1.20.1/go.mod h1:ut67FnggYJJqAdDWLhSPnj10P06QwbNU88RYNh9MvMc=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cloudnative-pg/api v1.28.1 h1:hp/TDgR+RrTa4EMp/pAKZia+kZ52i8ZPLG+JG10eeVU=
|
github.com/cloudnative-pg/api v1.28.1 h1:hp/TDgR+RrTa4EMp/pAKZia+kZ52i8ZPLG+JG10eeVU=
|
||||||
github.com/cloudnative-pg/api v1.28.1/go.mod h1:J0RTwrOYxQP17N1YMrDxcUmr/0wPYHQW179P7ibkVsM=
|
github.com/cloudnative-pg/api v1.28.1/go.mod h1:J0RTwrOYxQP17N1YMrDxcUmr/0wPYHQW179P7ibkVsM=
|
||||||
github.com/cloudnative-pg/barman-cloud v0.5.0 h1:DykSaX4o7ee2vyu5FQoG1RJsntHd+EIttIKZbJPlB1Q=
|
github.com/cloudnative-pg/barman-cloud v0.5.0 h1:DykSaX4o7ee2vyu5FQoG1RJsntHd+EIttIKZbJPlB1Q=
|
||||||
github.com/cloudnative-pg/barman-cloud v0.5.0/go.mod h1:SO2HzLa+GWlSIpGyxnISoJAFPIcaa/qDa33Bb3jefac=
|
github.com/cloudnative-pg/barman-cloud v0.5.0/go.mod h1:SO2HzLa+GWlSIpGyxnISoJAFPIcaa/qDa33Bb3jefac=
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.28.1 h1:HdOUWgFhta558uHfXeO/199qCApxaj5yi05x6nWNmgs=
|
github.com/cloudnative-pg/cloudnative-pg v1.29.0 h1:49Dm8+y4va7RODspJjeaK8uMWP3OGAD0gMsxhjm16Mo=
|
||||||
github.com/cloudnative-pg/cloudnative-pg v1.28.1/go.mod h1:yhRa4GqJAjNd0tT9AiRgk1KdqLhMjo/JmGGoASRl2CU=
|
github.com/cloudnative-pg/cloudnative-pg v1.29.0/go.mod h1:0Sgb/50VyaCnQm3IbWqgnhQG8Kb6mgqo8Jo1J+KtkSI=
|
||||||
github.com/cloudnative-pg/cnpg-i v0.3.1 h1:fKj8NoToWI11HUL2UWYJBpkVzmaTvbs3kDMo7wQF8RU=
|
github.com/cloudnative-pg/cnpg-i v0.5.0 h1:/TOzpNT6cwNgrpftTtrnLKdoHgMwd+88vZgXjlVgXeE=
|
||||||
github.com/cloudnative-pg/cnpg-i v0.3.1/go.mod h1:glRDiJLJY51FY8ScJIv/OkaGJxFnojJkkNAqSy5XC6s=
|
github.com/cloudnative-pg/cnpg-i v0.5.0/go.mod h1:7Gh4+UzhBpGhr4DreB1GN9wGYfvxwXCXZUyVt3zE/3I=
|
||||||
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2 h1:0reS9MtyLYINHXQ/MfxJ9jp39hhBf8e3Qdj+T5Nsq6I=
|
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2 h1:0reS9MtyLYINHXQ/MfxJ9jp39hhBf8e3Qdj+T5Nsq6I=
|
||||||
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2/go.mod h1:gvrKabgxXq0zGthXGucemDdsxakLEQDMxn43M4HLW30=
|
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2/go.mod h1:gvrKabgxXq0zGthXGucemDdsxakLEQDMxn43M4HLW30=
|
||||||
github.com/cloudnative-pg/machinery v0.3.3 h1:CaqXqLTJH9RrVv3R/YU0NmFaI/F18HLg2JfH3mQLcDk=
|
github.com/cloudnative-pg/machinery v0.3.3 h1:CaqXqLTJH9RrVv3R/YU0NmFaI/F18HLg2JfH3mQLcDk=
|
||||||
@ -143,8 +145,8 @@ github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 h1:bMqrb3UHgHbP+
|
|||||||
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0/go.mod h1:E3vdYxHj2C2q6qo8/Da4g7P+IcwqRZyy3gJBzYybV9Y=
|
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0/go.mod h1:E3vdYxHj2C2q6qo8/Da4g7P+IcwqRZyy3gJBzYybV9Y=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/lib/pq v1.11.1 h1:wuChtj2hfsGmmx3nf1m7xC2XpK6OtelS2shMY+bGMtI=
|
github.com/lib/pq v1.12.0 h1:mC1zeiNamwKBecjHarAr26c/+d8V5w/u4J0I/yASbJo=
|
||||||
github.com/lib/pq v1.11.1/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
|
github.com/lib/pq v1.12.0/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
|
||||||
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
||||||
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||||
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
|
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
|
||||||
@ -269,34 +271,34 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
|||||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4=
|
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4=
|
||||||
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=
|
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=
|
||||||
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
|
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||||
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
|
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
|
||||||
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
|
||||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||||
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
|
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
|
||||||
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
|
||||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@ -310,30 +312,30 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
k8s.io/api v0.35.2 h1:tW7mWc2RpxW7HS4CoRXhtYHSzme1PN1UjGHJ1bdrtdw=
|
k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ=
|
||||||
k8s.io/api v0.35.2/go.mod h1:7AJfqGoAZcwSFhOjcGM7WV05QxMMgUaChNfLTXDRE60=
|
k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4=
|
||||||
k8s.io/apiextensions-apiserver v0.35.2 h1:iyStXHoJZsUXPh/nFAsjC29rjJWdSgUmG1XpApE29c0=
|
k8s.io/apiextensions-apiserver v0.35.3 h1:2fQUhEO7P17sijylbdwt0nBdXP0TvHrHj0KeqHD8FiU=
|
||||||
k8s.io/apiextensions-apiserver v0.35.2/go.mod h1:OdyGvcO1FtMDWQ+rRh/Ei3b6X3g2+ZDHd0MSRGeS8rU=
|
k8s.io/apiextensions-apiserver v0.35.3/go.mod h1:tK4Kz58ykRpwAEkXUb634HD1ZAegEElktz/B3jgETd8=
|
||||||
k8s.io/apimachinery v0.35.2 h1:NqsM/mmZA7sHW02JZ9RTtk3wInRgbVxL8MPfzSANAK8=
|
k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8=
|
||||||
k8s.io/apimachinery v0.35.2/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
||||||
k8s.io/apiserver v0.35.2 h1:rb52v0CZGEL0FkhjS+I6jHflAp7fZ4MIaKcEHX7wmDk=
|
k8s.io/apiserver v0.35.3 h1:D2eIcfJ05hEAEewoSDg+05e0aSRwx8Y4Agvd/wiomUI=
|
||||||
k8s.io/apiserver v0.35.2/go.mod h1:CROJUAu0tfjZLyYgSeBsBan2T7LUJGh0ucWwTCSSk7g=
|
k8s.io/apiserver v0.35.3/go.mod h1:JI0n9bHYzSgIxgIrfe21dbduJ9NHzKJ6RchcsmIKWKY=
|
||||||
k8s.io/client-go v0.35.2 h1:YUfPefdGJA4aljDdayAXkc98DnPkIetMl4PrKX97W9o=
|
k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg=
|
||||||
k8s.io/client-go v0.35.2/go.mod h1:4QqEwh4oQpeK8AaefZ0jwTFJw/9kIjdQi0jpKeYvz7g=
|
k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c=
|
||||||
k8s.io/component-base v0.35.2 h1:btgR+qNrpWuRSuvWSnQYsZy88yf5gVwemvz0yw79pGc=
|
k8s.io/component-base v0.35.3 h1:mbKbzoIMy7JDWS/wqZobYW1JDVRn/RKRaoMQHP9c4P0=
|
||||||
k8s.io/component-base v0.35.2/go.mod h1:B1iBJjooe6xIJYUucAxb26RwhAjzx0gHnqO9htWIX+0=
|
k8s.io/component-base v0.35.3/go.mod h1:IZ8LEG30kPN4Et5NeC7vjNv5aU73ku5MS15iZyvyMYk=
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
|
||||||
k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ=
|
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY=
|
||||||
k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
|
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
|
||||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 h1:qPrZsv1cwQiFeieFlRqT627fVZ+tyfou/+S5S0H5ua0=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 h1:qPrZsv1cwQiFeieFlRqT627fVZ+tyfou/+S5S0H5ua0=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
||||||
sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
|
sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
|
||||||
sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
|
sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
|
||||||
sigs.k8s.io/gateway-api v1.4.0 h1:ZwlNM6zOHq0h3WUX2gfByPs2yAEsy/EenYJB78jpQfQ=
|
sigs.k8s.io/gateway-api v1.5.0 h1:duoo14Ky/fJXpjpmyMISE2RTBGnfCg8zICfTYLTnBJA=
|
||||||
sigs.k8s.io/gateway-api v1.4.0/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk=
|
sigs.k8s.io/gateway-api v1.5.0/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o=
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||||
sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs=
|
sigs.k8s.io/kustomize/api v0.21.1 h1:lzqbzvz2CSvsjIUZUBNFKtIMsEw7hVLJp0JeSIVmuJs=
|
||||||
@ -342,7 +344,7 @@ sigs.k8s.io/kustomize/kyaml v0.21.1 h1:IVlbmhC076nf6foyL6Taw4BkrLuEsXUXNpsE+ScX7
|
|||||||
sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ=
|
sigs.k8s.io/kustomize/kyaml v0.21.1/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ=
|
||||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||||
|
|||||||
@ -102,6 +102,8 @@ func NewCmd() *cobra.Command {
|
|||||||
_ = viper.BindPFlag("server-address", cmd.Flags().Lookup("server-address"))
|
_ = viper.BindPFlag("server-address", cmd.Flags().Lookup("server-address"))
|
||||||
|
|
||||||
_ = viper.BindEnv("sidecar-image", "SIDECAR_IMAGE")
|
_ = viper.BindEnv("sidecar-image", "SIDECAR_IMAGE")
|
||||||
|
_ = viper.BindEnv("custom-cnpg-group", "CUSTOM_CNPG_GROUP")
|
||||||
|
_ = viper.BindEnv("custom-cnpg-version", "CUSTOM_CNPG_VERSION")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,6 +57,8 @@ func NewCmd() *cobra.Command {
|
|||||||
_ = viper.BindEnv("pod-name", "POD_NAME")
|
_ = viper.BindEnv("pod-name", "POD_NAME")
|
||||||
_ = viper.BindEnv("pgdata", "PGDATA")
|
_ = viper.BindEnv("pgdata", "PGDATA")
|
||||||
_ = viper.BindEnv("spool-directory", "SPOOL_DIRECTORY")
|
_ = viper.BindEnv("spool-directory", "SPOOL_DIRECTORY")
|
||||||
|
_ = viper.BindEnv("custom-cnpg-group", "CUSTOM_CNPG_GROUP")
|
||||||
|
_ = viper.BindEnv("custom-cnpg-version", "CUSTOM_CNPG_VERSION")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,16 +28,15 @@ import (
|
|||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
extendedclient "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/instance/internal/client"
|
extendedclient "github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/instance/internal/client"
|
||||||
|
pluginscheme "github.com/cloudnative-pg/plugin-barman-cloud/internal/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start starts the sidecar informers and CNPG-i server
|
// Start starts the sidecar informers and CNPG-i server
|
||||||
@ -127,26 +126,7 @@ func generateScheme(ctx context.Context) *runtime.Scheme {
|
|||||||
|
|
||||||
utilruntime.Must(barmancloudv1.AddToScheme(result))
|
utilruntime.Must(barmancloudv1.AddToScheme(result))
|
||||||
utilruntime.Must(clientgoscheme.AddToScheme(result))
|
utilruntime.Must(clientgoscheme.AddToScheme(result))
|
||||||
|
pluginscheme.AddCNPGToScheme(ctx, result)
|
||||||
cnpgGroup := viper.GetString("custom-cnpg-group")
|
|
||||||
cnpgVersion := viper.GetString("custom-cnpg-version")
|
|
||||||
if len(cnpgGroup) == 0 {
|
|
||||||
cnpgGroup = cnpgv1.SchemeGroupVersion.Group
|
|
||||||
}
|
|
||||||
if len(cnpgVersion) == 0 {
|
|
||||||
cnpgVersion = cnpgv1.SchemeGroupVersion.Version
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proceed with custom registration of the CNPG scheme
|
|
||||||
schemeGroupVersion := schema.GroupVersion{Group: cnpgGroup, Version: cnpgVersion}
|
|
||||||
schemeBuilder := &scheme.Builder{GroupVersion: schemeGroupVersion}
|
|
||||||
schemeBuilder.Register(&cnpgv1.Cluster{}, &cnpgv1.ClusterList{})
|
|
||||||
schemeBuilder.Register(&cnpgv1.Backup{}, &cnpgv1.BackupList{})
|
|
||||||
schemeBuilder.Register(&cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{})
|
|
||||||
utilruntime.Must(schemeBuilder.AddToScheme(result))
|
|
||||||
|
|
||||||
schemeLog := log.FromContext(ctx)
|
|
||||||
schemeLog.Info("CNPG types registration", "schemeGroupVersion", schemeGroupVersion)
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,6 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
|
||||||
// +kubebuilder:scaffold:imports
|
// +kubebuilder:scaffold:imports
|
||||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
|
||||||
"github.com/cloudnative-pg/machinery/pkg/log"
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@ -38,25 +37,33 @@ import (
|
|||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/controller"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/controller"
|
||||||
|
pluginscheme "github.com/cloudnative-pg/plugin-barman-cloud/internal/scheme"
|
||||||
|
|
||||||
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
|
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
|
||||||
// to ensure that exec-entrypoint and run can make use of them.
|
// to ensure that exec-entrypoint and run can make use of them.
|
||||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
var scheme = runtime.NewScheme()
|
// generateScheme creates a runtime.Scheme with all type definitions
|
||||||
|
// needed by the operator. CNPG types are registered under a
|
||||||
|
// configurable API group to support custom CNPG-based operators.
|
||||||
|
func generateScheme(ctx context.Context) *runtime.Scheme {
|
||||||
|
result := runtime.NewScheme()
|
||||||
|
|
||||||
func init() {
|
utilruntime.Must(clientgoscheme.AddToScheme(result))
|
||||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
utilruntime.Must(barmancloudv1.AddToScheme(result))
|
||||||
utilruntime.Must(barmancloudv1.AddToScheme(scheme))
|
pluginscheme.AddCNPGToScheme(ctx, result)
|
||||||
utilruntime.Must(cnpgv1.AddToScheme(scheme))
|
|
||||||
// +kubebuilder:scaffold:scheme
|
// +kubebuilder:scaffold:scheme
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the manager
|
// Start starts the manager
|
||||||
func Start(ctx context.Context) error {
|
func Start(ctx context.Context) error {
|
||||||
setupLog := log.FromContext(ctx)
|
setupLog := log.FromContext(ctx)
|
||||||
|
|
||||||
|
scheme := generateScheme(ctx)
|
||||||
|
|
||||||
var tlsOpts []func(*tls.Config)
|
var tlsOpts []func(*tls.Config)
|
||||||
|
|
||||||
// if the enable-http2 flag is false (the default), http/2 should be disabled
|
// if the enable-http2 flag is false (the default), http/2 should be disabled
|
||||||
|
|||||||
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright © contributors to CloudNativePG, established as
|
|
||||||
CloudNativePG a Series of LF Projects, LLC.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package operator
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/utils/ptr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// setOwnerReference explicitly set the owner reference between an
|
|
||||||
// owner object and a controller one.
|
|
||||||
//
|
|
||||||
// Important: this function won't use any registered scheme and will
|
|
||||||
// fail unless the metadata has been correctly set into the owner
|
|
||||||
// object.
|
|
||||||
func setOwnerReference(owner, controlled metav1.Object) error {
|
|
||||||
ro, ok := owner.(runtime.Object)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("%T is not a runtime.Object, cannot call setOwnerReference", owner)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ro.DeepCopyObject().GetObjectKind().GroupVersionKind().Group) == 0 {
|
|
||||||
return fmt.Errorf("%T metadata have not been set, cannot call setOwnerReference", owner)
|
|
||||||
}
|
|
||||||
|
|
||||||
controlled.SetOwnerReferences([]metav1.OwnerReference{
|
|
||||||
{
|
|
||||||
APIVersion: ro.GetObjectKind().GroupVersionKind().GroupVersion().String(),
|
|
||||||
Kind: ro.GetObjectKind().GroupVersionKind().Kind,
|
|
||||||
Name: owner.GetName(),
|
|
||||||
UID: owner.GetUID(),
|
|
||||||
BlockOwnerDeletion: ptr.To(true),
|
|
||||||
Controller: ptr.To(true),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
158
internal/cnpgi/operator/rbac/ensure.go
Normal file
158
internal/cnpgi/operator/rbac/ensure.go
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
Copyright © contributors to CloudNativePG, established as
|
||||||
|
CloudNativePG a Series of LF Projects, LLC.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package rbac contains utilities to reconcile RBAC resources
|
||||||
|
// for the barman-cloud plugin.
|
||||||
|
package rbac
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||||
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/equality"
|
||||||
|
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
|
|
||||||
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/specs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EnsureRole ensures the RBAC Role for the given Cluster matches
|
||||||
|
// the desired state derived from the given ObjectStores. On creation,
|
||||||
|
// the Cluster is set as the owner of the Role for garbage collection.
|
||||||
|
//
|
||||||
|
// This function is called from both the Pre hook (gRPC) and the
|
||||||
|
// ObjectStore controller. To handle concurrent modifications
|
||||||
|
// gracefully, AlreadyExists on Create and Conflict on Patch are
|
||||||
|
// retried once rather than returned as errors.
|
||||||
|
func EnsureRole(
|
||||||
|
ctx context.Context,
|
||||||
|
c client.Client,
|
||||||
|
cluster *cnpgv1.Cluster,
|
||||||
|
barmanObjects []barmancloudv1.ObjectStore,
|
||||||
|
) error {
|
||||||
|
newRole := specs.BuildRole(cluster, barmanObjects)
|
||||||
|
|
||||||
|
roleKey := client.ObjectKey{
|
||||||
|
Namespace: newRole.Namespace,
|
||||||
|
Name: newRole.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
var role rbacv1.Role
|
||||||
|
err := c.Get(ctx, roleKey, &role)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case apierrs.IsNotFound(err):
|
||||||
|
role, err := createRole(ctx, c, cluster, newRole)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if role == nil {
|
||||||
|
// Created successfully, nothing else to do.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// AlreadyExists: fall through to patch with the re-read role.
|
||||||
|
return patchRoleRules(ctx, c, newRole.Rules, role)
|
||||||
|
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
|
||||||
|
default:
|
||||||
|
return patchRoleRules(ctx, c, newRole.Rules, &role)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// createRole attempts to create the Role. If another writer created
|
||||||
|
// it concurrently (AlreadyExists), it re-reads and returns the
|
||||||
|
// existing Role for the caller to patch. On success it returns nil.
|
||||||
|
func createRole(
|
||||||
|
ctx context.Context,
|
||||||
|
c client.Client,
|
||||||
|
cluster *cnpgv1.Cluster,
|
||||||
|
newRole *rbacv1.Role,
|
||||||
|
) (*rbacv1.Role, error) {
|
||||||
|
contextLogger := log.FromContext(ctx)
|
||||||
|
|
||||||
|
if err := controllerutil.SetControllerReference(cluster, newRole, c.Scheme()); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
contextLogger.Info("Creating role",
|
||||||
|
"name", newRole.Name, "namespace", newRole.Namespace)
|
||||||
|
|
||||||
|
createErr := c.Create(ctx, newRole)
|
||||||
|
if createErr == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if !apierrs.IsAlreadyExists(createErr) {
|
||||||
|
return nil, createErr
|
||||||
|
}
|
||||||
|
|
||||||
|
contextLogger.Info("Role was created concurrently, checking rules")
|
||||||
|
|
||||||
|
var role rbacv1.Role
|
||||||
|
if err := c.Get(ctx, client.ObjectKeyFromObject(newRole), &role); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &role, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// patchRoleRules patches the Role's rules if they differ from the
|
||||||
|
// desired state. On Conflict (concurrent modification), it retries
|
||||||
|
// once with a fresh read.
|
||||||
|
func patchRoleRules(
|
||||||
|
ctx context.Context,
|
||||||
|
c client.Client,
|
||||||
|
desiredRules []rbacv1.PolicyRule,
|
||||||
|
role *rbacv1.Role,
|
||||||
|
) error {
|
||||||
|
if equality.Semantic.DeepEqual(desiredRules, role.Rules) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
contextLogger := log.FromContext(ctx)
|
||||||
|
contextLogger.Info("Patching role",
|
||||||
|
"name", role.Name, "namespace", role.Namespace, "rules", desiredRules)
|
||||||
|
|
||||||
|
oldRole := role.DeepCopy()
|
||||||
|
role.Rules = desiredRules
|
||||||
|
|
||||||
|
patchErr := c.Patch(ctx, role, client.MergeFrom(oldRole))
|
||||||
|
if patchErr == nil || !apierrs.IsConflict(patchErr) {
|
||||||
|
return patchErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conflict: re-read and retry once.
|
||||||
|
contextLogger.Info("Role was modified concurrently, retrying patch")
|
||||||
|
if err := c.Get(ctx, client.ObjectKeyFromObject(role), role); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if equality.Semantic.DeepEqual(desiredRules, role.Rules) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
oldRole = role.DeepCopy()
|
||||||
|
role.Rules = desiredRules
|
||||||
|
|
||||||
|
return c.Patch(ctx, role, client.MergeFrom(oldRole))
|
||||||
|
}
|
||||||
175
internal/cnpgi/operator/rbac/ensure_test.go
Normal file
175
internal/cnpgi/operator/rbac/ensure_test.go
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
Copyright © contributors to CloudNativePG, established as
|
||||||
|
CloudNativePG a Series of LF Projects, LLC.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rbac_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
||||||
|
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||||
|
machineryapi "github.com/cloudnative-pg/machinery/pkg/api"
|
||||||
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||||
|
|
||||||
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/rbac"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newScheme() *runtime.Scheme {
|
||||||
|
s := runtime.NewScheme()
|
||||||
|
_ = rbacv1.AddToScheme(s)
|
||||||
|
_ = cnpgv1.AddToScheme(s)
|
||||||
|
_ = barmancloudv1.AddToScheme(s)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCluster(name, namespace string) *cnpgv1.Cluster {
|
||||||
|
return &cnpgv1.Cluster{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newObjectStore(name, namespace, secretName string) barmancloudv1.ObjectStore {
|
||||||
|
return barmancloudv1.ObjectStore{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Spec: barmancloudv1.ObjectStoreSpec{
|
||||||
|
Configuration: barmanapi.BarmanObjectStoreConfiguration{
|
||||||
|
DestinationPath: "s3://bucket/path",
|
||||||
|
BarmanCredentials: barmanapi.BarmanCredentials{
|
||||||
|
AWS: &barmanapi.S3Credentials{
|
||||||
|
AccessKeyIDReference: &machineryapi.SecretKeySelector{
|
||||||
|
LocalObjectReference: machineryapi.LocalObjectReference{
|
||||||
|
Name: secretName,
|
||||||
|
},
|
||||||
|
Key: "ACCESS_KEY_ID",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Describe("EnsureRole", func() {
|
||||||
|
var (
|
||||||
|
ctx context.Context
|
||||||
|
cluster *cnpgv1.Cluster
|
||||||
|
objects []barmancloudv1.ObjectStore
|
||||||
|
fakeClient client.Client
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
ctx = context.Background()
|
||||||
|
cluster = newCluster("test-cluster", "default")
|
||||||
|
objects = []barmancloudv1.ObjectStore{
|
||||||
|
newObjectStore("my-store", "default", "aws-creds"),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when the Role does not exist", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should create the Role with owner reference", func() {
|
||||||
|
err := rbac.EnsureRole(ctx, fakeClient, cluster, objects)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
var role rbacv1.Role
|
||||||
|
err = fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "test-cluster-barman-cloud",
|
||||||
|
}, &role)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(role.Rules).To(HaveLen(3))
|
||||||
|
|
||||||
|
// Verify owner reference is set to the Cluster
|
||||||
|
Expect(role.OwnerReferences).To(HaveLen(1))
|
||||||
|
Expect(role.OwnerReferences[0].Name).To(Equal("test-cluster"))
|
||||||
|
Expect(role.OwnerReferences[0].Kind).To(Equal("Cluster"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when the Role exists with matching rules", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||||
|
Expect(rbac.EnsureRole(ctx, fakeClient, cluster, objects)).To(Succeed())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should not patch the Role", func() {
|
||||||
|
var before rbacv1.Role
|
||||||
|
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "test-cluster-barman-cloud",
|
||||||
|
}, &before)).To(Succeed())
|
||||||
|
|
||||||
|
err := rbac.EnsureRole(ctx, fakeClient, cluster, objects)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
var after rbacv1.Role
|
||||||
|
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "test-cluster-barman-cloud",
|
||||||
|
}, &after)).To(Succeed())
|
||||||
|
|
||||||
|
Expect(after.ResourceVersion).To(Equal(before.ResourceVersion))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("when the Role exists with different rules", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||||
|
oldObjects := []barmancloudv1.ObjectStore{
|
||||||
|
newObjectStore("my-store", "default", "old-secret"),
|
||||||
|
}
|
||||||
|
Expect(rbac.EnsureRole(ctx, fakeClient, cluster, oldObjects)).To(Succeed())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should patch the Role with new rules and preserve owner reference", func() {
|
||||||
|
err := rbac.EnsureRole(ctx, fakeClient, cluster, objects)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
var role rbacv1.Role
|
||||||
|
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "test-cluster-barman-cloud",
|
||||||
|
}, &role)).To(Succeed())
|
||||||
|
|
||||||
|
secretsRule := role.Rules[2]
|
||||||
|
Expect(secretsRule.ResourceNames).To(ContainElement("aws-creds"))
|
||||||
|
Expect(secretsRule.ResourceNames).NotTo(ContainElement("old-secret"))
|
||||||
|
|
||||||
|
// Owner reference must survive the patch
|
||||||
|
Expect(role.OwnerReferences).To(HaveLen(1))
|
||||||
|
Expect(role.OwnerReferences[0].Name).To(Equal("test-cluster"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
32
internal/cnpgi/operator/rbac/suite_test.go
Normal file
32
internal/cnpgi/operator/rbac/suite_test.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
Copyright © contributors to CloudNativePG, established as
|
||||||
|
CloudNativePG a Series of LF Projects, LLC.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package rbac_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRBAC(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "RBAC Suite")
|
||||||
|
}
|
||||||
@ -28,12 +28,13 @@ import (
|
|||||||
"github.com/cloudnative-pg/cnpg-i/pkg/reconciler"
|
"github.com/cloudnative-pg/cnpg-i/pkg/reconciler"
|
||||||
"github.com/cloudnative-pg/machinery/pkg/log"
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
rbacv1 "k8s.io/api/rbac/v1"
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/equality"
|
|
||||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/rbac"
|
||||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/specs"
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/specs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ func (r ReconcilerImplementation) Pre(
|
|||||||
barmanObjects = append(barmanObjects, barmanObject)
|
barmanObjects = append(barmanObjects, barmanObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.ensureRole(ctx, &cluster, barmanObjects); err != nil {
|
if err := rbac.EnsureRole(ctx, r.Client, &cluster, barmanObjects); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,57 +138,6 @@ func (r ReconcilerImplementation) Post(
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r ReconcilerImplementation) ensureRole(
|
|
||||||
ctx context.Context,
|
|
||||||
cluster *cnpgv1.Cluster,
|
|
||||||
barmanObjects []barmancloudv1.ObjectStore,
|
|
||||||
) error {
|
|
||||||
contextLogger := log.FromContext(ctx)
|
|
||||||
newRole := specs.BuildRole(cluster, barmanObjects)
|
|
||||||
|
|
||||||
var role rbacv1.Role
|
|
||||||
if err := r.Client.Get(ctx, client.ObjectKey{
|
|
||||||
Namespace: newRole.Namespace,
|
|
||||||
Name: newRole.Name,
|
|
||||||
}, &role); err != nil {
|
|
||||||
if !apierrs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
contextLogger.Info(
|
|
||||||
"Creating role",
|
|
||||||
"name", newRole.Name,
|
|
||||||
"namespace", newRole.Namespace,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err := setOwnerReference(cluster, newRole); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.Client.Create(ctx, newRole)
|
|
||||||
}
|
|
||||||
|
|
||||||
if equality.Semantic.DeepEqual(newRole.Rules, role.Rules) {
|
|
||||||
// There's no need to hit the API server again
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
contextLogger.Info(
|
|
||||||
"Patching role",
|
|
||||||
"name", newRole.Name,
|
|
||||||
"namespace", newRole.Namespace,
|
|
||||||
"rules", newRole.Rules,
|
|
||||||
)
|
|
||||||
|
|
||||||
oldRole := role.DeepCopy()
|
|
||||||
|
|
||||||
// Apply to the role the new rules
|
|
||||||
role.Rules = newRole.Rules
|
|
||||||
|
|
||||||
// Push it back to the API server
|
|
||||||
return r.Client.Patch(ctx, &role, client.MergeFrom(oldRole))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r ReconcilerImplementation) ensureRoleBinding(
|
func (r ReconcilerImplementation) ensureRoleBinding(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
cluster *cnpgv1.Cluster,
|
cluster *cnpgv1.Cluster,
|
||||||
@ -213,7 +163,7 @@ func (r ReconcilerImplementation) createRoleBinding(
|
|||||||
cluster *cnpgv1.Cluster,
|
cluster *cnpgv1.Cluster,
|
||||||
) error {
|
) error {
|
||||||
roleBinding := specs.BuildRoleBinding(cluster)
|
roleBinding := specs.BuildRoleBinding(cluster)
|
||||||
if err := setOwnerReference(cluster, roleBinding); err != nil {
|
if err := controllerutil.SetControllerReference(cluster, roleBinding, r.Client.Scheme()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return r.Client.Create(ctx, roleBinding)
|
return r.Client.Create(ctx, roleBinding)
|
||||||
|
|||||||
@ -22,7 +22,6 @@ package restore
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
|
||||||
"github.com/cloudnative-pg/machinery/pkg/log"
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@ -33,14 +32,20 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
|
pluginscheme "github.com/cloudnative-pg/plugin-barman-cloud/internal/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
var scheme = runtime.NewScheme()
|
// generateScheme creates a runtime.Scheme with all type definitions
|
||||||
|
// needed by the restore sidecar. CNPG types are registered under a
|
||||||
|
// configurable API group to support custom CNPG-based operators.
|
||||||
|
func generateScheme(ctx context.Context) *runtime.Scheme {
|
||||||
|
result := runtime.NewScheme()
|
||||||
|
|
||||||
func init() {
|
utilruntime.Must(barmancloudv1.AddToScheme(result))
|
||||||
utilruntime.Must(barmancloudv1.AddToScheme(scheme))
|
utilruntime.Must(clientgoscheme.AddToScheme(result))
|
||||||
utilruntime.Must(cnpgv1.AddToScheme(scheme))
|
pluginscheme.AddCNPGToScheme(ctx, result)
|
||||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts the sidecar informers and CNPG-i server
|
// Start starts the sidecar informers and CNPG-i server
|
||||||
@ -48,6 +53,8 @@ func Start(ctx context.Context) error {
|
|||||||
setupLog := log.FromContext(ctx)
|
setupLog := log.FromContext(ctx)
|
||||||
setupLog.Info("Starting barman cloud instance plugin")
|
setupLog.Info("Starting barman cloud instance plugin")
|
||||||
|
|
||||||
|
scheme := generateScheme(ctx)
|
||||||
|
|
||||||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
||||||
Scheme: scheme,
|
Scheme: scheme,
|
||||||
Client: client.Options{
|
Client: client.Options{
|
||||||
|
|||||||
@ -23,12 +23,18 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||||
"github.com/cloudnative-pg/machinery/pkg/log"
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
|
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/rbac"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ObjectStoreReconciler reconciles a ObjectStore object.
|
// ObjectStoreReconciler reconciles a ObjectStore object.
|
||||||
@ -40,33 +46,96 @@ type ObjectStoreReconciler struct {
|
|||||||
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=rolebindings,verbs=create;patch;update;get;list;watch
|
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=rolebindings,verbs=create;patch;update;get;list;watch
|
||||||
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles,verbs=create;patch;update;get;list;watch
|
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles,verbs=create;patch;update;get;list;watch
|
||||||
// +kubebuilder:rbac:groups="",resources=secrets,verbs=create;list;get;watch;delete
|
// +kubebuilder:rbac:groups="",resources=secrets,verbs=create;list;get;watch;delete
|
||||||
|
// +kubebuilder:rbac:groups=postgresql.cnpg.io,resources=clusters,verbs=get;list;watch
|
||||||
// +kubebuilder:rbac:groups=postgresql.cnpg.io,resources=clusters/finalizers,verbs=update
|
// +kubebuilder:rbac:groups=postgresql.cnpg.io,resources=clusters/finalizers,verbs=update
|
||||||
// +kubebuilder:rbac:groups=postgresql.cnpg.io,resources=backups,verbs=get;list;watch
|
// +kubebuilder:rbac:groups=postgresql.cnpg.io,resources=backups,verbs=get;list;watch
|
||||||
// +kubebuilder:rbac:groups=barmancloud.cnpg.io,resources=objectstores,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=barmancloud.cnpg.io,resources=objectstores,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=barmancloud.cnpg.io,resources=objectstores/status,verbs=get;update;patch
|
// +kubebuilder:rbac:groups=barmancloud.cnpg.io,resources=objectstores/status,verbs=get;update;patch
|
||||||
// +kubebuilder:rbac:groups=barmancloud.cnpg.io,resources=objectstores/finalizers,verbs=update
|
// +kubebuilder:rbac:groups=barmancloud.cnpg.io,resources=objectstores/finalizers,verbs=update
|
||||||
|
|
||||||
// Reconcile is part of the main kubernetes reconciliation loop which aims to
|
// Reconcile ensures that the RBAC Role for each Cluster referencing
|
||||||
// move the current state of the cluster closer to the desired state.
|
// this ObjectStore is up to date with the current ObjectStore spec.
|
||||||
// TODO(user): Modify the Reconcile function to compare the state specified by
|
func (r *ObjectStoreReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||||
// the ObjectStore object against the actual cluster state, and then
|
contextLogger := log.FromContext(ctx).WithValues(
|
||||||
// perform operations to make the cluster state reflect the state specified by
|
"objectStoreName", req.Name,
|
||||||
// the user.
|
"namespace", req.Namespace,
|
||||||
//
|
)
|
||||||
// For more details, check Reconcile and its Result here:
|
ctx = log.IntoContext(ctx, contextLogger)
|
||||||
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/reconcile
|
|
||||||
func (r *ObjectStoreReconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) {
|
|
||||||
_ = log.FromContext(ctx)
|
|
||||||
|
|
||||||
// TODO(user): your logic here
|
contextLogger.Info("ObjectStore reconciliation start")
|
||||||
|
|
||||||
|
// List all Clusters in the same namespace
|
||||||
|
var clusterList cnpgv1.ClusterList
|
||||||
|
if err := r.List(ctx, &clusterList, client.InNamespace(req.Namespace)); err != nil {
|
||||||
|
return ctrl.Result{}, fmt.Errorf("while listing clusters: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each Cluster that references this ObjectStore, reconcile the Role
|
||||||
|
for i := range clusterList.Items {
|
||||||
|
cluster := &clusterList.Items[i]
|
||||||
|
|
||||||
|
pluginConfiguration := config.NewFromCluster(cluster)
|
||||||
|
referredObjects := pluginConfiguration.GetReferredBarmanObjectsKey()
|
||||||
|
|
||||||
|
if !referencesObjectStore(referredObjects, req.NamespacedName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
contextLogger.Info("Reconciling RBAC for cluster",
|
||||||
|
"clusterName", cluster.Name)
|
||||||
|
|
||||||
|
if err := r.reconcileRBACForCluster(ctx, cluster, referredObjects); err != nil {
|
||||||
|
return ctrl.Result{}, fmt.Errorf("while reconciling RBAC for cluster %s: %w", cluster.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contextLogger.Info("ObjectStore reconciliation completed")
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reconcileRBACForCluster ensures the Role for the given Cluster is
|
||||||
|
// up to date with the current ObjectStore specs.
|
||||||
|
func (r *ObjectStoreReconciler) reconcileRBACForCluster(
|
||||||
|
ctx context.Context,
|
||||||
|
cluster *cnpgv1.Cluster,
|
||||||
|
referredObjectKeys []client.ObjectKey,
|
||||||
|
) error {
|
||||||
|
contextLogger := log.FromContext(ctx)
|
||||||
|
barmanObjects := make([]barmancloudv1.ObjectStore, 0, len(referredObjectKeys))
|
||||||
|
for _, key := range referredObjectKeys {
|
||||||
|
var barmanObject barmancloudv1.ObjectStore
|
||||||
|
if err := r.Get(ctx, key, &barmanObject); err != nil {
|
||||||
|
if apierrs.IsNotFound(err) {
|
||||||
|
contextLogger.Info("ObjectStore not found, skipping",
|
||||||
|
"objectStoreName", key.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return fmt.Errorf("while getting ObjectStore %s: %w", key, err)
|
||||||
|
}
|
||||||
|
barmanObjects = append(barmanObjects, barmanObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rbac.EnsureRole(ctx, r.Client, cluster, barmanObjects)
|
||||||
|
}
|
||||||
|
|
||||||
|
// referencesObjectStore checks if the given ObjectStore is in the list
|
||||||
|
// of referred barman objects.
|
||||||
|
func referencesObjectStore(
|
||||||
|
referredObjects []client.ObjectKey,
|
||||||
|
objectStore client.ObjectKey,
|
||||||
|
) bool {
|
||||||
|
for _, ref := range referredObjects {
|
||||||
|
if ref.Name == objectStore.Name && ref.Namespace == objectStore.Namespace {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// SetupWithManager sets up the controller with the Manager.
|
// SetupWithManager sets up the controller with the Manager.
|
||||||
func (r *ObjectStoreReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
func (r *ObjectStoreReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
err := ctrl.NewControllerManagedBy(mgr).
|
err := ctrl.NewControllerManagedBy(mgr).
|
||||||
For(&barmancloudv1.ObjectStore{}).
|
For(&barmancloudv1.ObjectStore{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).
|
||||||
Complete(r)
|
Complete(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create controller: %w", err)
|
return fmt.Errorf("unable to create controller: %w", err)
|
||||||
|
|||||||
@ -22,70 +22,301 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||||
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
machineryapi "github.com/cloudnative-pg/machinery/pkg/api"
|
||||||
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||||
|
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("ObjectStore Controller", func() {
|
func newFakeScheme() *runtime.Scheme {
|
||||||
Context("When reconciling a resource", func() {
|
s := runtime.NewScheme()
|
||||||
const resourceName = "test-resource"
|
_ = rbacv1.AddToScheme(s)
|
||||||
|
_ = cnpgv1.AddToScheme(s)
|
||||||
|
_ = barmancloudv1.AddToScheme(s)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
func newTestCluster(name, namespace, objectStoreName string) *cnpgv1.Cluster {
|
||||||
|
return &cnpgv1.Cluster{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Spec: cnpgv1.ClusterSpec{
|
||||||
|
Plugins: []cnpgv1.PluginConfiguration{
|
||||||
|
{
|
||||||
|
Name: metadata.PluginName,
|
||||||
|
Parameters: map[string]string{
|
||||||
|
"barmanObjectName": objectStoreName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typeNamespacedName := types.NamespacedName{
|
func newTestObjectStore(name, namespace, secretName string) *barmancloudv1.ObjectStore {
|
||||||
Name: resourceName,
|
return &barmancloudv1.ObjectStore{
|
||||||
Namespace: "default", // TODO(user):Modify as needed
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
Spec: barmancloudv1.ObjectStoreSpec{
|
||||||
|
Configuration: barmanapi.BarmanObjectStoreConfiguration{
|
||||||
|
DestinationPath: "s3://bucket/path",
|
||||||
|
BarmanCredentials: barmanapi.BarmanCredentials{
|
||||||
|
AWS: &barmanapi.S3Credentials{
|
||||||
|
AccessKeyIDReference: &machineryapi.SecretKeySelector{
|
||||||
|
LocalObjectReference: machineryapi.LocalObjectReference{
|
||||||
|
Name: secretName,
|
||||||
|
},
|
||||||
|
Key: "ACCESS_KEY_ID",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = Describe("referencesObjectStore", func() {
|
||||||
|
It("should return true when ObjectStore is in the list", func() {
|
||||||
|
refs := []client.ObjectKey{
|
||||||
|
{Name: "store-a", Namespace: "default"},
|
||||||
|
{Name: "store-b", Namespace: "default"},
|
||||||
}
|
}
|
||||||
objectstore := &barmancloudv1.ObjectStore{}
|
Expect(referencesObjectStore(refs, client.ObjectKey{
|
||||||
|
Name: "store-b", Namespace: "default",
|
||||||
|
})).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
BeforeEach(func() {
|
It("should return false when ObjectStore is not in the list", func() {
|
||||||
By("creating the custom resource for the Kind ObjectStore")
|
refs := []client.ObjectKey{
|
||||||
err := k8sClient.Get(ctx, typeNamespacedName, objectstore)
|
{Name: "store-a", Namespace: "default"},
|
||||||
if err != nil && errors.IsNotFound(err) {
|
}
|
||||||
resource := &barmancloudv1.ObjectStore{
|
Expect(referencesObjectStore(refs, client.ObjectKey{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
Name: "store-b", Namespace: "default",
|
||||||
Name: resourceName,
|
})).To(BeFalse())
|
||||||
Namespace: "default",
|
})
|
||||||
},
|
|
||||||
Spec: barmancloudv1.ObjectStoreSpec{
|
|
||||||
Configuration: barmanapi.BarmanObjectStoreConfiguration{DestinationPath: "/tmp"},
|
|
||||||
},
|
|
||||||
// TODO(user): Specify other spec details if needed.
|
|
||||||
}
|
|
||||||
Expect(k8sClient.Create(ctx, resource)).To(Succeed())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
AfterEach(func() {
|
It("should return false when namespace differs", func() {
|
||||||
// TODO(user): Cleanup logic after each test, like removing the resource instance.
|
refs := []client.ObjectKey{
|
||||||
resource := &barmancloudv1.ObjectStore{}
|
{Name: "store-a", Namespace: "ns1"},
|
||||||
err := k8sClient.Get(ctx, typeNamespacedName, resource)
|
}
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(referencesObjectStore(refs, client.ObjectKey{
|
||||||
|
Name: "store-a", Namespace: "ns2",
|
||||||
|
})).To(BeFalse())
|
||||||
|
})
|
||||||
|
|
||||||
By("Cleanup the specific resource instance ObjectStore")
|
It("should return false for empty list", func() {
|
||||||
Expect(k8sClient.Delete(ctx, resource)).To(Succeed())
|
Expect(referencesObjectStore(nil, client.ObjectKey{
|
||||||
})
|
Name: "store-a", Namespace: "default",
|
||||||
It("should successfully reconcile the resource", func() {
|
})).To(BeFalse())
|
||||||
By("Reconciling the created resource")
|
})
|
||||||
controllerReconciler := &ObjectStoreReconciler{
|
})
|
||||||
Client: k8sClient,
|
|
||||||
Scheme: k8sClient.Scheme(),
|
var _ = Describe("ObjectStoreReconciler", func() {
|
||||||
|
var (
|
||||||
|
ctx context.Context
|
||||||
|
scheme *runtime.Scheme
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
ctx = context.Background()
|
||||||
|
scheme = newFakeScheme()
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("Reconcile", func() {
|
||||||
|
It("should create a Role for a Cluster that references the ObjectStore", func() {
|
||||||
|
objectStore := newTestObjectStore("my-store", "default", "aws-creds")
|
||||||
|
cluster := newTestCluster("my-cluster", "default", "my-store")
|
||||||
|
|
||||||
|
fakeClient := fake.NewClientBuilder().
|
||||||
|
WithScheme(scheme).
|
||||||
|
WithObjects(objectStore, cluster).
|
||||||
|
Build()
|
||||||
|
|
||||||
|
reconciler := &ObjectStoreReconciler{
|
||||||
|
Client: fakeClient,
|
||||||
|
Scheme: scheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
|
result, err := reconciler.Reconcile(ctx, reconcile.Request{
|
||||||
NamespacedName: typeNamespacedName,
|
NamespacedName: types.NamespacedName{
|
||||||
|
Name: "my-store",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
// TODO(user): Add more specific assertions depending on your controller's reconciliation logic.
|
Expect(result).To(Equal(reconcile.Result{}))
|
||||||
// Example: If you expect a certain status condition after reconciliation, verify it here.
|
|
||||||
|
var role rbacv1.Role
|
||||||
|
err = fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "my-cluster-barman-cloud",
|
||||||
|
}, &role)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(role.Rules).To(HaveLen(3))
|
||||||
|
|
||||||
|
// Verify the secrets rule contains the expected secret
|
||||||
|
secretsRule := role.Rules[2]
|
||||||
|
Expect(secretsRule.ResourceNames).To(ContainElement("aws-creds"))
|
||||||
|
|
||||||
|
// Verify owner reference is set to the Cluster
|
||||||
|
Expect(role.OwnerReferences).To(HaveLen(1))
|
||||||
|
Expect(role.OwnerReferences[0].Name).To(Equal("my-cluster"))
|
||||||
|
Expect(role.OwnerReferences[0].Kind).To(Equal("Cluster"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should skip Clusters that don't reference the ObjectStore", func() {
|
||||||
|
objectStore := newTestObjectStore("my-store", "default", "aws-creds")
|
||||||
|
cluster := newTestCluster("my-cluster", "default", "other-store")
|
||||||
|
|
||||||
|
fakeClient := fake.NewClientBuilder().
|
||||||
|
WithScheme(scheme).
|
||||||
|
WithObjects(objectStore, cluster).
|
||||||
|
Build()
|
||||||
|
|
||||||
|
reconciler := &ObjectStoreReconciler{
|
||||||
|
Client: fakeClient,
|
||||||
|
Scheme: scheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := reconciler.Reconcile(ctx, reconcile.Request{
|
||||||
|
NamespacedName: types.NamespacedName{
|
||||||
|
Name: "my-store",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(result).To(Equal(reconcile.Result{}))
|
||||||
|
|
||||||
|
// No Role should have been created
|
||||||
|
var role rbacv1.Role
|
||||||
|
err = fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "my-cluster-barman-cloud",
|
||||||
|
}, &role)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should succeed with no Clusters in the namespace", func() {
|
||||||
|
fakeClient := fake.NewClientBuilder().
|
||||||
|
WithScheme(scheme).
|
||||||
|
Build()
|
||||||
|
|
||||||
|
reconciler := &ObjectStoreReconciler{
|
||||||
|
Client: fakeClient,
|
||||||
|
Scheme: scheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := reconciler.Reconcile(ctx, reconcile.Request{
|
||||||
|
NamespacedName: types.NamespacedName{
|
||||||
|
Name: "my-store",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(result).To(Equal(reconcile.Result{}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("reconcileRBACForCluster", func() {
|
||||||
|
It("should skip deleted ObjectStores and still reconcile the Role", func() {
|
||||||
|
// Cluster references two ObjectStores, but one is deleted
|
||||||
|
cluster := newTestCluster("my-cluster", "default", "store-a")
|
||||||
|
existingStore := newTestObjectStore("store-a", "default", "aws-creds")
|
||||||
|
|
||||||
|
fakeClient := fake.NewClientBuilder().
|
||||||
|
WithScheme(scheme).
|
||||||
|
WithObjects(existingStore).
|
||||||
|
Build()
|
||||||
|
|
||||||
|
reconciler := &ObjectStoreReconciler{
|
||||||
|
Client: fakeClient,
|
||||||
|
Scheme: scheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass two keys, but "store-b" doesn't exist
|
||||||
|
err := reconciler.reconcileRBACForCluster(ctx, cluster, []client.ObjectKey{
|
||||||
|
{Name: "store-a", Namespace: "default"},
|
||||||
|
{Name: "store-b", Namespace: "default"},
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Role should be created with only store-a's secrets
|
||||||
|
var role rbacv1.Role
|
||||||
|
err = fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "my-cluster-barman-cloud",
|
||||||
|
}, &role)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(role.Rules).To(HaveLen(3))
|
||||||
|
|
||||||
|
// ObjectStore rule should only reference store-a
|
||||||
|
objectStoreRule := role.Rules[0]
|
||||||
|
Expect(objectStoreRule.ResourceNames).To(ContainElement("store-a"))
|
||||||
|
Expect(objectStoreRule.ResourceNames).NotTo(ContainElement("store-b"))
|
||||||
|
|
||||||
|
// Verify owner reference is set
|
||||||
|
Expect(role.OwnerReferences).To(HaveLen(1))
|
||||||
|
Expect(role.OwnerReferences[0].Name).To(Equal("my-cluster"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should update Role when ObjectStore credentials change", func() {
|
||||||
|
cluster := newTestCluster("my-cluster", "default", "my-store")
|
||||||
|
oldStore := newTestObjectStore("my-store", "default", "old-secret")
|
||||||
|
|
||||||
|
fakeClient := fake.NewClientBuilder().
|
||||||
|
WithScheme(scheme).
|
||||||
|
WithObjects(oldStore).
|
||||||
|
Build()
|
||||||
|
|
||||||
|
reconciler := &ObjectStoreReconciler{
|
||||||
|
Client: fakeClient,
|
||||||
|
Scheme: scheme,
|
||||||
|
}
|
||||||
|
|
||||||
|
// First reconcile - creates Role with old-secret
|
||||||
|
err := reconciler.reconcileRBACForCluster(ctx, cluster, []client.ObjectKey{
|
||||||
|
{Name: "my-store", Namespace: "default"},
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Update the ObjectStore with new credentials
|
||||||
|
var currentStore barmancloudv1.ObjectStore
|
||||||
|
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Name: "my-store", Namespace: "default",
|
||||||
|
}, ¤tStore)).To(Succeed())
|
||||||
|
currentStore.Spec.Configuration.BarmanCredentials.AWS.AccessKeyIDReference.LocalObjectReference.Name = "new-secret"
|
||||||
|
Expect(fakeClient.Update(ctx, ¤tStore)).To(Succeed())
|
||||||
|
|
||||||
|
// Second reconcile - should patch Role with new-secret
|
||||||
|
err = reconciler.reconcileRBACForCluster(ctx, cluster, []client.ObjectKey{
|
||||||
|
{Name: "my-store", Namespace: "default"},
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
var role rbacv1.Role
|
||||||
|
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "my-cluster-barman-cloud",
|
||||||
|
}, &role)).To(Succeed())
|
||||||
|
|
||||||
|
secretsRule := role.Rules[2]
|
||||||
|
Expect(secretsRule.ResourceNames).To(ContainElement("new-secret"))
|
||||||
|
Expect(secretsRule.ResourceNames).NotTo(ContainElement("old-secret"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -20,81 +20,14 @@ SPDX-License-Identifier: Apache-2.0
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
// +kubebuilder:scaffold:imports
|
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
|
||||||
"k8s.io/client-go/rest"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
|
||||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
|
||||||
|
|
||||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
|
|
||||||
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
|
|
||||||
|
|
||||||
var (
|
|
||||||
cfg *rest.Config
|
|
||||||
k8sClient client.Client
|
|
||||||
testEnv *envtest.Environment
|
|
||||||
ctx context.Context
|
|
||||||
cancel context.CancelFunc
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestControllers(t *testing.T) {
|
func TestControllers(t *testing.T) {
|
||||||
RegisterFailHandler(Fail)
|
RegisterFailHandler(Fail)
|
||||||
|
|
||||||
RunSpecs(t, "Controller Suite")
|
RunSpecs(t, "Controller Suite")
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = BeforeSuite(func() {
|
|
||||||
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
|
|
||||||
|
|
||||||
ctx, cancel = context.WithCancel(context.TODO())
|
|
||||||
|
|
||||||
By("bootstrapping test environment")
|
|
||||||
testEnv = &envtest.Environment{
|
|
||||||
CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")},
|
|
||||||
ErrorIfCRDPathMissing: true,
|
|
||||||
|
|
||||||
// The BinaryAssetsDirectory is only required if you want to run the tests directly
|
|
||||||
// without call the makefile target test. If not informed it will look for the
|
|
||||||
// default path defined in controller-runtime which is /usr/local/kubebuilder/.
|
|
||||||
// Note that you must have the required binaries setup under the bin directory to perform
|
|
||||||
// the tests directly. When we run make test it will be setup and used automatically.
|
|
||||||
BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s",
|
|
||||||
fmt.Sprintf("1.31.0-%s-%s", runtime.GOOS, runtime.GOARCH)),
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
// cfg is defined in this file globally.
|
|
||||||
cfg, err = testEnv.Start()
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(cfg).NotTo(BeNil())
|
|
||||||
|
|
||||||
err = barmancloudv1.AddToScheme(scheme.Scheme)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
// +kubebuilder:scaffold:scheme
|
|
||||||
|
|
||||||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
Expect(k8sClient).NotTo(BeNil())
|
|
||||||
})
|
|
||||||
|
|
||||||
var _ = AfterSuite(func() {
|
|
||||||
By("tearing down the test environment")
|
|
||||||
cancel()
|
|
||||||
err := testEnv.Stop()
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
})
|
|
||||||
|
|||||||
58
internal/scheme/cnpg.go
Normal file
58
internal/scheme/cnpg.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
Copyright © contributors to CloudNativePG, established as
|
||||||
|
CloudNativePG a Series of LF Projects, LLC.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package scheme provides utilities for building runtime schemes
|
||||||
|
// with support for custom CNPG API groups.
|
||||||
|
package scheme
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||||
|
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
crscheme "sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AddCNPGToScheme registers CNPG types into the given scheme using
|
||||||
|
// the API group configured via CUSTOM_CNPG_GROUP/CUSTOM_CNPG_VERSION
|
||||||
|
// environment variables, defaulting to postgresql.cnpg.io/v1.
|
||||||
|
// This allows the plugin to work with any CNPG-based operator.
|
||||||
|
func AddCNPGToScheme(ctx context.Context, s *runtime.Scheme) {
|
||||||
|
cnpgGroup := viper.GetString("custom-cnpg-group")
|
||||||
|
cnpgVersion := viper.GetString("custom-cnpg-version")
|
||||||
|
if len(cnpgGroup) == 0 {
|
||||||
|
cnpgGroup = cnpgv1.SchemeGroupVersion.Group
|
||||||
|
}
|
||||||
|
if len(cnpgVersion) == 0 {
|
||||||
|
cnpgVersion = cnpgv1.SchemeGroupVersion.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
schemeGroupVersion := schema.GroupVersion{Group: cnpgGroup, Version: cnpgVersion}
|
||||||
|
schemeBuilder := &crscheme.Builder{GroupVersion: schemeGroupVersion}
|
||||||
|
schemeBuilder.Register(&cnpgv1.Cluster{}, &cnpgv1.ClusterList{})
|
||||||
|
schemeBuilder.Register(&cnpgv1.Backup{}, &cnpgv1.BackupList{})
|
||||||
|
schemeBuilder.Register(&cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{})
|
||||||
|
utilruntime.Must(schemeBuilder.AddToScheme(s))
|
||||||
|
|
||||||
|
log.FromContext(ctx).Info("CNPG types registration", "schemeGroupVersion", schemeGroupVersion)
|
||||||
|
}
|
||||||
@ -870,6 +870,7 @@ rules:
|
|||||||
- postgresql.cnpg.io
|
- postgresql.cnpg.io
|
||||||
resources:
|
resources:
|
||||||
- backups
|
- backups
|
||||||
|
- clusters
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user