Silence applier-apply under --quiet and drop the retired bao callback default
The warden attended wrapper refuses any output, so --quiet now captures bao's own messages and skips the [OK] lines; a failure reports only the step and exit code. New OIDC scaffolds default to the operator-tunnel UI callback rather than bao.coulomb.social, which was retired on 2026-09-15. Existing CCRs keep their lists until amended. The CCR-2026-0033 test pins move to its approved/applied state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 132360@bnt-lap001 Assistant-Session: 769b1afd-4330-4c86-96b2-e510e26db42b
This commit is contained in:
parent
614d70fb8a
commit
720277bd39
3 changed files with 50 additions and 13 deletions
|
|
@ -117,14 +117,14 @@ python3 scripts/credential-change.py applier-apply credential-change-requests/CC
|
|||
# apply (attended platform-admin; one phrase per CCR)
|
||||
warden access openbao-platform-admin-login --exec -- \
|
||||
python3 scripts/credential-change.py applier-apply credential-change-requests/CCR-2026-0033.yaml \
|
||||
--confirm "DELEGATED APPLY CCR-2026-0033" --actor founder --record-state-hub
|
||||
--confirm "DELEGATED APPLY CCR-2026-0033" --actor founder --record-state-hub --quiet
|
||||
warden access openbao-platform-admin-login --exec -- \
|
||||
python3 scripts/credential-change.py applier-apply credential-change-requests/CCR-2026-0034.yaml \
|
||||
--confirm "DELEGATED APPLY CCR-2026-0034" --actor founder --record-state-hub
|
||||
--confirm "DELEGATED APPLY CCR-2026-0034" --actor founder --record-state-hub --quiet
|
||||
```
|
||||
|
||||
Expected: `[OK] CCR-2026-0033.yaml delegated metadata apply recorded`, the same for
|
||||
0034, and a value-free evidence entry in each CCR.
|
||||
Expected: exit 0 with no output (`--quiet`, which the warden wrapper requires) and a
|
||||
value-free `delegated_metadata_apply` evidence entry in each CCR.
|
||||
|
||||
ESO: `eso.draft.yaml` in this directory carries `railiance.io/admission:
|
||||
pending-review`. Promote it to `approved` in a reviewed commit after A2 first. Then:
|
||||
|
|
|
|||
|
|
@ -1182,7 +1182,7 @@ def render_runbook(payload: dict[str, Any]) -> str:
|
|||
return "\n".join(lines)
|
||||
|
||||
|
||||
def run_bao_metadata_apply(ccr: dict[str, Any], bao_bin: str) -> None:
|
||||
def run_bao_metadata_apply(ccr: dict[str, Any], bao_bin: str, quiet: bool = False) -> None:
|
||||
openbao = ccr["openbao"]
|
||||
auth = openbao["auth"]
|
||||
auth_path = f"auth/{auth['mount']}/role/{auth['role']}"
|
||||
|
|
@ -1196,7 +1196,14 @@ def run_bao_metadata_apply(ccr: dict[str, Any], bao_bin: str) -> None:
|
|||
[bao_bin, "write", auth_path, f"@{role_path}"],
|
||||
]
|
||||
for command in commands:
|
||||
subprocess.run(command, cwd=REPO_DIR, check=True)
|
||||
if not quiet:
|
||||
subprocess.run(command, cwd=REPO_DIR, check=True)
|
||||
continue
|
||||
# Silent mode for attended wrappers that refuse any output. bao's own
|
||||
# messages are discarded; a failure reports only the step and exit code.
|
||||
result = subprocess.run(command, cwd=REPO_DIR, capture_output=True)
|
||||
if result.returncode != 0:
|
||||
fail(f"bao {command[1]} failed with exit code {result.returncode}")
|
||||
finally:
|
||||
try:
|
||||
role_path.unlink()
|
||||
|
|
@ -1494,7 +1501,8 @@ def inventory_ccr_from_args(args: argparse.Namespace) -> dict[str, Any]:
|
|||
allowed_redirect_uris = list(getattr(args, "redirect_uri", None) or [])
|
||||
if args.auth_method == "oidc" and not allowed_redirect_uris:
|
||||
allowed_redirect_uris = [
|
||||
"https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback",
|
||||
# bao.coulomb.social was retired on 2026-09-15; the UI goes through the operator tunnel.
|
||||
"http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback",
|
||||
"http://localhost:8250/oidc/callback",
|
||||
"http://127.0.0.1:8250/oidc/callback",
|
||||
]
|
||||
|
|
@ -2053,7 +2061,7 @@ def command_applier_apply(args: argparse.Namespace) -> int:
|
|||
phrase = args.confirm or input("Type delegated apply confirmation phrase: ")
|
||||
if phrase != expected:
|
||||
fail(f"confirmation phrase mismatch; expected {expected!r}")
|
||||
run_bao_metadata_apply(ccr, args.bao_bin)
|
||||
run_bao_metadata_apply(ccr, args.bao_bin, quiet=args.quiet)
|
||||
set_status = "applied" if ccr.get("status") == "approved" else None
|
||||
details = delegated_apply_details(ccr, args.actor)
|
||||
ccr = append_evidence(
|
||||
|
|
@ -2064,7 +2072,8 @@ def command_applier_apply(args: argparse.Namespace) -> int:
|
|||
details,
|
||||
set_status=set_status,
|
||||
)
|
||||
print(f"[OK] {path.name} delegated metadata apply recorded")
|
||||
if not args.quiet:
|
||||
print(f"[OK] {path.name} delegated metadata apply recorded")
|
||||
if args.record_state_hub:
|
||||
event = record_evidence_state_hub(
|
||||
ccr,
|
||||
|
|
@ -2074,7 +2083,8 @@ def command_applier_apply(args: argparse.Namespace) -> int:
|
|||
"passed",
|
||||
details,
|
||||
)
|
||||
print(f"[OK] State Hub progress event {event.get('id', '<unknown>')}")
|
||||
if not args.quiet:
|
||||
print(f"[OK] State Hub progress event {event.get('id', '<unknown>')}")
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -436,6 +436,32 @@ class CredentialChangeTests(unittest.TestCase):
|
|||
self.assertEqual(payload["bound_service_account_namespaces"], ["external-secrets"])
|
||||
self.assertNotIn("bound_claims", payload)
|
||||
|
||||
def test_quiet_metadata_apply_captures_bao_output(self) -> None:
|
||||
ccr, errors, _warnings = credential_change.validate_ccr(self.sample)
|
||||
self.assertEqual(errors, [])
|
||||
seen = []
|
||||
|
||||
class Done:
|
||||
returncode = 0
|
||||
|
||||
def fake_run(command, **kwargs):
|
||||
seen.append(kwargs.get("capture_output"))
|
||||
return Done()
|
||||
|
||||
original = credential_change.subprocess.run
|
||||
credential_change.subprocess.run = fake_run
|
||||
try:
|
||||
credential_change.run_bao_metadata_apply(ccr, "bao", quiet=True)
|
||||
finally:
|
||||
credential_change.subprocess.run = original
|
||||
self.assertEqual(seen, [True, True])
|
||||
|
||||
def test_scaffold_default_redirects_exclude_retired_public_host(self) -> None:
|
||||
source = (REPO_DIR / "scripts/credential-change.py").read_text()
|
||||
default = source.split('if args.auth_method == "oidc" and not allowed_redirect_uris:', 1)[1].split("]", 1)[0]
|
||||
self.assertNotIn('"https://bao.coulomb.social', default)
|
||||
self.assertIn("http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback", default)
|
||||
|
||||
def test_oidc_auth_payload_includes_redirect_uris(self) -> None:
|
||||
ccr, errors, _warnings = credential_change.validate_ccr(self.sample)
|
||||
self.assertEqual(errors, [])
|
||||
|
|
@ -505,12 +531,13 @@ class CredentialChangeTests(unittest.TestCase):
|
|||
self.assertEqual(errors, [])
|
||||
self.assertNotIn("consumer_copy", ccr)
|
||||
self.assertEqual(ccr["target"]["domain"], "infotech")
|
||||
self.assertEqual(ccr["status"], "proposed")
|
||||
# Approved under 2ab717e1 and applied on 2026-10-07.
|
||||
self.assertIn(ccr["status"], credential_change.POST_APPLY_STATUSES)
|
||||
meta = ccr["openbao"]["kv_metadata"]
|
||||
self.assertEqual((meta["cas_required"], meta["max_versions"], meta["delete_version_after"]),
|
||||
(True, 2, "0s"))
|
||||
self.assertEqual(meta["custom_metadata"]["readers"], "eso-sso-issuer,oidc-secrets-engine-operator")
|
||||
self.assertIs(ccr["openbao"]["auth"]["bound_claims_confirmed"], False)
|
||||
self.assertIs(ccr["openbao"]["auth"]["bound_claims_confirmed"], True)
|
||||
|
||||
def test_apply_plan_refuses_unapproved_ccr(self) -> None:
|
||||
with self.assertRaises(SystemExit):
|
||||
|
|
@ -795,7 +822,7 @@ class CredentialChangeTests(unittest.TestCase):
|
|||
original_apply = credential_change.run_bao_metadata_apply
|
||||
original_post = credential_change.state_hub_post_json
|
||||
try:
|
||||
credential_change.run_bao_metadata_apply = lambda ccr, bao_bin: calls.append((ccr["id"], bao_bin))
|
||||
credential_change.run_bao_metadata_apply = lambda ccr, bao_bin, quiet=False: calls.append((ccr["id"], bao_bin))
|
||||
credential_change.state_hub_post_json = (
|
||||
lambda _base_url, _path, payload: events.append(payload) or {"id": "event-1"}
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue