Repository navigation
fix(workflows): create-tenant fails on an existing tenant - #1650
Conversation
create-tenant creates a tenant. When platform-gitops/tenants/<name> already existed, the commit step skipped writing the tenant and carried on provisioning, so a request for a taken name ended "Succeeded" without creating anything, and validate's "not already exists" never held. validate now clones the repository and fails on an existing tenant, naming the way to re-run. The re-run path that skip existed for (935f0bb, finishing a half-provisioned tenant) stays available behind an explicit reprovision=true parameter, default false, which refuses a tenant that does not exist. The commit step refuses an existing tenant without it too, for one created between validate and its own clone. A failed clone fails validate: "could not check" is not "absent". validate also reads its parameters from env instead of interpolating them into the script, and refuses a multi-line tenant name, which the per-line grep would otherwise accept on one good line. Claude-Session: https://claude.ai/code/session_01D1kGUJMWeA8hyhQuxKuHd2
|
Claude finished @mashkovd's task in 4m 25s —— View job Review complete ✅
Verdict: APPROVE (no P1/P2, 1 P3 nit posted inline) Checked:
P3 (non-blocking): inline comment on |
Antigravity (agy) review — informationalModel: gemini-3.8-flash-medium · commit Findings[P1] Unauthenticated HTTPS clone in
|
| # for a taken name fails here instead of skipping the files and | ||
| # provisioning on. A failed clone fails the step: "could not check" | ||
| # is not "does not exist". | ||
| git clone --depth=1 "https://github.com/${GITOPS_ORG}/${GITOPS_REPO}.git" /tmp/mctl-gitops |
There was a problem hiding this comment.
P3: This clones over anonymous HTTPS (no deploy-key mount), whereas tpl-validate-tenant and commit-tenant-to-git both clone via SSH with the mctl-gitops-deploy-key deploy key. The PR description says this clones "the same way tpl-validate-tenant does" — functionally it's actually better (least-privilege: a read-only existence check doesn't need a write-capable key), but it does mean this step now depends on unauthenticated GitHub HTTPS access and is worth calling out explicitly as an intentional deviation, not an oversight.
There was a problem hiding this comment.
No P1/P2 findings (1 P3). Good to merge.
Verified: existence check order (reprovision value validated before clone, clone failure under set -e fails the step), the multi-line-name wc -l guard, the -e vs -d tightening in commit-tenant-to-git, GITOPS_ORG/GITOPS_REPO present in mctl-platform-config, the argo-workflows namespace has no egress NetworkPolicy so the new HTTPS clone needs no network changes, and that the SKIP_GIT=true path correctly skips the whole write/commit/push block via the closing fi # end SKIP_GIT while create-vault-policy still runs unconditionally per-step as intended. Test suite extracts both shell blocks directly from the template rather than restating them, so it can't drift silently.
|
Reply to agy P1 (unauthenticated HTTPS clone fails on a private repository): not applicable. |
What
wft-create-tenantnow fails when the tenant already exists, unless the re-run is asked for explicitly.alpine/git,mctl-platform-config, the same way tpl-validate-tenant does);platform-gitops/tenants/<name>exists. The error names the way to re-run.reprovision(default"false"):"true"lets an existing tenant through, for re-running its provisioning (Vault policies and roles, ApplicationSet refresh) without writing its files;"true"refuses a tenant that does not exist;trueorfalseis refused.reprovision=true. This covers a tenant created between validate and the step's own clone. Withreprovision=true, the existing skip-and-continue path (SKIP_GIT) runs as before.grep -Ewould otherwise accept it on one good line.Why
Until now, the commit step treated an existing tenant directory as "skip the commit, continue provisioning". A request for a taken name therefore ended
Succeededwithout creating anything, and the template's own header ("Validates tenant name (DNS-safe, not already exists)") was not true.That skip was added on purpose in 935f0bb, as the way to re-run a half-provisioned tenant. Nothing else in the repository depends on it: the Backstage template and mctl-api only submit new tenants, and no doc or runbook re-runs create-tenant. So the path stays, but behind an explicit opt-in instead of being the silent default.
Re-running a tenant is done by hand:
argo submit --from clusterworkflowtemplate/create-tenant -p tenant_name=<t> -p reprovision=true.mctl-api does not declare
reprovision, so API and MCP submissions always take the default.Tests
tests/test_wft_create_tenant_existing.pyruns the template's own extracted validate source and commit-step check against a fixture checkout, withgit clonestubbed. It is wired into validate-manifests. It runs 12 checks:reprovision=trueon an existing tenant passes;reprovision=trueon a missing tenant fails;reprovisionvalue fails;The test also asserts that
reprovisiondefaults tofalseand is passed to both steps.On main's template the test fails: validate gets no
reprovision, and its existence check is missing. 8 of 8 mutations are caught:true;validate-shell-param-interpolation.py,validate-tenant-workflow-shared-writes.pyandvalidate-argocd-tenant-rbac.pypass.Note
#1648 also edits validate-tenant-name's reserved-name list.
git merge-treeagainst its head merges cleanly.Type of change
Checklist
python3 tests/test_wft_create_tenant_existing.py, plus the validators above)🤖 Generated with Claude Code
https://claude.ai/code/session_01D1kGUJMWeA8hyhQuxKuHd2