Skip to content

feat(api): combined-image mode + imagePullSecrets passthrough on DocumentDBSpec#374

Open
xgerman wants to merge 4 commits intodocumentdb:mainfrom
xgerman:feat/combined-image-and-image-pull-secrets
Open

feat(api): combined-image mode + imagePullSecrets passthrough on DocumentDBSpec#374
xgerman wants to merge 4 commits intodocumentdb:mainfrom
xgerman:feat/combined-image-and-image-pull-secrets

Conversation

@xgerman
Copy link
Copy Markdown
Collaborator

@xgerman xgerman commented May 8, 2026

Summary

Two narrow, opt-in extensions to DocumentDBSpec that broaden where the operator can deploy without changing default behaviour:

  1. Combined-image mode — for users who'd rather ship a single Postgres image that already bundles their extension/library set, instead of layering the official extension via ImageVolume. Triggered by leaving spec.documentDBImage empty; no change for any existing CR.
  2. spec.imagePullSecrets — standard corev1.LocalObjectReference list, forwarded verbatim to the underlying CNPG ClusterSpec.ImagePullSecrets. Lets users pull postgresImage, gatewayImage, and any plugin-injected sidecar image from a private registry (e.g., a token-protected ACR) with one field.

Both features are mode-agnostic: existing documentDBImage users see byte-identical output unless they opt in.

What's new on DocumentDBSpec

Field Purpose
postgresUID / postgresGID (*int32) Override the in-image Postgres UID/GID when the combined image runs as a non-root user. Pointer types preserve "unset vs explicit 0".
preloadLibraries ([]string) Replaces the operator's default shared_preload_libraries set. Honoured even in default mode for users with custom build setups.
postInitSQL ([]string) Replaces CNPG's default post-init SQL block (CREATE EXTENSION documentdb CASCADE + role setup).
imagePullSecrets ([]corev1.LocalObjectReference) Standard pull-secret list forwarded to the CNPG cluster pod.

Behaviour matrix

documentDBImage set? Mode What changes
Yes (default) ImageVolume Identical to today. New fields default to no-op.
No Combined-image Skip ImageVolume mount; honour preloadLibraries/postInitSQL verbatim; propagate postgresUID/GID to CNPG.

Test coverage

operator/src/internal/cnpg/cnpg_cluster_test.go — new Ginkgo Contexts:

  • combined-image mode — extension list, libraries, post-init SQL, UID/GID propagation, defaults preserved.
  • default ImageVolume mode preserves prior behaviour — proves the existing path is byte-identical.
  • imagePullSecrets propagation — single ref, multiple refs (order-preserving), unset-stays-nil.

make manifests generate regenerates the CRD + DeepCopy; both helm-chart and config/crd/bases/ copies are updated.

Compatibility

  • Default behaviour unchanged. CRs without any of these fields produce the same Cluster spec as before.
  • The new fields are all optional and additive on DocumentDBSpec.
  • imagePullSecrets is a no-op when empty/unset; no change to image-pull semantics for existing CRs.

Files

  • operator/src/api/preview/documentdb_types.go — new fields
  • operator/src/internal/cnpg/cnpg_cluster.go — wiring (combined-image branches + image-pull-secrets passthrough)
  • operator/src/internal/cnpg/cnpg_cluster_test.go — new test contexts
  • Generated: zz_generated.deepcopy.go, config/crd/bases/documentdb.io_dbs.yaml, documentdb-helm-chart/crds/documentdb.io_dbs.yaml

German and others added 4 commits May 8, 2026 16:17
Adds optional fields to DocumentDBSpec for deployments that bake
PostgreSQL extensions into a single combined image rather than mounting
them via OCI ImageVolume:

- postgresUID / postgresGID: UID/GID overrides for postgres in the image
- preloadLibraries:           shared_preload_libraries override
- postInitSQL:                CNPG PostInitSQL override

Default behaviour (all fields unset) is byte-identical to the previous
behaviour. Combined-image mode is triggered by leaving
spec.documentDBImage empty.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: German <geeichbe@microsoft.com>
When spec.documentDBImage is empty, the operator now produces a CNPG
Cluster spec that:
  - Uses spec.postgresImage directly as cluster.spec.imageName
  - Skips the Extensions ImageVolumeSource block
  - Skips documentdb-specific AdditionalLibraries / Parameters in favour
    of optional spec.preloadLibraries
  - Honours optional spec.postgresUID / spec.postgresGID
  - Honours optional spec.postInitSQL for the InitDB phase

The default ImageVolume path is unchanged when spec.documentDBImage is
set, preserving existing behaviour for all current users. A small
isCombinedImageMode helper makes the gating explicit at every call
site, and PostgresConfiguration assembly is split out into
buildPostgresConfiguration for readability.

Adds unit tests covering both the default ImageVolume path and the
combined-image path: Extensions/AdditionalLibraries/Parameters
shape, PostInitSQL default + override, PreloadLibraries
propagation, and PostgresUID/GID propagation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: German <geeichbe@microsoft.com>
…e fields

Re-run of `make manifests generate` after rebasing onto upstream/main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: German <geeichbe@microsoft.com>
Forwards spec.imagePullSecrets directly to the underlying CNPG
ClusterSpec.ImagePullSecrets. The cluster-level field applies to every
container scheduled into the cluster's pods (PG, gateway sidecar, any
plugin-injected sidecars), so a single field at the DocumentDB CR level
covers every image the operator schedules.

Required for deployments backed by private registries (e.g., a
token-protected ACR). The field uses the standard Kubernetes
corev1.LocalObjectReference contract that users already know from
Pod/Deployment specs and is translated to the structurally-equivalent
CNPG type at the boundary.

Includes generated CRD/deepcopy updates plus gofmt alignment fixes for
constants/comments touched in earlier combined-image commits.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: German <geeichbe@microsoft.com>
Copilot AI review requested due to automatic review settings May 8, 2026 23:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the DocumentDB Custom Resource to support more deployment scenarios by adding (1) a combined-image mode concept (to avoid ImageVolume-based extension wiring) and (2) imagePullSecrets passthrough to the underlying CNPG ClusterSpec, along with a few related knobs for preload libraries, post-init SQL, and Postgres UID/GID overrides.

Changes:

  • Add postgresUID/postgresGID, preloadLibraries, postInitSQL, and imagePullSecrets to DocumentDBSpec and regenerate CRDs / DeepCopy.
  • Refactor CNPG cluster spec generation to support a combined-image branch (skipping ImageVolume extensions plumbing) and to forward imagePullSecrets.
  • Add/adjust Ginkgo tests for the new wiring and behaviors.

Reviewed changes

Copilot reviewed 7 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
operator/src/internal/utils/pv_recovery.go Formatting-only constant alignment.
operator/src/internal/utils/constants.go Formatting-only constant alignment.
operator/src/internal/controller/documentdb_controller.go Removes a stray blank line.
operator/src/internal/cnpg/cnpg_sync.go Formatting-only alignment in JSON patch construction.
operator/src/internal/cnpg/cnpg_cluster.go Implements combined-image branching, refactors PostgresConfiguration building, adds UID/GID + imagePullSecrets plumbing, and adds post-init SQL override support.
operator/src/internal/cnpg/cnpg_cluster_test.go Adds/updates test contexts for combined-image mode, default mode behavior, postInitSQL override, and imagePullSecrets propagation.
operator/src/config/crd/bases/documentdb.io_dbs.yaml Regenerated CRD with new fields and validations (currently contains an invalid CEL quote issue).
operator/documentdb-helm-chart/crds/documentdb.io_dbs.yaml Helm CRD copy updated to match regenerated CRD (currently contains an invalid CEL quote issue).
operator/src/api/preview/zz_generated.deepcopy.go Regenerated deepcopy code for new spec fields.
operator/src/api/preview/documentdb_types.go Adds new DocumentDBSpec fields and updates bootstrap recovery XValidation (currently contains an invalid CEL quote issue).

Comment on lines +24 to +30
// isCombinedImageMode returns true when the DocumentDB CR opts into the
// combined-image path (single OCI image carrying both postgres binaries and
// extensions, no separate ImageVolume mount). Triggered by leaving
// spec.documentDBImage unset/empty.
func isCombinedImageMode(documentdb *dbpreview.DocumentDB) bool {
return strings.TrimSpace(documentdb.Spec.DocumentDBImage) == ""
}

// RecoveryConfiguration defines recovery settings for bootstrapping a DocumentDB cluster.
// +kubebuilder:validation:XValidation:rule="!(has(self.backup) && self.backup.name != '' && has(self.persistentVolume) && self.persistentVolume.name != '')",message="cannot specify both backup and persistentVolume recovery at the same time"
// +kubebuilder:validation:XValidation:rule="!(has(self.backup) && self.backup.name != && has(self.persistentVolume) && self.persistentVolume.name != )",message="cannot specify both backup and persistentVolume recovery at the same time"
Comment on lines +1087 to +1088
rule: '!(has(self.backup) && self.backup.name != && has(self.persistentVolume)
&& self.persistentVolume.name != )'
Comment on lines +1087 to +1088
rule: '!(has(self.backup) && self.backup.name != && has(self.persistentVolume)
&& self.persistentVolume.name != )'
Comment on lines +143 to +153
// PostgresUID is the UID under which CloudNative-PG launches PostgreSQL inside
// the postgresImage container. Default behaviour (unset) uses the CNPG default
// for the chosen image. Set this when using a combined image whose postgres
// user has a non-default UID. Must be set together with PostgresGID.
// +optional
PostgresUID *int32 `json:"postgresUID,omitempty"`

// PostgresGID is the GID under which CloudNative-PG launches PostgreSQL.
// See PostgresUID. Must be set together with PostgresUID.
// +optional
PostgresGID *int32 `json:"postgresGID,omitempty"`
@documentdb-triage-tool
Copy link
Copy Markdown

🤖 Auto-triaged by documentdb-triage-tool.

Applied: go, test, enhancement
Project fields suggested: Component controllers · Priority P2 · Effort L · Status Needs Review
Confidence: 0.88 (mixed)

Reasoning

component from path globs (controllers, api, manifests, test); effort from diff stats (547+65 LOC, 10 files); LLM: Adds multiple new optional fields to DocumentDBSpec (combined-image mode, imagePullSecrets, postgresUID/GID, preloadLibraries, postInitSQL) with CRD regeneration, controller logic changes, and new test coverage across multiple files.

If a label is wrong, remove it manually and ping @patty-chow so the rules can be tuned. The bot will not re-label items that already have component labels.

@documentdb-triage-tool documentdb-triage-tool Bot added enhancement New feature or request go Pull requests that update go code test labels May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request go Pull requests that update go code test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants