110 lines
3.0 KiB
Python
110 lines
3.0 KiB
Python
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
from clan_cli.clan_uri import FlakeId
|
|
from clan_cli.errors import ClanError
|
|
from clan_cli.facts.generate import generate_facts
|
|
from clan_cli.inventory import (
|
|
IwdConfig,
|
|
IwdConfigNetwork,
|
|
ServiceIwd,
|
|
ServiceIwdRole,
|
|
ServiceIwdRoleDefault,
|
|
ServiceMeta,
|
|
load_inventory_eval,
|
|
save_inventory,
|
|
)
|
|
from clan_cli.machines.machines import Machine
|
|
from clan_cli.secrets.sops import (
|
|
maybe_get_public_key,
|
|
maybe_get_user_or_machine,
|
|
)
|
|
|
|
from . import API
|
|
|
|
|
|
def instance_name(machine_name: str) -> str:
|
|
return f"{machine_name}_wifi_0_"
|
|
|
|
|
|
@API.register
|
|
def get_iwd_service(base_url: str, machine_name: str) -> ServiceIwd:
|
|
"""
|
|
Return the admin service of a clan.
|
|
|
|
There is only one admin service. This might be changed in the future
|
|
"""
|
|
inventory = load_inventory_eval(base_url)
|
|
service_config = inventory.services.iwd.get(instance_name(machine_name))
|
|
if service_config:
|
|
return service_config
|
|
|
|
# Empty service
|
|
return ServiceIwd(
|
|
meta=ServiceMeta(name="wifi_0"),
|
|
roles=ServiceIwdRole(default=ServiceIwdRoleDefault(machines=[machine_name])),
|
|
config=IwdConfig(networks={}),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class NetworkConfig:
|
|
ssid: str
|
|
password: str
|
|
|
|
|
|
@API.register
|
|
def set_iwd_service_for_machine(
|
|
base_url: str, machine_name: str, networks: dict[str, NetworkConfig]
|
|
) -> None:
|
|
"""
|
|
Set the admin service of a clan
|
|
Every machine is by default part of the admin service via the 'all' tag
|
|
"""
|
|
_instance_name = instance_name(machine_name)
|
|
|
|
inventory = load_inventory_eval(base_url)
|
|
|
|
instance = ServiceIwd(
|
|
meta=ServiceMeta(name="wifi_0"),
|
|
roles=ServiceIwdRole(
|
|
default=ServiceIwdRoleDefault(
|
|
machines=[machine_name],
|
|
)
|
|
),
|
|
config=IwdConfig(
|
|
networks={k: IwdConfigNetwork(v.ssid) for k, v in networks.items()}
|
|
),
|
|
)
|
|
|
|
inventory.services.iwd[_instance_name] = instance
|
|
|
|
save_inventory(
|
|
inventory,
|
|
base_url,
|
|
f"Set iwd service: '{_instance_name}'",
|
|
)
|
|
|
|
pubkey = maybe_get_public_key()
|
|
if not pubkey:
|
|
# TODO: do this automatically
|
|
# pubkey = generate_key()
|
|
raise ClanError(msg="No public key found. Please initialize your key.")
|
|
|
|
registered_key = maybe_get_user_or_machine(Path(base_url), pubkey)
|
|
if not registered_key:
|
|
# TODO: do this automatically
|
|
# username = os.getlogin()
|
|
# add_user(Path(base_url), username, pubkey, force=False)
|
|
raise ClanError(msg="Your public key is not registered for use with this clan.")
|
|
|
|
password_dict = {f"iwd.{net.ssid}": net.password for net in networks.values()}
|
|
for net in networks.values():
|
|
generate_facts(
|
|
service=f"iwd.{net.ssid}",
|
|
machines=[Machine(machine_name, FlakeId(base_url))],
|
|
regenerate=True,
|
|
# Just returns the password
|
|
prompt=lambda service, _msg: password_dict[service],
|
|
)
|