aboutsummaryrefslogtreecommitdiff
path: root/ansible
diff options
context:
space:
mode:
Diffstat (limited to 'ansible')
-rw-r--r--ansible/netbox/sync-unifi.py137
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(