Merge origin/main into feature/svc-net-wireguard

Brings in 225 commits, including the merged web-app-openbao work and the
LMStudio loopback fix.

Seven conflicts:

- The legacy svc-net-wireguard-core/plain/firewalled roles this branch deleted
  in e706170a0 were modified upstream. The deletion stands, which is the whole
  premise of the branch.
- The MCP audit takes upstream's list plus svc-net-firewall, with the three
  legacy wireguard entries collapsed into the single svc-net-wireguard: 23.
- web-app-openbao/README.md takes main's reviewed version wholesale.
- matrix.py takes both sides: upstream's app_id argument to _reset_credentials
  and this branch's _write_mesh call after it.

The merge pushed matrix.py to 511 lines against the 500 cap, so the step
runner moved to utils/tests/swarm/run.py, which is self-contained and leaves
matrix.py at 427. Its test moved with it.
This commit is contained in:
evangelostsak committed 2026-09-24 21:14:25 +02:00
commit 0a6700e378
437 files changed
+12903 -1724

No files matched your search

@@ -1,91 +0,0 @@
"""Unit tests for `cli.administration.deploy.development.inventory.nested_overrides`.
The service registry is stubbed: what matters is which role a claim is
attributed to, not how a service key resolves to its provider.
"""
from __future__ import annotations
import unittest
from unittest.mock import patch
from cli.administration.deploy.development.inventory.nested_overrides import (
NestedOverrideConflictError,
collect_provider_overrides,
)
_REGISTRY = {
"openwebui": {"role": "web-app-openwebui"},
"gitea": {"role": "web-app-gitea"},
}
_PATCH = (
"cli.administration.deploy.development.inventory.nested_overrides"
".build_service_registry_from_roles_dir"
)
class TestCollectProviderOverrides(unittest.TestCase):
def _collect(self, payloads, registry=None):
with patch(_PATCH, autospec=True) as build:
build.return_value = _REGISTRY if registry is None else registry
return collect_provider_overrides(payloads, roles_dir="/roles")
def test_a_named_topic_reaches_its_provider(self) -> None:
payloads = {
"web-app-moodle": {"services": {"openwebui": {"services": None}}},
}
self.assertEqual(
{"web-app-openwebui": {"services": None}}, self._collect(payloads)
)
def test_several_topics_of_one_provider_are_collected_together(self) -> None:
payloads = {
"web-app-moodle": {
"services": {
"openwebui": {"services": None, "addons": {"whisper": False}},
},
},
}
self.assertEqual(
{"web-app-openwebui": {"services": None, "addons": {"whisper": False}}},
self._collect(payloads),
)
def test_a_roles_own_entry_is_not_an_override(self) -> None:
payloads = {"web-app-gitea": {"services": {"gitea": {"users": {"a": 1}}}}}
self.assertEqual({}, self._collect(payloads))
def test_an_unregistered_service_key_is_skipped(self) -> None:
payloads = {"web-app-moodle": {"services": {"nowhere": {"services": None}}}}
self.assertEqual({}, self._collect(payloads))
def test_two_roles_agreeing_is_not_a_conflict(self) -> None:
payloads = {
"web-app-moodle": {"services": {"openwebui": {"services": None}}},
"web-app-gitea": {"services": {"openwebui": {"services": None}}},
}
self.assertEqual(
{"web-app-openwebui": {"services": None}}, self._collect(payloads)
)
def test_two_roles_demanding_different_values_raises(self) -> None:
payloads = {
"web-app-moodle": {"services": {"openwebui": {"services": None}}},
"web-app-gitea": {"services": {"openwebui": {"services": {"a": 1}}}},
}
with self.assertRaises(NestedOverrideConflictError):
self._collect(payloads)
def test_a_round_without_overrides_never_builds_the_registry(self) -> None:
payloads = {"web-app-moodle": {"services": {"openwebui": {"enabled": True}}}}
with patch(_PATCH, autospec=True) as build:
build.return_value = _REGISTRY
self.assertEqual(
{}, collect_provider_overrides(payloads, roles_dir="/roles")
)
build.assert_not_called()
if __name__ == "__main__":
unittest.main()
@@ -53,6 +53,10 @@ users:
6e6577730a
biber:
password: VeryUnsecurePassword!1
keycloak-bot:
password: !vault |
$ANSIBLE_VAULT;1.1;AES256
626f740a
"""
DECLARED_USERS = """\
@@ -63,6 +67,14 @@ newsletter:
uid: 1002
"""
KEYCLOAK_USERS = (
DECLARED_USERS
+ """\
keycloak-bot:
uid: 1003
"""
)
class TestResetCredentials(unittest.TestCase):
def setUp(self):
@@ -70,10 +82,14 @@ class TestResetCredentials(unittest.TestCase):
self.addCleanup(shutil.rmtree, self.workdir, ignore_errors=True)
self.roles_dir = self.workdir / "roles"
for application_id in ("web-app-a", "web-app-keycloak"):
declarations = {
"web-app-a": DECLARED_USERS,
"web-app-keycloak": KEYCLOAK_USERS,
}
for application_id, declared in declarations.items():
users_file = self.roles_dir / application_id / ROLE_FILE_META_USERS
users_file.parent.mkdir(parents=True, exist_ok=True)
users_file.write_text(DECLARED_USERS, encoding="utf-8")
users_file.write_text(declared, encoding="utf-8")
self.host_vars_file = self.workdir / "host_vars" / "localhost.yml"
self.host_vars_file.parent.mkdir(parents=True, exist_ok=True)
@@ -125,6 +141,32 @@ class TestResetCredentials(unittest.TestCase):
self._reset(exclude={"administrator", "web-app-keycloak"})
self.assertIn("database_password", self._credentials("web-app-keycloak"))
def test_an_application_outside_the_rotation_keeps_its_credentials(self):
"""Dropping must not outrun regeneration.
The drop side walks the document while the generate side walks
`credential_ids`. A matrix host_vars file carries a block per mirror
artefact too, so a document-wide drop would delete credentials the
caller never writes back.
"""
_, credentials, _ = self._reset(credential_ids=["web-app-a"])
self.assertIn("database_password", self._credentials("web-app-keycloak"))
self.assertNotIn("api_key", self._credentials("web-app-a"))
self.assertEqual(credentials.call_args.kwargs["application_ids"], ["web-app-a"])
def test_narrowing_the_credentials_still_rotates_every_user(self):
"""A narrowed credential scope must not narrow the user passwords.
Both halves used to share one id list, so scoping the credentials to
the round silently stopped rotating the users of every other role.
"""
_, _, users = self._reset(credential_ids=["web-app-a"])
self.assertNotIn("password", self._document()["users"]["keycloak-bot"])
self.assertEqual(
users.call_args.kwargs["application_ids"],
["web-app-a", "web-app-keycloak"],
)
def test_an_excluded_user_keeps_its_password(self):
self._reset()
users = self._document()["users"]
@@ -164,7 +206,7 @@ class TestResetCredentials(unittest.TestCase):
def test_the_rotated_count_covers_both_sections(self):
rotated, _, _ = self._reset()
self.assertEqual(rotated, 4)
self.assertEqual(rotated, 5)
def test_rotating_nothing_aborts(self):
with self.assertRaises(SystemExit):
@@ -188,6 +188,36 @@ class TestApplyServicesDisabled(unittest.TestCase):
dump_yaml(role_dir / ROLE_FILE_META_SERVICES, services)
dump_yaml(role_dir / ROLE_FILE_VARS_MAIN, {"application_id": role_name})
def test_a_role_without_shared_in_its_contract_does_not_get_one(self):
self._write_host_vars(
{"applications": {"web-svc-cdn": {"services": {"dashboard": {}}}}}
)
self._make_role("web-svc-cdn", {"dashboard": {"enabled": False}})
apply_services_disabled(self.host_vars, ["dashboard"], self.roles_dir)
service = self._read_host_vars()["applications"]["web-svc-cdn"]["services"][
"dashboard"
]
self.assertEqual(False, service["enabled"])
self.assertNotIn("shared", service)
def test_a_role_declaring_both_toggles_still_gets_both(self):
self._write_host_vars(
{"applications": {"web-app-nextcloud": {"services": {"dashboard": {}}}}}
)
self._make_role(
"web-app-nextcloud", {"dashboard": {"enabled": True, "shared": True}}
)
apply_services_disabled(self.host_vars, ["dashboard"], self.roles_dir)
service = self._read_host_vars()["applications"]["web-app-nextcloud"][
"services"
]["dashboard"]
self.assertEqual(False, service["enabled"])
self.assertEqual(False, service["shared"])
def test_disables_service_in_host_vars_and_removes_from_inventory(self):
self._write_host_vars(
{