Refactor configuration handling to use directory-per-resource layout
- Introduced `_write_castle_config` function to scatter nested config into separate YAML files for programs, services, and jobs. - Updated `castle_root` fixture to utilize the new config writing method. - Added tests for configuration aggregation and scattering in `test_health.py`. - Removed legacy unit handling from `manifest.py` and refactored related code in `config.py`. - Updated documentation to reflect new configuration directory structure. - Removed obsolete unit tests related to unit expansion.
This commit is contained in:
@@ -17,10 +17,25 @@ from castle_core.registry import (
|
||||
)
|
||||
|
||||
|
||||
def _write_castle_config(root: Path, config: dict) -> None:
|
||||
"""Scatter a nested castle config dict into the directory-per-resource layout."""
|
||||
globals_data = {k: v for k, v in config.items() if k in ("gateway", "repo")}
|
||||
(root / "castle.yaml").write_text(yaml.dump(globals_data, default_flow_style=False))
|
||||
for section in ("programs", "services", "jobs"):
|
||||
entries = config.get(section) or {}
|
||||
if not entries:
|
||||
continue
|
||||
section_dir = root / section
|
||||
section_dir.mkdir(parents=True, exist_ok=True)
|
||||
for name, spec in entries.items():
|
||||
(section_dir / f"{name}.yaml").write_text(
|
||||
yaml.dump(spec, default_flow_style=False)
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def castle_root(tmp_path: Path) -> Generator[Path, None, None]:
|
||||
"""Create a temporary castle root with castle.yaml."""
|
||||
castle_yaml = tmp_path / "castle.yaml"
|
||||
"""Create a temporary castle root with directory-per-resource config."""
|
||||
config = {
|
||||
"gateway": {"port": 9000},
|
||||
"programs": {
|
||||
@@ -77,7 +92,7 @@ def castle_root(tmp_path: Path) -> Generator[Path, None, None]:
|
||||
},
|
||||
},
|
||||
}
|
||||
castle_yaml.write_text(yaml.dump(config, default_flow_style=False))
|
||||
_write_castle_config(tmp_path, config)
|
||||
yield tmp_path
|
||||
|
||||
|
||||
@@ -143,7 +158,14 @@ def registry_path(tmp_path: Path, castle_root: Path) -> Generator[Path, None, No
|
||||
"config_editor.get_castle_root": config_editor_mod.get_castle_root,
|
||||
}
|
||||
|
||||
for mod in [api_config, routes_mod, services_mod, nodes_mod, stream_mod, config_editor_mod]:
|
||||
for mod in [
|
||||
api_config,
|
||||
routes_mod,
|
||||
services_mod,
|
||||
nodes_mod,
|
||||
stream_mod,
|
||||
config_editor_mod,
|
||||
]:
|
||||
if hasattr(mod, "get_registry"):
|
||||
mod.get_registry = _get_registry
|
||||
if hasattr(mod, "get_castle_root"):
|
||||
|
||||
@@ -268,3 +268,36 @@ class TestGateway:
|
||||
assert data["routes"]
|
||||
for r in data["routes"]:
|
||||
assert r["kind"] in ("static", "proxy", "remote")
|
||||
|
||||
|
||||
class TestConfigEditor:
|
||||
"""Virtual castle.yaml aggregation/scatter endpoints."""
|
||||
|
||||
def test_get_aggregates_resources(self, client: TestClient) -> None:
|
||||
"""GET /config returns a unified YAML aggregating all resource files."""
|
||||
import yaml
|
||||
|
||||
response = client.get("/config")
|
||||
assert response.status_code == 200
|
||||
data = yaml.safe_load(response.json()["yaml_content"])
|
||||
assert "test-tool" in data["programs"]
|
||||
assert "test-svc" in data["services"]
|
||||
assert "test-job" in data["jobs"]
|
||||
|
||||
def test_put_scatters_and_prunes(self, client: TestClient, castle_root) -> None:
|
||||
"""PUT /config writes resource files and prunes removed ones."""
|
||||
import yaml
|
||||
|
||||
current = yaml.safe_load(client.get("/config").json()["yaml_content"])
|
||||
current["services"].pop("test-svc")
|
||||
current["programs"]["new-tool"] = {
|
||||
"description": "Brand new",
|
||||
"behavior": "tool",
|
||||
}
|
||||
resp = client.put("/config", json={"yaml_content": yaml.dump(current)})
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert not (castle_root / "services" / "test-svc.yaml").exists()
|
||||
assert (castle_root / "programs" / "new-tool.yaml").exists()
|
||||
after = yaml.safe_load(client.get("/config").json()["yaml_content"])
|
||||
assert "new-tool" in after["programs"]
|
||||
assert "test-svc" not in (after.get("services") or {})
|
||||
|
||||
Reference in New Issue
Block a user