diff --git a/clientdocs/self-service-guide.md b/clientdocs/self-service-guide.md index 6bcd2cb..ee9a594 100644 --- a/clientdocs/self-service-guide.md +++ b/clientdocs/self-service-guide.md @@ -92,6 +92,11 @@ The cluster gets its own load balancer for the API and can publish Services of type LoadBalancer through the same mechanism. +If you create your own template, leave the Public and Hidden checkboxes +unchecked: templates are project-scoped, publishing cloud-wide is +operator-only, and setting either flag makes the whole create fail with +the generic "Error: Unable to create cluster template." + ## When you need us instead - Quota raise, password reset, custodian change: via an authorized requester. diff --git a/clientdocs/sweep-receipt.txt b/clientdocs/sweep-receipt.txt index adc7c53..0425931 100644 --- a/clientdocs/sweep-receipt.txt +++ b/clientdocs/sweep-receipt.txt @@ -21,11 +21,11 @@ d45eb3738d7fb2742ea1a3abb5af464df8a96bfd4e6c2f56b7182b42f997b289 clientdocs/scripts/clouds.yaml.template 3dd17ab9e95d99bea0c9f36a2662e77d25ea9d691f8c60d1d314f237c7c3f655 clientdocs/scripts/smoke-test.sh 7667bb1d2ff1e315f8ecaa2b4f680d04978a79ceeeb8cc3f5e16de2b295b2205 clientdocs/scripts/tenancy-audit.sh -f20aaadc560af4af558e3e70b228c342dd38b1632108ff276cbba46178b57f9a clientdocs/self-service-guide.md +9dc67421cc8ad4248f7ce9924a1f49679a9b823131506e4c0eb31b12f6029723 clientdocs/self-service-guide.md 7644e527b6ce66804fa9e08315e51e06159a8feb525a8b7d1b8c9edf23e4a86a clientdocs/tenant-skill/SKILL.md c7708c35d1d5fceab763268f6a10ed214e23e9458018b115cb944b6a3168f182 clientdocs/tenant-skill/references/ci-automation.md 22e7ec9c16bc66fcd64264ee2fb9bd2f12076594d7702ffd94bff0f00ddc7713 clientdocs/tenant-skill/references/day2-operations.md -69bd29f8c20d6a57cc5240e0fed6e8f5022683bf3ea687e74c761552993468a4 clientdocs/tenant-skill/references/kubernetes.md +0acbc175a3b7a0c0a5af49a0a731f25ce8f0114619066c1b32473045a05483b2 clientdocs/tenant-skill/references/kubernetes.md b844e00610df813275779320a13ecc131525a89b052bd5c8ab522d7666eb4fad clientdocs/tenant-skill/references/troubleshooting.md 2135f05ccdd411ce707bc6ec54c61040284259142b4b388c0c94cae5f6e7efcb clientdocs/welcome.md e00900e6d08d19c195edee6cab5d8198295a35371cd6333a50ca5ad28940b129 docs/tenant-onboarding-contract.md diff --git a/clientdocs/tenant-skill/references/kubernetes.md b/clientdocs/tenant-skill/references/kubernetes.md index 11b2244..7dc7d4f 100644 --- a/clientdocs/tenant-skill/references/kubernetes.md +++ b/clientdocs/tenant-skill/references/kubernetes.md @@ -39,10 +39,13 @@ ## Cluster lifecycle -Your cluster template was delivered at handover: +The standard onboarding delivers a cluster template at handover: openstack coe cluster template show {{TENANT_SHORT_NAME}}-k8s +If that template is missing, or you need a variant, create your own -- +see "Creating your own cluster template" below. + Create (node counts are limited by your quota; builds take TENS OF MINUTES -- poll slowly or just wait): @@ -65,6 +68,43 @@ openstack coe cluster delete +## Creating your own cluster template + +Templates are PROJECT-SCOPED: everyone in your project can already use +them. The one hard rule: NEVER set the Public or Hidden flag (the two +checkboxes in the dashboard's Create Cluster Template dialog, or +`--public` / `--hidden` on the CLI). Publishing a template cloud-wide +is an operator-only action, and the platform refuses the whole create +with: + + Not authorized to set public or hidden flag for cluster template (HTTP 403) + +In the dashboard this surfaces only as the generic "Error: Unable to +create cluster template." -- if you see that toast, the Public/Hidden +checkboxes are the FIRST thing to check. You lose nothing by leaving +them unchecked. + +A known-good CLI starting point, mirroring the platform-delivered +template (works signed in as `-svc` or `-cluster`): + + openstack coe cluster template create \ + --coe kubernetes \ + --image \ + --external-network provider-ext \ + --master-flavor --flavor \ + --network-driver calico --docker-storage-driver overlay2 \ + --master-lb-enabled --floating-ip-enabled \ + --fixed-network {{TENANT_SHORT_NAME}}-net \ + --fixed-subnet {{TENANT_SHORT_NAME}}-subnet + +Pick the two machine sizes from `openstack flavor list`; if you have +the delivered template, `openstack coe cluster template show +{{TENANT_SHORT_NAME}}-k8s` shows the platform's known-good choices. + +Do NOT bake `--keypair` into the template: the keypair is owned by the +`-cluster` account (see the trap above), so it is passed at cluster +create time instead, exactly as the lifecycle section shows. + ## Deploying workloads: Services of type LoadBalancer The cluster gets its own load balancer for the Kubernetes API, and it diff --git a/docs/session-ledger.md b/docs/session-ledger.md index 975c564..10b6366 100644 --- a/docs/session-ledger.md +++ b/docs/session-ledger.md @@ -21,7 +21,7 @@ ## Machine-derived (re-seed from `scripts/ledger-scan.sh`; do not hand-edit) -_As of 2026-07-07 (post-addendum-33; re-run the scan to refresh):_ +_As of 2026-07-08 (post-addendum-39; re-run the scan to refresh):_ - **PROPOSED / OPEN decisions:** D-068 (Vault substrate hardening, Roosevelt -- 1.16 ruled out per amendment; off-EOL path OPEN), D-071 (routine update cadence + @@ -31,8 +31,8 @@ - **OPEN security rows:** SEC-001 (rotate at v1 close, re-ruled 2026-07-06), SEC-003 (custodians + second-person unseal -- DEFERRED; keeps d011-06 MANUAL), SEC-004 (flip repo to private at v1 close -- deferral reaffirmed). -- **Next-free numbers:** D = 075, DOCFIX = 118, BUNDLEFIX = 012. - (Scan and the addendum-33 changelog next-free pointer agree.) +- **Next-free numbers:** D = 076, DOCFIX = 123, BUNDLEFIX = 012. + (Seeded from the 2026-07-08 scan, post-addendum-39.) --- @@ -281,6 +281,23 @@ 38/38. Deferred S-class + minor R items in docs/script-quality-findings-20260707.md (operator has NOT ruled S1-S5/S7/S8). +## Jumphost stream -- session 2026-07-08: devteam cluster-template incident (addendum 39) + +- **DIAGNOSED + DELIVERED:** devteam "Unable to create cluster template" = + Public/Hidden flag -> `clustertemplate:publish` (admin_api) refusal, BY + DESIGN; read-only diagnosis, no cloud change. DOCFIX-121 (clientdocs + template-creation guidance + Public/Hidden warning) + DOCFIX-122 + (appendix-A symptom entry); L7 receipt re-recorded; ~/devteam-package + re-rendered (kubernetes.md, self-service-guide.md) for tonight's push. +- **OPEN (operator option, unruled): stage5 for devteam** -- `devteam-k8s` + was never delivered (window ran stages 0-4); one gated command + (`bash scripts/tenant-onboard.sh devteam 5`) closes the docs' delivered- + template promise; else devteam self-creates per new docs. +- **OPEN (operator, small):** role-less GUI test user in the devteam + domain (grant member or delete); Role-dropdown question on the + dashboard-override test (why load-balancer_admin was submitted) -- + evidence folded into the D-076 draft (worktree, uncommitted). + ## REMAINING OPEN WORK (single list for session resume; 2026-07-07, updated post-devteam-window) 1. **Devteam delivery -- last two steps are OPERATOR-MANUAL (everything diff --git a/docs/v1-redeploy-changelog.md b/docs/v1-redeploy-changelog.md index 980e569..aa35752 100644 --- a/docs/v1-redeploy-changelog.md +++ b/docs/v1-redeploy-changelog.md @@ -2859,4 +2859,59 @@ - Numbers consumed: DOCFIX-119, DOCFIX-120. REVERT: git checkout HEAD~ -- clientdocs docs/tenant-onboarding-contract.md docs/session-ledger.md docs/v1-redeploy-changelog.md; then bash scripts/repo-lint.sh --record-clientdocs-sweep (re-pin the receipt); cloud-side already reverted in-window. +### 2026-07-08 (addendum 39, jumphost stream) -- devteam cluster-template 403 diagnosed (Public flag, by design); DOCFIX-121/122; package re-render + +Incident: devteam (and the operator, reproducing) hit Horizon "Error: +Unable to create cluster template." as `devteam-cluster`. Diagnosed +read-only; NO cloud change made or needed. + +- **Root cause (measured):** magnum-api werkzeug log shows POST + /v1/clustertemplates -> 403 x3 (2026-07-07 23:37/23:38/23:59) then 201 + (00:06) for the SAME user+project (devteam-cluster/devteam-prod); + dashboard unit error.log carries the masked verbatim reply "Not + authorized to set public or hidden flag for cluster template (HTTP + 403)"; /etc/magnum/policy.json: `clustertemplate:create` = + deny_cluster_user (tenant-open) but `clustertemplate:publish` = + admin_api, enforced additionally when public/hidden is set. Operator + confirmed by A/B test (00:10 retest with Public checked -> 403; + unchecked -> 201). VERDICT: anti-isolation flag correctly refused -- + policy stands, do NOT relax. +- **DOCFIX-122 -- appendix-A symptom entry** ("Horizon 'Error: Unable to + create cluster template.' (Magnum 403)"): symptom/cause/trap (generic + toast masks the policy message; tracks the checkbox, not time; localize + at dashboard error.log or magnum-api, not keystone)/fix/gate. +- **DOCFIX-121 -- clientdocs template-creation guidance:** kubernetes.md + new "Creating your own cluster template" section (Public/Hidden hard + rule with the verbatim refusal + the masked-toast tell; known-good CLI + starting point mirroring stage5 flags with flavors left to + `openstack flavor list` -- the T3 leak gate correctly refused the + internal flavor literal; no --keypair in templates, keypair rides + cluster create) + delivery claim softened to "standard onboarding + delivers... if missing, create your own"; self-service-guide.md + Kubernetes section gets the same one-paragraph warning. Gates: + clientdocs-skill 8/8, clientdocs-scripts 47/47, repo-lint 0 fail, + L7 receipt re-recorded (29 files). +- **FINDING (logged, unruled): devteam has NO delivered template** -- + `devteam-k8s` does not exist; the onboarding window ran stages 0-4 only + and stage5 (template, as -svc appcred) was never executed for devteam, + while clientdocs promised "delivered at handover" (claim now softened + by DOCFIX-121). OPTION for operator: run + `bash scripts/tenant-onboard.sh devteam 5` (gated, tenant-scoped + mutation) to deliver `devteam-k8s` per contract; else devteam + self-creates per the new docs (their GUI `test1` already exists, + tenant-owned). +- **Dashboard-override side evidence (draft-only):** operator's second + GUI identity test create_grant 403 root-caused -- Horizon submitted a + `load-balancer_admin` grant (keystone access log + role-ID resolution); + domain-manager policy refused per is_domain_managed_role AS DESIGNED; + evidence + rework TODOs folded into the D-076 draft (agent worktree, + uncommitted). Operator-side leftovers: role-less test user in the + devteam domain (complete member grant or delete); why the Role + dropdown carried load-balancer_admin (answer pending). +- **Package:** ~/devteam-package re-rendered for the two changed files + (kubernetes.md, self-service-guide.md; values carried from the + delivered copies, zero tokens verified); operator pushes tonight. +- Numbers consumed: DOCFIX-121, DOCFIX-122. +REVERT: git checkout HEAD~ -- clientdocs runbooks/appendix-A-troubleshooting.md docs/session-ledger.md docs/v1-redeploy-changelog.md; then bash scripts/repo-lint.sh --record-clientdocs-sweep (re-pin the receipt); re-render the two package files from the reverted templates (or restore from the operator's previous copy); no cloud-side change to revert. + Next-free after this push (per scan, keep this line unwrapped): D-076, DOCFIX-121, BUNDLEFIX-012. diff --git a/runbooks/appendix-A-troubleshooting.md b/runbooks/appendix-A-troubleshooting.md index 1465459..8163315 100644 --- a/runbooks/appendix-A-troubleshooting.md +++ b/runbooks/appendix-A-troubleshooting.md @@ -619,6 +619,34 @@ -> exactly `302 http://10.12.4.58/horizon` (no port suffix). -------------------------------------------------------------------------------- +## Horizon "Error: Unable to create cluster template." (Magnum 403) [added DOCFIX-122] +-------------------------------------------------------------------------------- +SYMPTOM: Horizon (Container Infra > Cluster Templates > Create Cluster + Template) fails with the generic toast "Error: Unable to create + cluster template."; the identical form may succeed minutes later. + CLI equivalent: `openstack coe cluster template create ... --public` + (or `--hidden`) returns HTTP 403. +CAUSE: the request carried public=true or hidden=true (GUI checkboxes). + magnum enforces `clustertemplate:publish` = `rule:admin_api` ON TOP + of `clustertemplate:create` whenever either flag is set: cloud-wide + template visibility is operator-only BY DESIGN (hard tenant + isolation). Verbatim magnum reply, visible on the dashboard unit in + /var/log/apache2/error.log but NOT in the Horizon toast: + "Not authorized to set public or hidden flag for cluster template + (HTTP 403)". (First seen 2026-07-07/08, devteam GUI template create; + three 403s then a 201 as the checkbox varied.) +TRAP: Horizon's toast hides the policy message, so it presents as an + intermittent platform fault -- it tracks the CHECKBOX, not time. + Localize at the dashboard error.log (magnumclient Forbidden) or the + magnum-api werkzeug line (POST /v1/clustertemplates -> 403); keystone + logs show nothing for this. +FIX: none on the platform -- the policy is correct; the tenant unchecks + Public/Hidden (templates are project-scoped regardless). Do NOT + relax clustertemplate:publish. Client-facing wording: DOCFIX-121. +GATE: the same create with Public/Hidden unchecked returns 201 and the + template lists under the tenant project. + +-------------------------------------------------------------------------------- ## Point-of-use identifier index [added DOCFIX-077] -------------------------------------------------------------------------------- These identifiers are DEFINED where they are used (runbook/bundle comments), not