IP address¶
A single IP address. Lives inside exactly one Prefix, inherits its VRF.
Fields¶
| Field | Type | Default | Notes |
|---|---|---|---|
id |
UUID | uuid4() |
PK |
tenant |
FK → Tenant |
required | Denormalised from prefix.tenant |
prefix |
FK → Prefix |
required | The containing prefix |
vrf |
FK → VRF |
NULL | Mirrors prefix.vrf; denormalised for the unique constraint |
ip_address |
inet | required | |
status |
choice | assigned |
available · assigned · reserved · dhcp_pool · floating |
role |
choice | "" |
"" · gateway · loopback · vip · hsrp · vrrp · anycast · secondary |
description |
text | "" |
|
mac_address |
char(17) | "" |
Hardware address paired with this IP (e.g. a DHCP reservation) |
dns_name |
char(255) | "" |
Hostname / DNS name (PTR). Auto-filled by reverse-DNS monitoring when enabled |
last_seen |
datetime | NULL | Last time the check engine saw this IP reachable. Engine-set, read-only |
custom_fields |
JSONB | {} |
Anything org-specific lives here, not as a hardcoded column |
tags |
M2M Tag | empty |
Uniqueness¶
UniqueConstraint(
fields=["tenant", "vrf", "ip_address"],
nulls_distinct=False,
name="uniq_ip_tenant_vrf_addr",
)
Same IP in two VRFs is fine.
Status vs role¶
| Concept | What it means | Examples |
|---|---|---|
| Status | Lifecycle | available, assigned, reserved, DHCP-pool, floating |
| Role | Functional purpose | gateway, VIP, HSRP, VRRP, loopback, anycast, secondary |
These are orthogonal. An assigned IP can also be a VIP. A reserved IP can have no role (just a hold).
Gateway role¶
Setting an IP's role = gateway:
- Clears
roleon any other IP in the same prefix that was previously gateway - Sets
prefix.gatewayto this IP's address
Done via the _make_gateway(prefix, ip) helper. Both the auto-spawn flow (on
prefix create) and the "Set as gateway" form-button on the prefix detail page
use it.
Validation¶
- Must fall inside its parent prefix's CIDR — enforced in
IPAddressSerializer.validate()(the SPA/API path): rejected with a 400 if the address isn't a member of the selected prefix's network, or if its family (v4/v6) doesn't match. - Must not collide with another IP in the same
(tenant, vrf)— DB-level unique constraint (failsafe).
Host-part prefill — when adding an IP inside a prefix, the form prefills the
network portion from the prefix CIDR (the fully-fixed leading octets, e.g.
10.0.10.0/24 → 10.0.10.) so the operator types only the host part. See
networkPrefill() in frontend/src/components/ip-form.tsx.
Related¶
- Prefix — parent model
- Gateway autospawn — how role=gateway happens automatically