cloudnative-pg / cloudnative-pg/charts

Add declarative `Publication` and `Subscription` support to the cluster chart

Open
#862 1 comment 0 reactions 0 assignees View on GitHub
chart( cluster )
Dominant language
Go Template
Stars
621
Forks
265
Avg merge
7d 12h
Merged PRs (30d)
7

Description

## Summary

The CNPG operator supports declarative management of [`Publication`](https://cloudnative-pg.io/documentation/current/declarative_publication_management/) and [`Subscription`](https://cloudnative-pg.io/documentation/current/declarative_subscription_management/) CRDs, but the `cluster` Helm chart currently has no way to render them. Users wanting native logical replication (e.g. for major-version upgrades or cross-cluster migration) have to drop down to raw manifests alongside the chart.

I'd like to propose adding first-class support to the `cluster` chart and am volunteering to do the work, opening this issue first per CONTRIBUTING.md to align on shape before submitting a PR.

## Prior discussion

- #732: user asked for exactly this; closed stale without resolution.
- #692: broader chart-coverage proposal that lists publications/subscriptions among the gaps; closed stale.
- #831: open bug. Standalone mode strips `externalClusters`, which blocks the subscriber side of any cross-cluster logical replication.
- #832: open PR fixing #831 by allowing a raw `cluster.externalClusters` to render in standalone mode.

I have no maintainer signal that any of the above is being actively pursued; happy to coordinate if so.

## Proposal

Add three things to the `cluster` chart:

1. **`publications: []`**: list rendering one `postgresql.cnpg.io/v1` `Publication` per entry. Fields: `name`, `dbname`, `target` (`allTables` xor `objects`), optional `parameters`, `publicationReclaimPolicy`.
2. **`subscriptions: []`**: list rendering one `Subscription` per entry. Fields: `name`, `dbname`, `publicationName`, `externalClusterName`, optional `parameters`, `subscriptionReclaimPolicy`.
3. **A way to declare the source cluster connection** for `Subscription.externalClusterName`. See open question below.

Plus: documentation page, two examples (publisher / subscriber), and a chainsaw test that stands up two clusters, replicates rows, and asserts row counts on the subscriber.

## Open question: connection-config shape

There are two reasonable places for the externalCluster connection to live:

**Option A: typed `logicalReplication.externalClusters`** (what I prototyped):

```yaml
logicalReplication:
externalClusters:
- name: source-cluster
host: source-rw.default.svc
port: 5432
username: app
database: app
sslMode: verify-full
passwordSecret: { create: false, name: source-app, key: password }
sslRootCertSecret: { name: ..., key: ... }
```

Pros: helm-validated schema, optional secret creation (`create: true` with `value:`), familiar shape (mirrors `recovery.pg_basebackup.source`).
Cons: duplicates the CNPG `externalClusters` schema.

**Option B: reuse `cluster.externalClusters` from #832**
Once #832 lands, users put the full upstream `externalClusters` entry directly into `cluster.externalClusters` and reference it by name from `subscriptions[].externalClusterName`.
Pros: single source of truth, no schema duplication, automatically inherits any new CRD fields.
Cons: no helm-side validation, no convenience secret creation; users hand-write the full CNPG shape.

I have a working implementation of Option A but am happy to rework to Option B (or a hybrid where Option A renders into the same `externalClusters` list #832 introduces). What's your preference, @itay-grudev?

## What I have ready

A working branch with:

- the three template files,
- `values.schema.json` updates,
- `helm-docs`-regenerated README,
- examples for publisher and subscriber,
- three chainsaw tests (`logical-replication`, `logical-replication-objects`, `logical-replication-schema`) covering `allTables`, specific objects, and schema-scoped publications, with `test`-style assertions on row counts and replicated objects.

I'll rebase onto current `main`, sign off commits per DCO, and open the PR as `dev/` once the shape question is resolved.

## Out of scope (for this issue)

- The standalone-mode `externalClusters` rendering itself, tracked in #831 / #832.
- Replica clusters / `replica.origin` changes, separate concern.
- Plugin-based logical replication (if/when CNPG adds it).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.