diff options
Diffstat (limited to 'ansible/netbox/sync-unifi.py')
-rw-r--r-- | ansible/netbox/sync-unifi.py | 137 |
1 files changed, 92 insertions, 45 deletions
diff --git a/ansible/netbox/sync-unifi.py b/ansible/netbox/sync-unifi.py index e26f1d5..49b815f 100644 --- a/ansible/netbox/sync-unifi.py +++ b/ansible/netbox/sync-unifi.py @@ -12,6 +12,7 @@ class Db(): self.devices = [] self.interfaces = [] self.ips = [] + self.macs = [] class Ip(): def __init__(self, vrf): @@ -19,6 +20,16 @@ class Ip(): self.vrf = vrf self.ips = ips +class Query(): + def __init__(self, query): + self.query = query + +def find_device(nb, name: str): + return Query(lambda: nb.dcim.devices.get(name=name).id) + +def find_interface(nb, device: str, name: str): + return Query(lambda: nb.dcim.interfaces.get(device=device, name=name).id) + class NetboxCache(): def __init__(self, nb): self.nb = nb @@ -71,77 +82,111 @@ class NetboxCache(): self.ip_addresses[key] = ip return ip - def create_or_update_device(self, d): - device = self.nb.dcim.devices.get(name = d["name"]) - if device is None: - device = self.nb.dcim.devices.create(d) - print(f"Created device id={device.id}, name={device.name}") +def create_or_update_device(nb, d): + device = nb.dcim.devices.get(name = d["name"]) + if device is None: + device = nb.dcim.devices.create(d) + print(f"Created device id={device.id}, name={device.name}") - return device + return device - print(f"Updating device id={device.id}, name={device.name}") - device.update(d) + print(f"Updating device id={device.id}, name={device.name}") + device.update(d) - return device + return nb.dcim.devices.get(id=device.id) + +def create_or_update_interface(nb, i): + iface = nb.dcim.interfaces.get(device_id=i["device"], name=i["name"]) + if iface is None: + iface = nb.dcim.interfaces.create(i) + print(f"Created interface id={iface.id}, name={iface.name}") - def create_or_update_interface(self, i): - iface = self.nb.dcim.interfaces.get(device_id=i["device"], name=i["name"]) - if iface is None: - iface = self.nb.dcim.interfaces.create(i) - print(f"Created interface id={iface.id}, name={iface.name}") + return iface - return iface + print(f"Updating interface id={iface.id}, name={iface.name}") + iface.update(i) + return nb.dcim.interfaces.get(id=iface.id) - print(f"Updating interface id={iface.id}, name={iface.name}") - iface.update(i) - return self.nb.dcim.interfaces.get(id=iface.id) +def create_or_update_mac_address(nb, data): + ma = nb.dcim.mac_addresses.get(mac_address=data["mac_address"]) + if ma is None: + ma = nb.dcim.mac_addresses.create(data) + print(f"Created MAC address id={ma.id}, address={ma.mac_address}") - def create_or_update_mac_address(self, data): - ma = self.nb.dcim.mac_addresses.get(mac_address=data["mac_address"]) - if ma is None: - ma = self.nb.dcim.mac_addresses.create(data) - print(f"Created MAC address id={ma.id}, address={ma.mac_address}") + return ma - return ma + print(f"Updating MAC address id={ma.id}, address={ma.mac_address}") + ma.update(data) + return nb.dcim.mac_addresses.get(id=ma.id) - print(f"Updating MAC address id={ma.id}, address={ma.mac_address}") - ma.update(data) - return self.nb.dcim.mac_addresses.get(id=ma.id) +def create_or_update_ip_address(nb, data): + ip = nb.ipam.ip_addresses.get(address=data["address"]) + if ip is None: + ip = nb.ipam.ip_addresses.create(data) + print(f"Created IP address id={ip.id}, ip={ip.address}") + + return ip + + print(f"Updating IP address id={ip.id}, ip={ip.address}") + ip.update(data) + return nb.ipam.ip_addresses.get(id=ip.id) def process_switch(d: UnifiDevice, db: Db, nb: NetboxCache, site, vrf): - device = nb.create_or_update_device({ + 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": site.id, + "site_name": site, }) - i = { - "device": device.id, + db.interfaces.append({ + "device": find_device(nb.nb, name=d.name), "name": "switch0", -# "mac": d.mac, TODO: create the ipam.mac first "type": "virtual", - } - iface = nb.create_or_update_interface(i) + }) - ip = nb.get_or_create_ip_address(f"{d.ip}/32", vrf, { - "assigned_object": iface, - "assigned_object_id": iface.id, - "assigned_object_type": "dcim.interface", + 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", }) - ma = nb.create_or_update_mac_address({ - "mac_address": d.mac, - "assigned_object_id": iface.id, + 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 }) - pprint("Interface") - pprint(iface.serialize()) - pprint("IP") - pprint(ip.serialize()) + # TODO: add cables + +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() + + for device in db.devices: + resolve_query(device) + create_or_update_device(nb, device) + + for iface in db.interfaces: + resolve_query(iface) + create_or_update_interface(nb, iface) + + for mac in db.macs: + resolve_query(mac) + create_or_update_mac_address(nb, mac) + + for ip in db.ips: + resolve_query(ip) + create_or_update_ip_address(nb, ip) def main(): unifi_url=os.getenv("UNIFI_URL") @@ -169,6 +214,8 @@ def main(): if d.model == "US8P150": process_switch(d, db, nb_cache, netbox_site, netbox_vrf) + sync_db(db, nb) + def controller_login(url, username, password) -> UnifiController: # try: controller = UnifiController( |