Merge pull request 'feat(docs,api): expose inventory.instances interface' (#3721) from hsjobeki/clan-core:inventory-services-1 into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3721
This commit is contained in:
hsjobeki
2025-05-20 15:29:14 +00:00
7 changed files with 166 additions and 56 deletions

View File

@@ -30,6 +30,7 @@ Note: This module assumes the presence of other modules and classes such as `Cla
"""
import dataclasses
import inspect
from dataclasses import dataclass, fields, is_dataclass
from enum import Enum
from pathlib import Path
@@ -261,6 +262,10 @@ def construct_value(
return t(field_value) # type: ignore
if inspect.isclass(t) and t.__name__ == "Unknown":
# Return the field value as is
return field_value
msg = f"Unhandled field type {t} with value {field_value}"
raise ClanError(msg)

View File

@@ -1,5 +1,6 @@
import copy
import dataclasses
import inspect
import pathlib
from dataclasses import MISSING
from enum import EnumType
@@ -110,6 +111,12 @@ def type_to_dict(
if t is None:
return {"type": "null"}
if inspect.isclass(t) and t.__name__ == "Unknown":
# Empty should represent unknown
# We don't know anything about this type
# Nor about the nested fields, if there are any
return {}
if dataclasses.is_dataclass(t):
fields = dataclasses.fields(t)
properties = {}

View File

@@ -8,53 +8,104 @@
from typing import Any, Literal, NotRequired, TypedDict
# Mimic "unknown".
# 'Any' is unsafe because it allows any operations
# This forces the user to use type-narrowing or casting in the code
class Unknown:
pass
InstanceModuleNameType = str
InstanceModuleInputType = str
class InstanceModule(TypedDict):
name: str
input: NotRequired[InstanceModuleInputType]
InstanceRoleMachineSettingsType = Unknown
class InstanceRoleMachine(TypedDict):
settings: NotRequired[InstanceRoleMachineSettingsType]
class InstanceRoleTag(TypedDict):
pass
InstanceRoleMachinesType = dict[str, InstanceRoleMachine]
InstanceRoleSettingsType = Unknown
InstanceRoleTagsType = dict[str, InstanceRoleTag]
class InstanceRole(TypedDict):
machines: NotRequired[InstanceRoleMachinesType]
settings: NotRequired[InstanceRoleSettingsType]
tags: NotRequired[InstanceRoleTagsType]
InstanceModuleType = InstanceModule
InstanceRolesType = dict[str, InstanceRole]
class Instance(TypedDict):
module: NotRequired[InstanceModuleType]
roles: NotRequired[InstanceRolesType]
MachineDeployTargethostType = str
class MachineDeploy(TypedDict):
targetHost: NotRequired[str]
MachineDeployTargethostType = NotRequired[str]
targetHost: NotRequired[MachineDeployTargethostType]
MachineDeployType = MachineDeploy
MachineDescriptionType = str
MachineIconType = str
MachineMachineclassType = Literal["nixos", "darwin"]
MachineNameType = str
MachineTagsType = list[str]
class Machine(TypedDict):
deploy: NotRequired[MachineDeploy]
description: NotRequired[str]
icon: NotRequired[str]
machineClass: NotRequired[Literal["nixos", "darwin"]]
name: NotRequired[str]
tags: NotRequired[list[str]]
MachineDeployType = NotRequired[MachineDeploy]
MachineDescriptionType = NotRequired[str]
MachineIconType = NotRequired[str]
MachineMachineclassType = NotRequired[Literal["nixos", "darwin"]]
MachineNameType = NotRequired[str]
MachineTagsType = NotRequired[list[str]]
deploy: NotRequired[MachineDeployType]
description: NotRequired[MachineDescriptionType]
icon: NotRequired[MachineIconType]
machineClass: NotRequired[MachineMachineclassType]
name: NotRequired[MachineNameType]
tags: NotRequired[MachineTagsType]
MetaNameType = str
MetaDescriptionType = str
MetaIconType = str
class Meta(TypedDict):
name: str
description: NotRequired[str]
icon: NotRequired[str]
MetaNameType = str
MetaDescriptionType = NotRequired[str]
MetaIconType = NotRequired[str]
description: NotRequired[MetaDescriptionType]
icon: NotRequired[MetaIconType]
Service = dict[str, Any]
InventoryInstancesType = dict[str, Instance]
InventoryMachinesType = dict[str, Machine]
InventoryMetaType = Meta
InventoryModulesType = dict[str, Any]
InventoryServicesType = dict[str, Service]
InventoryTagsType = dict[str, Any]
class Inventory(TypedDict):
machines: NotRequired[dict[str, Machine]]
meta: NotRequired[Meta]
modules: NotRequired[dict[str, Any]]
services: NotRequired[dict[str, Service]]
tags: NotRequired[dict[str, Any]]
InventoryMachinesType = NotRequired[dict[str, Machine]]
InventoryMetaType = NotRequired[Meta]
InventoryModulesType = NotRequired[dict[str, Any]]
InventoryServicesType = NotRequired[dict[str, Service]]
InventoryTagsType = NotRequired[dict[str, Any]]
instances: NotRequired[InventoryInstancesType]
machines: NotRequired[InventoryMachinesType]
meta: NotRequired[InventoryMetaType]
modules: NotRequired[InventoryModulesType]
services: NotRequired[InventoryServicesType]
tags: NotRequired[InventoryTagsType]