fix: task templates use ingress CP_URL (https://agents.oreillyit.nz/api), not svc.cluster.local:8100
The deploy repo NetworkPolicy admits :8100 only from named apps and the traefik/cms-proxy namespaces; agent/script pods time out, so state-tx / cp-cli calls silently lost transitions. Invariant now rejects the in-cluster form and pins the ingress URL. Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
This commit is contained in:
@@ -60,3 +60,58 @@ def test_state_tx_node_declares_from_states(name):
|
||||
assert doc["output"]["state"] not in states
|
||||
# The template's own input state must be an acceptable from-state.
|
||||
assert doc["input"]["state"] in states
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# CP_URL must be the ingress form, never the in-cluster Service on :8100.
|
||||
#
|
||||
# The deploy repo's networkpolicy-cp-internal-traefik-only.yaml admits :8100 only
|
||||
# from dashboard / git-planner-backend / cert-expiry-checker and the traefik and
|
||||
# cms-proxy namespaces. Agent/script pods are dropped, so a template pointing
|
||||
# CP_URL at svc.cluster.local:8100 times out (30s) and, with on_fail: continue,
|
||||
# silently loses the transition. The workflow scripts join CP_URL + "/v1/...",
|
||||
# so the /api ingress path prefix is preserved.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
CP_URL_INGRESS = "https://agents.oreillyit.nz/api"
|
||||
_FORBIDDEN_CP_URL_MARKERS = ("svc.cluster.local:8100", "controlplane.agent-runtimes.svc")
|
||||
|
||||
_ALL_TEMPLATES = sorted(_DIR.glob("*.yaml"))
|
||||
|
||||
|
||||
def _cp_url_values(path: Path) -> list[str]:
|
||||
doc = yaml.safe_load(path.read_text())
|
||||
return [
|
||||
(n.get("runtime_env") or {})["CP_URL"]
|
||||
for n in (doc.get("nodes") or [])
|
||||
if "CP_URL" in (n.get("runtime_env") or {})
|
||||
]
|
||||
|
||||
|
||||
def test_cp_url_templates_discovered():
|
||||
names = {p.name for p in _ALL_TEMPLATES if _cp_url_values(p)}
|
||||
assert {
|
||||
"test-validate@1.yaml",
|
||||
"frozen-fixture-emit@1.yaml",
|
||||
"bug-ancestor-auto-advance@1.yaml",
|
||||
"scope-decompose-sonnet@1.yaml",
|
||||
"scope-decompose-sonnet@2.yaml",
|
||||
"bug-verify-sonnet@1.yaml",
|
||||
"bug-verify-sonnet@2.yaml",
|
||||
} <= names
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", _ALL_TEMPLATES, ids=lambda p: p.name)
|
||||
def test_cp_url_is_ingress_not_in_cluster_service(path):
|
||||
for value in _cp_url_values(path):
|
||||
assert not any(m in value for m in _FORBIDDEN_CP_URL_MARKERS), (
|
||||
f"{path.name}: CP_URL={value!r} targets the in-cluster CP service; agent pods "
|
||||
"are blocked on :8100 by NetworkPolicy"
|
||||
)
|
||||
assert value == CP_URL_INGRESS, f"{path.name}: CP_URL={value!r}"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("path", _ALL_TEMPLATES, ids=lambda p: p.name)
|
||||
def test_no_template_mentions_in_cluster_cp_service(path):
|
||||
text = path.read_text()
|
||||
assert not any(m in text for m in _FORBIDDEN_CP_URL_MARKERS)
|
||||
|
||||
Reference in New Issue
Block a user