Refactor nbhelper

Change-Id: I69d10d164fac3eb319e072447a520905880c31dd
diff --git a/scripts/nbhelper/network.py b/scripts/nbhelper/network.py
new file mode 100644
index 0000000..5520d48
--- /dev/null
+++ b/scripts/nbhelper/network.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+
+# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+# nbhelper.py
+# Helper functions for building YAML output from Netbox API calls
+
+import netaddr
+
+from .utils import logger, check_name_dns
+from .container import PrefixContainer
+from .container import DeviceContainer, VirtualMachineContainer
+
+
+class Prefix:
+    def __init__(self, data, name_segments):
+        from .utils import netboxapi
+
+        self.data = data
+        self.name_segments = name_segments
+        self.nbapi = netboxapi
+
+        if self.data.description:
+            self.domain_extension = check_name_dns(self.data.description)
+
+        # ip centric info
+        self.subnet = self.data.prefix
+        self.dhcp_range = list()
+        self.routes = list()
+        self.reserved_ips = {}
+
+        self.neighbor = list()
+
+        # build item lists
+        self.build_prefix()
+
+        # Find the neighbor relationship in prefix level
+        self.find_neighbor()
+
+        PrefixContainer().add(self.data.prefix, self)
+
+    def __repr__(self):
+        return str(self.data.prefix)
+
+    def check_ip_belonging(self, ip):
+        """
+        Check if an IP address is belonging to this prefix
+        """
+        return ip in netaddr.IPSet([self.data.prefix])
+
+    def find_neighbor(self):
+
+        parent_prefixes = list()
+        for prefix in PrefixContainer().all():
+            if not prefix.data.description:
+                parent_prefixes.append(prefix)
+
+        for prefix in PrefixContainer().all():
+            if not prefix.data.description:
+                continue
+
+            targetSubnet = netaddr.IPNetwork(prefix.subnet)
+            mySubnet = netaddr.IPNetwork(self.subnet)
+
+            for parent in parent_prefixes:
+                parentSubnet = netaddr.IPNetwork(parent.subnet)
+                if mySubnet in parentSubnet and targetSubnet in parentSubnet:
+                    if prefix not in self.neighbor:
+                        self.neighbor.append(prefix)
+                    if self not in prefix.neighbor:
+                        prefix.neighbor.append(self)
+
+
+    def build_prefix(self):
+        """
+        find ip information for items (devices/vms, reserved_ips, dhcp_range) in prefix
+        """
+        ips = self.nbapi.ipam.ip_addresses.filter(parent=self.data.prefix)
+
+        for ip in sorted(ips, key=lambda k: k["address"]):
+
+            logger.debug("prefix_item ip: %s, data: %s", ip, dict(ip))
+
+            # if it's a DHCP range, add that range to the dev list as prefix_dhcp
+            if ip.status.value == "dhcp":
+                self.dhcp_range.append(str(ip.address))
+
+            # reserved IPs
+            if ip.status.value == "reserved":
+                self.reserved_ips[str(ip)] = {
+                    "name": ip.description.lower().split(" ")[0],
+                    "description": ip.description,
+                    "ip4": str(ip.address),
+                    "custom_fields": ip.custom_fields,
+                }
+                self.routes.append(
+                    {
+                        "ip": str(ip.address),
+                        "rfc3442routes": [ip.custom_fields.get("rfc3442routes")],
+                    }
+                )