Test that source defines no Traefik labels

This commit is contained in:
BirSite Automation
2026-07-19 18:04:49 +00:00
parent 9540db8b46
commit d2f763c1e5

View File

@@ -16,16 +16,6 @@ COMPOSE_FILE = ROOT / "compose.yaml"
DOCKERFILE = ROOT / "Dockerfile" DOCKERFILE = ROOT / "Dockerfile"
COMPOSE_BIN = os.environ.get("COMPOSE_BIN", "/opt/data/tmp/docker-compose-birweb") COMPOSE_BIN = os.environ.get("COMPOSE_BIN", "/opt/data/tmp/docker-compose-birweb")
SYNTHETIC_RESOURCE_UUID = "contract-test-resource" SYNTHETIC_RESOURCE_UUID = "contract-test-resource"
ROUTER_PRIORITY_LABELS = {
f"traefik.http.routers.http-0-{SYNTHETIC_RESOURCE_UUID}-site.priority": "500",
f"traefik.http.routers.https-0-{SYNTHETIC_RESOURCE_UUID}-site.priority": "500",
}
SOURCE_ROUTER_PRIORITY_TEMPLATES = {
"traefik.http.routers.http-0-${UUID}-site.priority=500",
"traefik.http.routers.https-0-${UUID}-site.priority=500",
}
DOCKERFILE_SHA256 = "748bd362b43475779d241074a1955ae880967c923a7f68c693cb1c67f8b242dd" DOCKERFILE_SHA256 = "748bd362b43475779d241074a1955ae880967c923a7f68c693cb1c67f8b242dd"
BASE_IMAGE = ( BASE_IMAGE = (
"nginxinc/nginx-unprivileged:1.27-alpine@" "nginxinc/nginx-unprivileged:1.27-alpine@"
@@ -176,44 +166,33 @@ class ComposeContract(unittest.TestCase):
self.assertGreaterEqual(memory, 16 * 1024**2) self.assertGreaterEqual(memory, 16 * 1024**2)
self.assertLessEqual(memory, 512 * 1024**2) self.assertLessEqual(memory, 512 * 1024**2)
def test_rendered_traefik_router_priorities_are_exact(self) -> None: def test_source_defines_no_traefik_labels(self) -> None:
rendered_labels = self.service().get("labels") source_label_names = {
self.assertIsInstance(rendered_labels, dict) match.group(1).strip("'\"")
labels = rendered_labels if isinstance(rendered_labels, dict) else {}
self.assertEqual(labels, ROUTER_PRIORITY_LABELS)
self.assertTrue(all(isinstance(value, str) for value in labels.values()))
def test_priority_labels_use_source_list_syntax_and_uuid_interpolation(self) -> None:
source_label_items = {
match.group(1)
for match in re.finditer( for match in re.finditer(
r'^\s*-\s*["\']?(traefik\.(?:http\.)?[^"\']+?)["\']?\s*$', r'^\s*-\s*([^\s=]+)(?:=.*)?$',
self.source, self.source,
re.MULTILINE, re.IGNORECASE | re.MULTILINE,
) )
} }
required_interpolation = re.compile( source_label_names.update(
r"\$\{COOLIFY_RESOURCE_UUID:\?[^}\r\n]+\}" key
)
normalized_items = {
required_interpolation.sub("${UUID}", item)
for item in source_label_items
}
self.assertEqual(normalized_items, SOURCE_ROUTER_PRIORITY_TEMPLATES)
self.assertTrue(
all(required_interpolation.search(item) for item in source_label_items),
"each Traefik label must use required COOLIFY_RESOURCE_UUID interpolation",
)
self.assertNotIn(SYNTHETIC_RESOURCE_UUID, self.source)
mapping_labels = [
(key, line)
for _, key, line in source_mapping_keys(self.source) for _, key, line in source_mapping_keys(self.source)
if key.startswith("traefik.") )
] traefik_labels = sorted(
self.assertEqual(mapping_labels, [], "Traefik labels must use Compose list syntax") name
for name in source_label_names
if re.search(r"(?:^|[._-])traefik(?:[._-]|$)", name, re.IGNORECASE)
)
# Interpolating a label key is unsafe: Coolify preprocesses list labels
# into a mapping before Compose interpolation, leaving that key literal.
self.assertEqual(
traefik_labels,
[],
f"source Traefik labels are forbidden; Coolify owns them: {traefik_labels}",
)
def test_resource_uuid_interpolation_fails_closed_when_missing_or_empty(self) -> None: def test_compose_renders_without_resource_uuid(self) -> None:
missing_env = os.environ.copy() missing_env = os.environ.copy()
missing_env.pop("COOLIFY_RESOURCE_UUID", None) missing_env.pop("COOLIFY_RESOURCE_UUID", None)
empty_env = os.environ.copy() empty_env = os.environ.copy()
@@ -222,12 +201,11 @@ class ComposeContract(unittest.TestCase):
for case, env in (("missing", missing_env), ("empty", empty_env)): for case, env in (("missing", missing_env), ("empty", empty_env)):
with self.subTest(case=case): with self.subTest(case=case):
rendered = run(self.render_command, env=env) rendered = run(self.render_command, env=env)
self.assertNotEqual( self.assertEqual(
rendered.returncode, rendered.returncode,
0, 0,
f"Compose config accepted a {case} COOLIFY_RESOURCE_UUID", f"Compose config rejected a {case} COOLIFY_RESOURCE_UUID:\n{rendered.stderr}",
) )
self.assertIn("COOLIFY_RESOURCE_UUID", rendered.stderr)
def test_no_secrets_bind_mounts_or_forbidden_source_keys(self) -> None: def test_no_secrets_bind_mounts_or_forbidden_source_keys(self) -> None:
service = self.service() service = self.service()