Repository navigation
Tags: plan4better/charts
Tags
fix(goat): CNPG managed-role field is `bypassrls` (lowercase), not `b… …ypassRls` CI's kubeconform step flagged the field as not in the cnpg.io/cluster_v1 schema. Confirmed against the bundled CRD — it really is one-word lowercase (`bypassrls`), matching the Postgres SQL keyword. Both spellings were never valid; v0.3.4 happened to render but CI was red. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ci(workflows): switch azure/setup-helm to @v5.0.0 tag (drop SHA pin) Codeload was failing to serve the SHA-pinned v5.0.0 just as it had with v4. Use the @v5.0.0 tag instead — looks like a GitHub-side cache hiccup that floating-tag resolution handles differently. Will revisit pinning once the codeload issue clears. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
feat(goat): move windmill workspace + token + password bootstrap into…
… chart hooks (v0.3.4)
Until now the chart deployed windmill server + workers but left the
application-level bootstrap (workspace creation, API-token mint, default
password rotation, script sync) to whoever was driving the install. Civitas
did it via Ansible (`civitas-goat-addon/tasks/06_windmill.yml`). A bare
`helm install` produced a windmill that nobody could write to without
manual API calls.
Move that bootstrap into the chart as Helm post-install/post-upgrade hooks:
- `templates/windmill/bootstrap-admin-password-secret.yaml`: K8s Secret
holding the desired superadmin password. Auto-generated with
`randAlphaNum 32` on first install, preserved across upgrades via the
`lookup` + `helm.sh/resource-policy: keep` pattern. Operators can supply
their own via `windmill.bootstrap.adminPasswordSecret`.
- `templates/windmill/bootstrap-script-configmap.yaml`: stdlib-only Python
script. Waits for `/api/version`, logs in with the desired password
(falling back to `changeme` and rotating immediately), creates the
workspace, mints a non-expiring API token, writes it to a K8s Secret via
the in-cluster API using the hook's ServiceAccount. Idempotent.
- `templates/windmill/bootstrap-rbac.yaml`: ServiceAccount + minimal Role
(create on Secrets in namespace; get/patch/update scoped to the token
Secret's resourceName).
- `templates/windmill/bootstrap-hook.yaml`: the Job, annotated with
`helm.sh/hook: post-install,post-upgrade` and
`helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded`.
hook-weight 0.
- `templates/windmill/script-sync-hook.yaml`: optional second hook
(weight 20, opt-in via `windmill.scriptSync.enabled: true`) using the
`windmill-worker-tools` image to run `goatlib.tools.sync_windmill` and
`goatlib.tasks.sync_windmill` against the workspace.
- `values.yaml`: new `windmill.bootstrap.{enabled,workspace,adminEmail,
adminPasswordSecret,tokenSecret}` and `windmill.scriptSync.{enabled,image}`
blocks. Bootstrap is on by default; script sync is off.
- `README.md`: documents the bootstrap flow, the post-install Job, and the
`processes.extraEnv` snippet needed to wire `WINDMILL_TOKEN` from the
bootstrap-produced Secret.
Net effect: a bare `helm install goat ...` produces a usable windmill —
workspace exists, default password is rotated to a chart-managed secret,
token is queryable from `kubectl get secret <release>-windmill-token`.
Consumers like `processes` just secretKeyRef the token.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
feat(goat): zero-config windmill DB on CNPG path + external-mode docs…
… (v0.3.3)
The chart now handles windmill's database/role provisioning natively when
operators use the bundled CNPG cluster (`postgresql.cluster.enabled: true`):
- `templates/postgresql/cluster.yaml`: when `windmill.server.enabled` and
`windmill.db.reuseGoatConnection: false` (the new default), the Cluster
CR adds the windmill database via `postInitSQL`, declares the three
required windmill roles (`windmill_user`, `windmill_admin` BYPASSRLS,
`windmill_owner_user`) with the IN-ROLE grants windmill expects, pins
`search_path = public` for windmill_owner_user in the windmill DB so
the sqlx pool's migrations land where its runtime queries look.
- `templates/postgresql/windmill-cred-secret.yaml`: chart materializes
the K8s Secret CNPG reads for `windmill_owner_user`'s password.
Password is generated once with `randAlphaNum 32` and preserved across
upgrades via `lookup` + `helm.sh/resource-policy: keep`.
- `_secrets.tpl`: `windmill.postgresql.{secretName,host}` helpers fall
through to the chart-managed names in cluster mode, so windmill server
+ workers wire to the right credentials without any extra values.
- `values.yaml`: `windmill.db.reuseGoatConnection` default flipped from
`true` to `false`. Sharing the goat DB writes ~100 tables in the goat
user's default schema and the migrations need role-creation privileges
the goat owner typically lacks — almost always wrong. Comment block
spells out the three resolution paths (CNPG-managed, external,
shared goat DB).
- `README.md`: new "Quick start — external Postgres" section with the
SQL block operators need to run as superuser (goat user + extensions,
windmill user + windmill_admin / windmill_user roles with proper
inherits, search_path pin). Also documents the Zalando alternative
via `preparedDatabases`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(goat): wire windmill.db.reuseGoatConnection through templates (v0…
….3.2)
The values.yaml has long offered `windmill.db.reuseGoatConnection: false`
+ `windmill.db.external.*` as a way to point windmill at a dedicated
database. The knobs existed but nothing read them — server and workers
hardcoded the `goat.postgresql.*` helpers, so windmill always landed in
the shared goat DB. That's bad in two ways:
1. Windmill's migrations write ~100 tables in whatever schema the user's
search_path resolves to. In a Zalando-style setup where the goat
owner's default search_path is `"$user", data`, those tables collide
with goat-core's data schema.
2. Windmill's first migration does `GRANT ... TO windmill_admin`. If
the connecting role lacks CREATEROLE (typical for application roles),
migration aborts. Operators are forced to add CREATEROLE grants or
pre-create windmill_admin out-of-band.
Both problems disappear with a dedicated DB whose owner has
freshly-minted, role-creation-capable credentials.
Adds `windmill.postgresql.*` template helpers that branch on
`reuseGoatConnection` and fall back to the goat helpers when true (so
existing default-config installs are unchanged). Updates server +
worker-{default,print,tools,workflows} deployments to consume the new
helpers.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
chore(goat): bump chart to 0.3.1 Releases the NextAuth Keycloak wiring fix (ba2501e) + extraVolumes support on web/geoapi/processes (e9426c0). 0.3.0 on OCI is broken for any deployment using auth.enabled — it sets KEYCLOAK_ISSUER instead of NEXT_PUBLIC_KEYCLOAK_ISSUER, so the bundle's entrypoint.sh never substitutes the build-time placeholder. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
feat(goat): v0.3.0 — real OIDC/Keycloak auth wiring
core and web read Keycloak credentials from a K8s Secret (named via
core.auth.existingSecret / web.auth.existingSecret) when auth.enabled
is true. Previous releases used inert placeholder values.
Schema:
core.auth:
enabled: bool
existingSecret: string # name of the K8s Secret
existingSecretKeys: # override key names if non-default
serverUrl: server-url
realm: realm
clientId: client-id
clientSecret: client-secret
web.auth:
+ nextauthSecret: nextauth-secret # NextAuth.js signing key
+ publicUrl: '' # NEXTAUTH_URL override
When auth is wired via secret, both deployments construct env from the
secret and the configmaps omit the corresponding placeholder keys.
Web's KEYCLOAK_ISSUER is constructed at pod start via Kubernetes env
substitution: '$(KEYCLOAK_SERVER_URL_RAW)/realms/$(REALM_NAME_RAW)'.
Companion: civitas-goat-addon v0.2.0 ships the Keycloak realm-client
provisioning that creates this secret automatically.
PreviousNext