fix(database): k8s-valid label value for mirror-of (#315) #316

Merged
forgejo_admin merged 1 commit from 315-fix-mirror-label-value into main 2026-04-30 11:08:38 +00:00
Contributor

Summary

Replace / with . in the mirror-of label value on kubernetes_secret_v1.admin_app_db_url_westside_admin. K8s API rejects / in label values; tofu validate doesn't catch it.

Why

PR #310 added the mirror secret with label mirror-of = "basketball-api/admin-app-db-url". K8s label VALUES (vs label key prefixes like app.kubernetes.io/managed-by) cannot contain / per the k8s validation regex (([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?. The / was meant as a namespace/name reference; replacing with . preserves intent and passes validation.

Discovered when Ava ran make tofu-apply after Lucas's "do it" auth — apply errored on this resource. Pre-merge tofu validate passed because it's syntactically valid HCL. Only runtime k8s API validation surfaces it.

Changes

  • terraform/modules/database/main.tf line 309 — change "basketball-api/admin-app-db-url" to "basketball-api.admin-app-db-url"

Test Plan

  • Local tofu plan -lock=false -var-file=k3s.tfvars (in worktree) shows the resource still planned with new label
  • After merge: tofu apply proceeds past kubernetes_secret_v1.admin_app_db_url_westside_admin without label error
  • After apply: kubectl get secret admin-app-db-url -n westside-admin --show-labels shows mirror-of=basketball-api.admin-app-db-url

Review Checklist

  • Single-line value change
  • No structural change to resource
  • Label value still preserves provenance intent (namespace.name instead of namespace/name)
  • Closes #315
  • Story+arch trace present (story:admin-row-crud, arch:postgres)
  • Caused by: PR #310 (mirror secret addition, merged unblocked)
  • Blocks: pal-e-platform PR #304 apply (same plan run)
  • Lesson: any new k8s resource PR's verification should include actual tofu apply against state, not just tofu validate. Worth a follow-up to convention.
  • Memory: feedback_verification_before_completion

Closes #315

## Summary Replace `/` with `.` in the `mirror-of` label value on `kubernetes_secret_v1.admin_app_db_url_westside_admin`. K8s API rejects `/` in label values; tofu validate doesn't catch it. ## Why PR #310 added the mirror secret with label `mirror-of = "basketball-api/admin-app-db-url"`. K8s label VALUES (vs label key prefixes like `app.kubernetes.io/managed-by`) cannot contain `/` per the k8s validation regex `(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?`. The `/` was meant as a `namespace/name` reference; replacing with `.` preserves intent and passes validation. Discovered when Ava ran `make tofu-apply` after Lucas's "do it" auth — apply errored on this resource. Pre-merge tofu validate passed because it's syntactically valid HCL. Only runtime k8s API validation surfaces it. ## Changes - `terraform/modules/database/main.tf` line 309 — change `"basketball-api/admin-app-db-url"` to `"basketball-api.admin-app-db-url"` ## Test Plan - [x] Local `tofu plan -lock=false -var-file=k3s.tfvars` (in worktree) shows the resource still planned with new label - [ ] After merge: `tofu apply` proceeds past `kubernetes_secret_v1.admin_app_db_url_westside_admin` without label error - [ ] After apply: `kubectl get secret admin-app-db-url -n westside-admin --show-labels` shows `mirror-of=basketball-api.admin-app-db-url` ## Review Checklist - [x] Single-line value change - [x] No structural change to resource - [x] Label value still preserves provenance intent (`namespace.name` instead of `namespace/name`) - [x] Closes #315 - [x] Story+arch trace present (`story:admin-row-crud`, `arch:postgres`) ## Related Notes - Caused by: PR #310 (mirror secret addition, merged unblocked) - Blocks: pal-e-platform PR #304 apply (same plan run) - Lesson: any new k8s resource PR's verification should include actual `tofu apply` against state, not just `tofu validate`. Worth a follow-up to convention. - Memory: `feedback_verification_before_completion` Closes #315
fix(database): k8s-valid label value for mirror-of (#315)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
4cb7ca8b61
Replace '/' with '.' in mirror-of label value. K8s API rejects
'/' in label VALUES (only valid in label key prefixes). Tofu
validate passed because it's syntactically valid HCL — only the
runtime k8s API validation catches it.

Closes #315

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Author
Contributor

PR #316 Review

DOMAIN REVIEW

Tech stack: Terraform / Kubernetes (kubernetes_secret_v1).

  • Diff is exactly the 1-character change at terraform/modules/database/main.tf line 309 — no collateral.
  • Label key mirror-of is unprefixed (bare key), which is valid; bare keys do not allow / in their values either, so the fix is correct.
  • New value basketball-api.admin-app-db-url satisfies k8s label value regex (([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])? — starts/ends alphanumeric, only contains -, ., alphanumerics, well under 63 chars.
  • Semantics preserved: namespace.name substitution for namespace/name retains provenance intent. Downstream consumers (label selectors, kubectl queries) need to use the dot form — no consumers exist yet, so no breakage.
  • Resource structure unchanged.

BLOCKERS

None.

NITS

  • Consider promoting the lesson ("tofu validate doesn't catch runtime k8s API rejections; apply against state is the real gate") into a convention note as the PR body itself suggests. Track as a follow-up.

SOP COMPLIANCE

  • Branch named 315-fix-mirror-label-value (issue-prefixed)
  • PR body has Summary / Why / Changes / Test Plan / Related
  • Closes #315 present
  • story:admin-row-crud + arch:postgres traceability labels present in resource and noted in body
  • No secrets, no scope creep
  • Single-file, single-line surgical fix

PROCESS OBSERVATIONS

Tight cycle time, minimal blast radius, unblocks tofu apply for PR #304 plan run. Change failure risk near zero. Reinforces the "apply-against-state" verification gap noted in PR body — worth a convention note as discovered scope.

VERDICT: APPROVED

## PR #316 Review ### DOMAIN REVIEW Tech stack: Terraform / Kubernetes (kubernetes_secret_v1). - Diff is exactly the 1-character change at `terraform/modules/database/main.tf` line 309 — no collateral. - Label key `mirror-of` is unprefixed (bare key), which is valid; bare keys do not allow `/` in their values either, so the fix is correct. - New value `basketball-api.admin-app-db-url` satisfies k8s label value regex `(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?` — starts/ends alphanumeric, only contains `-`, `.`, alphanumerics, well under 63 chars. - Semantics preserved: `namespace.name` substitution for `namespace/name` retains provenance intent. Downstream consumers (label selectors, kubectl queries) need to use the dot form — no consumers exist yet, so no breakage. - Resource structure unchanged. ### BLOCKERS None. ### NITS - Consider promoting the lesson ("tofu validate doesn't catch runtime k8s API rejections; apply against state is the real gate") into a convention note as the PR body itself suggests. Track as a follow-up. ### SOP COMPLIANCE - [x] Branch named `315-fix-mirror-label-value` (issue-prefixed) - [x] PR body has Summary / Why / Changes / Test Plan / Related - [x] `Closes #315` present - [x] story:admin-row-crud + arch:postgres traceability labels present in resource and noted in body - [x] No secrets, no scope creep - [x] Single-file, single-line surgical fix ### PROCESS OBSERVATIONS Tight cycle time, minimal blast radius, unblocks `tofu apply` for PR #304 plan run. Change failure risk near zero. Reinforces the "apply-against-state" verification gap noted in PR body — worth a convention note as discovered scope. ### VERDICT: APPROVED
forgejo_admin deleted branch 315-fix-mirror-label-value 2026-04-30 11:08:38 +00:00
Sign in to join this conversation.
No description provided.