/api/clan_modules: init
All checks were successful
checks-impure / test (pull_request) Successful in 39s
checks / test (pull_request) Successful in 2m6s

- add GET /api/clan_modules entry point returning a list of modules available for import
This commit is contained in:
DavHau 2023-10-25 17:22:35 +01:00
parent a6f51d4dae
commit 25708d1a1a
5 changed files with 83 additions and 1 deletions

View File

@ -0,0 +1,39 @@
import json
import subprocess
from pathlib import Path
from typing import Optional
from clan_cli.dirs import get_clan_flake_toplevel
from clan_cli.nix import nix_eval
def get_clan_module_names(
flake: Optional[Path] = None,
) -> tuple[list[str], Optional[str]]:
"""
Get the list of clan modules from the clan-core flake input
"""
if flake is None:
flake = get_clan_flake_toplevel()
proc = subprocess.run(
nix_eval(
[
"--impure",
"--show-trace",
"--expr",
f"""
let
flake = builtins.getFlake (toString {flake});
in
builtins.attrNames flake.inputs.clan-core.clanModules
""",
],
),
capture_output=True,
text=True,
cwd=flake,
)
if proc.returncode != 0:
return [], proc.stderr
module_names = json.loads(proc.stdout)
return module_names, None

View File

@ -8,7 +8,7 @@ from fastapi.staticfiles import StaticFiles
from ..errors import ClanError
from .assets import asset_path
from .error_handlers import clan_error_handler
from .routers import flake, health, machines, root, vms
from .routers import clan_modules, flake, health, machines, root, vms
origins = [
"http://localhost:3000",
@ -26,6 +26,7 @@ def setup_app() -> FastAPI:
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(clan_modules.router)
app.include_router(flake.router)
app.include_router(health.router)
app.include_router(machines.router)

View File

@ -0,0 +1,21 @@
# Logging setup
import logging
from fastapi import APIRouter, HTTPException
from clan_cli.clan_modules import get_clan_module_names
from ..schemas import (
ClanModulesResponse,
)
log = logging.getLogger(__name__)
router = APIRouter()
@router.get("/api/clan_modules")
async def list_clan_modules() -> ClanModulesResponse:
module_names, error = get_clan_module_names()
if error is not None:
raise HTTPException(status_code=400, detail=error)
return ClanModulesResponse(clan_modules=module_names)

View File

@ -13,6 +13,10 @@ class Status(Enum):
UNKNOWN = "unknown"
class ClanModulesResponse(BaseModel):
clan_modules: list[str]
class Machine(BaseModel):
name: str
status: Status

View File

@ -0,0 +1,17 @@
from pathlib import Path
import pytest
from api import TestClient
@pytest.mark.impure()
def test_configure_machine(api: TestClient, test_flake_with_core: Path) -> None:
# retrieve the list of available clanModules
response = api.get("/api/clan_modules")
response_json = response.json()
assert response.status_code == 200
assert isinstance(response_json, dict)
assert "clan_modules" in response_json
assert len(response_json["clan_modules"]) > 0
# ensure all entries are a string
assert all(isinstance(x, str) for x in response_json["clan_modules"])