K8SPG-1057: Allow using etcd as patroni DCS#1647
Conversation
|
I will wait for the jira ticket to open the PR in the helm charts repo |
|
and another note - this is my first OSS contribute so be gentel 😄 |
egegunes
left a comment
There was a problem hiding this comment.
@yoav-katz the implementation looks good to me in general. but we definitely need an e2e test that deploys etcd and configures PerconaPGCluster to use it.
|
would love to see this merged! |
…erator into etcd-dcs
There was a problem hiding this comment.
Pull request overview
This PR adds support for using external etcd as Patroni’s DCS backend (in addition to the existing Kubernetes Endpoints DCS), enabling deployments where workloads cannot reach the Kubernetes control plane API. It introduces a new spec.patroni.dcs API, updates Patroni config generation, RBAC/service behavior, and adds validations plus unit/E2E coverage for the etcd path.
Changes:
- Add
spec.patroni.dcs(defaultkubernetes, optionaletcd) with CEL immutability validation and generated deepcopy/CRD updates. - When
etcdDCS is selected: generateetcd3:Patroni config, add role-change callbacks, adjust primary Service selection logic, and validate referenced TLS/auth Secrets (with Secret watch/indexing). - Add unit tests and a new KUTTL E2E scenario (
etcd-dcs) to validate config, behavior, and immutability.
Reviewed changes
Copilot reviewed 41 out of 42 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/apis/upstream.pgv2.percona.com/v1beta1/zz_generated.deepcopy.go | Generated deepcopy updates for new Patroni DCS types. |
| pkg/apis/upstream.pgv2.percona.com/v1beta1/patroni_types.go | Adds dcs API types, helpers, and CEL validations. |
| pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go | Adds etcd DCS validation and Secret indexer for reconciliation triggers. |
| pkg/apis/pgv2.percona.com/v2/perconapgcluster_types_test.go | Unit tests for Percona CR validation of etcd DCS endpoints. |
| percona/controller/pgcluster/patroni_etcd.go | Reconcile-time Secret presence/key validation + Warning events for etcd DCS Secrets. |
| percona/controller/pgcluster/patroni_etcd_test.go | Unit tests for etcd DCS Secret validation reconciliation behavior. |
| percona/controller/pgcluster/controller.go | Watches Secrets via multiple field indexes (envFrom + patroni etcd secrets) with dedupe. |
| internal/patroni/reconcile.go | Mount etcd TLS Secret and inject Patroni etcd auth env vars into instance Pods. |
| internal/patroni/rbac.go | Conditionalize Endpoints/Service create RBAC rules based on DCS type. |
| internal/patroni/config.go | Emit etcd3: config + callbacks for etcd DCS; keep Kubernetes DCS behavior unchanged. |
| internal/patroni/config_test.go | Adds unit coverage for etcd DCS Patroni YAML generation and env behavior. |
| internal/controller/postgrescluster/patroni.go | Skip k8s-DCS-specific artifacts/status reads when using etcd DCS. |
| internal/controller/postgrescluster/cluster.go | Use selector-based primary Service for etcd DCS; avoid applying Endpoints when not used. |
| e2e-tests/tests/etcd-dcs/00-deploy-operator.yaml | E2E setup step: deploy operator and client. |
| e2e-tests/tests/etcd-dcs/00-assert.yaml | E2E assertions for operator/CRD readiness. |
| e2e-tests/tests/etcd-dcs/01-etcd-setup.yaml | E2E step: deploy a single-node etcd StatefulSet for testing. |
| e2e-tests/tests/etcd-dcs/01-assert.yaml | E2E assertion: etcd is ready. |
| e2e-tests/tests/etcd-dcs/02-create-cluster.yaml | E2E step: create cluster configured for etcd DCS. |
| e2e-tests/tests/etcd-dcs/02-assert.yaml | E2E assertions: cluster reaches ready state with etcd DCS. |
| e2e-tests/tests/etcd-dcs/03-write-data.yaml | E2E: write data to primary via client. |
| e2e-tests/tests/etcd-dcs/04-read-from-primary.yaml | E2E: read data back from primary. |
| e2e-tests/tests/etcd-dcs/04-assert.yaml | E2E assertion: expected read result. |
| e2e-tests/tests/etcd-dcs/05-assert.yaml | E2E assertions for created resources. |
| e2e-tests/tests/etcd-dcs/06-check-patroni-config.yaml | E2E: verify Patroni config contains etcd3 + callbacks and omits kubernetes:. |
| e2e-tests/tests/etcd-dcs/07-check-patronictl.yaml | E2E: verify patronictl list shows running/leader. |
| e2e-tests/tests/etcd-dcs/08-check-etcd-keys.yaml | E2E: verify Patroni keys appear in etcd. |
| e2e-tests/tests/etcd-dcs/09-check-no-warning-events.yaml | E2E: ensure no unexpected Warning events for etcd secrets. |
| e2e-tests/tests/etcd-dcs/10-check-dcs-immutability.yaml | E2E: ensure DCS type immutability is enforced by admission/CEL. |
| e2e-tests/tests/etcd-dcs/11-check-pod-labels.yaml | E2E: verify role labels are present (callback executed). |
| e2e-tests/tests/etcd-dcs/99-remove-cluster-gracefully.yaml | E2E teardown: remove resources and validate operator stability. |
| e2e-tests/run-release.csv | Adds etcd-dcs to release E2E run list. |
| e2e-tests/run-pr.csv | Adds etcd-dcs to PR E2E run list. |
| deploy/cw-bundle.yaml | Bundle CRD updates to include new DCS schema/validations. |
| deploy/crd.yaml | Generated CRD updates for new DCS schema/validations. |
| deploy/bundle.yaml | Bundle CRD updates for new DCS schema/validations. |
| config/crd/bases/upstream.pgv2.percona.com_postgresclusters.yaml | Base CRD schema updates for DCS fields/validations. |
| config/crd/bases/pgv2.percona.com_perconapgclusters.yaml | Base CRD schema updates for DCS fields/validations. |
| cmd/postgres-operator/main.go | Adds field index registration for etcd DCS referenced Secrets. |
| build/postgres-operator/patroni-role-change.sh | New Patroni callback script to patch pod role label + status annotation. |
| build/postgres-operator/init-entrypoint.sh | Installs the new Patroni role-change script into runtime bindir. |
| build/postgres-operator/Dockerfile | Ships the new Patroni role-change script in the image. |
| build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml | Generated Percona CRD output updated for new DCS schema/validations. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@egegunes Im not sure what caused this failure, my commit only touched unit test files so lint will pass😅 |
|
It seems to fail on cluster deletion due to timeout. I doubt it's something caused by these changes. I retriggered it. |
|
@mayankshah1607 |
… etcd in-place restore
…erator into etcd-dcs
commit: 2f836f1 |
CHANGE DESCRIPTION
Problem:
Patroni supports multiple DCS backends, but the operator hardcodes Kubernetes Endpoints as the only option. This blocks clusters on managed Kubernetes platforms where workloads cannot reach the control plane API.
Cause:
The kubernetes: stanza was hardcoded in the generated Patroni config with no mechanism to select a different backend.
Several other pieces of the operator also assumed k8s DCS: RBAC rules unconditionally granted Endpoints permissions, the primary service routed through Patroni-managed Endpoints objects, and pod role labels/annotations were expected to be set by Patroni itself (which only happens with k8s DCS).
Solution:
Add a spec.patroni.dcs field (type: kubernetes default, type: etcd alternative). The field is immutable after cluster creation, enforced by a CEL validation rule on the CRD.
When type: etcd, the operator:
The Kubernetes DCS path is unchanged.
CHECKLIST
Jira
Needs Doc) and QA (Needs QA)?Tests
Config/Logging/Testability