fix(script): update populate script
This commit is contained in:
@@ -27,18 +27,18 @@ uv run python scripts/provision_fabric.py
|
||||
|
||||
### Custom Fields
|
||||
|
||||
| Object Type | Field | Description |
|
||||
|-------------|-------|-------------|
|
||||
| Device | `asn` | BGP ASN |
|
||||
| Device | `mlag_domain_id` | MLAG domain identifier |
|
||||
| Device | `mlag_peer_address` | MLAG peer IP |
|
||||
| Device | `mlag_local_address` | MLAG local IP |
|
||||
| Device | `mlag_virtual_mac` | Shared virtual MAC |
|
||||
| Interface | `mlag_peer_link` | Marks peer-link interfaces |
|
||||
| Interface | `mlag_id` | MLAG ID for host LAGs |
|
||||
| VRF | `l3vni` | L3 VNI for EVPN |
|
||||
| VRF | `vrf_vlan` | VLAN for L3 VNI SVI |
|
||||
| IP Address | `virtual_ip` | Anycast/virtual IP flag |
|
||||
| Object Type | Field | Description |
|
||||
| ----------- | -------------------- | -------------------------- |
|
||||
| Device | `asn` | BGP ASN |
|
||||
| Device | `mlag_domain_id` | MLAG domain identifier |
|
||||
| Device | `mlag_peer_address` | MLAG peer IP |
|
||||
| Device | `mlag_local_address` | MLAG local IP |
|
||||
| Device | `mlag_virtual_mac` | Shared virtual MAC |
|
||||
| Interface | `mlag_peer_link` | Marks peer-link interfaces |
|
||||
| Interface | `mlag_id` | MLAG ID for host LAGs |
|
||||
| VRF | `l3vni` | L3 VNI for EVPN |
|
||||
| VRF | `vrf_vlan` | VLAN for L3 VNI SVI |
|
||||
| IP Address | `virtual_ip` | Anycast/virtual IP flag |
|
||||
|
||||
### Organization
|
||||
|
||||
@@ -49,14 +49,14 @@ uv run python scripts/provision_fabric.py
|
||||
|
||||
### Devices
|
||||
|
||||
| Device | Role | ASN | MLAG Domain |
|
||||
|--------|------|-----|-------------|
|
||||
| spine1, spine2 | Spine | 65000 | - |
|
||||
| leaf1, leaf2 | Leaf | 65001 | MLAG1 |
|
||||
| leaf3, leaf4 | Leaf | 65002 | MLAG2 |
|
||||
| leaf5, leaf6 | Leaf | 65003 | MLAG3 |
|
||||
| leaf7, leaf8 | Leaf | 65004 | MLAG4 |
|
||||
| host1-4 | Server | - | - |
|
||||
| Device | Role | ASN | MLAG Domain |
|
||||
| -------------- | ------ | ----- | ----------- |
|
||||
| spine1, spine2 | Spine | 65000 | - |
|
||||
| leaf1, leaf2 | Leaf | 65001 | MLAG1 |
|
||||
| leaf3, leaf4 | Leaf | 65002 | MLAG2 |
|
||||
| leaf5, leaf6 | Leaf | 65003 | MLAG3 |
|
||||
| leaf7, leaf8 | Leaf | 65004 | MLAG4 |
|
||||
| host1-4 | Server | - | - |
|
||||
|
||||
### Cabling
|
||||
|
||||
@@ -66,14 +66,14 @@ uv run python scripts/provision_fabric.py
|
||||
|
||||
### IP Addressing
|
||||
|
||||
| Purpose | Prefix |
|
||||
|---------|--------|
|
||||
| Spine1-Leaf P2P | 10.0.1.0/24 |
|
||||
| Spine2-Leaf P2P | 10.0.2.0/24 |
|
||||
| MLAG iBGP P2P | 10.0.3.0/24 |
|
||||
| MLAG Peer VLAN | 10.0.199.0/24 |
|
||||
| Purpose | Prefix |
|
||||
| --------------------- | ------------- |
|
||||
| Spine1-Leaf P2P | 10.0.1.0/24 |
|
||||
| Spine2-Leaf P2P | 10.0.2.0/24 |
|
||||
| MLAG iBGP P2P | 10.0.3.0/24 |
|
||||
| MLAG Peer VLAN | 10.0.199.0/24 |
|
||||
| Loopback0 (Router-ID) | 10.0.250.0/24 |
|
||||
| Loopback1 (VTEP) | 10.0.255.0/24 |
|
||||
| Loopback1 (VTEP) | 10.0.255.0/24 |
|
||||
|
||||
## Idempotency
|
||||
|
||||
|
||||
@@ -521,6 +521,7 @@ def create_vlans(nb: pynetbox.api, site) -> dict:
|
||||
nb.ipam.vlans,
|
||||
{"vid": vlan["vid"], "group_id": vlan_group.id},
|
||||
{
|
||||
"vid": vlan["vid"],
|
||||
"name": vlan["name"],
|
||||
"description": vlan.get("description", ""),
|
||||
"group": vlan_group.id, # Create expects 'group', filter expects 'group_id'
|
||||
@@ -546,7 +547,7 @@ def create_vrfs(nb: pynetbox.api) -> dict:
|
||||
rt_obj, created = get_or_create(
|
||||
nb.ipam.route_targets,
|
||||
{"name": rt},
|
||||
{"description": f"Import RT for {vrf_def['name']}"},
|
||||
{"name": rt, "description": f"Import RT for {vrf_def['name']}"},
|
||||
)
|
||||
import_rts.append(rt_obj.id)
|
||||
log_result("RouteTarget", "RouteTarget", rt, created)
|
||||
@@ -561,6 +562,7 @@ def create_vrfs(nb: pynetbox.api) -> dict:
|
||||
nb.ipam.vrfs,
|
||||
{"name": vrf_def["name"]},
|
||||
{
|
||||
"name": vrf_def["name"],
|
||||
"rd": vrf_def.get("rd"),
|
||||
"import_targets": import_rts,
|
||||
"export_targets": export_rts,
|
||||
@@ -587,7 +589,10 @@ def create_prefixes(nb: pynetbox.api, vrfs: dict):
|
||||
if vrf_id:
|
||||
vrf_id = vrf_id.id
|
||||
|
||||
create_params = {"prefix": prefix_def["prefix"], "description": prefix_def.get("description", "")}
|
||||
create_params = {
|
||||
"prefix": prefix_def["prefix"],
|
||||
"description": prefix_def.get("description", ""),
|
||||
}
|
||||
if vrf_id:
|
||||
create_params["vrf"] = vrf_id
|
||||
|
||||
@@ -610,6 +615,7 @@ def create_devices(nb: pynetbox.api, org: dict) -> dict:
|
||||
nb.dcim.devices,
|
||||
{"name": spine["name"]},
|
||||
{
|
||||
"name": spine["name"],
|
||||
"device_type": org["device_type"].id,
|
||||
"role": org["roles"]["spine"].id,
|
||||
"site": org["site"].id,
|
||||
@@ -635,6 +641,7 @@ def create_devices(nb: pynetbox.api, org: dict) -> dict:
|
||||
nb.dcim.devices,
|
||||
{"name": leaf["name"]},
|
||||
{
|
||||
"name": leaf["name"],
|
||||
"device_type": org["device_type"].id,
|
||||
"role": org["roles"]["leaf"].id,
|
||||
"site": org["site"].id,
|
||||
@@ -651,6 +658,7 @@ def create_devices(nb: pynetbox.api, org: dict) -> dict:
|
||||
nb.dcim.devices,
|
||||
{"name": host["name"]},
|
||||
{
|
||||
"name": host["name"],
|
||||
"device_type": org["server_type"].id,
|
||||
"role": org["roles"]["server"].id,
|
||||
"site": org["site"].id,
|
||||
@@ -717,11 +725,13 @@ def create_interfaces(nb: pynetbox.api, devices: dict) -> dict:
|
||||
intf = existing
|
||||
created = False
|
||||
else:
|
||||
intf = nb.dcim.interfaces.create({
|
||||
"device": device.id,
|
||||
"name": intf_name,
|
||||
"type": intf_type,
|
||||
})
|
||||
intf = nb.dcim.interfaces.create(
|
||||
{
|
||||
"device": device.id,
|
||||
"name": intf_name,
|
||||
"type": intf_type,
|
||||
}
|
||||
)
|
||||
created = True
|
||||
|
||||
# Set custom fields for MLAG peer-link
|
||||
@@ -755,11 +765,19 @@ def create_ip_addresses(nb: pynetbox.api, devices: dict, interfaces: dict, vrfs:
|
||||
},
|
||||
{
|
||||
"address": spine["loopback0"],
|
||||
"role": "loopback",
|
||||
"assigned_object_type": "dcim.interface",
|
||||
"assigned_object_id": intf.id,
|
||||
"description": f"{spine['name']} Router-ID",
|
||||
},
|
||||
)
|
||||
if not created:
|
||||
current_role = ip.role.value if hasattr(ip.role, "value") else ip.role
|
||||
if current_role != "loopback":
|
||||
ip.role = "loopback"
|
||||
ip.save()
|
||||
log_result("IP", "IP Address", f"{spine['loopback0']} (updated role)", True)
|
||||
|
||||
log_result("IP", "IP Address", spine["loopback0"], created)
|
||||
|
||||
# Loopback addresses for leafs
|
||||
@@ -776,11 +794,19 @@ def create_ip_addresses(nb: pynetbox.api, devices: dict, interfaces: dict, vrfs:
|
||||
},
|
||||
{
|
||||
"address": leaf["loopback0"],
|
||||
"role": "loopback",
|
||||
"assigned_object_type": "dcim.interface",
|
||||
"assigned_object_id": intf.id,
|
||||
"description": f"{leaf['name']} Router-ID",
|
||||
},
|
||||
)
|
||||
if not created:
|
||||
current_role = ip.role.value if hasattr(ip.role, "value") else ip.role
|
||||
if current_role != "loopback":
|
||||
ip.role = "loopback"
|
||||
ip.save()
|
||||
log_result("IP", "IP Address", f"{leaf['loopback0']} (updated role)", True)
|
||||
|
||||
log_result("IP", "IP Address", leaf["loopback0"], created)
|
||||
|
||||
# Loopback1 (VTEP)
|
||||
@@ -793,11 +819,19 @@ def create_ip_addresses(nb: pynetbox.api, devices: dict, interfaces: dict, vrfs:
|
||||
},
|
||||
{
|
||||
"address": leaf["loopback1"],
|
||||
"role": "anycast",
|
||||
"assigned_object_type": "dcim.interface",
|
||||
"assigned_object_id": intf.id,
|
||||
"description": f"{leaf['name']} VTEP",
|
||||
},
|
||||
)
|
||||
if not created:
|
||||
current_role = ip.role.value if hasattr(ip.role, "value") else ip.role
|
||||
if current_role != "anycast":
|
||||
ip.role = "anycast"
|
||||
ip.save()
|
||||
log_result("IP", "IP Address", f"{leaf['loopback1']} (updated role)", True)
|
||||
|
||||
log_result("IP", "IP Address", leaf["loopback1"], created)
|
||||
|
||||
# P2P addresses for Spine1-Leaf links
|
||||
@@ -881,7 +915,9 @@ def create_cables(nb: pynetbox.api, interfaces: dict):
|
||||
b_intf = interfaces.get(leaf, {}).get(leaf_intf)
|
||||
|
||||
if not a_intf or not b_intf:
|
||||
print(f" [Skip] Cable: {spine}:{spine_intf} <-> {leaf}:{leaf_intf} (interface not found)")
|
||||
print(
|
||||
f" [Skip] Cable: {spine}:{spine_intf} <-> {leaf}:{leaf_intf} (interface not found)"
|
||||
)
|
||||
continue
|
||||
|
||||
# Check if cable already exists
|
||||
@@ -943,8 +979,12 @@ def create_cables(nb: pynetbox.api, interfaces: dict):
|
||||
try:
|
||||
cable = nb.dcim.cables.create(
|
||||
{
|
||||
"a_terminations": [{"object_type": "dcim.interface", "object_id": a_intf.id}],
|
||||
"b_terminations": [{"object_type": "dcim.interface", "object_id": host_eth1.id}],
|
||||
"a_terminations": [
|
||||
{"object_type": "dcim.interface", "object_id": a_intf.id}
|
||||
],
|
||||
"b_terminations": [
|
||||
{"object_type": "dcim.interface", "object_id": host_eth1.id}
|
||||
],
|
||||
"status": "connected",
|
||||
"type": "cat6a",
|
||||
}
|
||||
@@ -965,8 +1005,12 @@ def create_cables(nb: pynetbox.api, interfaces: dict):
|
||||
try:
|
||||
cable = nb.dcim.cables.create(
|
||||
{
|
||||
"a_terminations": [{"object_type": "dcim.interface", "object_id": b_intf.id}],
|
||||
"b_terminations": [{"object_type": "dcim.interface", "object_id": host_eth2.id}],
|
||||
"a_terminations": [
|
||||
{"object_type": "dcim.interface", "object_id": b_intf.id}
|
||||
],
|
||||
"b_terminations": [
|
||||
{"object_type": "dcim.interface", "object_id": host_eth2.id}
|
||||
],
|
||||
"status": "connected",
|
||||
"type": "cat6a",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user