Declare or update a node underlay connection (bootstrap-admin).
curl --request PUT \ --url https://stratum.example.com/v1/admin/network/underlay/nodes/example/connections/example \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "kind": "ethernet", "interface": "example", "parent": "example", "vlanId": 1, "addresses": [ "example" ], "mtu": 1, "trafficClass": "", "zone": "example", "controller": "example", "bond": { "mode": "802.3ad", "xmitHashPolicy": "example", "miimonMs": 1, "lacpRate": "slow" }, "neverDefault": true, "purposes": [ "oob" ] }'Declare a host NIC/VLAN connection as desired state. The
per-node reconciler renders it into a host-helper intent applied under a
NetworkManager checkpoint. Install-scope; gates on
network:DeclareUnderlayConnection. 400 INVALID_INPUT on a bad
kind/interface/vlan/address/mtu.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”body for PUT…/connections/{name} (name comes from the path).
object
Firewalld zone. A cluster-internal link left in NetworkManager’s default
public zone comes up and silently drops the traffic it exists to carry, so the fabric declares trusted explicitly.
The bond this connection is a member of. A member carries no addresses of its own — the bond’s VLANs own the addressing, and an addressed member is how a link ends up half in the aggregate.
802.3ad (or active-backup) aggregation for a bond connection.
xmitHashPolicy is required for 802.3ad and is not a tuning preference.
Geneve puts every tunnel between a single MAC/IP pair, so the kernel default
(layer2) hashes ALL overlay traffic onto one member: the bond reports UP,
both links report UP, and half the fabric is unreachable.
object
Required for 802.3ad. Use layer3+4 so overlay traffic spreads across members.
Link-monitor interval in milliseconds, e.g. 100.
Keep this connection’s route out of the default path. A storage or overlay VLAN taking the default route would pull cluster egress onto the fabric.
What the link carries: the network half of
the node’s hardware plan. trafficClass is the primary one (the first
of mgmt, storage, overlay, provider); send either, or both agreeing.
oob is the stage-1 lifeline and is never an underlay connection.
Responses
Section titled “Responses”Declared.
declared host underlay connection (a NIC, VLAN or bond + addressing).
object
Resulting host interface name (<= 15 chars). e.g. enp2s0f0np0 or vlan40.
Parent device for a vlan connection.
Static CIDRs, e.g. [“192.0.2.111/24”].
traffic class this connection serves.
Firewalld zone. A cluster-internal link left in NetworkManager’s default
public zone comes up and silently drops the traffic it exists to carry, so the fabric declares trusted explicitly.
The bond this connection is a member of. A member carries no addresses of its own — the bond’s VLANs own the addressing, and an addressed member is how a link ends up half in the aggregate.
802.3ad (or active-backup) aggregation for a bond connection.
xmitHashPolicy is required for 802.3ad and is not a tuning preference.
Geneve puts every tunnel between a single MAC/IP pair, so the kernel default
(layer2) hashes ALL overlay traffic onto one member: the bond reports UP,
both links report UP, and half the fabric is unreachable.
object
Required for 802.3ad. Use layer3+4 so overlay traffic spreads across members.
Link-monitor interval in milliseconds, e.g. 100.
Keep this connection’s route out of the default path. A storage or overlay VLAN taking the default route would pull cluster egress onto the fabric.
What the link carries: the network half of
the node’s hardware plan. trafficClass is the primary one (the first
of mgmt, storage, overlay, provider); send either, or both agreeing.
oob is the stage-1 lifeline and is never an underlay connection.
Example
{ "kind": "ethernet", "trafficClass": "", "bond": { "mode": "802.3ad", "lacpRate": "slow" }, "purposes": [ "oob" ]}Bad request.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Authenticated but not authorized.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}