control node

GET /controlnode/bmc/{bmc_ip}/disks

Get available disks and NICs for a BMC

Fetch disk and NIC information from NetBox database for UI selection

Parameters:
  • bmc_ip (string) – BMC IP Address

Status Codes:
GET /controlnode/bmc/{bmc_ip}/gpus

Get available GPUs for a BMC

Fetch GPU inventory information from NetBox for UI selection

Parameters:
  • bmc_ip (string) – BMC IP Address

Status Codes:
DELETE /controlnode/fabric-config

Delete network fabric configuration

Deletes the cluster-wide network fabric configuration (hard delete).

Status Codes:
GET /controlnode/fabric-config

Get the current network fabric config

Returns the cluster-wide FabricConfig row.

Status Codes:
Response JSON Object:
  • acked_by (string) – operator identity for audit log

  • advertise_all_vni (boolean)

  • as (integer) – BGP core

  • bfd_enabled (boolean)

  • bgp_mode (string) – read-only derived: “ibgp” | “ebgp”

  • bgp_password (string) – inbound plaintext (POST/PUT only)

  • bgp_password_is_set (boolean) – read-only: a secret is configured

  • clear_bgp_password (boolean) – explicit removal (empty input = “unchanged”)

  • clear_ospf_auth_key (boolean)

  • expected_nodes (integer) – Sizing hints. Drive VTEP pool calc + capacity warnings. Validated 1..1000 / 1..10000. 0 = unset, validation skipped on POST/apply when entire row predates the field (legacy rows). Plan path requires.

  • expected_vms (integer)

  • external_route_reflector (boolean) – ExternalRouteReflector — when true, the BGP route-reflector lives on the fabric switch (PICA8 / Cumulus / Cisco / Arista with RR config rendered via switch_templates.go). Cube software-RR on the GW Linux node is dropped: cube GW becomes a regular iBGP peer of the external switch RR. When false (default), the existing cube GW software-RR model remains. Defaults false to preserve existing-deployment behaviour. Validator (validate.go) requires fabric_switch_peering_ip + fabric_switch_as + a BGP-EVPN-capable NOS when this is true.

  • fabric_switch_as (integer)

  • fabric_switch_name (string) – Fabric switch — only what’s needed for BGP peering

  • fabric_switch_nos (string) – sonic, cumulus, nxos, eos

  • fabric_switch_peering_ip (string) – Loopback IP = BGP peer address

  • fabric_switch_role (string) – spine, leaf, border-leaf

  • frr_hmac_sha_capable (boolean) – FRRHMACShaCapable is the result of the preflight HMAC-SHA capability probe (controlnode/fabric/preflight.go). Tri-state pointer: nil = never probed (HMAC blocked by validation until proven), false = probed unsupported, true = probed supported. Read-only to the API.

  • last_job (any) – LastJob carries the latest fabric_apply / fabric_teardown job view inline when RolloutStatus is failed or degraded. Populated by GetNetworkFabricConfig from configure.Jobs via fabric.GetLatestFabricJob so a single GET shows both the declared intent and the last observed failure reason (including first_fail_node + first_fail_error and the per-node Nodes[] slice). UI renders without a second round-trip to /fabric-config/latest. Type is any rather than *fabric.FabricJobView to avoid a controlnode/models → controlnode/fabric import cycle (fabric already imports controlnode/models). The handler assigns the FabricJobView pointer directly; JSON marshal preserves the same shape FabricJobView serialises to today.

  • management_cidr (string) – VTEP IP allocation (managed by evpn_setup at runtime)

  • ospf_area (string)

  • ospf_auth_key (string) – inbound plaintext (POST/PUT only)

  • ospf_auth_key_id (integer)

  • ospf_auth_key_is_set (boolean) – read-only: a key is configured

  • ospf_auth_type (string) – OSPF underlay authentication. Type ∈ {”” / “none”, “message-digest”, “hmac-sha-256”}. FRR OSPF auth is PER-INTERFACE, so a non-none type requires OSPFFabricInterface (enforced in validate.go). hmac-sha-256 is gated by the preflight FRR-capability probe (FRRHMACShaCapable). OSPFAuthKey is the secret, stored AES-256-GCM (same scheme as BGPPassword); write-only with input/is_set transient fields.

  • ospf_auto_ref_bw (integer)

  • ospf_dead_interval (integer)

  • ospf_enabled (boolean) – OSPF underlay

  • ospf_fabric_interface (string) – Interface facing the fabric switch (e.g., “eth1”)

  • ospf_hello_interval (integer)

  • physnet (any) – PhysnetStatus is a read-only projection of the VXLAN fabric physical network (present / has-Guest-traffic-type / id). Not persisted (gorm:”-“); populated only on GET by GetNetworkFabricConfig. Mirrors the LastJob transient-field pattern so the UI response shape stays FabricConfig. Defined locally (not network/utils.VXLANPhysnetStatus) because network/utils imports controlnode — a direct import here would close a cycle. The handler converts.

  • public_mtu (integer)

  • rollout_status (string) – RolloutStatus tracks propagation of this fabric to compute nodes. Values: “pending” | “rolling_out” | “ready” | “failed” | “degraded”. Empty string is treated as “ready” for rows predating this column. Used by controlnode/fabric.CheckVXLANAllowed to gate VXLAN physnet and L2 guest-network creation — both require status=ready.

  • router_id_base (string) – VTEP loopback start IP (e.g., “10.255.0.1”)

  • router_id_cidr (string) – RouterIDCIDR is a transient convenience: a single “A.B.C.D/N” the UI sends instead of base+prefixlen. When present it is decoded server-side into the authoritative RouterIDBase + RouterIDPrefixLen. GET re-emits it (derived) so the UI can render one field. Never persisted (gorm:”-“).

  • router_id_prefix_len (integer) – Subnet prefix length (e.g., 24 for /24)

  • skip_switch_ack (boolean) – lab/CI bypass — production should require FABRIC_ADMIN perm

  • switch_acked (boolean) – Switch-side ack-gate fields for VTEP-pool resize. Transient — accepted on the POST request body, never persisted (gorm:”-“). When the operator changes RouterIDBase / RouterIDPrefixLen, karios-core returns 409 REQUIRES_SWITCH_RECONFIG_ACK with per-NOS BGP listen-range diff snippets. Operator pastes the snippet on the fabric switch, runs the verify command, then re-POSTs with these fields populated.

  • switch_nos (string) – NOS being acked (defaults to FabricSwitchNOS)

  • switch_snippet_hash (string) – sha256 echoed from the 409 response

  • vxlan_mtu (integer) – VXLAN

POST /controlnode/fabric-config

Store network fabric configuration

Stores or updates the cluster-wide network fabric configuration (BGP AS, OSPF, fabric switch info, VTEP settings, BFD, etc.). Called by karios-bootstrap during initial setup. Uses upsert semantics — creates on first call, updates on subsequent. This config is later read by configureFRRForNode during compute node setup to generate frr.conf and allocate VTEP IPs.

Request JSON Object:
  • acked_by (string) – operator identity for audit log

  • advertise_all_vni (boolean)

  • as (integer) – BGP core

  • bfd_enabled (boolean)

  • bgp_mode (string) – read-only derived: “ibgp” | “ebgp”

  • bgp_password (string) – inbound plaintext (POST/PUT only)

  • bgp_password_is_set (boolean) – read-only: a secret is configured

  • clear_bgp_password (boolean) – explicit removal (empty input = “unchanged”)

  • clear_ospf_auth_key (boolean)

  • expected_nodes (integer) – Sizing hints. Drive VTEP pool calc + capacity warnings. Validated 1..1000 / 1..10000. 0 = unset, validation skipped on POST/apply when entire row predates the field (legacy rows). Plan path requires.

  • expected_vms (integer)

  • external_route_reflector (boolean) – ExternalRouteReflector — when true, the BGP route-reflector lives on the fabric switch (PICA8 / Cumulus / Cisco / Arista with RR config rendered via switch_templates.go). Cube software-RR on the GW Linux node is dropped: cube GW becomes a regular iBGP peer of the external switch RR. When false (default), the existing cube GW software-RR model remains. Defaults false to preserve existing-deployment behaviour. Validator (validate.go) requires fabric_switch_peering_ip + fabric_switch_as + a BGP-EVPN-capable NOS when this is true.

  • fabric_switch_as (integer)

  • fabric_switch_name (string) – Fabric switch — only what’s needed for BGP peering

  • fabric_switch_nos (string) – sonic, cumulus, nxos, eos

  • fabric_switch_peering_ip (string) – Loopback IP = BGP peer address

  • fabric_switch_role (string) – spine, leaf, border-leaf

  • frr_hmac_sha_capable (boolean) – FRRHMACShaCapable is the result of the preflight HMAC-SHA capability probe (controlnode/fabric/preflight.go). Tri-state pointer: nil = never probed (HMAC blocked by validation until proven), false = probed unsupported, true = probed supported. Read-only to the API.

  • last_job (any) – LastJob carries the latest fabric_apply / fabric_teardown job view inline when RolloutStatus is failed or degraded. Populated by GetNetworkFabricConfig from configure.Jobs via fabric.GetLatestFabricJob so a single GET shows both the declared intent and the last observed failure reason (including first_fail_node + first_fail_error and the per-node Nodes[] slice). UI renders without a second round-trip to /fabric-config/latest. Type is any rather than *fabric.FabricJobView to avoid a controlnode/models → controlnode/fabric import cycle (fabric already imports controlnode/models). The handler assigns the FabricJobView pointer directly; JSON marshal preserves the same shape FabricJobView serialises to today.

  • management_cidr (string) – VTEP IP allocation (managed by evpn_setup at runtime)

  • ospf_area (string)

  • ospf_auth_key (string) – inbound plaintext (POST/PUT only)

  • ospf_auth_key_id (integer)

  • ospf_auth_key_is_set (boolean) – read-only: a key is configured

  • ospf_auth_type (string) – OSPF underlay authentication. Type ∈ {”” / “none”, “message-digest”, “hmac-sha-256”}. FRR OSPF auth is PER-INTERFACE, so a non-none type requires OSPFFabricInterface (enforced in validate.go). hmac-sha-256 is gated by the preflight FRR-capability probe (FRRHMACShaCapable). OSPFAuthKey is the secret, stored AES-256-GCM (same scheme as BGPPassword); write-only with input/is_set transient fields.

  • ospf_auto_ref_bw (integer)

  • ospf_dead_interval (integer)

  • ospf_enabled (boolean) – OSPF underlay

  • ospf_fabric_interface (string) – Interface facing the fabric switch (e.g., “eth1”)

  • ospf_hello_interval (integer)

  • physnet (any) – PhysnetStatus is a read-only projection of the VXLAN fabric physical network (present / has-Guest-traffic-type / id). Not persisted (gorm:”-“); populated only on GET by GetNetworkFabricConfig. Mirrors the LastJob transient-field pattern so the UI response shape stays FabricConfig. Defined locally (not network/utils.VXLANPhysnetStatus) because network/utils imports controlnode — a direct import here would close a cycle. The handler converts.

  • public_mtu (integer)

  • rollout_status (string) – RolloutStatus tracks propagation of this fabric to compute nodes. Values: “pending” | “rolling_out” | “ready” | “failed” | “degraded”. Empty string is treated as “ready” for rows predating this column. Used by controlnode/fabric.CheckVXLANAllowed to gate VXLAN physnet and L2 guest-network creation — both require status=ready.

  • router_id_base (string) – VTEP loopback start IP (e.g., “10.255.0.1”)

  • router_id_cidr (string) – RouterIDCIDR is a transient convenience: a single “A.B.C.D/N” the UI sends instead of base+prefixlen. When present it is decoded server-side into the authoritative RouterIDBase + RouterIDPrefixLen. GET re-emits it (derived) so the UI can render one field. Never persisted (gorm:”-“).

  • router_id_prefix_len (integer) – Subnet prefix length (e.g., 24 for /24)

  • skip_switch_ack (boolean) – lab/CI bypass — production should require FABRIC_ADMIN perm

  • switch_acked (boolean) – Switch-side ack-gate fields for VTEP-pool resize. Transient — accepted on the POST request body, never persisted (gorm:”-“). When the operator changes RouterIDBase / RouterIDPrefixLen, karios-core returns 409 REQUIRES_SWITCH_RECONFIG_ACK with per-NOS BGP listen-range diff snippets. Operator pastes the snippet on the fabric switch, runs the verify command, then re-POSTs with these fields populated.

  • switch_nos (string) – NOS being acked (defaults to FabricSwitchNOS)

  • switch_snippet_hash (string) – sha256 echoed from the 409 response

  • vxlan_mtu (integer) – VXLAN

Status Codes:
POST /controlnode/fabric-config/apply

Manually trigger a fabric rollout to compute nodes

Re-runs the EVPN setup steps (FRR install, dpkg-divert, vtep0, BGP config, MTU sync) on every registered compute node. Use after recovering from a failed/degraded rollout, or to force re-apply when a new compute node has joined. Returns 202 with apply_job_id; SSE channel “fabric” event_type “fabric_switch” streams per-node progress.

Status Codes:
Response JSON Object:
  • apply_job_id (string)

  • created (boolean) – true if new record, false if updated

  • id (integer)

  • message (string)

POST /controlnode/fabric-config/apply/{job_id}/cancel

Cancel an in-flight fabric apply

Aborts the currently running fabric apply job and rolls the cluster back to baseline (same teardown path strict-mode uses on per-node failure). Returns 202 immediately; the cancellation completes asynchronously via the apply_cancelling → apply_cancelled SSE sequence. Idempotent — multiple cancel calls for the same job_id are safe. Returns 404 when the job_id does not match the in-flight apply (already terminal, wrong id, or never existed).

Parameters:
  • job_id (string) – Apply job UUID

Status Codes:
GET /controlnode/fabric-config/batches/{id}/postdeploy

Post-deployment aggregate for a provisioning batch

Parameters:
  • id (string) – provision batch id

Status Codes:
GET /controlnode/fabric-config/latest

Get the most recent fabric lifecycle job

Returns the latest fabric_apply or fabric_teardown job row — used by the UI on page refresh to replay the last rollout or teardown state when SSE connection is fresh and missed prior events. JobType field distinguishes apply vs teardown.

Status Codes:
Response JSON Object:
  • completed_nodes (integer)

  • created_at (string)

  • error (string)

  • fabric_id (string)

  • failed_nodes (integer)

  • first_fail_error (string)

  • first_fail_node (string) – FirstFailNode + FirstFailError surface the first per-node failure verbatim so a UI rendering only the headline shows the real reason (e.g. “BGP neighbor 172.30.10.254 not Established”) without walking Nodes[]. Populated by finalizeApply on failed/degraded outcomes.

  • job_id (string)

  • job_status (string) – running|completed|failed|partial

  • job_type (string) – fabric_apply | fabric_teardown

  • nodes[].error (string)

  • nodes[].fqdn (string)

  • nodes[].node_ip (string)

  • nodes[].ok (boolean)

  • nodes[].reachable (boolean) – false = SSH dial failed before EVPN step ran

  • progress (integer) – 0..100

  • state (string) – last SSE state: apply_*/teardown_*/node_*

  • total_nodes (integer)

  • updated_at (string)

DELETE /controlnode/fabric-config/node/{node_ip}

Tear down EVPN/FRR on a single node

Parameters:
  • node_ip (string) – OS IP of the target node

Status Codes:
Response JSON Object:
  • message (string)

  • removed (boolean)

  • steps[] (string)

POST /controlnode/fabric-config/node/{node_ip}/apply

Apply EVPN/FRR config to a single node

Parameters:
  • node_ip (string) – OS IP of the target node

Status Codes:
GET /controlnode/fabric-config/node/{node_ip}/postdeploy

Post-deployment step checklist for one node

Parameters:
  • node_ip (string) – OS IP of the node

Status Codes:
Response JSON Object:
  • [].batch_id (string)

  • [].bmc_ip (string) – BMCIP is carried because the ENTIRE web batch surface keys by bmc_ip (store key bmc:${bmc_ip}, batch rows carry only bmc_ip) and has no os_ip↔bmc_ip bridge — the backend owns the wire shape, so it ships both identities rather than forcing a UI-side lookup that does not exist.

  • [].created_at (string)

  • [].message (string)

  • [].node_ip (string)

  • [].progress (integer)

  • [].status (string)

  • [].step_id (string)

  • [].updated_at (string)

POST /controlnode/fabric-config/plan

Dry-run a fabric configuration

Returns a preview FabricConfig with auto-sized VTEP pool, suggested switch ASN/peering IP, VNI range, plan_hash, and operator-actionable risks/notes. No DB write — operator commits via POST /controlnode/fabric-config.

Request JSON Object:
  • expected_nodes (integer) – sizing hint only — planner auto-picks default VTEP prefix when unset

  • expected_vms (integer) – sizing hint for tenant subnets (notes only)

  • fabric_switch_as (integer) – 0 => planner suggests

  • fabric_switch_name (string)

  • fabric_switch_nos (string) – sonic|cumulus|nxos|eos|other (required)

  • fabric_switch_peering_ip (string) – empty => planner suggests

  • fabric_switch_role (string) – spine|leaf|border-leaf

  • local_as (integer) – 0 => auto-pick

  • management_cidr (string) – e.g. “192.168.111.0/24” (required)

  • public_mtu (integer) – VR public-side MTU — required in DC mode, ignored in Cube (no VR)

  • router_id_base (string) – empty => 10.255.0.0 default

  • router_id_prefix_len (integer) – 0 => auto-size; operator value honored verbatim

  • underlay_mode (string) – “” / “ospf” (default) | “bgp” (no-OSPF: one iBGP session over the mgmt subnet carries ipv4-unicast loopback /32s + EVPN — lab-proven env05/env06)

  • vxlan_mtu (integer) – fabric/data-plane MTU (1500 default; 9216 max for jumbo on 100GbE) (required)

Status Codes:
Response JSON Object:
  • config.advertise_all_vni (boolean)

  • config.as (integer)

  • config.bfd_enabled (boolean)

  • config.bgp_password (string)

  • config.fabric_switch_as (integer)

  • config.fabric_switch_name (string)

  • config.fabric_switch_nos (string)

  • config.fabric_switch_peering_ip (string)

  • config.fabric_switch_role (string)

  • config.management_cidr (string)

  • config.ospf_area (string)

  • config.ospf_auto_ref_bw (integer)

  • config.ospf_dead_interval (integer)

  • config.ospf_enabled (boolean)

  • config.ospf_fabric_interface (string)

  • config.ospf_hello_interval (integer)

  • config.public_mtu (integer)

  • config.rollout_status (string)

  • config.router_id_base (string)

  • config.router_id_prefix_len (integer)

  • config.vxlan_mtu (integer)

  • deployment_mode (string)

  • notes[] (string)

  • plan_hash (string)

  • risks[] (string)

  • switch_config (string) – rendered for cfg.FabricSwitchNOS only; use “other” for vendor-neutral reference

  • vtep_capacity (integer)

POST /controlnode/fabric-config/preflight

Preflight underlay resolution per compute node

POST (not GET) because (a) future iterations carry a node_overrides[] array that doesn’t fit cleanly in a query string, (b) preflight does an SSH fan-out which is not “safe” in the HTTP-method sense, and (c) GET responses risk being cached by intermediaries while preflight is live cluster state. Matches the pattern used by GraphQL, Elasticsearch _search, and k8s dry-run. Read-only: scans every compute node’s bridges and returns whether each one has a bridge with an IPv4 address inside the supplied underlay_cidr. Nodes resolving via an existing bridge enter mode=reuse (no operator input needed). Nodes that don’t resolve return mode=needs_override. Used by the UI to gate the Save&Apply button and to populate the per-node bridge field. No kernel mutation occurs.

Request JSON Object:
  • expected_nodes (integer) – override stored sizing hint for capacity warn

  • node_overrides[].node_ip (string) – (required)

  • node_overrides[].underlay_bridge_name (string) – optional, derive from CIDR when empty

  • node_overrides[].underlay_iface_hint (string) – (required)

  • node_overrides[].underlay_ip (string) – host/CIDR, e.g. “10.60.200.5/24” (required)

  • router_id_base (string) – VTEP pool base, falls back to stored FabricConfig

  • router_id_prefix_len (integer) – VTEP pool prefix, falls back to stored FabricConfig

  • underlay_cidr (string) – IPv4 CIDR, e.g. “10.60.200.0/24” (required)

Status Codes:
Response JSON Object:
  • matched_bridges[] (string)

  • mtu_drift[].bridge (string)

  • mtu_drift[].bridge_mtu (integer)

  • mtu_drift[].fqdn (string)

  • mtu_drift[].node_ip (string)

  • nodes[].bridge (string) – populated when Mode=reuse

  • nodes[].bridge_mtu (integer) – live kernel MTU of the matched bridge (Mode=reuse only). 0 when iface absent or non-reuse.

  • nodes[].fqdn (string)

  • nodes[].mode (string)

  • nodes[].needs_override (boolean)

  • nodes[].node_ip (string)

  • nodes[].reason (string) – human-readable explanation when Mode=needs_override or unreachable

  • nodes[].underlay_ip (string) – existing IP/CIDR on the bridge, populated when Mode=reuse

  • ready (boolean) – true ⟺ every node ∈ {reuse}; needs_override or unreachable flips this to false

  • underlay_cidr (string)

  • underlay_mtu (integer) – UnderlayMTU is the cluster-wide consensus MTU across reuse-mode nodes’ matched underlay bridges. It is the value the UI should auto-populate into the fabric-config form’s vxlan_mtu field and the value the backend rejects drift against (see ErrMTUDriftRejected in validate.go). Resolution: - All reuse-mode nodes agree on MTU N (>0) → UnderlayMTU = N, MTUDrift empty - Reuse-mode nodes disagree → UnderlayMTU = 0, MTUDrift populated with every observed (node, mtu) pair - No reuse-mode nodes (cold-start cluster) → UnderlayMTU = 0, MTUDrift empty

  • vtep_pool.capacity (integer) – usable host count in the pool

  • vtep_pool.expected_nodes (integer) – operator-declared sizing hint (FabricConfig.ExpectedNodes)

  • vtep_pool.headroom (integer) – capacity - expected_nodes

  • vtep_pool.overalloc_warn (boolean) – true when headroom < 0

  • vtep_pool.router_id_base (string)

  • vtep_pool.router_id_prefix_len (integer)

GET /controlnode/fabric-config/vtep-pool

Get VTEP IP pool status

Returns the current capacity of the VTEP loopback IP pool: total, allocated, remaining, and whether the pool is exhausted. Reads from FabricConfig in DB.

Status Codes:
Response JSON Object:
  • allocated (integer) – Number of IPs already assigned

  • exhausted (boolean) – True if no IPs remain

  • last_allocated_ip (string) – Most recently assigned IP

  • prefix_length (integer) – Subnet prefix (e.g. 24)

  • remaining (integer) – IPs still available

  • router_id_base (string) – Base IP (e.g. “10.255.0.1”)

  • start_ip (string) – First usable IP in the pool

  • subnet_cidr (string) – Network CIDR (e.g. “10.255.0.0/24”)

  • total_usable (integer) – Total usable IPs (excluding .0 and .255 per /24 block)

POST /controlnode/firstboot

Receive first boot OS IP report

Called by installed OS on first boot to report its IP address

Request JSON Object:
  • bmc_ip (string) – (required)

  • os_ip (string) – (required)

Status Codes:
GET /controlnode/job/{id}

Get Job Status

Retrieve job status and details by job ID

Parameters:
  • id (string) – Job-Id

Status Codes:
Response JSON Object:
  • created_at (string)

  • id (string)

  • job_status (string)

  • job_type (string)

  • metadata (string)

  • node_ip (string)

  • parent_id (string)

  • progress (integer)

  • resource_name (string)

  • status (string)

  • total_jobs (integer)

  • updated_at (string)

PATCH /controlnode/job/{id}

Patch Job Status

Patch job related status with given id

Parameters:
  • id (string) – Job-Id

Status Codes:
Response JSON Object:
  • created_at (string)

  • id (string)

  • job_status (string)

  • job_type (string)

  • metadata (string)

  • node_ip (string)

  • parent_id (string)

  • progress (integer)

  • resource_name (string)

  • status (string)

  • total_jobs (integer)

  • updated_at (string)

POST /controlnode/job/{id}/cancel

Cancel a running provision job

Cancels a running provision job by job ID

Parameters:
  • id (string) – Job ID (UUID)

Status Codes:
POST /controlnode/job/{id}/complete

Mark job as installation complete

HTTP callback from installation script to signal that OS installation is complete

Parameters:
  • id (string) – Job ID

Request JSON Object:
  • os_ip (string)

  • os_password (string)

Status Codes:
POST /controlnode/job/{id}/step

Receive an install step status report from the live ISO

Called by the provisioning script running on the target node to report each OS installation step. Broadcasts step progress via SSE, updates job status, and resets the stuck-detection timer. No auth required.

Parameters:
  • id (string) – Job ID

Request JSON Object:
  • percent (integer)

  • state (string) – “active” | “done” | “failed” (required)

  • step (string) – (required)

Status Codes:
POST /controlnode/provision

Provision a node with Debian OS

Build custom Debian ISO with preseed and provision via Redfish

Request JSON Object:
  • arch (string)

  • bmc_IP (string) – (required)

  • branch (string)

  • cache_dir (string)

  • controlnode_host (string)

  • controlnode_port (string)

  • debian_version (string)

  • device_id (integer) – NetBox Device ID for tracking

  • gpu_passthrough (any) – GPU passthrough config for IOMMU/vfio-pci

  • hostname (string)

  • kubernetes_cluster_name (string)

  • kubernetes_cluster_type (string)

  • location (string)

  • mac_address (string)

  • network_role (string) – IPAM fields for static IP allocation

  • os_password (string) – OS password (default: adminadmin)

  • os_username (string) – OS credentials for provisioned system

  • output_iso (string)

  • pool_type (string) – “mirror”, “raidz1”, “raidz2”, “stripe”, “single”

  • prefix_id (integer) – Prefix ID from VLAN query response

  • pxe_path (string)

  • pxe_server (string)

  • rack_number (string)

  • root_pass (string)

  • selected_disks[] (string)

  • selected_nic (string) – e.g., “enp0s3” - DHCP enabled on this interface

  • selected_nic_legacy (string) – Legacy kernel name for the NIC (e.g., “eth0”)

  • selected_nic_mac (string) – MAC address of the selected NIC

  • sys_iuri (string)

  • vendor (string) – (required)

  • vm_slot (string)

  • zone (string)

Status Codes:
POST /controlnode/provision/cisco

Provision a Cisco node with Debian OS

Build custom Debian ISO with preseed and provision via Cisco CIMC Redfish

Request JSON Object:
  • arch (string)

  • bmc_IP (string) – (required)

  • branch (string)

  • cache_dir (string)

  • controlnode_host (string)

  • controlnode_port (string)

  • debian_version (string)

  • device_id (integer) – NetBox Device ID for tracking

  • gpu_passthrough (any) – GPU passthrough config for IOMMU/vfio-pci

  • hostname (string)

  • kubernetes_cluster_name (string)

  • kubernetes_cluster_type (string)

  • location (string)

  • mac_address (string)

  • network_role (string) – IPAM fields for static IP allocation

  • os_password (string) – OS password (default: adminadmin)

  • os_username (string) – OS credentials for provisioned system

  • output_iso (string)

  • pool_type (string) – “mirror”, “raidz1”, “raidz2”, “stripe”, “single”

  • prefix_id (integer) – Prefix ID from VLAN query response

  • pxe_path (string)

  • pxe_server (string)

  • rack_number (string)

  • root_pass (string)

  • selected_disks[] (string)

  • selected_nic (string) – e.g., “enp0s3” - DHCP enabled on this interface

  • selected_nic_legacy (string) – Legacy kernel name for the NIC (e.g., “eth0”)

  • selected_nic_mac (string) – MAC address of the selected NIC

  • sys_iuri (string)

  • vendor (string) – (required)

  • vm_slot (string)

  • zone (string)

Status Codes:
POST /controlnode/provision/dell

Provision a Dell node with Debian OS

Build custom Debian ISO with preseed and provision via Dell iDRAC Redfish

Request JSON Object:
  • arch (string)

  • bmc_IP (string) – (required)

  • branch (string)

  • cache_dir (string)

  • controlnode_host (string)

  • controlnode_port (string)

  • debian_version (string)

  • device_id (integer) – NetBox Device ID for tracking

  • gpu_passthrough (any) – GPU passthrough config for IOMMU/vfio-pci

  • hostname (string)

  • kubernetes_cluster_name (string)

  • kubernetes_cluster_type (string)

  • location (string)

  • mac_address (string)

  • network_role (string) – IPAM fields for static IP allocation

  • os_password (string) – OS password (default: adminadmin)

  • os_username (string) – OS credentials for provisioned system

  • output_iso (string)

  • pool_type (string) – “mirror”, “raidz1”, “raidz2”, “stripe”, “single”

  • prefix_id (integer) – Prefix ID from VLAN query response

  • pxe_path (string)

  • pxe_server (string)

  • rack_number (string)

  • root_pass (string)

  • selected_disks[] (string)

  • selected_nic (string) – e.g., “enp0s3” - DHCP enabled on this interface

  • selected_nic_legacy (string) – Legacy kernel name for the NIC (e.g., “eth0”)

  • selected_nic_mac (string) – MAC address of the selected NIC

  • sys_iuri (string)

  • vendor (string) – (required)

  • vm_slot (string)

  • zone (string)

Status Codes:
POST /controlnode/provision/hp

Provision an HP node with Debian OS

Build custom Debian ISO with preseed and provision via HPE iLO Redfish

Request JSON Object:
  • arch (string)

  • bmc_IP (string) – (required)

  • branch (string)

  • cache_dir (string)

  • controlnode_host (string)

  • controlnode_port (string)

  • debian_version (string)

  • device_id (integer) – NetBox Device ID for tracking

  • gpu_passthrough (any) – GPU passthrough config for IOMMU/vfio-pci

  • hostname (string)

  • kubernetes_cluster_name (string)

  • kubernetes_cluster_type (string)

  • location (string)

  • mac_address (string)

  • network_role (string) – IPAM fields for static IP allocation

  • os_password (string) – OS password (default: adminadmin)

  • os_username (string) – OS credentials for provisioned system

  • output_iso (string)

  • pool_type (string) – “mirror”, “raidz1”, “raidz2”, “stripe”, “single”

  • prefix_id (integer) – Prefix ID from VLAN query response

  • pxe_path (string)

  • pxe_server (string)

  • rack_number (string)

  • root_pass (string)

  • selected_disks[] (string)

  • selected_nic (string) – e.g., “enp0s3” - DHCP enabled on this interface

  • selected_nic_legacy (string) – Legacy kernel name for the NIC (e.g., “eth0”)

  • selected_nic_mac (string) – MAC address of the selected NIC

  • sys_iuri (string)

  • vendor (string) – (required)

  • vm_slot (string)

  • zone (string)

Status Codes:
POST /controlnode/provision/lenovo

Provision a Lenovo node with Debian OS

Build custom Debian ISO with preseed and provision via Lenovo XCC virtual media

Request JSON Object:
  • arch (string)

  • bmc_IP (string) – (required)

  • branch (string)

  • cache_dir (string)

  • controlnode_host (string)

  • controlnode_port (string)

  • debian_version (string)

  • device_id (integer) – NetBox Device ID for tracking

  • gpu_passthrough (any) – GPU passthrough config for IOMMU/vfio-pci

  • hostname (string)

  • kubernetes_cluster_name (string)

  • kubernetes_cluster_type (string)

  • location (string)

  • mac_address (string)

  • network_role (string) – IPAM fields for static IP allocation

  • os_password (string) – OS password (default: adminadmin)

  • os_username (string) – OS credentials for provisioned system

  • output_iso (string)

  • pool_type (string) – “mirror”, “raidz1”, “raidz2”, “stripe”, “single”

  • prefix_id (integer) – Prefix ID from VLAN query response

  • pxe_path (string)

  • pxe_server (string)

  • rack_number (string)

  • root_pass (string)

  • selected_disks[] (string)

  • selected_nic (string) – e.g., “enp0s3” - DHCP enabled on this interface

  • selected_nic_legacy (string) – Legacy kernel name for the NIC (e.g., “eth0”)

  • selected_nic_mac (string) – MAC address of the selected NIC

  • sys_iuri (string)

  • vendor (string) – (required)

  • vm_slot (string)

  • zone (string)

Status Codes:
POST /controlnode/provision/progress

Get latest provision progress for a BMC IP

Fetches the most recent provisioning state from provision_progresses table. Useful for UI recovery after timeout/logout.

Request JSON Object:
  • bmc_ip (string)

Status Codes:
Response JSON Object:
  • bmc_ip (string)

  • created_at (string)

  • id (integer)

  • job_id (string) – active queue job id for UI cancel recovery

  • message (string) – detailed status message

  • percent_complete (integer) – 0-100

  • stage (string) – e.g., “Building ISO”, “Mounting ISO”, “Installing OS”

  • status (string) – running, completed, failed, cancelled

  • updated_at (string)

POST /controlnode/provision/progress/all

Get all provision progress records for a BMC IP

Fetches all provisioning states from provision_progresses table for a specific BMC IP, ordered by timestamp.

Request JSON Object:
  • bmc_ip (string)

Status Codes:
Response JSON Object:
  • [].bmc_ip (string)

  • [].created_at (string)

  • [].id (integer)

  • [].job_id (string) – active queue job id for UI cancel recovery

  • [].message (string) – detailed status message

  • [].percent_complete (integer) – 0-100

  • [].stage (string) – e.g., “Building ISO”, “Mounting ISO”, “Installing OS”

  • [].status (string) – running, completed, failed, cancelled

  • [].updated_at (string)

GET /controlnode/provision/queue

Get provision queue status

Returns all pending and active ISO-build queue entries

Status Codes:
POST /controlnode/provision/supermicro

Provision a Supermicro node with Debian OS

Build custom Debian ISO with preseed and provision via Supermicro BMC Redfish

Request JSON Object:
  • arch (string)

  • bmc_IP (string) – (required)

  • branch (string)

  • cache_dir (string)

  • controlnode_host (string)

  • controlnode_port (string)

  • debian_version (string)

  • device_id (integer) – NetBox Device ID for tracking

  • gpu_passthrough (any) – GPU passthrough config for IOMMU/vfio-pci

  • hostname (string)

  • kubernetes_cluster_name (string)

  • kubernetes_cluster_type (string)

  • location (string)

  • mac_address (string)

  • network_role (string) – IPAM fields for static IP allocation

  • os_password (string) – OS password (default: adminadmin)

  • os_username (string) – OS credentials for provisioned system

  • output_iso (string)

  • pool_type (string) – “mirror”, “raidz1”, “raidz2”, “stripe”, “single”

  • prefix_id (integer) – Prefix ID from VLAN query response

  • pxe_path (string)

  • pxe_server (string)

  • rack_number (string)

  • root_pass (string)

  • selected_disks[] (string)

  • selected_nic (string) – e.g., “enp0s3” - DHCP enabled on this interface

  • selected_nic_legacy (string) – Legacy kernel name for the NIC (e.g., “eth0”)

  • selected_nic_mac (string) – MAC address of the selected NIC

  • sys_iuri (string)

  • vendor (string) – (required)

  • vm_slot (string)

  • zone (string)

Status Codes:
POST /controlnode/register

Register the control node (1st node) in bmc_infos

Registers the management/control node in the bmc_infos table with is_control_node=true

Request JSON Object:
  • atlas_device_id (integer) – NetBox Device ID

  • atlas_location_id (integer) – NetBox Location ID

  • atlas_rack_id (integer) – NetBox Rack ID

  • atlas_site_id (integer) – Optional Atlas/NetBox IDs (populated from NetBox sync result during bootstrap)

  • bmc_ip (string) – Required field - BMC IP is the primary key (required)

  • bmc_password (string) – BMC password

  • bmc_username (string) – Optional BMC credentials

  • fqdn (string) – Fully qualified domain name

  • os_hostname (string) – Hostname (e.g., mgmt-01)

  • os_ip (string) – Optional OS info

  • os_password (string) – SSH password (will be hex encoded)

  • os_username (string) – SSH username (default: root)

  • primary_mac (string) – Primary NIC MAC address

  • serial_number (string) – Used as UUID

  • vendor (string) – Optional hardware info

Status Codes:
Response JSON Object:
  • created (boolean) – true if new record, false if updated existing

  • hostname (string)

  • message (string)

  • node_ip (string)

  • success (boolean)

  • created – true if new record, false if updated existing

  • hostname

  • message

  • node_ip

  • success

POST /controlnode/unprovision

Unprovision a node

Unprovision a node by wiping storage using Debian live-build wipe ISO

Request JSON Object:
  • bmc_ip (string) – (required)

  • bmc_pass (string)

  • bmc_user (string)

  • vendor (string)

Status Codes: