From cead6ab2a095ee3847b7f6cf5bce2fb0399d5360 Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sat, 3 Oct 2026 17:33:37 +1000 Subject: [PATCH] Add the chassis_mac custom field and drop the switch device type Switches are created by hand in the NetBox UI, so the model and its port templates have no consumer. --- README.md | 27 ++++++++---------------- config/au/syd1/custom-fields.yaml | 7 ++++++ config/au/syd1/device-types/sg3429x.yaml | 14 ------------ modules/netbox/catalogue.tf | 24 --------------------- modules/netbox/variables.tf | 14 ++---------- 5 files changed, 18 insertions(+), 68 deletions(-) delete mode 100644 config/au/syd1/device-types/sg3429x.yaml diff --git a/README.md b/README.md index f4a7684..db7294e 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,14 @@ reference data a host is planned against. Device records are not here. | Owner | Objects | |-------|---------| -| **this repo** | sites, prefixes, DHCP pool ranges, gateways, managed IPs, VLAN groups + VLANs, device types (incl. switch models and their interface templates), manufacturers, device roles, platforms, custom-field definitions, network profiles | +| **this repo** | sites, prefixes, DHCP pool ranges, gateways, managed IPs, VLAN groups + VLANs, device types, manufacturers, device roles, platforms, custom-field definitions, network profiles | | **autodiscovery agent** | device records, interfaces, MAC addresses, switch cabling | | **UI** | host names, role assignment, IP allocation (inventory -> planned) | Writing a device from here would fight both of them, so the module declares no -`netbox_device`. +`netbox_device`. The handful of network switches are created by hand in the +NetBox UI; this repo only defines the `chassis_mac` field discovery matches them +on. > Supersedes `terraform-infra`, which also drove Kea DHCP. Kea is managed by the > [kea-operator](https://git.unkin.net/unkin/kea-operator) CRs in argocd-apps @@ -23,7 +25,7 @@ Writing a device from here would fight both of them, so the module declares no ``` config///sites.yaml # site slug -> name/description config///subnets/net-----.yaml -config///device-types/.yaml # manufacturer, model, port templates +config///device-types/.yaml # manufacturer, model config///device-roles.yaml config///platforms.yaml # slug -> display name config///vlans.yaml # keyed per site @@ -64,22 +66,10 @@ repo without re-deriving them. ## Device types (`device-types/.yaml`) -`ports` declares interface templates as ranges, not 28 hand-written entries. -NetBox instantiates them on every device created from the type. - ```yaml -manufacturer: TP-Link -model: Omada SG3429X +manufacturer: Dell +model: OptiPlex 3070 u_height: 1 -ports: - - name_format: two-gigabitEthernet 1/0/%d # single %d - type: 2.5gbase-t - first: 1 - count: 24 - - name_format: ten-gigabitEthernet 1/0/%d - type: 10gbase-x-sfpp - first: 25 - count: 4 ``` ## VLANs (`vlans.yaml`) @@ -115,7 +105,8 @@ interfaces: ## Custom fields (`custom-fields.yaml`) Field **definitions** for what bootapi reads: `pxe_enabled`, -`provision_template`, `domain`, `nameservers`, `gateway`. `content_types` are +`provision_template`, `domain`, `nameservers`, `gateway`; plus `chassis_mac`, +which autodiscovery matches an LLDP neighbour on. `content_types` are NetBox `app_label.model` strings. `pxe_enabled`'s *value* is deliberately not managed here — it is runtime state cleared by bootapi's `/provisioned` callback. diff --git a/config/au/syd1/custom-fields.yaml b/config/au/syd1/custom-fields.yaml index fd02bf4..c92b12d 100644 --- a/config/au/syd1/custom-fields.yaml +++ b/config/au/syd1/custom-fields.yaml @@ -36,3 +36,10 @@ gateway: content_types: - dcim.device - ipam.ipaddress + +chassis_mac: + type: text + label: Chassis MAC + description: LLDP advertises a neighbour's ChassisID MAC but not its serial, so the autodiscovery agent matches an LLDP neighbour to this device by chassis MAC rather than the mutable SysName. + content_types: + - dcim.device diff --git a/config/au/syd1/device-types/sg3429x.yaml b/config/au/syd1/device-types/sg3429x.yaml deleted file mode 100644 index 37d14bd..0000000 --- a/config/au/syd1/device-types/sg3429x.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# TP-Link Omada SG3429X: 24x 2.5G copper + 4x 10G SFP+. -# NetBox instantiates these interfaces on every device created from the type. -manufacturer: TP-Link -model: Omada SG3429X -u_height: 1 -ports: - - name_format: two-gigabitEthernet 1/0/%d - type: 2.5gbase-t - first: 1 - count: 24 - - name_format: ten-gigabitEthernet 1/0/%d - type: 10gbase-x-sfpp - first: 25 - count: 4 diff --git a/modules/netbox/catalogue.tf b/modules/netbox/catalogue.tf index 421d00a..2e16baa 100644 --- a/modules/netbox/catalogue.tf +++ b/modules/netbox/catalogue.tf @@ -1,20 +1,5 @@ locals { manufacturers = toset([for t in var.device_types : t.manufacturer]) - - # One interface template per port, flattened to ":". - interface_templates = merge([ - for slug, t in var.device_types : { - for e in flatten([ - for p in t.ports : [ - for i in range(p.count) : { - name = format(p.name_format, p.first + i) - type = p.type - mgmt_only = p.mgmt_only - } - ] - ]) : "${slug}:${e.name}" => merge(e, { device_type = slug }) - } - ]...) } resource "netbox_manufacturer" "this" { @@ -33,15 +18,6 @@ resource "netbox_device_type" "this" { u_height = each.value.u_height } -resource "netbox_interface_template" "this" { - for_each = local.interface_templates - - device_type_id = tonumber(netbox_device_type.this[each.value.device_type].id) - name = each.value.name - type = each.value.type - mgmt_only = each.value.mgmt_only -} - resource "netbox_device_role" "this" { for_each = var.device_roles diff --git a/modules/netbox/variables.tf b/modules/netbox/variables.tf index 1059c1b..012f81a 100644 --- a/modules/netbox/variables.tf +++ b/modules/netbox/variables.tf @@ -35,23 +35,13 @@ variable "subnets" { variable "device_types" { description = <<-EOT - Device-type catalogue keyed by NetBox slug. `ports` declares interface - templates as ranges: each block names `count` ports from `first`, formatted - with `name_format` (a single %d). NetBox instantiates them on every device - created from the type. Manufacturers are created from the distinct - `manufacturer` values. + Device-type catalogue keyed by NetBox slug. Manufacturers are created from + the distinct `manufacturer` values. EOT type = map(object({ manufacturer = string model = string u_height = optional(number, 1) - ports = optional(list(object({ - name_format = string - type = string - first = optional(number, 1) - count = number - mgmt_only = optional(bool, false) - })), []) })) default = {} }