feat(ansible): a run's scope reads as the target or group it names
#5014 "Ansible run scope is shown as a raw id" - inventory_gen.describe_scope / scope_labels turn "steward:target:<uuid>" into "target web-1", "steward:group:<uuid>" into "group Docker Swarm", and a deleted one into "target abcdef01 (deleted)". - MCP run and schedule rows carry scope_label beside the stored scope; the ansible.run.started audit detail records it too. - The web run page and schedules table show the name, with the stored scope as the tooltip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -128,3 +128,13 @@ def test_yaml_injected_hostvars_survive():
|
||||
def test_yaml_empty_targets():
|
||||
parsed = yaml.safe_load(inventory_to_yaml(generate_inventory([])))
|
||||
assert parsed == {"all": {"hosts": {}}}
|
||||
|
||||
|
||||
def test_describe_scope_names_what_a_run_targeted():
|
||||
from steward.ansible.inventory_gen import describe_scope
|
||||
targets, groups = {"t1": "web-1"}, {"g1": "Docker Swarm"}
|
||||
assert describe_scope("steward:all", targets, groups) == "all inventory targets"
|
||||
assert describe_scope("steward:target:t1", targets, groups) == "target web-1"
|
||||
assert describe_scope("steward:group:g1", targets, groups) == "group Docker Swarm"
|
||||
assert describe_scope("steward:target:abcdef0123", targets, groups) == "target abcdef01 (deleted)"
|
||||
assert describe_scope("repo:homelab:hosts.yml", targets, groups) == "homelab/hosts.yml"
|
||||
|
||||
@@ -121,6 +121,8 @@ def test_runs_schedules_and_alert_actions_through_mcp(app, tmp_path):
|
||||
done = await a.wait_for_run(started["run_id"], timeout_s=120)
|
||||
assert done["finished"] and done["status"] == "success", done["tail"]
|
||||
assert done["check"] is True and done["triggered_by"] == username
|
||||
# The scope reads as the target's name, not its id.
|
||||
assert done["scope"].startswith("steward:target:") and done["scope_label"] == f"target {target_name}"
|
||||
assert not out_file.exists()
|
||||
log = "\n".join(done["tail"])
|
||||
assert "GREETING-yo" in log and f"TOKEN-LEN-{len(SECRET)}" in log
|
||||
@@ -134,6 +136,7 @@ def test_runs_schedules_and_alert_actions_through_mcp(app, tmp_path):
|
||||
detail = json.loads(rows[0].detail_json)
|
||||
assert detail["check"] is True and detail["token_id"] == 42
|
||||
assert detail["secret_vars"] == ["api_token"] and SECRET not in rows[0].detail_json
|
||||
assert detail["scope_label"].startswith(f"target {target_name}")
|
||||
|
||||
# ── applying a confirm playbook needs confirmed=true ──────────────
|
||||
with pytest.raises(ValueError, match="flagged destructive"):
|
||||
@@ -166,7 +169,7 @@ def test_runs_schedules_and_alert_actions_through_mcp(app, tmp_path):
|
||||
sc = await a.create_schedule(f"sched-{tag}", src, "play.yml", 3600,
|
||||
scope=f"target:{target_name}",
|
||||
extra_vars={"out_file": str(out_file)})
|
||||
assert sc["check"] is True and sc["enabled"] is True
|
||||
assert sc["check"] is True and sc["enabled"] is True and sc["scope_label"] == f"target {target_name}"
|
||||
up = await a.update_schedule(f"sched-{tag}", enabled=False, interval_s=86400)
|
||||
assert (up["enabled"], up["interval_s"], up["check"]) == (False, 86400, True)
|
||||
assert up["extra_vars"] == {"out_file": str(out_file)} # untouched fields stay
|
||||
|
||||
Reference in New Issue
Block a user