mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 11:46:35 +00:00
Adds a `swarm:` subcategory under `svc:` in roles/categories.yml so the shared-cluster role is properly invokable, and renames the existing `svc-swarm` role + inventory group to `svc-swarm-node` (with `get_entity_name`-aligned primary key `node:` in meta/services.yml). `svc-swarm-manager` stays as the manager-marker role, becoming invokable via the same new category and re-keyed to `manager:`. Consumers of the cluster-orchestration service (svc-registry-cache, svc-registry-docker, svc-swarm-manager) now reference the service-key `node:` (was `swarm:`), matching the renamed primary entry. The planner empirically resolves `service_registry['node']` -> `svc-swarm-node` and emits it into --include for stack-host deploys, so the CI failure on `universal-svc-registry-docker` (`svc-swarm: not present in inventory`) no longer reaches `ValidDeployId`. Breaking change for operators: inventory groups named `svc-swarm:` must be renamed to `svc-swarm-node:`. `DEPLOYMENT_MODE` reads `groups['svc-swarm-node']`, so a stale `svc-swarm:` group silently falls back to compose mode. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
133 lines
3.8 KiB
Python
133 lines
3.8 KiB
Python
"""Unit tests for utils.inventory.groups.inventory_has_group."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import textwrap
|
|
import unittest
|
|
from pathlib import Path
|
|
from tempfile import TemporaryDirectory
|
|
|
|
from utils.inventory.groups import inventory_has_group
|
|
|
|
|
|
class TestInventoryHasGroupYaml(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.tmp = TemporaryDirectory()
|
|
self.addCleanup(self.tmp.cleanup)
|
|
self.root = Path(self.tmp.name)
|
|
|
|
def _write(self, name: str, body: str) -> str:
|
|
path = self.root / name
|
|
path.write_text(textwrap.dedent(body).lstrip("\n"), encoding="utf-8")
|
|
return str(path)
|
|
|
|
def test_yaml_finds_nested_group(self) -> None:
|
|
path = self._write(
|
|
"inv.yml",
|
|
"""
|
|
all:
|
|
children:
|
|
svc-swarm-node:
|
|
hosts:
|
|
swarm-mgr-01: {}
|
|
svc-swarm-manager:
|
|
hosts:
|
|
swarm-mgr-01: {}
|
|
""",
|
|
)
|
|
self.assertTrue(inventory_has_group(path, "svc-swarm-manager"))
|
|
self.assertTrue(inventory_has_group(path, "svc-swarm-node"))
|
|
|
|
def test_yaml_missing_group_returns_false(self) -> None:
|
|
path = self._write(
|
|
"inv.yml",
|
|
"""
|
|
all:
|
|
children:
|
|
svc-swarm-node:
|
|
hosts:
|
|
swarm-mgr-01: {}
|
|
""",
|
|
)
|
|
self.assertFalse(inventory_has_group(path, "svc-swarm-manager"))
|
|
|
|
def test_yaml_skips_scalar_key(self) -> None:
|
|
path = self._write(
|
|
"inv.yml",
|
|
"""
|
|
all:
|
|
children:
|
|
some-key: just-a-string
|
|
actual-group:
|
|
hosts: {}
|
|
""",
|
|
)
|
|
self.assertFalse(inventory_has_group(path, "some-key"))
|
|
self.assertTrue(inventory_has_group(path, "actual-group"))
|
|
|
|
|
|
class TestInventoryHasGroupIni(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.tmp = TemporaryDirectory()
|
|
self.addCleanup(self.tmp.cleanup)
|
|
self.root = Path(self.tmp.name)
|
|
|
|
def _write(self, name: str, body: str) -> str:
|
|
path = self.root / name
|
|
path.write_text(textwrap.dedent(body).lstrip("\n"), encoding="utf-8")
|
|
return str(path)
|
|
|
|
def test_ini_finds_section_header(self) -> None:
|
|
path = self._write(
|
|
"hosts",
|
|
"""
|
|
[svc-swarm-manager]
|
|
mgr-01
|
|
|
|
[web-app-mediawiki]
|
|
mgr-01
|
|
""",
|
|
)
|
|
self.assertTrue(inventory_has_group(path, "svc-swarm-manager"))
|
|
self.assertTrue(inventory_has_group(path, "web-app-mediawiki"))
|
|
|
|
def test_ini_finds_host_in_section(self) -> None:
|
|
path = self._write(
|
|
"hosts",
|
|
"""
|
|
[grp]
|
|
host-a, host-b host-c
|
|
""",
|
|
)
|
|
self.assertTrue(inventory_has_group(path, "host-a"))
|
|
self.assertTrue(inventory_has_group(path, "host-b"))
|
|
self.assertTrue(inventory_has_group(path, "host-c"))
|
|
|
|
def test_ini_skips_comments(self) -> None:
|
|
path = self._write(
|
|
"hosts",
|
|
"""
|
|
# [comment-group]
|
|
; [also-comment]
|
|
[real-group]
|
|
mgr-01
|
|
""",
|
|
)
|
|
self.assertFalse(inventory_has_group(path, "comment-group"))
|
|
self.assertFalse(inventory_has_group(path, "also-comment"))
|
|
self.assertTrue(inventory_has_group(path, "real-group"))
|
|
|
|
def test_ini_missing_group_returns_false(self) -> None:
|
|
path = self._write(
|
|
"hosts",
|
|
"""
|
|
[other]
|
|
mgr-01
|
|
""",
|
|
)
|
|
self.assertFalse(inventory_has_group(path, "missing"))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|