95 lines
2.6 KiB
Python
95 lines
2.6 KiB
Python
from typing import TypedDict
|
|
|
|
from clan_lib.api import API
|
|
from clan_lib.errors import ClanError
|
|
from clan_lib.flake.flake import Flake
|
|
from clan_lib.machines.machines import Machine
|
|
from clan_lib.nix_models.clan import (
|
|
InventoryMachine,
|
|
)
|
|
from clan_lib.persist.inventory_store import InventoryStore
|
|
from clan_lib.persist.util import set_value_by_path
|
|
|
|
|
|
class MachineFilter(TypedDict):
|
|
tags: list[str]
|
|
|
|
|
|
class ListOptions(TypedDict):
|
|
filter: MachineFilter
|
|
|
|
|
|
@API.register
|
|
def list_machines(
|
|
flake: Flake, opts: ListOptions | None = None
|
|
) -> dict[str, InventoryMachine]:
|
|
"""
|
|
List machines of a clan
|
|
|
|
Usage Example:
|
|
|
|
machines = list_machines(flake, {"filter": {"tags": ["foo" "bar"]}})
|
|
|
|
lists only machines that include both "foo" AND "bar"
|
|
|
|
"""
|
|
inventory_store = InventoryStore(flake=flake)
|
|
inventory = inventory_store.read()
|
|
|
|
machines = inventory.get("machines", {})
|
|
|
|
if opts and opts.get("filter"):
|
|
filtered_machines = {}
|
|
filter_tags = opts.get("filter", {}).get("tags", [])
|
|
|
|
for machine_name, machine in machines.items():
|
|
machine_tags = machine.get("tags", [])
|
|
if all(ft in machine_tags for ft in filter_tags):
|
|
filtered_machines[machine_name] = machine
|
|
|
|
return filtered_machines
|
|
|
|
return machines
|
|
|
|
|
|
@API.register
|
|
def get_machine(flake: Flake, name: str) -> InventoryMachine:
|
|
"""
|
|
Retrieve a machine's inventory details by name from the given flake.
|
|
|
|
Args:
|
|
flake (Flake): The flake object representing the configuration source.
|
|
name (str): The name of the machine to retrieve from the inventory.
|
|
|
|
Returns:
|
|
InventoryMachine: An instance representing the machine's inventory details.
|
|
|
|
Raises:
|
|
ClanError: If the machine with the specified name is not found in the inventory.
|
|
"""
|
|
inventory_store = InventoryStore(flake=flake)
|
|
inventory = inventory_store.read()
|
|
|
|
machine_inv = inventory.get("machines", {}).get(name)
|
|
if machine_inv is None:
|
|
msg = f"Machine {name} not found in inventory"
|
|
raise ClanError(msg)
|
|
|
|
return InventoryMachine(**machine_inv)
|
|
|
|
|
|
@API.register
|
|
def set_machine(machine: Machine, update: InventoryMachine) -> None:
|
|
"""
|
|
Update the machine information in the inventory.
|
|
"""
|
|
assert machine.name == update.get("name", machine.name), "Machine name mismatch"
|
|
|
|
inventory_store = InventoryStore(flake=machine.flake)
|
|
inventory = inventory_store.read()
|
|
|
|
set_value_by_path(inventory, f"machines.{machine.name}", update)
|
|
inventory_store.write(
|
|
inventory, message=f"Update information about machine {machine.name}"
|
|
)
|