aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2025-06-11 19:46:44 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2025-06-11 19:46:44 +0200
commitcaf1626e21ead3f23b54d37d254a23b452498659 (patch)
tree3b13656816057cf17779b691c96a420f92b6f276
parentf90c416dc512003c14b4a366a9b67082859e5b48 (diff)
downloadinfra-caf1626e21ead3f23b54d37d254a23b452498659.tar.gz
infra-caf1626e21ead3f23b54d37d254a23b452498659.tar.bz2
infra-caf1626e21ead3f23b54d37d254a23b452498659.tar.xz
infra-caf1626e21ead3f23b54d37d254a23b452498659.zip
netbox
-rw-r--r--ansible/netbox/sync-unifi.py147
1 files changed, 97 insertions, 50 deletions
diff --git a/ansible/netbox/sync-unifi.py b/ansible/netbox/sync-unifi.py
index 49b815f..27d5a5b 100644
--- a/ansible/netbox/sync-unifi.py
+++ b/ansible/netbox/sync-unifi.py
@@ -13,22 +13,25 @@ class Db():
self.interfaces = []
self.ips = []
self.macs = []
-
-class Ip():
- def __init__(self, vrf):
- self.address = address
- self.vrf = vrf
- self.ips = ips
+ self.cables = []
class Query():
- def __init__(self, query):
+ def __init__(self, args, query):
+ self.args = args
self.query = query
def find_device(nb, name: str):
- return Query(lambda: nb.dcim.devices.get(name=name).id)
+ return Query({}, lambda: nb.dcim.devices.get(name=name).id)
+
+def find_interface_by_mac(nb, mac_address: str):
+ args = locals()
+ del args["nb"]
+ return Query(args, lambda: nb.dcim.interfaces.get(mac_address=mac_address).id)
def find_interface(nb, device: str, name: str):
- return Query(lambda: nb.dcim.interfaces.get(device=device, name=name).id)
+ args = locals()
+ del args["nb"]
+ return Query(args, lambda: nb.dcim.interfaces.get(device=device, name=name).id)
class NetboxCache():
def __init__(self, nb):
@@ -132,62 +135,106 @@ def create_or_update_ip_address(nb, data):
return nb.ipam.ip_addresses.get(id=ip.id)
def process_switch(d: UnifiDevice, db: Db, nb: NetboxCache, site, vrf):
- db.devices.append({
- "name": d.name,
- "device_type": nb.get_device_type("ubiquiti-us-8-150w").id,
- "role": nb.get_device_role("switch").id,
- "serial": d.serial,
- "site_name": site,
- })
-
- db.interfaces.append({
- "device": find_device(nb.nb, name=d.name),
- "name": "switch0",
- "type": "virtual",
- })
-
- db.ips.append({
- "address": f"{d.ip}/32",
- "is_primary": "true",
- "vrf": vrf.id,
-# "assigned_object": iface,
- "assigned_object_id": find_interface(nb.nb, device=d.name, name="switch0"),
- "assigned_object_type": "dcim.interface",
- })
-
- db.macs.append({
- "assigned_object_id": find_interface(nb.nb, device=d.name, name="switch0"),
- "assigned_object_type": "dcim.interface",
- "mac_address": d.mac,
-# "is_primary": "true", does not work
- })
-
- # TODO: add cables
+# db.devices.append({
+# "name": d.name,
+# "device_type": nb.get_device_type("ubiquiti-us-8-150w").id,
+# "role": nb.get_device_role("switch").id,
+# "serial": d.serial,
+# "site_name": site,
+# })
+#
+# db.interfaces.append({
+# "device": find_device(nb.nb, name=d.name),
+# "name": "switch0",
+# "type": "virtual",
+# })
+#
+# db.ips.append({
+# "address": f"{d.ip}/32",
+# "is_primary": "true",
+# "vrf": vrf.id,
+# "assigned_object_id": find_interface(nb.nb, device=d.name, name="switch0"),
+# "assigned_object_type": "dcim.interface",
+## "is_primary": "true" TODO: does not work
+# })
+#
+# db.macs.append({
+# "mac_address": d.mac,
+# "assigned_object_id": find_interface(nb.nb, device=d.name, name="switch0"),
+# "assigned_object_type": "dcim.interface",
+## "is_primary": "true" TODO: does not work
+# })
+
+ pprint(d.lldp_info)
+
+ for e in d.lldp_info:
+ a = [
+ {
+ "object_type": "dcim.interface",
+ "object_id": find_interface(nb.nb, device=d.name, name=f"Port {e.local_port_idx} (PoE)"),
+ }
+ ]
+ b = [
+ {
+ "object_type": "dcim.interface",
+ "object_id": find_interface_by_mac(nb.nb, e.chassis_id),
+ }
+ ]
+
+ if e.chassis_id > d.mac:
+ a = b
+ b = a
+
+ db.cables.append({
+ "a_terminations": a,
+ "b_terminations": b,
+ "status": "connected",
+ })
def sync_db(db: Db, nb):
- def resolve_query(data):
- for k, v in data.items():
- if not isinstance(v, Query):
- continue
-
- data[k] = v.query()
+ def resolve_query(value):
+ if value is None or isinstance(value, str) or isinstance(value, int):
+ return value
+ elif isinstance(value, Query):
+ try:
+ return value.query()
+ except Exception as e:
+ print("Query failed: ")
+ print(f"Arguments: {value.args}")
+ print(e)
+ raise e
+ elif isinstance(value, dict):
+ for k, v in value.items():
+ value[k] = resolve_query(v)
+ elif isinstance(value, list):
+ for i, item in enumerate(value):
+ value[i] = resolve_query(item)
+ else:
+ raise Exception(f"unsupported type: {value}")
+ return value
for device in db.devices:
- resolve_query(device)
+ device = resolve_query(device)
create_or_update_device(nb, device)
for iface in db.interfaces:
- resolve_query(iface)
+ iface = resolve_query(iface)
create_or_update_interface(nb, iface)
for mac in db.macs:
- resolve_query(mac)
+ mac = resolve_query(mac)
create_or_update_mac_address(nb, mac)
for ip in db.ips:
- resolve_query(ip)
+ ip = resolve_query(ip)
create_or_update_ip_address(nb, ip)
+ for cable in db.cables:
+ pprint(cable)
+ cable = resolve_query(cable)
+ pprint(cable)
+# create_or_update_cable(nb, cable)
+
def main():
unifi_url=os.getenv("UNIFI_URL")
unifi_username=os.getenv("UNIFI_USERNAME")