feat(agentgateway-bootstrap): wire CNPG connection URI into AgentgatewayParameters#306
Merged
Andy Lo-A-Foe (loafoe) merged 2 commits intoJul 23, 2026
Conversation
…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.
…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).
Andy Lo-A-Foe (loafoe)
deleted the
feat/agentgateway-bootstrap-postgres-wire-job
branch
July 23, 2026 14:06
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #305 (CNPG
Clusterprovisioning).agentgateway'sdatabase.url(therequest-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>-appSecret once theClusterisReady, alreadyincluding a combined
urikey inpostgresql://user:pass@host:port/dbnameformat(confirmed via CNPG's own source,
pkg/specs/secrets.go). This adds an ArgoCDSync-hookJob—ServiceAccount+Role+RoleBinding+Job, matching theexisting pattern in
charts/grafana/templates/grafana-credentials-job.yaml— thatwaits for the
Clusterto reportReady, reads thaturikey, andkubectl patches it intoAgentgatewayParameters.spec.rawConfig.database.url.No
helm lookup, no External Secrets Operator, no Crossplane — idempotency comes fromthe Job's own
kubectl wait/getcalls against live cluster state at Job-run time,not from anything Helm renders statically.
Also extracts the CNPG
Clustername into a newagentgateway-bootstrap.postgresClusterNamehelper sopostgres-cluster.yamland thenew
postgres-config-job.yamlcan't compute it differently and drift apart.Test plan
CLUSTER_NAME/PARAMS_NAME/APP_SECRET_NAMEall resolving to the expected names