api/machines: ensure name is valid hostname
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -23,10 +23,6 @@ class Machine(BaseModel):
|
||||
status: Status
|
||||
|
||||
|
||||
class MachineCreate(BaseModel):
|
||||
name: str
|
||||
|
||||
|
||||
class MachinesResponse(BaseModel):
|
||||
machines: list[Machine]
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user