Merge pull request 'Take the database password from PGPASSWORD, not the DSN' (#9) from postgres-dsn-password into main
Reviewed-on: #9
This commit was merged in pull request #9.
This commit is contained in:
@@ -87,11 +87,12 @@ fmt: ## Report unformatted files
|
|||||||
echo "gofmt needed:"; echo "$$unformatted"; gofmt -d .; exit 1; \
|
echo "gofmt needed:"; echo "$$unformatted"; gofmt -d .; exit 1; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# database.dsnSecret.name has no default and the deployment `required`s it: the
|
# database.dsn has no default and the deployment `required`s it: the chart
|
||||||
# chart provisions no database and cannot guess where the credentials live, so a
|
# provisions no database and cannot guess where it is, so a render without it is
|
||||||
# render without it is meant to fail. Setting it here keeps the lint honest about
|
# meant to fail. Setting it here keeps the lint honest about what a working
|
||||||
# what a working install needs.
|
# install needs.
|
||||||
HELM_LINT_SET = --set image.tag=v0.0.0 --set database.dsnSecret.name=terdut-db
|
HELM_LINT_SET = --set image.tag=v0.0.0 \
|
||||||
|
--set 'database.dsn=postgres://terdut@terdut-postgres:5432/terdut?sslmode=require'
|
||||||
|
|
||||||
.PHONY: helm-lint
|
.PHONY: helm-lint
|
||||||
helm-lint: ## Lint and render the chart
|
helm-lint: ## Lint and render the chart
|
||||||
|
|||||||
@@ -119,17 +119,24 @@ than an `Ingress`. TLS is terminated at the gateway, so the server itself never
|
|||||||
| `networking.listener` | `""` | Gateway listener (`sectionName`) to bind to. Empty attaches to every matching listener, **including plaintext HTTP** — set it to the HTTPS listener's name to serve TLS only |
|
| `networking.listener` | `""` | Gateway listener (`sectionName`) to bind to. Empty attaches to every matching listener, **including plaintext HTTP** — set it to the HTTPS listener's name to serve TLS only |
|
||||||
| `networking.servicePort` | `8080` | Port the route forwards to; keep in sync with `service.port` |
|
| `networking.servicePort` | `8080` | Port the route forwards to; keep in sync with `service.port` |
|
||||||
| `bootstrap.enabled` | `true` | Runs a post-install hook that creates the first user and stores its API key in the `<release>-admin-key` Secret. Already-bootstrapped servers are left alone |
|
| `bootstrap.enabled` | `true` | Runs a post-install hook that creates the first user and stores its API key in the `<release>-admin-key` Secret. Already-bootstrapped servers are left alone |
|
||||||
| `database.dsnSecret.name` | `""` | **Required.** Existing Secret holding the Postgres DSN. The chart provisions no database |
|
| `database.dsn` | `""` | **Required.** Postgres DSN, with no password in it. The chart provisions no database |
|
||||||
| `database.dsnSecret.key` | `dsn` | Key within that Secret |
|
| `database.passwordSecret.name` | `""` | Secret supplying `PGPASSWORD`. With the Zalando postgres operator, the Secret it generates for the role |
|
||||||
|
| `database.passwordSecret.key` | `password` | Key within that Secret |
|
||||||
|
|
||||||
The API key travels in an `Authorization: Bearer` header, so set `networking.listener` whenever the
|
The API key travels in an `Authorization: Bearer` header, so set `networking.listener` whenever the
|
||||||
hostname is reachable outside a trusted network.
|
hostname is reachable outside a trusted network.
|
||||||
|
|
||||||
#### The database
|
#### The database
|
||||||
|
|
||||||
The chart provisions no database: it takes a DSN from a Secret and expects a Postgres that already
|
The chart provisions no database: it takes a DSN and expects a Postgres that already exists. In this
|
||||||
exists. In this cluster the wrapper chart declares an `acid.zalan.do/v1 postgresql` CR and passes
|
cluster the wrapper chart declares an `acid.zalan.do/v1 postgresql` CR; anywhere else, any reachable
|
||||||
the Secret the operator writes; anywhere else, any reachable Postgres 14+ will do.
|
Postgres 14+ will do.
|
||||||
|
|
||||||
|
The DSN carries no password. pgx falls back to libpq's environment variables for whatever the DSN
|
||||||
|
leaves out, so the password arrives as `PGPASSWORD` from a Secret and never appears in values, in
|
||||||
|
the rendered manifest or in `kubectl describe pod`. With the postgres operator that Secret is the
|
||||||
|
one it generates for the role, so a rebuild mints a new password with nothing to keep in sync —
|
||||||
|
the same wiring miniflux uses.
|
||||||
|
|
||||||
The server migrates its own schema on startup, so a new database only has to exist and be writable.
|
The server migrates its own schema on startup, so a new database only has to exist and be writable.
|
||||||
|
|
||||||
|
|||||||
@@ -32,14 +32,18 @@ spec:
|
|||||||
env:
|
env:
|
||||||
- name: TERDUT_ADDR
|
- name: TERDUT_ADDR
|
||||||
value: ":{{ .Values.service.port }}"
|
value: ":{{ .Values.service.port }}"
|
||||||
# The connection string, from a Secret: it carries the password.
|
|
||||||
# The wrapper chart points this at the Secret the Postgres operator
|
|
||||||
# writes for this database's role.
|
|
||||||
- name: TERDUT_DB_DSN
|
- name: TERDUT_DB_DSN
|
||||||
|
value: {{ required "database.dsn is required" .Values.database.dsn | quote }}
|
||||||
|
{{- if .Values.database.passwordSecret.name }}
|
||||||
|
# The password reaches pgx through libpq's environment variable
|
||||||
|
# rather than through the DSN, so it stays out of the rendered
|
||||||
|
# manifest. pgx fills in from PG* whatever the DSN leaves out.
|
||||||
|
- name: PGPASSWORD
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: {{ required "database.dsnSecret.name is required" .Values.database.dsnSecret.name }}
|
name: {{ .Values.database.passwordSecret.name }}
|
||||||
key: {{ .Values.database.dsnSecret.key }}
|
key: {{ .Values.database.passwordSecret.key }}
|
||||||
|
{{- end }}
|
||||||
- name: TERDUT_STALE_AFTER
|
- name: TERDUT_STALE_AFTER
|
||||||
value: "{{ .Values.sweeper.staleAfter }}"
|
value: "{{ .Values.sweeper.staleAfter }}"
|
||||||
- name: TERDUT_ARCHIVE_AFTER
|
- name: TERDUT_ARCHIVE_AFTER
|
||||||
|
|||||||
@@ -11,16 +11,28 @@ image:
|
|||||||
tag: "latest"
|
tag: "latest"
|
||||||
pullPolicy: IfNotPresent
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
# Postgres connection, as a DSN in an existing Secret:
|
# Postgres connection. The chart provisions no database; it expects one to exist.
|
||||||
# postgres://user:password@host:5432/terdut?sslmode=require
|
|
||||||
#
|
|
||||||
# The chart provisions no database. In this cluster the wrapper chart declares an
|
|
||||||
# acid.zalan.do postgresql CR and points this at the Secret the operator writes;
|
|
||||||
# anywhere else, any reachable Postgres will do.
|
|
||||||
database:
|
database:
|
||||||
dsnSecret:
|
# Required. A DSN with no password in it:
|
||||||
|
# postgres://terdut@terdut-postgres:5432/terdut?sslmode=require
|
||||||
|
#
|
||||||
|
# The password is deliberately a separate setting. pgx falls back to libpq's
|
||||||
|
# environment variables for anything the DSN omits, so PGPASSWORD supplies it
|
||||||
|
# without the credential appearing in values, in the rendered manifest, or in
|
||||||
|
# `kubectl describe pod`.
|
||||||
|
dsn: ""
|
||||||
|
# Where PGPASSWORD comes from. With the Zalando postgres operator this is the
|
||||||
|
# Secret it generates for the role — `<user>.<cluster>.credentials.postgresql.acid.zalan.do`,
|
||||||
|
# whose keys are `username` and `password` — so a from-scratch rebuild mints a
|
||||||
|
# new password and the server picks it up with nothing to keep in sync.
|
||||||
|
#
|
||||||
|
# Read at process start only: rotating the password needs a pod restart.
|
||||||
|
#
|
||||||
|
# Leave name empty only if the DSN carries its own password, which puts it in
|
||||||
|
# the manifest.
|
||||||
|
passwordSecret:
|
||||||
name: ""
|
name: ""
|
||||||
key: dsn
|
key: password
|
||||||
|
|
||||||
service:
|
service:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
|
|||||||
Reference in New Issue
Block a user