Skip to content

feat(agentgateway-bootstrap): wire CNPG connection URI into AgentgatewayParameters#306

Merged
Andy Lo-A-Foe (loafoe) merged 2 commits into
mainfrom
feat/agentgateway-bootstrap-postgres-wire-job
Jul 23, 2026
Merged

feat(agentgateway-bootstrap): wire CNPG connection URI into AgentgatewayParameters#306
Andy Lo-A-Foe (loafoe) merged 2 commits into
mainfrom
feat/agentgateway-bootstrap-postgres-wire-job

Conversation

@loafoe

Copy link
Copy Markdown
Member

Summary

Follow-up to #305 (CNPG Cluster provisioning). agentgateway's database.url (the
request-logging DB config powering its cost dashboard/Analytics UI) is a static
config-file field — confirmed via agentgateway's own Rust source and JSON schema, it
has no env-var override and no secret-ref mechanism of any kind.

CNPG generates its own <cluster>-app Secret once the Cluster is Ready, already
including a combined uri key in postgresql://user:pass@host:port/dbname format
(confirmed via CNPG's own source, pkg/specs/secrets.go). This adds an ArgoCD
Sync-hook JobServiceAccount + Role + RoleBinding + Job, matching the
existing pattern in charts/grafana/templates/grafana-credentials-job.yaml — that
waits for the Cluster to report Ready, reads that uri key, and
kubectl patches it into AgentgatewayParameters.spec.rawConfig.database.url.

No helm lookup, no External Secrets Operator, no Crossplane — idempotency comes from
the Job's own kubectl wait/get calls against live cluster state at Job-run time,
not from anything Helm renders statically.

Also extracts the CNPG Cluster name into a new
agentgateway-bootstrap.postgresClusterName helper so postgres-cluster.yaml and the
new postgres-config-job.yaml can't compute it differently and drift apart.

Test plan

  • helm template shows the Job/ServiceAccount/Role/RoleBinding rendering correctly, with CLUSTER_NAME/PARAMS_NAME/APP_SECRET_NAME all resolving to the expected names
  • database.enabled=false renders none of these resources
  • helm lint passes

…wayParameters

agentgateway's database.url (request-logging DB for cost tracking) is a
static config-file field with no env-var or secret-ref support of any
kind. CNPG generates its own <cluster>-app Secret once the Cluster is
ready, already including a combined uri key
(postgresql://user:pass@host:port/dbname). This adds a Sync-hook Job
(ServiceAccount + Role + RoleBinding + Job, matching the pattern already
used by charts/grafana/templates/grafana-credentials-job.yaml) that
waits for the Cluster to report Ready, reads that uri key, and
kubectl-patches it into AgentgatewayParameters.spec.rawConfig.database.url.

No helm lookup, no External Secrets Operator, no Crossplane - idempotency
comes from the Job's own kubectl wait/get calls against live cluster
state, not Helm's render-time state.

Also extracts the CNPG Cluster name into a new
agentgateway-bootstrap.postgresClusterName helper so postgres-cluster.yaml
and postgres-config-job.yaml can't drift out of sync on the name they
each compute.
@loafoe
Andy Lo-A-Foe (loafoe) requested a review from a team as a code owner July 23, 2026 13:42
…failures

Adversarial review caught and empirically reproduced (real kind cluster)
a silent-corruption bug: DATABASE_URL=$(kubectl get secret ... | base64 -d)
does not trip `set -e` on a failing kubectl get in ash (busybox's /bin/sh,
which alpine/k8s actually uses) - the last command in the pipe (base64 -d)
exits 0 on empty stdin, so a transient secret-read failure silently
blanks out database.url on every subsequent Sync-hook rerun, with no
error surfaced anywhere (the Job still reports Succeeded, and
HookSucceeded deletes it).

Fix: `set -eo pipefail` (verified in ash) plus an explicit empty-value
guard before patching. Also switch the raw printf JSON construction to
jq (bundled in alpine/k8s) for robust escaping regardless of what
characters end up in the connection URI, and drop the unused `get` verb
on agentgatewayparameters (the script only ever patches it).
@loafoe
Andy Lo-A-Foe (loafoe) merged commit ed6c801 into main Jul 23, 2026
5 checks passed
@loafoe
Andy Lo-A-Foe (loafoe) deleted the feat/agentgateway-bootstrap-postgres-wire-job branch July 23, 2026 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant