tritonctl networking commands
The seven tenant networking command families of tritonctl: vpc, subnet,
nat-gateway, floating-ip, route-table, route, and firewall-rule. Each
family has the same four subcommands, list, show, create, and delete,
except floating-ip, which adds attach and detach.
For the global flags, credential resolution, and output formats that apply to every command below, see the tritonctl command index.
Common behavior
Every resource is addressed by UUID. No argument in these families accepts a resource name.
Your tenant comes from the bearer token. tritonctl never sends a tenant=
selector. The global --project flag is forwarded as project= on vpc list,
floating-ip list, nat-gateway list, route-table list, route list, and
firewall-rule list. subnet list sends vpc= only.
What project= does depends on the handler:
| Command | Effect of project= |
|---|---|
vpc list, floating-ip list | Selects the project whose rows are returned. Required, along with tenant=. |
nat-gateway list, route-table list, firewall-rule list | Compared against the parent VPC's project. A mismatch returns 404 Not Found. It does not filter rows. |
route list | Ignored. The handler reads the tenant= selector only. |
List endpoints return an envelope with an items array and an optional
next_page cursor. Every networking list handler returns its rows in a single
page and leaves next_page unset. The store caps a scan at 10,000 rows.
tritonctl reads items and exposes no page-size or page-token flag.
Enum-valued fields render through their serde wire form. AddressFamily renders
as v4 or v6. FirewallDirection, FirewallAction, and FirewallProtocol
render as their lowercase names. RouteTarget is internally tagged on kind, so
the TARGET column of tritonctl route list and the target: line of
tritonctl route show render a JSON object:
{"kind":"blackhole"}
{"kind":"nat_gateway","nat_gateway_id":"11111111-1111-4111-8111-111111111111"}
Resource names are validated at the storage layer before the row is written: 1 to
63 bytes, no / or \, no ASCII control bytes, and no leading or trailing
whitespace. A name that breaks a rule returns 409 Conflict.
-o json and -o yaml replace the rendered output of list, show, create,
attach, and detach with the raw server record. Every delete subcommand
prints its one confirmation line regardless of --output.
vpc list, vpc create, floating-ip list, and floating-ip create cannot
complete against the current server. Each handler requires both a tenant= and a
project= selector, and tritonctl sends project= only, so the server returns
400 MissingScope.
vpc
A VPC is the tenant's isolated overlay network. It carries a server-assigned Geneve VNI and one or two CIDR blocks.
vpc subcommands
| Command | Request | Description |
|---|---|---|
tritonctl vpc list | GET /v1/vpcs | List VPCs. Sends project= when --project is set. |
tritonctl vpc show <VPC_UUID> | GET /v1/vpcs/{vpc_id} | Show one VPC. |
tritonctl vpc create | POST /v1/vpcs?project= | Create a VPC in the project named by --project. |
tritonctl vpc delete <VPC_UUID> | DELETE /v1/vpcs/{vpc_id} | Delete a VPC. |
vpc options
| Subcommand | Flag | Value | Required | Behavior |
|---|---|---|---|---|
create | --project | UUID | Yes | Global flag. Without it the command fails before sending a request. |
create | --name | String | Yes | VPC name. Unique within the project. |
create | --description | String | No | Free-text description. Unset when omitted. |
create | --ipv4-block | CIDR | One of the two | IPv4 CIDR for the overlay, for example 10.0.0.0/16. |
create | --ipv6-block | CIDR | One of the two | IPv6 CIDR for the overlay. |
Without --project, create fails locally with:
--project is required to create a vpc
vpc output
list renders the columns ID, NAME, and VNI.
show and create print the lines id:, name:, vni:, and project:,
followed by (use -o json for the full record).
delete prints Vpc <VPC_UUID> deleted.
vpc constraints
- The server requires both
tenant=andproject=onGET /v1/vpcsandPOST /v1/vpcs.tritonctlsendsproject=only. - A create with neither
--ipv4-blocknor--ipv6-blockreturns400withvpc must specify ipv4_block, ipv6_block, or both. - The VNI is assigned by the server from the non-reserved VNI range and is unique rack-wide.
- Creating a VPC also creates a route table named
mainin the same transaction, with a description ofMain route table for VPC <VPC_NAME>. New subnets inherit that route table. - A project outside the caller's tenant resolves as
404 Not Found. - Delete returns
409 Conflictwhile any subnet still references the VPC, and again while any non-main route table does. Deleting the VPC deletes itsmainroute table.
subnet
A subnet carves a CIDR out of its parent VPC. An instance NIC attaches to one subnet at create time.
subnet subcommands
| Command | Request | Description |
|---|---|---|
tritonctl subnet list --vpc <VPC_UUID> | GET /v1/subnets?vpc= | List the subnets of one VPC. |
tritonctl subnet show <SUBNET_UUID> | GET /v1/subnets/{subnet_id} | Show one subnet. |
tritonctl subnet create --vpc <VPC_UUID> | POST /v1/subnets?vpc= | Create a subnet inside a VPC. |
tritonctl subnet delete <SUBNET_UUID> | DELETE /v1/subnets/{subnet_id} | Delete a subnet. |
subnet options
| Subcommand | Flag | Value | Required | Behavior |
|---|---|---|---|---|
list | --vpc | UUID | Yes | Parent VPC. Required by both the CLI and the server. |
create | --vpc | UUID | Yes | Parent VPC. The server resolves the tenant and project from it. |
create | --name | String | Yes | Subnet name. Unique within the VPC. |
create | --description | String | No | Free-text description. Unset when omitted. |
create | --ipv4-block | CIDR | One of the two | IPv4 CIDR, contained in the VPC's IPv4 block. |
create | --ipv6-block | CIDR | One of the two | IPv6 CIDR, contained in the VPC's IPv6 block. |
subnet output
list renders the columns ID, NAME, and VPC.
show and create print the lines id:, name:, and vpc:, followed by
(use -o json for the full record).
delete prints Subnet <SUBNET_UUID> deleted.
subnet constraints
- A create with neither
--ipv4-blocknor--ipv6-blockreturns400withsubnet must specify ipv4_block, ipv6_block, or both. - Each block must be contained in the parent VPC's block of the same family. A
block whose family the VPC does not plan for returns
409 Conflict, as does a block that is not contained in the parent block. - A block that overlaps an existing subnet block in the same VPC, in either
family, returns
409 Conflictnaming the peer subnet. - A subnet created through this command is always an internal overlay subnet. Its
kindisinternal, and it carries no NIC tag and no VLAN id. External subnets come from the operator surface. - The new subnet is associated with the VPC's
mainroute table. - A VPC that is not visible to the caller's tenant resolves as
404 Not Found.
nat-gateway
A NAT gateway is the project-owned egress point of a VPC. It reserves one public address at create time.
nat-gateway subcommands
| Command | Request | Description |
|---|---|---|
tritonctl nat-gateway list | GET /v1/nat-gateways | List NAT gateways. Sends vpc= and project= when set. |
tritonctl nat-gateway show <NAT_GATEWAY_UUID> | GET /v1/nat-gateways/{nat_gateway_id} | Show one NAT gateway. |
tritonctl nat-gateway create --vpc <VPC_UUID> | POST /v1/nat-gateways?vpc= | Create a NAT gateway on a VPC. |
tritonctl nat-gateway delete <NAT_GATEWAY_UUID> | DELETE /v1/nat-gateways/{nat_gateway_id} | Delete a NAT gateway. |
nat-gateway options
| Subcommand | Flag | Value | Required | Behavior |
|---|---|---|---|---|
list | --vpc | UUID | Server-required | Optional in the CLI. The server returns 400 MissingScope without it. |
create | --vpc | UUID | Yes | Parent VPC. The server resolves the tenant and project from it. |
create | --name | String | Yes | Gateway name. Unique within the VPC. |
create | --description | String | No | Defaults to the empty string. |
create | --family | ipv4, v4, ipv6, v6 | No | Address family to reserve. Defaults to ipv4. Matched case-insensitively. |
A --family value outside the accepted set fails in the CLI before any request:
unknown family `<VALUE>`; expected ipv4 or ipv6
nat-gateway output
list renders the columns ID, NAME, and PUBLIC_ADDR.
show prints the lines id:, name:, vpc:, project:, public_address:,
and family:. The family: line renders the wire value, v4 or v6.
create prints Created NAT gateway <NAT_GATEWAY_UUID> followed by name:,
vpc:, and public_address:.
delete prints NAT gateway <NAT_GATEWAY_UUID> deleted.
nat-gateway constraints
- The server requires
vpc=on bothGET /v1/nat-gatewaysandPOST /v1/nat-gateways. - Create and delete each run a saga,
nat-gateway-createandnat-gateway-delete. The audit record carries the saga id asoperation_id. - The public address is drawn from a hardcoded pool:
203.0.113.0/24foripv4and2001:db8::/48foripv6. Both are documentation ranges, reserved by RFC 5737 and RFC 3849. An exhausted pool returns409 Conflict. - A name that already exists in the VPC returns
409 Conflict. - Delete returns
409 Conflictwhile any route still targets the gateway, withnat gateway <NAT_GATEWAY_UUID> is still referenced by routes.
floating-ip
A floating IP is a tenant-managed external address. It persists across attach and detach cycles and across instance deletes.
floating-ip subcommands
| Command | Request | Description |
|---|---|---|
tritonctl floating-ip list | GET /v1/floating-ips | List floating IPs. Sends project= when --project is set. |
tritonctl floating-ip show <FIP_UUID> | GET /v1/floating-ips/{floating_ip_id} | Show one floating IP. |
tritonctl floating-ip create | POST /v1/floating-ips?project= | Allocate a floating IP in the project named by --project. |
tritonctl floating-ip delete <FIP_UUID> | DELETE /v1/floating-ips/{floating_ip_id} | Delete a floating IP. |
tritonctl floating-ip attach <FIP_UUID> | POST /v1/tenants/{tenant_id}/projects/{project_id}/floating-ips/{floating_ip_id}/attach | Bind the address to a NIC. |
tritonctl floating-ip detach <FIP_UUID> | POST /v1/tenants/{tenant_id}/projects/{project_id}/floating-ips/{floating_ip_id}/detach | Release the address from its NIC. |
floating-ip options
| Subcommand | Flag | Value | Required | Behavior |
|---|---|---|---|---|
create | --project | UUID | Yes | Global flag. Without it the command fails before sending a request. |
create | --name | String | Yes | Floating IP name. Unique within the project. |
create | --description | String | No | Free-text description. Unset when omitted. |
create | --family | ipv4, v4, ipv6, v6 | No | Pool to allocate from. Defaults to ipv4. Matched exactly, with no case folding. |
attach | --nic | UUID | Yes | Target NIC. |
Without --project, create fails locally with:
--project is required to create a floating IP
A --family value outside the accepted set fails in the CLI before any request:
unknown family <VALUE>; expected ipv4 or ipv6
floating-ip output
list renders the columns ID, NAME, ADDRESS, and ATTACHED_TO. The
ATTACHED_TO cell is nic=<NIC_UUID> when the address is bound and - when it
is not.
show and create print the lines id:, name:, address:, and
attached_to:, followed by (use -o json for the full record).
delete prints Floating IP <FIP_UUID> deleted.
attach prints
Floating IP <FIP_UUID> attached to NIC <NIC_UUID> (address <ADDRESS>).
detach prints Floating IP <FIP_UUID> detached (address <ADDRESS>).
floating-ip constraints
- The server requires both
tenant=andproject=onGET /v1/floating-ipsandPOST /v1/floating-ips.tritonctlsendsproject=only. - The API accepts three mutually exclusive allocation sources,
family,network_id, andpool_id.tritonctlalways sendsfamilyand has no flag for the other two. - With
family, the address is drawn from a hardcoded pool:203.0.113.0/24foripv4and2001:db8::/48foripv6. Both are documentation ranges, reserved by RFC 5737 and RFC 3849. An exhausted pool returns409 Conflict. - Create runs the
floating-ip-allocatesaga,attachrunsfloating-ip-attach, anddetachrunsfloating-ip-detach. attachanddetachfirst read the floating IP to recover the tenant and project path parameters, then call the project-scoped route. Both commands therefore issue two requests.attachcaptures the current binding before it starts, so the saga can restore it on failure. Attaching an already-bound address moves it.- Delete returns
409 Conflictwhile the address is attached, withfloating ip <FIP_UUID> is currently attached; detach first. A successful delete releases the address back to the pool, where a later create can hand it to a different project. - A floating IP whose tenant and project do not match the path parameters resolves
as
404 Not Found.
route-table
A route table holds the routes applied to the subnets associated with it. Each
VPC has one table named main, created with the VPC.
route-table subcommands
| Command | Request | Description |
|---|---|---|
tritonctl route-table list | GET /v1/route-tables | List route tables. Sends vpc= and project= when set. |
tritonctl route-table show <ROUTE_TABLE_UUID> | GET /v1/route-tables/{route_table_id} | Show one route table. |
tritonctl route-table create --vpc <VPC_UUID> | POST /v1/route-tables?vpc= | Create a non-main route table inside a VPC. |
tritonctl route-table delete <ROUTE_TABLE_UUID> | DELETE /v1/route-tables/{route_table_id} | Delete a route table. |
route-table options
| Subcommand | Flag | Value | Required | Behavior |
|---|---|---|---|---|
list | --vpc | UUID | Server-required | Optional in the CLI. The server returns 400 MissingScope without it. |
create | --vpc | UUID | Yes | Parent VPC. The server resolves the tenant and project from it. |
create | --name | String | Yes | Route table name. Unique within the VPC. |
create | --description | String | No | Defaults to the empty string. |
route-table output
list renders the columns ID, NAME, and MAIN. The MAIN cell is yes or
no.
show prints the lines id:, name:, vpc:, project:, and is_main:.
create prints Created route table <ROUTE_TABLE_UUID> followed by name: and
vpc:.
delete prints Route table <ROUTE_TABLE_UUID> deleted.
route-table constraints
- The server requires
vpc=on bothGET /v1/route-tablesandPOST /v1/route-tables. - A table created through this command is never the main table. Its
is_mainfield isfalse. - The name
mainis taken by the table the VPC created, so a create that reuses it returns409 Conflict. - Deleting the main table returns
409 Conflict. Delete the VPC instead. - Delete returns
409 Conflictwhile the table still holds routes, and again while any subnet is still associated with it.
route
A route sends traffic for one destination CIDR to one target. Routes live in a route table.
route subcommands
| Command | Request | Description |
|---|---|---|
tritonctl route list | GET /v1/routes | List routes. Sends route_table= when --route-table is set. |
tritonctl route show <ROUTE_UUID> | GET /v1/routes/{route_id} | Show one route. |
tritonctl route create --route-table <ROUTE_TABLE_UUID> | POST /v1/routes?route_table= | Create a route in a route table. |
tritonctl route delete <ROUTE_UUID> | DELETE /v1/routes/{route_id} | Delete a route. |
route options
| Subcommand | Flag | Value | Required | Behavior |
|---|---|---|---|---|
list | --route-table | UUID | Server-required | Optional in the CLI. The server returns 400 MissingScope without it. |
create | --route-table | UUID | Yes | Parent route table. The server resolves the tenant, project, and VPC from it. |
create | --name | String | Yes | Route name. |
create | --description | String | No | Defaults to the empty string. |
create | --destination | CIDR | Yes | Destination prefix. |
create | --target-nat-gateway | UUID | One target | Send matching traffic to a NAT gateway in the same VPC. |
create | --target-blackhole | Flag | One target | Drop matching traffic without an ICMP response. |
create | --target-reject | Flag | One target | Drop matching traffic with an ICMP unreachable. |
create | --target-virtual-gateway | Flag | One target | Send matching traffic to the VPC virtual gateway. |
Any count of --target-* flags other than one fails in the CLI before any
request:
exactly one of --target-nat-gateway, --target-blackhole, --target-reject, --target-virtual-gateway must be provided (<COUNT> given)
route output
list renders the columns ID, NAME, DEST, and TARGET. The TARGET cell
holds the tagged JSON object described in Common behavior.
show prints the lines id:, name:, description:, vpc:, route_table:,
destination:, and target:.
create prints Created route <ROUTE_UUID> followed by name:, destination:,
and target:.
delete prints Route <ROUTE_UUID> deleted.
route constraints
- The server requires
route_table=on bothGET /v1/routesandPOST /v1/routes. OnGET /v1/routestheproject=selector thattritonctlsends is ignored. - The floating-IP route target is rejected on this surface with
400andfloating ip route targets are system-installed only in v1. The system installs that target itself. - A NAT gateway target outside the caller's tenant and project resolves as
404 Not Found. A NAT gateway in another VPC returns400withnat gateway <NAT_GATEWAY_UUID> is not in vpc <VPC_UUID>. - The destination is canonicalized to its network address before it is stored.
- A destination whose address family the parent VPC does not plan for returns
409 Conflict, and so does a destination that already exists in the same route table.
firewall-rule
A firewall rule permits or denies traffic on a VPC by direction, protocol, CIDR, and port range. Every NIC in the VPC inherits every rule of that VPC.
The FoundationDB store does not implement firewall rule storage. Against a
tritond backed by FoundationDB, firewall-rule create, show, and delete
return 500, and firewall-rule list returns an empty list rather than an
error. The rules exist only on the in-memory store.
firewall-rule subcommands
| Command | Request | Description |
|---|---|---|
tritonctl firewall-rule list | GET /v1/firewall-rules | List firewall rules. Sends vpc= and project= when set. |
tritonctl firewall-rule show <RULE_UUID> | GET /v1/firewall-rules/{firewall_rule_id} | Show one firewall rule. |
tritonctl firewall-rule create --vpc <VPC_UUID> | POST /v1/firewall-rules?vpc= | Create a firewall rule on a VPC. |
tritonctl firewall-rule delete <RULE_UUID> | DELETE /v1/firewall-rules/{firewall_rule_id} | Delete a firewall rule. |
firewall-rule options
| Subcommand | Flag | Value | Required | Behavior |
|---|---|---|---|---|
list | --vpc | UUID | Server-required | Optional in the CLI. The server returns 400 MissingScope without it. |
create | --vpc | UUID | Yes | Parent VPC. The server resolves the tenant and project from it. |
create | --name | String | Yes | Rule name. Unique within the VPC. |
create | --description | String | No | Defaults to the empty string. |
create | --action | allow, deny | Yes | Matched case-insensitively. |
create | --direction | inbound, in, outbound, out | Yes | Matched case-insensitively. |
create | --protocol | any, tcp, udp, icmp4, icmp, icmp6 | No | Defaults to any. icmp is an alias for icmp4. Matched case-insensitively. |
create | --priority | Integer, 0 to 65535 | Yes | Rule priority. Higher numbers evaluate first within a layer. |
create | --source-cidr | CIDR | No | Omitted means any source. |
create | --destination-cidr | CIDR | No | Omitted means any destination. |
create | --source-ports | LOW-HIGH or a single port | No | Ignored for protocols other than TCP and UDP. |
create | --destination-ports | LOW-HIGH or a single port | No | Ignored for protocols other than TCP and UDP. |
An unrecognized value for --action, --direction, or --protocol fails in the
CLI before any request:
unknown action `<VALUE>`; expected allow or deny
unknown direction `<VALUE>`; expected inbound or outbound
unknown protocol `<VALUE>`
firewall-rule output
list renders the columns ID, NAME, DIR, ACTION, PRIO, and DEST. The
DEST cell is the destination CIDR, or any when the rule has none.
show and create print the lines id:, name:, description:, vpc:,
project:, direction:, action:, protocol:, priority:, source:, and
destination:, followed by (use -o json for the full record). The source: and
destination: lines print any when the rule carries no CIDR.
delete prints FirewallRule <RULE_UUID> deleted.
firewall-rule constraints
- The server requires
vpc=on bothGET /v1/firewall-rulesandPOST /v1/firewall-rules. - A port range is parsed as
LOW-HIGH, or as a single port that becomes both bounds. A non-integer bound and a range whose low bound exceeds the high bound both fail in the CLI before any request. - The CLI sends no ICMP type or code. The API field exists and the server rejects it on a non-ICMP protocol, but no flag sets it.
- On the in-memory store, a source or destination CIDR whose address family the
parent VPC does not plan for returns
409 Conflict, stored CIDRs are canonicalized to their network address, and a rule name that already exists in the VPC returns409 Conflict.