api/tags: add from all possible sources
This commit is contained in:
committed by
Brian McGee
parent
2608bee30a
commit
cbd3b08296
@@ -1,12 +0,0 @@
|
||||
"""
|
||||
DEPRECATED:
|
||||
|
||||
Don't use this module anymore
|
||||
|
||||
Instead use:
|
||||
'clan_lib.persist.inventoryStore'
|
||||
|
||||
Which is an abstraction over the inventory
|
||||
|
||||
Interacting with 'clan_lib.inventory' is NOT recommended and will be removed
|
||||
"""
|
||||
@@ -1,29 +0,0 @@
|
||||
from typing import TypedDict
|
||||
|
||||
from clan_lib.api import API
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.persist.inventory_store import InventoryStore
|
||||
|
||||
readonly_tags = {"all", "nixos", "darwin"}
|
||||
|
||||
|
||||
class MachineTag(TypedDict):
|
||||
name: str
|
||||
readonly: bool
|
||||
|
||||
|
||||
@API.register
|
||||
def list_inventory_tags(flake: Flake) -> list[MachineTag]:
|
||||
inventory_store = InventoryStore(flake=flake)
|
||||
inventory = inventory_store.read()
|
||||
|
||||
machines = inventory.get("machines", {})
|
||||
|
||||
tags: dict[str, MachineTag] = {}
|
||||
|
||||
for _, machine in machines.items():
|
||||
machine_tags = machine.get("tags", [])
|
||||
for tag in machine_tags:
|
||||
tags[tag] = MachineTag(name=tag, readonly=tag in readonly_tags)
|
||||
|
||||
return sorted(tags.values(), key=lambda x: x["name"])
|
||||
@@ -1,72 +0,0 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
import pytest
|
||||
|
||||
from clan_lib.flake import Flake
|
||||
|
||||
from .actions import MachineTag, list_inventory_tags
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_list_inventory_tags(clan_flake: Callable[..., Flake]) -> None:
|
||||
flake = clan_flake(
|
||||
{
|
||||
"inventory": {
|
||||
"machines": {
|
||||
"jon": {
|
||||
# machineClass defaults to nixos
|
||||
"tags": ["foo", "bar"],
|
||||
},
|
||||
"sara": {
|
||||
"machineClass": "darwin",
|
||||
"tags": ["foo", "baz", "fizz"],
|
||||
},
|
||||
"bob": {
|
||||
"machineClass": "nixos",
|
||||
"tags": ["foo", "bar"],
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
tags = list_inventory_tags(flake)
|
||||
|
||||
assert tags == [
|
||||
MachineTag(name="all", readonly=True),
|
||||
MachineTag(name="bar", readonly=False),
|
||||
MachineTag(name="baz", readonly=False),
|
||||
MachineTag(name="darwin", readonly=True),
|
||||
MachineTag(name="fizz", readonly=False),
|
||||
MachineTag(name="foo", readonly=False),
|
||||
MachineTag(name="nixos", readonly=True),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_list_inventory_tags_defaults(clan_flake: Callable[..., Flake]) -> None:
|
||||
flake = clan_flake(
|
||||
{
|
||||
"inventory": {
|
||||
"machines": {
|
||||
"jon": {
|
||||
# machineClass defaults to nixos
|
||||
},
|
||||
"sara": {
|
||||
"machineClass": "darwin",
|
||||
},
|
||||
"bob": {
|
||||
"machineClass": "nixos",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
tags = list_inventory_tags(flake)
|
||||
|
||||
assert tags == [
|
||||
MachineTag(name="all", readonly=True),
|
||||
MachineTag(name="darwin", readonly=True),
|
||||
MachineTag(name="nixos", readonly=True),
|
||||
]
|
||||
@@ -12,6 +12,7 @@ from clan_lib.nix_models.clan import (
|
||||
InventoryMachinesType,
|
||||
InventoryMetaType,
|
||||
InventoryServicesType,
|
||||
InventoryTagsType,
|
||||
)
|
||||
|
||||
from .util import (
|
||||
@@ -106,6 +107,7 @@ class InventorySnapshot(TypedDict):
|
||||
instances: NotRequired[InventoryInstancesType]
|
||||
meta: NotRequired[InventoryMetaType]
|
||||
services: NotRequired[InventoryServicesType]
|
||||
tags: NotRequired[InventoryTagsType]
|
||||
|
||||
|
||||
class InventoryStore:
|
||||
|
||||
34
pkgs/clan-cli/clan_lib/tags/list.py
Normal file
34
pkgs/clan-cli/clan_lib/tags/list.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from typing import Any
|
||||
|
||||
from clan_lib.api import API
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.persist.inventory_store import InventoryStore
|
||||
|
||||
|
||||
@API.register
|
||||
def list_tags(flake: Flake) -> set[str]:
|
||||
inventory_store = InventoryStore(flake=flake)
|
||||
inventory = inventory_store.read()
|
||||
|
||||
machines = inventory.get("machines", {})
|
||||
|
||||
tags: set[str] = set()
|
||||
|
||||
for machine in machines.values():
|
||||
machine_tags = machine.get("tags", [])
|
||||
for tag in machine_tags:
|
||||
tags.add(tag)
|
||||
|
||||
instances = inventory.get("instances", {})
|
||||
for instance in instances.values():
|
||||
roles: dict[str, Any] = instance.get("roles", {})
|
||||
for role in roles.values():
|
||||
role_tags = role.get("tags", {})
|
||||
for tag in role_tags:
|
||||
tags.add(tag)
|
||||
|
||||
global_tags = inventory.get("tags", {})
|
||||
for tag in global_tags:
|
||||
tags.add(tag)
|
||||
|
||||
return tags
|
||||
78
pkgs/clan-cli/clan_lib/tags/list_test.py
Normal file
78
pkgs/clan-cli/clan_lib/tags/list_test.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
import pytest
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.persist.inventory_store import InventoryStore
|
||||
from clan_lib.persist.util import get_value_by_path, set_value_by_path
|
||||
from clan_lib.tags.list import list_tags
|
||||
|
||||
|
||||
@pytest.mark.with_core
|
||||
def test_list_inventory_tags(clan_flake: Callable[..., Flake]) -> None:
|
||||
flake = clan_flake(
|
||||
{
|
||||
"inventory": {
|
||||
"machines": {
|
||||
"jon": {
|
||||
"tags": ["foo", "bar"],
|
||||
},
|
||||
"sara": {
|
||||
"tags": ["foo", "baz", "fizz"],
|
||||
},
|
||||
"bob": {
|
||||
"tags": ["foo", "bar"],
|
||||
},
|
||||
},
|
||||
"instances": {
|
||||
"instance1": {
|
||||
"roles": {
|
||||
"role1": {"tags": {"predefined": {}, "maybe": {}}},
|
||||
"role2": {"tags": {"predefined2": {}, "maybe2": {}}},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
raw=r"""
|
||||
{
|
||||
inventory.tags = {
|
||||
"global" = [ "future_machine" ];
|
||||
};
|
||||
}
|
||||
""",
|
||||
)
|
||||
|
||||
inventory_store = InventoryStore(flake=flake)
|
||||
inventory = inventory_store.read()
|
||||
curr_tags = get_value_by_path(inventory, "machines.jon.tags", [])
|
||||
new_tags = ["managed1", "managed2"]
|
||||
set_value_by_path(inventory, "machines.jon.tags", [*curr_tags, *new_tags])
|
||||
inventory_store.write(inventory, message="Test add tags via API")
|
||||
|
||||
# Check that the tags were updated
|
||||
persisted = inventory_store._get_persisted() # noqa: SLF001
|
||||
assert get_value_by_path(persisted, "machines.jon.tags", []) == new_tags
|
||||
|
||||
tags = list_tags(flake)
|
||||
|
||||
assert tags == set(
|
||||
{
|
||||
# Predefined tags
|
||||
"all",
|
||||
"global",
|
||||
"darwin",
|
||||
"nixos",
|
||||
# Tags defined in nix
|
||||
"bar",
|
||||
"baz",
|
||||
"fizz",
|
||||
"foo",
|
||||
"predefined",
|
||||
"predefined2",
|
||||
"maybe",
|
||||
"maybe2",
|
||||
# Tags managed by the UI
|
||||
"managed1",
|
||||
"managed2",
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user