Skip to content

Add adminSecretFileRef as alternative to adminSecretRef for file-based credentials in ClusterConnection - #60

Merged
ThoSap merged 6 commits into
aboutbits:mainfrom
ordercloud:main
Sep 4, 2026
Merged

Add adminSecretFileRef as alternative to adminSecretRef for file-based credentials in ClusterConnection#60
ThoSap merged 6 commits into
aboutbits:mainfrom
ordercloud:main

Conversation

@fredordercloud

Copy link
Copy Markdown
Contributor

Summary

  • Add adminSecretFileRef field to ClusterConnectionSpec as an alternative to adminSecretRef, allowing admin credentials to be loaded from a JSON file mounted into the operator pod
    (e.g. via AWS Secrets Manager CSI driver)
  • Add CRD validation rule enforcing exactly one of adminSecretRef or adminSecretFileRef must be set
  • Add ResourceFileRef model class with path validation
  • Add KubernetesService.getSecretFileRefCredentials() to parse JSON credential files (requires password, optional username)
  • Add comprehensive unit tests for both file-ref and secret-ref credential resolution
  • Update docs: cluster-connection, docker-environment, and Terraform pitfalls

Test plan

  • Unit tests for getSecretFileRefCredentials — happy path, missing password, missing file, invalid JSON, null username
  • Unit tests for credential dispatcher — delegates to correct strategy based on which ref is set, throws when neither set
  • Unit tests for existing getSecretRefCredentials — unchanged behavior verified
  • Manual: apply ClusterConnection with adminSecretFileRef pointing to mounted credentials file

@ThoSap

ThoSap commented Sep 3, 2026

Copy link
Copy Markdown
Member

Hi @fredordercloud thanks for the contribution, I'm reviewing this PR right now and will come back to you.

@ThoSap ThoSap left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the PR and for adding this feature and KubernetesServiceTest. The Secret path had no tests before.

We still have some work before we can merge this:

Blocking

  • A missing username in the file crashes the connection with a NullPointerException. A username is always required for PostgreSQL. Reject a missing one with a clear error and document it as required.
  • cluster-connection.md is the reference page. Add the JSON file format there and move the mount instructions there from the dev environment page.
  • Remove the gradle.properties change and the .gitignore entries from this PR. They are not related to the feature. Open an issue that describes the Windows build problem, then we will fix it.
  • Remove "AWS Secrets Manager" from the error messages and the Javadoc. The operator reads a file. Where the file comes from does not matter.

Requested

  • JSpecify @Nullable on the two new spec fields, like RoleSpec.
  • A CRD validation test for the new CEL rule, like DefaultPrivilegeReconcilerTest.
  • Tests: remove the duplicate and the two overlapping dispatcher tests, use @ParameterizedTest for the missing/null cases, use the fabric8 mock server instead of mocking the client chain, add one end-to-end case with a file.
  • Naming and style: var, blank lines, FileRef, getAdminCredentials.

On our side

  • We will add volumes and volumeMounts values to the Helm chart in a follow-up PR. Add one sentence to the docs that the chart does not support this yet.
  • Enable ErrorProne rule Varifier to throw an error

Comment thread .gitignore Outdated
Comment thread docs/cluster-connection.md Outdated
Comment thread docs/docker-environment.md Outdated

#### Mount the credentials file

The file must be accessible inside the operator pod at the path specified in `adminSecretFileRef.path`. Mount it using a Volume and VolumeMount on the operator Deployment:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[follow-up] The operator is installed with the generated Helm chart, but the chart exposes no volumes or volumeMounts values.
So a chart user cannot mount this file without patching the rendered Deployment, and the feature is not usable through the documented install path.
This page also describes the local dev setup, where the operator runs on your machine and there is no pod to patch.

Fix: We will add app.volumes and app.volumeMounts chart values in a follow-up PR on our side, since quarkus-helm cannot add fields that Quarkus does not generate (quarkiverse/quarkus-helm#453).

Comment thread docs/docker-environment.md Outdated
Comment thread gradle.properties Outdated
Comment on lines +16 to +18

# Workaround for Windows: avoid forked process where -D args with {{ }} get mangled by cmd.exe
systemProp.gradle.quarkus.gradle-worker.no-process=true

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This property is not related to the feature and it changes the build for everyone, including CI.

Quarkus reads gradle.quarkus.gradle-worker.no-process and then runs its build steps inside the Gradle daemon with classloader isolation instead of a separate process (QuarkusTask.java:58 in Quarkus 3.35.3).

Put it in your own ~/.gradle/gradle.properties, and open an issue that describes the problem with Windows instead (I am using a MacBook due to work), then we will fix it.

Suggested change
# Workaround for Windows: avoid forked process where -D args with {{ }} get mangled by cmd.exe
systemProp.gradle.quarkus.gradle-worker.no-process=true

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@ThoSap I will open a new issue then, thanks.

Comment thread operator/src/test/java/it/aboutbits/postgresql/core/KubernetesServiceTest.java Outdated
Comment thread operator/src/test/java/it/aboutbits/postgresql/core/KubernetesServiceTest.java Outdated
Comment thread operator/src/test/java/it/aboutbits/postgresql/core/KubernetesServiceTest.java Outdated
Comment thread docs/docker-environment.md Outdated
Comment thread docs/docker-environment.md Outdated
Fred Campos added 3 commits September 3, 2026 13:40
… rename to FileRef, use fabric8 mock server, remove AWS references, updated unit tests and docs
@fredordercloud

Copy link
Copy Markdown
Contributor Author

Addresses all first-round feedback: FileRef rename, AWS refs removed, username required for fileRef, fabric8 mock server, parameterized tests, docs consolidated.

@ThoSap ThoSap left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Almost there 🎉

Thanks for the fast turnaround. 15 of the first-round threads are resolved: the FileRef rename, the fabric8 mock server, the parameterized tests, the moved docs, the removed Gradle property and more.

I request changes once more for the points below. Each has an inline comment, and the carried-over ones link to the first-round comment.

Blocking

  • The username check covers the file branch only. A Secret without username still reaches Properties.setProperty and throws a NullPointerException. Move the check after both branches in getAdminCredentials.
  • The first Javadoc line of FileRef is cut off: "A reference to a file inside".
  • The docs still say ResourceFileRef in the spec table and the heading, and the Deployment snippet names the container operator instead of postgresql-operator.
  • The duplicate test is still there (lines 199 and 248), and the end-to-end test with a file ref is still missing. The two new AdminSecretExclusivity tests only check the rejection.

Small

  • Inject the ObjectMapper, check isTextual() or switch to readValue. The comment has a sketch.
  • Message wording: "Credentials file" as suggested, lowercase at line 75.
  • Blank path test case for the CEL rule.
  • Heading level and duplicated format text in cluster-connection.md.
  • Move **/out/ into the IntelliJ section.

Still open from round one

  • If you want and if it is still relevant, please open and describe the issue for the Windows issue, see #60 (comment).

On our side

  • The Helm chart values for volumes and volumeMounts come in a follow-up PR.
  • The ErrorProne Varifier rule in a follow-up PR

Comment thread .gitignore Outdated
# Quinoa
.quinoa/

**/out/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Follow-up to #60 (comment). The pattern is generic now, thanks. Please move it into the "IntelliJ IDEA" section above (lines 13-22) instead of the end of the file.

@fredordercloud why was this needed in the first place, did you not use the Gradle tasks but the IntelliJ builder instead?

Comment thread docs/cluster-connection.md Outdated
Comment thread docs/cluster-connection.md Outdated
Comment thread docs/cluster-connection.md Outdated
Comment thread operator/src/main/java/it/aboutbits/postgresql/core/FileRef.java Outdated
Comment thread operator/src/main/java/it/aboutbits/postgresql/core/KubernetesService.java Outdated
Comment thread operator/src/main/java/it/aboutbits/postgresql/core/KubernetesService.java Outdated
@fredordercloud

Copy link
Copy Markdown
Contributor Author

Addressed PR review: inject ObjectMapper, fix Secret username NPE, use readValue with record, rename to FileRef in docs, fix error messages, add missing tests, restructure docs

@ThoSap ThoSap added documentation Improvements or additions to documentation enhancement New feature or request labels Sep 4, 2026

@ThoSap ThoSap left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Well done, thanks again for your contribution 🔥

I take the liberty of applying a few small changes myself in a follow-up PR, so you do not have to do another round for them.

I will also open a different follow-up PR, which adds volumes and volumeMounts values to the Helm chart, because without them this feature cannot be used through helm install.

@ThoSap ThoSap changed the title Add adminSecretFileRef as alternative to adminSecretRef for file-based credentials in ClusterConnection Add adminSecretFileRef as alternative to adminSecretRef for file-based credentials in ClusterConnection Sep 4, 2026
@ThoSap
ThoSap merged commit e09164c into aboutbits:main Sep 4, 2026
4 checks passed
@ThoSap ThoSap mentioned this pull request Sep 4, 2026
ThoSap added a commit that referenced this pull request Sep 4, 2026
ThoSap added a commit that referenced this pull request Sep 4, 2026
Two files in #60 were committed with CRLF although .editorconfig asks for LF.
Git now normalizes every text file to LF on commit and checks it out as LF on
every platform, so the editor setting can no longer be bypassed. gradlew.bat
keeps CRLF in the working tree. jar and png files are marked binary.

Also fix the linguist-generated pattern: the jOOQ sources live under
generated/src/, not src/generated/, so the old pattern matched nothing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants