Merge pull request 'API/Machine: refactor api returns readonly' (#4627) from readonly into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/4627
This commit is contained in:
@@ -98,23 +98,23 @@ def set_machine(machine: Machine, update: InventoryMachine) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class Writeability(TypedDict):
|
class FieldSchema(TypedDict):
|
||||||
writable: bool
|
readonly: bool
|
||||||
reason: str | None
|
reason: str | None
|
||||||
|
|
||||||
|
|
||||||
@API.register
|
@API.register
|
||||||
def get_machine_writeability(machine: Machine) -> dict[str, Writeability]:
|
def get_machine_fields_schema(machine: Machine) -> dict[str, FieldSchema]:
|
||||||
"""
|
"""
|
||||||
Get writeability information for the fields of a machine.
|
Get attributes for each field of the machine.
|
||||||
|
|
||||||
This function checks which fields of the 'machine' resource are writable and provides a reason for each field's writability.
|
This function checks which fields of the 'machine' resource are readonly and provides a reason if so.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
machine (Machine): The machine object for which to retrieve writeability.
|
machine (Machine): The machine object for which to retrieve fields.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict[str, Writeability]: A map from field-names to { 'writable' (bool) and 'reason' (str or None ) }
|
dict[str, FieldSchema]: A map from field-names to { 'readonly' (bool) and 'reason' (str or None ) }
|
||||||
"""
|
"""
|
||||||
|
|
||||||
inventory_store = InventoryStore(machine.flake)
|
inventory_store = InventoryStore(machine.flake)
|
||||||
@@ -122,15 +122,24 @@ def get_machine_writeability(machine: Machine) -> dict[str, Writeability]:
|
|||||||
|
|
||||||
field_names = retrieve_typed_field_names(InventoryMachine)
|
field_names = retrieve_typed_field_names(InventoryMachine)
|
||||||
|
|
||||||
# TODO: handle this more generically
|
protected_fields = {
|
||||||
|
"name", # name is always readonly
|
||||||
|
"machineClass", # machineClass can only be set during create
|
||||||
|
}
|
||||||
|
# TODO: handle this more generically. I.e via json schema
|
||||||
|
|
||||||
# persisted_data = inventory_store._get_persisted() #
|
# persisted_data = inventory_store._get_persisted() #
|
||||||
# unmerge_lists(all_list, persisted_data)
|
# unmerge_lists(all_list, persisted_data)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
field: {
|
field: {
|
||||||
"writable": False
|
"readonly": (
|
||||||
if field == "name"
|
True
|
||||||
else is_writeable_key(f"machines.{machine.name}.{field}", write_info),
|
if field in protected_fields
|
||||||
|
else not is_writeable_key(
|
||||||
|
f"machines.{machine.name}.{field}", write_info
|
||||||
|
)
|
||||||
|
),
|
||||||
# TODO: Provide a meaningful reason
|
# TODO: Provide a meaningful reason
|
||||||
"reason": None,
|
"reason": None,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from clan_lib.machines import actions as actions_module
|
|||||||
from clan_lib.machines.machines import Machine
|
from clan_lib.machines.machines import Machine
|
||||||
from clan_lib.nix_models.clan import Clan, InventoryMachine, Unknown
|
from clan_lib.nix_models.clan import Clan, InventoryMachine, Unknown
|
||||||
|
|
||||||
from .actions import get_machine, get_machine_writeability, list_machines, set_machine
|
from .actions import get_machine, get_machine_fields_schema, list_machines, set_machine
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.with_core
|
@pytest.mark.with_core
|
||||||
@@ -191,13 +191,13 @@ def test_get_machine_writeability(clan_flake: Callable[..., Flake]) -> None:
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
write_info = get_machine_writeability(Machine("jon", flake))
|
write_info = get_machine_fields_schema(Machine("jon", flake))
|
||||||
|
|
||||||
# {'tags': {'writable': True, 'reason': None}, 'machineClass': {'writable': False, 'reason': None}, 'name': {'writable': False, 'reason': None}, 'description': {'writable': True, 'reason': None}, 'deploy.buildHost': {'writable': True, 'reason': None}, 'icon': {'writable': True, 'reason': None}, 'deploy.targetHost': {'writable': True, 'reason': None}}
|
# {'tags': {'writable': True, 'reason': None}, 'machineClass': {'writable': False, 'reason': None}, 'name': {'writable': False, 'reason': None}, 'description': {'writable': True, 'reason': None}, 'deploy.buildHost': {'writable': True, 'reason': None}, 'icon': {'writable': True, 'reason': None}, 'deploy.targetHost': {'writable': True, 'reason': None}}
|
||||||
writeable_fields = {field for field, info in write_info.items() if info["writable"]}
|
writeable_fields = {
|
||||||
read_only_fields = {
|
field for field, info in write_info.items() if not info["readonly"]
|
||||||
field for field, info in write_info.items() if not info["writable"]
|
|
||||||
}
|
}
|
||||||
|
read_only_fields = {field for field, info in write_info.items() if info["readonly"]}
|
||||||
|
|
||||||
assert writeable_fields == {
|
assert writeable_fields == {
|
||||||
"tags",
|
"tags",
|
||||||
|
|||||||
Reference in New Issue
Block a user