feat(postgres): add TLS support via CNPG operator-managed certificates - #2686
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds tri-state TLS enablement to PostgreSQL CRD types and Helm chart surfaces, updating deepcopy, values/schema, templates, tests, README, and ApplicationDefinition metadata to control CNPG operator-managed certificate SAN injection. ChangesPostgreSQL TLS Configuration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates native TLS support for PostgreSQL managed services by leveraging the CNPG operator's built-in certificate management. By shifting from a chart-rendered cert-manager chain to operator-managed certificates, the implementation avoids previous admission webhook conflicts and simplifies the certificate lifecycle. The changes include a flexible tri-state configuration for TLS, updated schema definitions, and robust validation via new test suites. Highlights
New Features🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a tri-state TLS configuration for the PostgreSQL package, enabling automatic TLS for external connections while allowing users to explicitly force the setting. The feedback highlights a documentation error regarding the certificate management mechanism and notes that the implementation for forcing TLS off is currently incomplete, as it lacks the necessary PostgreSQL parameter overrides. Additionally, a naming convention update was requested for the Go API types to correctly use the TLS initialism.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/apps/postgres/README.md`:
- Around line 163-171: Update the README text to remove references to
cert-manager resources and the CNPG fields spec.certificates.serverCASecret and
spec.certificates.serverTLSSecret (these describe the old cert-manager flow) and
instead document the current operator-managed certificate flow: state that the
operator manages the CA and leaf certificates internally, that the chart no
longer creates <release>-selfsigned / <release>-ca / <release>-tls cert-manager
resources, and that when external TLS is enabled the operator injects only
spec.certificates.serverAltDNSNames; also adjust verification guidance to show
how to validate the operator-managed chain (e.g., inspect the CNPG Cluster
status/conditions or the operator logs) rather than looking for cert-manager
Secrets.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ba298fb0-b458-4b59-a5c8-7a6e0c5b6c52
📒 Files selected for processing (10)
api/apps/v1alpha1/postgresql/types.goapi/apps/v1alpha1/postgresql/zz_generated.deepcopy.gopackages/apps/postgres/Makefilepackages/apps/postgres/README.mdpackages/apps/postgres/templates/_tls.tplpackages/apps/postgres/templates/db.yamlpackages/apps/postgres/tests/tls_test.yamlpackages/apps/postgres/values.schema.jsonpackages/apps/postgres/values.yamlpackages/system/postgres-rd/cozyrds/postgres.yaml
5b9c4f9 to
2ccc31a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/apps/postgres/README.md (1)
163-171:⚠️ Potential issue | 🟠 MajorTLS documentation describes the old cert-manager flow, not the current operator-managed flow.
Lines 163-171 state that the chart creates cert-manager resources (
<release>-selfsigned,<release>-ca,<release>-tls) and that the CNPG Cluster referencesspec.certificates.serverCASecretandspec.certificates.serverTLSSecret. This contradicts the implemented operator-managed certificate flow where the CNPG operator auto-generates the CA and leaf certificates, and the chart only setsspec.certificates.serverAltDNSNameswhen external TLS is enabled.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/apps/postgres/README.md` around lines 163 - 171, Update the README section that currently claims the chart creates cert-manager resources and that the CNPG Cluster references spec.certificates.serverCASecret and spec.certificates.serverTLSSecret: change it to describe the operator-managed flow where the CNPG operator auto-generates the CA and leaf certificates (so cert-manager resources like <release>-selfsigned / <release>-ca / <release>-tls are not created by the chart), and note that the chart only sets spec.certificates.serverAltDNSNames when external TLS is enabled; replace references to serverCASecret/serverTLSSecret with the operator auto-generation behavior and the use of spec.certificates.serverAltDNSNames.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/apps/postgres/Makefile`:
- Around line 5-8: Add a precondition check that validates the generator's
original output before mutating values.schema.json: use jq -e to assert that
.properties.tls.properties.enabled.type is exactly ["boolean"] (the expected
cozyvalues-gen output) and fail early if not, then perform the jq assignment
that changes it to ["boolean","null"], and finally keep the existing post-patch
equality check; refer to the jq expression
'.properties.tls.properties.enabled.type' and the file values.schema.json to
locate where to insert the precondition check.
---
Duplicate comments:
In `@packages/apps/postgres/README.md`:
- Around line 163-171: Update the README section that currently claims the chart
creates cert-manager resources and that the CNPG Cluster references
spec.certificates.serverCASecret and spec.certificates.serverTLSSecret: change
it to describe the operator-managed flow where the CNPG operator auto-generates
the CA and leaf certificates (so cert-manager resources like
<release>-selfsigned / <release>-ca / <release>-tls are not created by the
chart), and note that the chart only sets spec.certificates.serverAltDNSNames
when external TLS is enabled; replace references to
serverCASecret/serverTLSSecret with the operator auto-generation behavior and
the use of spec.certificates.serverAltDNSNames.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: caa4178d-7dd4-4cf9-b64c-72e89c006a2b
📒 Files selected for processing (10)
api/apps/v1alpha1/postgresql/types.goapi/apps/v1alpha1/postgresql/zz_generated.deepcopy.gopackages/apps/postgres/Makefilepackages/apps/postgres/README.mdpackages/apps/postgres/templates/_tls.tplpackages/apps/postgres/templates/db.yamlpackages/apps/postgres/tests/tls_test.yamlpackages/apps/postgres/values.schema.jsonpackages/apps/postgres/values.yamlpackages/system/postgres-rd/cozyrds/postgres.yaml
6c8e6e1 to
d63f82e
Compare
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
LGTM — postgres now extends the CNPG operator-managed cert with the external hostname via spec.certificates.serverAltDNSNames when external+TLS; tri-state tls.enabled is well-tested; the chart correctly does NOT expose the operator-managed <release>-ca Secret (which holds the CA private key) to tenant use access. Two non-blocking follow-ups below — neither is unique to this PR.
Business context: the earlier iteration tried supplying serverCASecret / serverTLSSecret from a chart-rendered cert-manager chain, which failed the CNPG admission webhook (missing ca.key — cert-manager writes the private key under tls.key, not ca.key). This PR shifts to operator-managed mode, where the chart only contributes the external hostname SAN. CNPG keeps its built-in TLS on the wire regardless of tls.enabled; the toggle controls SAN injection only, which is correctly documented in values.yaml and the new README section.
Verified:
- Tri-state evaluation in
templates/_tls.tpl:11-17useskindIs "invalid"for null-detection and inherits from.Values.external.tests/tls_test.yamlcovers all four cells of the truth table. templates/db.yaml:9correctly gates thecertificatesblock on bothtlsEnabledandexternal— without an external hostname there is nothing to append to the SAN list, and the operator's default SAN set already covers the rw/r/ro DNS forms.templates/dashboard-resourcemap.yamlintentionally does NOT grant read access on<release>-ca. The operator-managed CA Secret carries bothca.crtandca.key; exposing it to tenantuseaccess would leak the CA private key (the inverse of the mariadb #2680 blocker). README directs users to retrieve the CA viakubectl get secret <release>-ca, which is the right path.- README's
sslmode=verify-full+sslrootcert=ca.crtexample matches CNPG's documented client-trust workflow. - All CodeRabbit / Gemini threads on this PR are resolved.
Non-blocking follow-ups (both apply across the TLS series, not just here):
-
packages/system/postgres-rd/cozyrds/postgres.yaml:42listspostgres-{{ .name }}-caundersecrets.include, but the chart's dashboard-resources Role does not grant read access on it. The dashboard will advertise the secret name and tenant users will get RBAC-denied on read. The chart's restrictive RBAC is the right call — drop-cafrom cozyrds'ssecrets.includeso the discovery layer stops promising a read that the chart deliberately doesn't grant. -
Both
values.schema.jsonand the cozyrdsopenAPISchemause"type":["boolean","null"]fortls.enabled.pkg/registry/apps/application/rest.go:103-105unmarshals the schema intoapiextv1.JSONSchemaProps, whoseTypefield is a single string — I reproducedjson: cannot unmarshal array into Go struct field JSONSchemaProps.properties.type of type stringagainst v0.34.1. The error is logged andspecSchemastays nil, so server-side defaulting viarest_defaulting.gois silently disabled for this app; Helm-side defaults still apply, so user-visible breakage is minimal but the app loses schema-driven defaulting. Same pattern in #2681 kafka and likely the rest of the TLS series. Worth a separate fix to switch to the apiextv1 idiom (nullable: true) or to droptypeentirely on the tri-state property.
|
Addressed your non-blocking follow-ups:
No cert-manager changes (CNPG operator-managed certs). Ready for re-review. |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/apps/postgres/tests/tls_test.yaml`:
- Around line 7-10: Update the commented test header to accurately reflect
behavior: change the `tls.enabled: true` bullet to note that while TLS is forced
on, chart-side SAN injection into `spec.certificates` only occurs when an
`external` hostname is present, and clarify that `tls.enabled: false` forces TLS
off regardless of `external`; reference the keys `tls.enabled`, `external`,
`spec.certificates`, and the phrase “chart-side SAN injection” so the comment
matches the actual assertions in the test.
In `@packages/apps/postgres/values.schema.json`:
- Around line 127-128: The schema description for the boolean property
incorrectly mentions “null” while the generated "type": "boolean" disallows
null; update the source text used by cozyvalues-gen to replace “omitted (null)”
with “omitted/absent” (or similar non-null wording) for that property’s
description, then re-run the cozyvalues-gen pipeline and `make generate` so the
values.schema.json is regenerated consistently; locate the original description
string in the values source used by cozyvalues-gen (the property whose generated
schema contains the shown description) and change only the wording, not the
schema type.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: eb159f45-6eaf-4af6-99af-a3063a3c8030
📒 Files selected for processing (5)
packages/apps/postgres/README.mdpackages/apps/postgres/templates/db.yamlpackages/apps/postgres/tests/tls_test.yamlpackages/apps/postgres/values.schema.jsonpackages/system/postgres-rd/cozyrds/postgres.yaml
✅ Files skipped from review due to trivial changes (1)
- packages/apps/postgres/README.md
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
LGTM on the new SHA. Both non-blocking follow-ups from my prior LGTM are now closed:
edcb656bb fix(postgres): drop CA Secret from cozyrds — tenant retrieves ca.crt from user-credentials Secret—packages/system/postgres-rd/cozyrds/postgres.yamlnow lists onlypostgres-{{ .name }}-credentialsundersecrets.include, andpackages/apps/postgres/templates/dashboard-resourcemap.yamlmatches (only<release>-credentials). The dashboard no longer advertises a CA Secret that RBAC didn't actually grant, AND CNPG's operator-managed<release>-ca(which would carryca.key) stays unexposed to tenantuse. Both layers consistent now.184be891d refactor(postgres): drop null from tls.enabled schema, use kindIs invalid pattern— same schema convention as the rest of the batch;"type":["boolean","null"]would failapiextv1.JSONSchemaPropsunmarshal. Resolved.
d63f82ed9 build(postgres): assert schema shape before patching tls.enabled.type adds a defensive grep before the jq patch in the Makefile so a future cozyvalues-gen format change fails the build loud instead of producing a malformed schema silently. Good belt-and-suspenders.
Operator-managed CNPG chain still owns the cert lifecycle end-to-end; chart only injects external-hostname SAN when external+TLS — same shape as before, just cleaner cozyrds advertisement.
- Extend PostgresSpec with nullable Tls.Enabled (*bool) for tri-state control - Regenerate deepcopy and update go.mod with k8s.io/utils as direct dep - Add TLS fields to values.yaml, values.schema.json (with nullable support) - Update README and Makefile; propagate TLS field to cozyrds postgres.yaml Signed-off-by: Arsolitt <arsolitt@gmail.com>
- Add _tls.tpl helper with tri-state resolution logic (nil/false/true) - Add certmanager.yaml to provision CA and leaf Certificate resources - Wire TLS listener configuration into db.yaml when TLS is enabled Signed-off-by: Arsolitt <arsolitt@gmail.com>
- Add helm-unittest suite covering tri-state TLS (nil/false/true), CA/leaf cert properties, external SAN injection, and cert-manager resource absence when disabled Signed-off-by: Arsolitt <arsolitt@gmail.com>
…ection CNPG admission webhook rejects spec.certificates that combines a serverTLSSecret with serverAltDNSNames, and the operator's internal client-CA generation step expects ca.key on the secret bound to serverCASecret — a field cert-manager does not produce, since it stores the private key as tls.key. The previous chart configuration triggered exactly this path and left the Cluster stuck on "generating client CA certificate: missing ca.key secret data". Drop the chart-rendered cert-manager Issuer/Certificate chain and the spec.certificates.serverCASecret/serverTLSSecret references. CNPG now auto-generates the self-signed CA and signs server, replication, and client certs from it, producing the expected per-purpose secrets (<release>-ca, <release>-server, <release>-replication). The operator's default SAN list already covers the three built-in services (rw, r, ro) in four DNS forms each. The chart still needs to inject the external LoadBalancer hostname when external=true, since that name lives outside the operator's auto-derived set. Emit spec.certificates.serverAltDNSNames with that single entry under that condition only. End-to-end test on dev13: Cluster reaches "healthy state", probe pod with PGSSLMODE=verify-full against the operator-managed CA succeeds and SHOW ssl reports on. Signed-off-by: Arsolitt <arsolitt@gmail.com>
Drop the templates/certmanager.yaml suite entirely (the file no longer exists) and rewrite the spec.certificates assertions to match the new operator-managed flow: certificates block emitted only when both TLS is on AND external is true, with serverAltDNSNames carrying just the external hostname. Signed-off-by: Arsolitt <arsolitt@gmail.com>
…direct Signed-off-by: Arsolitt <arsolitt@gmail.com>
The README still described the chart-side cert-manager chain that was replaced when the chart switched to CNPG operator-managed TLS via spec.certificates.serverAltDNSNames. Rewrite the section to explain the actual cert ownership boundary (CNPG owns the chain, chart only injects the external hostname), the trust anchor location (operator-managed <release>-ca Secret, key ca.crt), and the chart-side semantics of the tri-state tls.enabled flag. The values.yaml @field comment is updated in the same direction, with regenerated schema/types.go/cozyrds. Clarifies that tls.enabled=false only skips the chart-side SAN injection - CNPG retains its built-in TLS on the wire regardless of this flag. To force PostgreSQL TLS off entirely, the caller would set postgresql.parameters.ssl="off" at the CNPG layer. Signed-off-by: Arsolitt <arsolitt@gmail.com>
Add a precondition that fails early if cozyvalues-gen no longer emits tls.enabled.type as the bare "boolean" string the patch step expects. Without the guard, a generator output that drops or moves the field would silently create it via the assignment, and the post-patch equality check would still pass against the synthetic value. Signed-off-by: Arsolitt <arsolitt@gmail.com>
…from user-credentials Secret The dashboard RBAC intentionally does not grant access to the operator-managed <release>-ca Secret (it contains ca.key, which would leak the private key). Advertising it in cozyrds secrets.include created a UX gap: the dashboard showed a Secret the tenant could never read. CNPG bundles ca.crt in every user-credentials Secret it creates, so tenants already have the trust anchor they need via the <release>-credentials Secret which is covered by RBAC. Update README and the db.yaml comment to point there. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Arsolitt <arsolitt@gmail.com>
…alid pattern Remove the jq post-processing patch that widened tls.enabled type to ["boolean","null"] in values.schema.json and the openAPISchema embedded in the cozyrds CRD. Plain "type":"boolean" is emitted directly by cozyvalues-gen and is the correct form. The cozystack-api server unmarshals openAPISchema into apiextv1.JSONSchemaProps whose Type field is a single string; an array value silently zeros the field and disables server-side defaulting for the entire app. Tri-state semantics are preserved on the Helm template side via kindIs "invalid": omitting tls.enabled triggers the external-based fallback; null is no longer a valid input and is rejected by the schema. Remove two helm-unittest cases that injected tls.enabled: null (now intentionally rejected) and update the suite comment to match. Signed-off-by: Arsolitt <arsolitt@gmail.com>
184be89 to
0c7c393
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/apps/postgres/README.md`:
- Line 217: The `version` parameter is incorrectly listed under the TLS table in
packages/apps/postgres README; update the source that generates the `##
Parameters` block so `version` is defined in the general/app parameters section
(not in the TLS group), then run the doc generator (cozyvalues-gen via `make
generate`) to regenerate the `## Parameters` block in README.md; target the
parameter named `version` and the README's `## Parameters` generation logic so
the entry appears in the general parameters table rather than the TLS table.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c856b0cb-228e-419e-abc8-fa14454507db
📒 Files selected for processing (9)
api/apps/v1alpha1/postgresql/types.goapi/apps/v1alpha1/postgresql/zz_generated.deepcopy.gopackages/apps/postgres/README.mdpackages/apps/postgres/templates/_tls.tplpackages/apps/postgres/templates/db.yamlpackages/apps/postgres/tests/tls_test.yamlpackages/apps/postgres/values.schema.jsonpackages/apps/postgres/values.yamlpackages/system/postgres-rd/cozyrds/postgres.yaml
🚧 Files skipped from review as they are similar to previous changes (7)
- packages/apps/postgres/values.yaml
- api/apps/v1alpha1/postgresql/zz_generated.deepcopy.go
- packages/apps/postgres/values.schema.json
- api/apps/v1alpha1/postgresql/types.go
- packages/system/postgres-rd/cozyrds/postgres.yaml
- packages/apps/postgres/templates/_tls.tpl
- packages/apps/postgres/tests/tls_test.yaml
The generated JSON schema types tls.enabled as a scalar boolean, which rejects an explicit null value; describe the tri-state unset case as "omitted" so the wording matches what the schema actually accepts. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Arsolitt <arsolitt@gmail.com>
version is a general deployment parameter, not a TLS setting; relocate its @param/@enum block back into Common parameters so the generated parameter reference groups it correctly instead of under TLS. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Arsolitt <arsolitt@gmail.com>
Resolve the conflict in the generated packages/system/postgres-rd/cozyrds/postgres.yaml by regenerating openAPISchema and keysOrder from the merged values. The CRD now carries both the chart's tls.enabled field and main's backup useSystemBucket / BackupClass-driven fields. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Arsolitt <arsolitt@gmail.com>
Aleksei Sviridkin (lexfrei)
left a comment
There was a problem hiding this comment.
LGTM — operator-managed CNPG TLS is correctly wired, the tri-state toggle is honestly documented as controlling SAN injection rather than on-the-wire TLS, generated artifacts are in sync, and tests pass.
Business context: managed Postgres on CNPG already serves TLS by default; this PR's tls.enabled tri-state does not turn TLS on or off — it controls whether the chart appends the external hostname (<release>.<_namespace.host>) to the operator-generated server cert via spec.certificates.serverAltDNSNames, replacing an earlier cert-manager chain that failed CNPG's admission webhook (missing ca.key).
Non-blocking follow-ups
_namespace.hostis dereferenced unconditionally whenexternal=trueandtls.enabledis unset (packages/apps/postgres/templates/db.yaml:25). This matches the platform contract every tenant app relies on (harbor, kubernetes, vpn all read.Values._namespace.hostunconditionally), and the chart cannot render under barehelm templateregardless — not a real-path regression. The genuine residual: when a tenant has no apex domain,_namespace.hostis empty and the SAN renders as<release>.(trailing dot) rather than failing. Thegatewaypackagefails on empty host; arequired/failguard here would match that precedent.- The field is named
tls.enabledbut its effect is "inject external hostname into the cert SAN", not an on/off TLS switch. Now thoroughly documented (values.yaml, schema, README each spell out that CNPG keeps TLS on the wire regardless and point topostgresql.parameters.ssl=offfor a true disable). Noting as a design observation.
| # client pods to verify TLS. | ||
| certificates: | ||
| serverAltDNSNames: | ||
| - {{ printf "%s.%s" .Release.Name .Values._namespace.host }} |
There was a problem hiding this comment.
When external: true and a tenant has no apex domain, _namespace.host is the empty string and this renders a malformed SAN <release>. (trailing dot). The gateway package fails on empty _namespace.host; a required-gate on a non-empty host here would match that precedent. Bare-helm template nil-pointer is not a real-path regression (the chart already requires platform-injected _namespace/_cluster, same as harbor/kubernetes/vpn), so this is non-blocking.
What this PR does
Adds TLS support to the Postgres managed service via the CNPG operator's built-in cert management.
tls.enabledfield with tri-state semantics: when unset, defaults to the value ofexternal(auto-on for externally published services, off for cluster-internal). Explicittls.enabledalways wins..ns,.ns.svc,.ns.svc.<cluster-domain>).external: trueand TLS is on, the chart setsspec.certificates.serverAltDNSNamesso the operator appends the external hostname<release>.<tenant-host>to the auto-generated leaf cert. In all other cases the chart leavesspec.certificatesabsent and the operator uses its default SAN set.<release>-caOpaque Secret (keyca.crt). Mount that key into client pods to verify TLS.Why operator-managed instead of a chart-side cert-manager chain: an earlier iteration that supplied
serverCASecretandserverTLSSecretfrom a chart-rendered cert-manager chain failed the CNPG admission webhook withmissing ca.key secret data. CNPG expects aca.keyfield onserverCASecret, while cert-manager writes the private key undertls.key. Operator-managed mode avoids the schema fight entirely.Verified end-to-end on a sandbox cluster: cert chain is created by the operator within ~60 seconds, leaf cert's SAN list includes both the standard service forms and the external hostname, TLSv1.3 handshake via
openssl s_client -starttls postgresagainst the rw service with the operator CA returns verify code 0.Release note
Summary by CodeRabbit
New Features
Documentation
Tests