Add valkey/redis driver with operator-secret auto-configuration
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/pre-commit Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/build Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/pre-commit Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Apps fronted by valkey-operator instances need the same wait-for-ready initContainer postgres workloads already get, and wiring per-field secretKeyRefs for operator-generated secrets is boilerplate. waitfordb now speaks enough RESP to AUTH and PING, and natively understands the secret shapes CNPG and valkey-operator generate so an initContainer is just envFrom plus a mode variable. - valkey driver (alias: redis): fresh TCP connection per attempt, optional AUTH (ACL user or default), PING, reusing the existing retry/backoff wait loop; redis:///valkey:// DSNs; default port 6379 - WAITFORDB_SECRET_FORMAT=cnpg|valkey for envFrom-injected operator secrets: CNPG <cluster>-app host/port/dbname/user/password keys, and valkey-operator key-per-username secrets (_operator preferred, or WAITFORDB_USER's same-named key) - autodetection from injected keys (CNPG keys -> postgres, valkey keys -> valkey); explicit WAITFORDB_DRIVER/WAITFORDB_* always win, PG* fallback and all existing flags unchanged - valkey needs no user/database to be valid (unauthenticated PING) - tests: secret shape parsing/autodetect/mismatch, fake RESP server covering NOAUTH/WRONGPASS/ACL auth/DSN, retry-until-up wait - README: envFrom initContainer snippets for CNPG and valkey-operator
This commit is contained in:
@@ -5,33 +5,85 @@ It is designed to run as a Kubernetes **initContainer** so an app never starts
|
||||
before its database can serve queries, without hand-writing a `psql`-in-a-shell
|
||||
probe in every workload.
|
||||
|
||||
Readiness means a trivial liveness query (`SELECT 1`) succeeds under the given
|
||||
credentials and database — proving the **server is up, auth works, and the
|
||||
target database/role exist**. On timeout it exits non-zero so the pod fails
|
||||
fast and Kubernetes restarts it.
|
||||
Readiness means a trivial liveness query (`SELECT 1`, or `PING` for
|
||||
valkey/redis) succeeds under the given credentials and database — proving the
|
||||
**server is up, auth works, and the target database/role exist**. On timeout it
|
||||
exits non-zero so the pod fails fast and Kubernetes restarts it.
|
||||
|
||||
`postgres` is the default driver; `mysql` is also supported. Configuration is
|
||||
entirely via environment variables.
|
||||
`postgres` is the default driver; `mysql` and `valkey` (alias: `redis`) are
|
||||
also supported. Configuration is entirely via environment variables.
|
||||
|
||||
## Environment variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --------------------------- | ------------ | ------------------------------------------------------------------ |
|
||||
| `WAITFORDB_DRIVER` | `postgres` | Database driver: `postgres` or `mysql`. |
|
||||
| `WAITFORDB_DRIVER` | `postgres` | Database driver: `postgres`, `mysql`, or `valkey` (alias: `redis`). |
|
||||
| `WAITFORDB_HOST` | `localhost` | Database host. Postgres falls back to `PGHOST`. |
|
||||
| `WAITFORDB_PORT` | `5432`/`3306`| Database port (driver default). Postgres falls back to `PGPORT`. |
|
||||
| `WAITFORDB_USER` | — | Username. Postgres falls back to `PGUSER`. Required (unless DSN). |
|
||||
| `WAITFORDB_PASSWORD` | — | Password. Postgres falls back to `PGPASSWORD`. |
|
||||
| `WAITFORDB_DATABASE` | — | Database name. Postgres falls back to `PGDATABASE`. Required (unless DSN). |
|
||||
| `WAITFORDB_SSLMODE` | driver default | Postgres sslmode (e.g. `disable`). Falls back to `PGSSLMODE`. |
|
||||
| `WAITFORDB_DSN` | — | Full driver-native connection string. Overrides all fields above. |
|
||||
| `WAITFORDB_DSN` | — | Full driver-native connection string. Overrides all fields above. Valkey accepts `redis://`/`valkey://` URLs. |
|
||||
| `WAITFORDB_SECRET_FORMAT` | autodetected | Operator secret shape injected via `envFrom`: `cnpg` or `valkey`. See below. |
|
||||
| `WAITFORDB_TIMEOUT` | `0` (forever)| Total wait budget as a Go duration (e.g. `5m`). `0` waits forever. |
|
||||
| `WAITFORDB_INTERVAL` | `2s` | Gap between retries. |
|
||||
| `WAITFORDB_CONNECT_TIMEOUT` | `5s` | Per-attempt connect timeout, so a black-holed host cannot hang. |
|
||||
|
||||
**Precedence for connection parameters:** `WAITFORDB_DSN` > `WAITFORDB_*` > `PG*`.
|
||||
The `PG*` (libpq) fallback applies to the **postgres** driver only, so the tool
|
||||
is a drop-in replacement anywhere those variables are already set.
|
||||
**Precedence for connection parameters:** `WAITFORDB_DSN` > `WAITFORDB_*` >
|
||||
`PG*` > operator-secret keys. The `PG*` (libpq) fallback applies to the
|
||||
**postgres** driver only, so the tool is a drop-in replacement anywhere those
|
||||
variables are already set.
|
||||
|
||||
## Operator secrets via `envFrom`
|
||||
|
||||
waitfordb natively understands the secrets that CloudNativePG and
|
||||
valkey-operator generate, so an initContainer is just an `envFrom` plus (at
|
||||
most) a mode variable — no `secretKeyRef` plumbing per field.
|
||||
|
||||
- **`cnpg`** — a CNPG `<cluster>-app` secret (`host`/`port`/`dbname`/`user`/
|
||||
`password` keys) fills the postgres connection parameters.
|
||||
- **`valkey`** — a valkey-operator generated secret where each key is a
|
||||
username and its value the password (e.g. the system-passwords secret with
|
||||
`_operator`/`_replication`). waitfordb authenticates as `_operator` when
|
||||
present, or as `WAITFORDB_USER` with the password taken from the key of the
|
||||
same name.
|
||||
|
||||
The format is autodetected from the injected keys (CNPG keys → postgres,
|
||||
valkey/redis keys → valkey); set `WAITFORDB_SECRET_FORMAT` to pin it. Explicit
|
||||
`WAITFORDB_*` variables always win over secret keys.
|
||||
|
||||
Wait for a CNPG cluster:
|
||||
|
||||
```yaml
|
||||
initContainers:
|
||||
- name: wait-for-db
|
||||
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/waitfordb:latest
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: mydb-app # CNPG <cluster>-app secret
|
||||
env:
|
||||
- name: WAITFORDB_TIMEOUT
|
||||
value: 5m
|
||||
```
|
||||
|
||||
Wait for a valkey-operator instance:
|
||||
|
||||
```yaml
|
||||
initContainers:
|
||||
- name: wait-for-valkey
|
||||
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/waitfordb:latest
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: internal-myapp-valkey-system-passwords
|
||||
env:
|
||||
- name: WAITFORDB_SECRET_FORMAT
|
||||
value: valkey # optional; autodetected from the _operator key
|
||||
- name: WAITFORDB_HOST
|
||||
value: myapp-valkey.myns.svc
|
||||
- name: WAITFORDB_TIMEOUT
|
||||
value: 5m
|
||||
```
|
||||
|
||||
### Exit codes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user