# scripts/lib-hosts.sh
#
# Single source of truth for the four OpenStack KVM host VMs (VR0 / Baldurkeep):
# their enrollment identity and virsh power parameters. SOURCED, not executed.
# ASCII + LF. Contains constants + read-only helpers ONLY; no mutations.
#
# WHY hostname-keyed (NOT system_id-keyed): MAAS system_ids are minted fresh on
# every (re-)enrollment. The old 4na83t/qdbqd6/h8frng/tmsafc died when the hosts
# were decomposed on 2026-06-26 and re-enrollment assigned new random ids. The
# stable identities are the hostname and the libvirt domain name, so every map
# here keys on hostname and the live system_id is resolved AT RUNTIME via
# host_sysid(). This SUPERSEDES the SYSID-keyed maps in lib-net.sh (DOCFIX-040).
#
# NO SECRET lives here. The libvirt SSH password is read interactively at run time
# (reenroll-hosts.sh) and is never written to a file, a command line, or the repo.

# shellcheck shell=bash
# shellcheck disable=SC2034  # constants are consumed by sourcing scripts

# Guard: sourced only.
if [ "${BASH_SOURCE[0]:-}" = "${0}" ]; then
  echo "lib-hosts.sh is a sourced library; do not run it directly." >&2
  exit 2
fi

# The four OpenStack KVM hosts. libvirt domain name == MAAS hostname == power_id.
HOSTS=( openstack0 openstack1 openstack2 openstack3 )

# host -> last IPv4 octet on every plane (.40-.43). Stable by design (D-052 index).
declare -A HOST_OCTET=( [openstack0]=40 [openstack1]=41 [openstack2]=42 [openstack3]=43 )

# host -> PXE/boot NIC MAC == the 2_metal interface (libvirt <boot order='1'/>).
# Fixed in the libvirt domain XML; captured 2026-06-26. The boot NIC MUST be the
# metal/PXE plane or commissioning cannot DHCP/PXE.
declare -A HOST_BOOT_MAC=(
  [openstack0]=52:54:00:4f:1c:0b
  [openstack1]=52:54:00:83:25:1f
  [openstack2]=52:54:00:23:bd:72
  [openstack3]=52:54:00:b2:7b:30
)

# virsh power (non-secret). MAAS reaches libvirt over SSH on the OOB host address.
# Mirrors the surviving juju/lxd/tailscale virsh machines' live config (read
# 2026-06-26). power_id is set per host to the hostname by the caller.
VIRSH_POWER_ADDRESS="qemu+ssh://logxen@10.12.64.1/system"
HOST_ARCH="amd64"

# MAAS tag the deploy bundle places units against (constraint tags=openstack).
# Must be (re-)applied to every host post-commission or the bundle cannot bind.
HOST_TAG="openstack"

# host_sysid <hostname>: resolve the LIVE MAAS system_id by hostname (never
# hardcode it). Echoes the system_id, or empty if the host is not enrolled.
host_sysid() {
  local hn="$1"
  maas "${MAAS_PROFILE:-admin}" machines read 2>/dev/null \
    | jq -r --arg h "$hn" '.[] | select(.hostname==$h) | .system_id' | head -1
}

# --- $DC selector convention (2026-07-09, tooling gap register #1) ---
#
# Mirrors lib-net.sh's lib_net_select_dc -- SAME region-qualified selectors
# (D-119), but the answer here is honestly different, not a parallel no-op:
# HOSTS / HOST_OCTET / HOST_BOOT_MAC above are VR0 DC0's real, measured,
# enrolled hosts. VR1 DC0's and VR1 DC1's node VMs are created by
# opentofu/modules/node-vm (Stage 3 / buildout-design Phase 2), which has not
# run -- their hostnames, boot MACs, and octets do not exist yet, and
# VIRSH_POWER_ADDRESS above is VR0 DC0's own vcloud host connection (the
# buildout design's VR1 vcloud host is a distinct, not-yet-measured endpoint --
# see opentofu's root `libvirt_uri` variable, also unset). Selecting either VR1
# DC FAILS LOUDLY rather than inventing placeholder host data or silently
# reusing VR0 DC0's real hosts for a different DC.
#
# DELIBERATE ASYMMETRY WITH lib-net.sh: `vr1-dc0` is a NO-OP there (D-101 says
# it inherits VR0 DC0's v4 layout) but FAILS here (it has no enrolled hosts).
# That is intentional and is asserted by tests/dc-selector.
lib_hosts_select_dc() {
  local dc="${1:?usage: lib_hosts_select_dc <vr0-dc0|vr1-dc0|vr1-dc1>}"
  case "$dc" in
    vr0-dc0)
      : # already the sourced defaults above -- explicit no-op, not a guess.
      ;;
    vr1-dc0|vr1-dc1)
      echo "FAIL: $dc has no enrolled hosts yet -- Phase 2/3 node-VM creation (opentofu/modules/node-vm) and MAAS enrollment haven't run for it. Do not invent HOSTS/HOST_OCTET/HOST_BOOT_MAC/VIRSH_POWER_ADDRESS values; populate this file with a real \$dc block once those hosts are actually enrolled and measured." >&2
      return 1
      ;;
    dc0|dc1|dc2)
      echo "FAIL: bare '$dc' is RETIRED (D-119). It was AMBIGUOUS ACROSS REGIONS: 'dc0' meant VR0's live DC0 here, but VR1's FIRST DC in the NetBox importer. Use the region-qualified selector: vr0-dc0 | vr1-dc0 | vr1-dc1" >&2
      return 1
      ;;
    *)
      echo "FAIL: unknown DC '$dc' (expected vr0-dc0, vr1-dc0, or vr1-dc1)" >&2
      return 1
      ;;
  esac
}
