api/machines: ensure name is valid hostname

This commit is contained in:
DavHau 2023-11-10 16:07:01 +07:00
parent eec22d7d39
commit 236ca4f98c
4 changed files with 29 additions and 8 deletions

View File

@ -1,4 +1,5 @@
import logging
import re
from pathlib import Path
from typing import Any
@ -30,3 +31,16 @@ class MachineConfig(BaseModel):
# allow extra fields to cover the full spectrum of a nixos config
class Config:
extra = Extra.allow
class MachineCreate(BaseModel):
name: str
@classmethod
@validator("name")
def validate_hostname(cls, v: str) -> str:
# Define a regular expression for a valid hostname
hostname_regex = r"^(?!-)[A-Za-z0-9-]{1,63}(?<!-)$"
if not re.match(hostname_regex, v):
raise ValueError("Machine name must be a valid hostname")
return v

View File

@ -23,10 +23,6 @@ class Machine(BaseModel):
status: Status
class MachineCreate(BaseModel):
name: str
class MachinesResponse(BaseModel):
machines: list[Machine]

View File

@ -5,7 +5,7 @@ from typing import Annotated
from fastapi import APIRouter, Body
from clan_cli.webui.api_errors import MissingClanImports
from clan_cli.webui.api_inputs import MachineConfig
from clan_cli.webui.api_inputs import MachineConfig, MachineCreate
from ...config.machine import (
config_for_machine,
@ -19,7 +19,6 @@ from ...types import FlakeName
from ..api_outputs import (
ConfigResponse,
Machine,
MachineCreate,
MachineResponse,
MachinesResponse,
SchemaResponse,
@ -75,9 +74,9 @@ async def set_machine_config(
responses={400: {"model": MissingClanImports}},
)
async def get_machine_schema(
flake_name: FlakeName, config: Annotated[dict, Body()]
flake_name: FlakeName, config: Annotated[MachineConfig, Body()]
) -> SchemaResponse:
schema = machine_schema(flake_name, config=config)
schema = machine_schema(flake_name, config=dict(config))
return SchemaResponse(schema=schema)

View File

@ -52,6 +52,18 @@ def test_schema_invalid_clan_imports(
assert "non-existing-clan-module" in response.json()["detail"]["modules_not_found"]
def test_create_machine_invalid_hostname(
api: TestClient, test_flake: FlakeForTest
) -> None:
response = api.post(
f"/api/{test_flake.name}/machines", json={"name": "-invalid-hostname"}
)
assert response.status_code == 422
assert (
"Machine name must be a valid hostname" in response.json()["detail"][0]["msg"]
)
@pytest.mark.with_core
def test_configure_machine(api: TestClient, test_flake_with_core: FlakeForTest) -> None:
# ensure error 404 if machine does not exist when accessing the config