diff --git a/scripts/nbhelper/__init__.py b/scripts/nbhelper/__init__.py
new file mode 100644
index 0000000..7755623
--- /dev/null
+++ b/scripts/nbhelper/__init__.py
@@ -0,0 +1,8 @@
+from .utils import initialize
+from .tenant import Tenant
+from .device import Device, VirtualMachine
+from .service import (
+    dhcpSubnetConfigGenerator,
+    dnsFowardZoneConfigGenerator,
+    dnsReverseZoneConfigGenerator,
+)
diff --git a/scripts/nbhelper/container.py b/scripts/nbhelper/container.py
new file mode 100644
index 0000000..6e0cfcf
--- /dev/null
+++ b/scripts/nbhelper/container.py
@@ -0,0 +1,291 @@
+import netaddr
+
+
+class Singleton(type):
+    _instances = {}
+
+    def __call__(cls, *args, **kwargs):
+        if cls not in cls._instances:
+            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
+        return cls._instances[cls]
+
+
+class Container(object):
+    def __init__(self):
+        self.instances = dict()
+
+    def add(self, instance_id, instance):
+        if instance_id in self.instances:
+            raise Exception()
+        self.instances[instance_id] = instance
+
+    def get(self, instance_id):
+        if instance_id not in self.instances:
+            return instance_id
+        return self.instances[instance_id]
+
+
+class AssignedObjectContainer(Container):
+    # AssignedObjectContainer is the parent class
+    # which is with the shared function of Devices/VMs Container
+
+    def all(self):
+        return self.instances.values()
+
+    def getDNSServer(self):
+        for instance in self.instances.values():
+            if "dns" in list(map(str, instance.services)):
+                return instance
+
+    def getDHCPServer(self):
+        for instance in self.instances.values():
+            if "tftp" in list(map(str, instance.services)):
+                return instance
+
+    def getNTPServer(self):
+        for instance in self.instances.values():
+            if "ntp" in list(map(str, instance.services)):
+                return instance
+
+    def getRouters(self):
+        """ Get a list of Devices/VMs which type is Router """
+
+        ret = list()
+        for instance in self.instances.values():
+            if instance.role == "router":
+                ret.append(instance)
+
+        return ret
+
+    def getRouterIPforPrefix(self, prefix):
+        """ Get the first found IP address of exist routers as string """
+
+        for router in self.getRouters():
+            for interface in router.interfaces.values():
+
+                # The mgmt-only interface will not act as gateway
+                if interface["mgmtOnly"]:
+                    continue
+
+                for address in interface["addresses"]:
+                    if netaddr.IPNetwork(address).ip in netaddr.IPNetwork(
+                        prefix.subnet
+                    ):
+                        return str(netaddr.IPNetwork(address).ip)
+
+
+class DeviceContainer(AssignedObjectContainer, metaclass=Singleton):
+    # DeviceContainer holds all devices fetch from Netbox, device_id as key
+    pass
+
+
+class VirtualMachineContainer(AssignedObjectContainer, metaclass=Singleton):
+    # DeviceContainer holds all devices fetch from Netbox, vm_id as key
+    pass
+
+
+class PrefixContainer(Container, metaclass=Singleton):
+    # PrefixContainer holds all prefixes fetch from Netbox, prefix(str) as key
+
+    def get(self, instance_id, name_segments=1):
+        return super().get(instance_id)
+
+    def all(self):
+        return self.instances.values()
+
+    def all_reserved_ips(self, ip_addr=""):
+        ret = list()
+
+        for prefix in self.instances.values():
+            if ip_addr and netaddr.IPNetwork(ip_addr).ip in netaddr.IPNetwork(
+                prefix.subnet
+            ):
+                if prefix.reserved_ips:
+                    return list(prefix.reserved_ips.values())
+            else:
+                if prefix.reserved_ips:
+                    ret.extend(list(prefix.reserved_ips.values()))
+
+        return ret
+
+
+class ServiceInfoContainer(Container, metaclass=Singleton):
+    # ServiceInfoContainer holds hosts DNS/DHCP information in Tenant networks
+
+    def __init__(self):
+        super().__init__()
+        self.initialized = False
+
+    def all(self):
+        return self.instances.items()
+
+    def initialize(self):
+        if self.initialized:
+            return
+
+        deviceContainer = DeviceContainer()
+        vmContainer = VirtualMachineContainer()
+        prefixContainer = PrefixContainer()
+
+        for prefix in prefixContainer.all():
+
+            subnet = netaddr.IPNetwork(prefix.subnet)
+            domain = prefix.data.description or ""
+
+            if not domain:
+                continue
+
+            # If prefix has set the Router IP, use this value as defualt,
+            # otherwise find router in this subnet and get its IP address
+            routes = (
+                prefix.routes
+                or deviceContainer.getRouterIPforPrefix(prefix)
+                or vmContainer.getRouterIPforPrefix(prefix)
+                or ""
+            )
+
+            self.instances[prefix.data.description] = {
+                "domain": domain,
+                "subnet": prefix.subnet,
+                "router": routes,
+                "dhcprange": prefix.dhcp_range or "",
+                "hosts": dict(),
+                "dnsServer": None,
+                "ntpServer": None,
+                "dhcpServer": None,
+            }
+
+            # Find the service IP address for this network
+            serviceMap = {
+                "dnsServer": deviceContainer.getDNSServer()
+                or vmContainer.getDNSServer(),
+                "ntpServer": deviceContainer.getNTPServer()
+                or vmContainer.getNTPServer(),
+                "dhcpServer": deviceContainer.getDHCPServer()
+                or vmContainer.getDHCPServer(),
+            }
+
+            # Loop through the device's IP, and set IP to dataset
+            for service, device in serviceMap.items():
+                for interface in device.interfaces.values():
+                    for address in interface["addresses"]:
+                        address = netaddr.IPNetwork(address).ip
+                        if address in subnet:
+                            self.instances[domain][service] = {
+                                "name": device.name,
+                                "address": str(address),
+                            }
+                        else:
+                            for neighbor in prefix.neighbor:
+                                neighborSubnet = netaddr.IPNetwork(neighbor.subnet)
+                                if address in neighborSubnet:
+                                    self.instances[domain][service] = {
+                                        "name": device.name,
+                                        "address": str(address),
+                                    }
+                                    break
+
+            # A dict to check if the device exists in this domain (prefix)
+            deviceInDomain = dict()
+
+            # Gather all Devices/VMs in this tenant, build IP/Hostname map
+            for device in list(deviceContainer.all()) + list(vmContainer.all()):
+
+                # Iterate the interface owned by device
+                for intfName, interface in device.interfaces.items():
+
+                    # Iterate the address with each interface
+                    for address in interface["addresses"]:
+
+                        # Extract the IP address from interface's IP (w/o netmask)
+                        address = netaddr.IPNetwork(address).ip
+
+                        # Only record the IP address in current subnet,
+                        # Skip if the mac_address is blank
+                        if address in subnet:
+
+                            # deviceInDomain store the interface information like:
+                            # {"mgmtserver1": {
+                            #     "non-mgmt-counter": 1,
+                            #     "interface": {
+                            #         "bmc": {
+                            #             "mgmtOnly": True,
+                            #             "macaddr": "ca:fe:ba:be:00:00",
+                            #             "ipaddr": [IPAddress("10.32.4.1")]
+                            #         }
+                            #         "eno1": {
+                            #             "mgmtOnly": False,
+                            #             "macaddr": "ca:fe:ba:be:11:11",
+                            #             "ipaddr": [IPAddress("10.32.4.129"), IPAddress("10.32.4.130")]
+                            #         }
+                            #    }
+                            #  "mgmtswitch1": ...
+                            # }
+
+                            deviceInDomain.setdefault(device.name, dict())
+                            deviceInDomain[device.name].setdefault(
+                                "non-mgmt-counter", 0
+                            )
+                            deviceInDomain[device.name].setdefault("interfaces", dict())
+
+                            # Set up a interface structure in deviceInDomain[device.name]
+                            deviceInDomain[device.name]["interfaces"].setdefault(
+                                intfName, dict()
+                            )
+                            interfaceDict = deviceInDomain[device.name]["interfaces"][
+                                intfName
+                            ]
+                            interfaceDict.setdefault("mgmtOnly", False)
+
+                            # Use interface["mac_address"] as the default value, but if the mac_address
+                            #  is None, that means we are dealing with a virtual interfaces
+                            #  so we can get the linked interface's mac_address instead
+
+                            interfaceDict.setdefault(
+                                "mac_address", interface["mac_address"] or
+                                device.interfaces[interface["instance"].label]["mac_address"]
+                            )
+                            interfaceDict.setdefault("ip_addresses", list())
+                            interfaceDict["ip_addresses"].append(address)
+
+                            # If the interface is mgmtOnly, set the attribute to True
+                            # Otherwise, increase the non-mgmt-counter, the counter uses to
+                            #  find out how many interfaces of this device has IPs on subnet
+                            if interface["mgmtOnly"]:
+                                interfaceDict["mgmtOnly"] = True
+                            else:
+                                deviceInDomain[device.name]["non-mgmt-counter"] += 1
+
+            for deviceName, data in deviceInDomain.items():
+
+                nonMgmtCounter = data["non-mgmt-counter"]
+                for intfName, interface in data["interfaces"].items():
+
+                    # If current interface doesn't have mac address set, skip
+                    if not interface["mac_address"]:
+                        continue
+
+                    # In the default situation, hostname is deviceName
+                    hostname_list = [deviceName]
+
+                    # If the condition is -
+                    #  1. multiple interfaces show on this subnet
+                    #  2. the interface is a management-only interface
+                    # then add interface name into hostname
+                    if nonMgmtCounter > 1 or interface["mgmtOnly"]:
+                        hostname_list.append(intfName)
+
+                    # Iterate the IP address owns by current interface,
+                    # if the interface has multiple IP addresses,
+                    # add last digit to hostname for identifiability
+                    for address in interface["ip_addresses"]:
+                        hostname = hostname_list.copy()
+                        if len(interface["ip_addresses"]) > 1:
+                            hostname.append(str(address.words[-1]))
+
+                        self.instances[domain]["hosts"][str(address)] = {
+                            "hostname": "-".join(hostname),
+                            "macaddr": interface["mac_address"].lower(),
+                        }
+
+        self.initialized = True
diff --git a/scripts/nbhelper/device.py b/scripts/nbhelper/device.py
new file mode 100644
index 0000000..a88740b
--- /dev/null
+++ b/scripts/nbhelper/device.py
@@ -0,0 +1,441 @@
+#!/usr/bin/env python3
+
+# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+# device.py
+#
+
+import netaddr
+
+from .utils import logger, clean_name_dns
+from .network import Prefix
+from .container import DeviceContainer, VirtualMachineContainer, PrefixContainer
+
+
+class AssignedObject:
+    """
+    Assigned Object is either a Device or Virtual Machine, which function
+    nearly identically in the NetBox data model.
+
+    This parent class holds common functions for those two child classes
+
+    An assignedObject (device or VM) should have following attributes:
+    - self.data: contains the original copy of data from NetBox
+    - self.id: Device ID or VM ID
+    - self.interfaces: A dictionary contains interfaces belong to this AO
+                       the interface dictionary looks like:
+
+    {
+        "eno1": {
+            "address": ["192.168.0.1/24", "192.168.0.2/24"],
+            "instance": <interface_instance>,
+            "isPrimary": True,
+            "mgmtOnly": False,
+            "isVirtual": False
+        }
+    }
+    """
+
+    objects = dict()
+
+    def __init__(self, data):
+        from .utils import netboxapi, netbox_config
+
+        self.data = data
+        self.nbapi = netboxapi
+
+        # The AssignedObject attributes
+        self.id = self.data.id
+        self.tenant = None
+        self.primary_ip = None
+
+        # In Netbox, we use FQDN as the Device name, but in the script,
+        # we use the first segment to be the name of device.
+        # For example, if the device named "mgmtserver1.stage1.menlo" on Netbox,
+        #  then we will have "mgmtserver1" as name.
+        self.fullname = self.data.name
+        self.name = self.fullname.split(".")[0]
+
+        # The device role which can be ["server", "router", "switch", ...]
+        self.role = None
+
+        # The NetBox objects related with this AssignedObject
+        self.interfaces = dict()
+        self.services = None
+
+        # Generated configuration for ansible playbooks
+        self.netplan_config = dict()
+        self.extra_config = dict()
+
+        if self.__class__ == Device:
+            self.role = self.data.device_role.slug
+            self.services = self.nbapi.ipam.services.filter(device_id=self.id)
+            interfaces = self.nbapi.dcim.interfaces.filter(device_id=self.id)
+            ip_addresses = self.nbapi.ipam.ip_addresses.filter(device_id=self.id)
+        elif self.__class__ == VirtualMachine:
+            self.role = self.data.role.slug
+            self.services = self.nbapi.ipam.services.filter(virtual_machine_id=self.id)
+            interfaces = self.nbapi.virtualization.interfaces.filter(
+                virtual_machine_id=self.id
+            )
+            ip_addresses = self.nbapi.ipam.ip_addresses.filter(
+                virtual_machine_id=self.id
+            )
+
+        self.primary_ip = self.data.primary_ip
+
+        for interface in interfaces:
+            # The Device's interface structure is different from VM's interface
+            # VM interface doesn't have mgmt_only and type, Therefore,
+            # the default value of mgmtOnly is False, isVirtual is True
+
+            self.interfaces[interface.name] = {
+                "addresses": list(),
+                "mac_address": interface.mac_address,
+                "instance": interface,
+                "isPrimary": False,
+                "mgmtOnly": getattr(interface, "mgmt_only", False),
+                "isVirtual": interface.type.value == "virtual"
+                if hasattr(interface, "type")
+                else True,
+            }
+
+        for address in ip_addresses:
+            interface = self.interfaces[address.assigned_object.name]
+            interface["addresses"].append(address.address)
+
+            # ipam.ip_addresses doesn't have primary tag,
+            # the primary tag is only available is only in the Device.
+            # So we need to compare address to check which one is primary ip
+            if address.address == self.primary_ip.address:
+                interface["isPrimary"] = True
+
+            # mgmt_only = False is a hack for VirtualMachine type
+            if self.__class__ == VirtualMachine:
+                interface["instance"].mgmt_only = False
+
+    def __repr__(self):
+        return str(dict(self.data))
+
+    @property
+    def type(self):
+        return "AssignedObject"
+
+    @property
+    def internal_interfaces(self):
+        """
+        The function internal_interfaces
+        """
+
+        ret = dict()
+        for intfName, interface in self.interfaces.items():
+            if (
+                not interface["isPrimary"]
+                and not interface["mgmtOnly"]
+                and interface["addresses"]
+            ):
+                ret[intfName] = interface
+
+        return ret
+
+    def generate_netplan(self):
+        """
+        Get the interface config of specific server belongs to this tenant
+        """
+
+        if self.netplan_config:
+            return self.netplan_config
+
+        primary_if = None
+        for interface in self.interfaces.values():
+            if interface["isPrimary"] is True:
+                primary_if = interface["instance"]
+
+        if primary_if is None:
+            logger.error("The primary interface wasn't set for device %s", self.name)
+            return dict()
+
+        # Initialize the part of "ethernets" configuration
+        self.netplan_config["ethernets"] = dict()
+
+        # If the current selected device is a Router
+        if (isinstance(self, Device) and self.data.device_role.name == "Router") or (
+            isinstance(self, VirtualMachine) and self.data.role.name == "Router"
+        ):
+            for intfName, interface in self.interfaces.items():
+                if interface["mgmtOnly"] or interface["isVirtual"]:
+                    continue
+
+                # Check if this address is public IP address (e.g. "8.8.8.8" on eth0)
+                isExternalAddress = True
+                for prefix in PrefixContainer().all():
+                    for address in interface["addresses"]:
+                        if address in netaddr.IPSet([prefix.subnet]):
+                            isExternalAddress = False
+
+                # If this interface has the public IP address, netplan shouldn't include it
+                if isExternalAddress:
+                    continue
+
+                self.netplan_config["ethernets"].setdefault(intfName, {})
+                self.netplan_config["ethernets"][intfName].setdefault(
+                    "addresses", []
+                ).append(address)
+
+        # If the current selected device is a Server
+        elif isinstance(self, Device) and self.data.device_role.name == "Server":
+            if primary_if:
+                self.netplan_config["ethernets"][primary_if.name] = {
+                    "dhcp4": "yes",
+                    "dhcp4-overrides": {"route-metric": 100},
+                }
+
+            for intfName, interface in self.interfaces.items():
+                if (
+                    not interface["isVirtual"]
+                    and intfName != primary_if.name
+                    and not interface["mgmtOnly"]
+                    and interface["addresses"]
+                ):
+                    self.netplan_config["ethernets"][intfName] = {
+                        "dhcp4": "yes",
+                        "dhcp4-overrides": {"route-metric": 200},
+                    }
+
+        else:
+            # Exclude the device type which is not Router and Server
+            return None
+
+        # Get interfaces own by AssignedObject and is virtual (VLAN interface)
+        for intfName, interface in self.interfaces.items():
+
+            # If the interface is not a virtual interface or
+            # the interface doesn't have VLAN tagged, skip this interface
+            if not interface["isVirtual"] or not interface["instance"].tagged_vlans:
+                continue
+
+            if "vlans" not in self.netplan_config:
+                self.netplan_config["vlans"] = dict()
+
+            vlan_object_id = interface["instance"].tagged_vlans[0].id
+            vlan_object = self.nbapi.ipam.vlans.get(vlan_object_id)
+
+            routes = list()
+            for address in interface["addresses"]:
+
+                for reserved_ip in PrefixContainer().all_reserved_ips(address):
+
+                    destination = reserved_ip["custom_fields"].get("rfc3442routes", "")
+                    if not destination:
+                        continue
+
+                    # If interface address is in destination subnet, we don't need this route
+                    if netaddr.IPNetwork(address).ip in netaddr.IPNetwork(destination):
+                        continue
+
+                    for dest_addr in destination.split():
+                        new_route = {
+                            "to": dest_addr,
+                            "via": str(netaddr.IPNetwork(reserved_ip["ip4"]).ip),
+                            "metric": 100,
+                        }
+
+                        if new_route not in routes:
+                            routes.append(new_route)
+
+            self.netplan_config["vlans"][intfName] = {
+                "id": vlan_object.vid,
+                "link": interface["instance"].label,
+                "addresses": interface["addresses"],
+            }
+
+            # Only the fabric virtual interface will need to route to other network segments
+            if routes and "fab" in intfName:
+                self.netplan_config["vlans"][intfName]["routes"] = routes
+
+        return self.netplan_config
+
+    def generate_nftables(self):
+
+        ret = dict()
+
+        internal_if = None
+        external_if = None
+
+        # Use isPrimary == True as the identifier to select external interface
+        for interface in self.interfaces.values():
+            if interface["isPrimary"] is True:
+                external_if = interface["instance"]
+
+        if external_if is None:
+            logger.error("The primary interface wasn't set for device %s", self.name)
+            sys.exit(1)
+
+        for interface in self.interfaces.values():
+            # If "isVirtual" set to False and "mgmtOnly" set to False
+            if (
+                not interface["isVirtual"]
+                and not interface["mgmtOnly"]
+                and interface["instance"] is not external_if
+            ):
+                internal_if = interface["instance"]
+                break
+
+        ret["external_if"] = external_if.name
+        ret["internal_if"] = internal_if.name
+
+        if self.services:
+            ret["services"] = list()
+
+        for service in self.services:
+            ret["services"].append(
+                {
+                    "name": service.name,
+                    "protocol": service.protocol.value,
+                    "port": service.port,
+                }
+            )
+
+        # Only management server needs to be configured the whitelist netrange of internal interface
+        if self.data.device_role.name == "Router":
+
+            ret["interface_subnets"] = dict()
+            ret["ue_routing"] = dict()
+            ret["ue_routing"]["ue_subnets"] = self.data.config_context["ue_subnets"]
+
+            # Create the interface_subnets in the configuration
+            # It's using the interface as the key to list IP addresses
+            for intfName, interface in self.interfaces.items():
+                if interface["mgmtOnly"]:
+                    continue
+
+                for address in interface["addresses"]:
+                    for prefix in PrefixContainer().all():
+                        intfAddr = netaddr.IPNetwork(address).ip
+
+                        # If interface IP doesn't belong to this prefix, skip
+                        if intfAddr not in netaddr.IPNetwork(prefix.subnet):
+                            continue
+
+                        # If prefix is a parent prefix (parent prefix won't config domain name)
+                        # skip to add in interface_subnets
+                        if not prefix.data.description:
+                            continue
+
+                        ret["interface_subnets"].setdefault(intfName, list())
+
+                        if prefix.subnet not in ret["interface_subnets"][intfName]:
+                            ret["interface_subnets"][intfName].append(prefix.subnet)
+                        for neighbor in prefix.neighbor:
+                            if neighbor.subnet not in ret["interface_subnets"][intfName]:
+                                ret["interface_subnets"][intfName].append(neighbor.subnet)
+
+            for prefix in PrefixContainer().all():
+
+                if "fab" in prefix.data.description:
+                    ret["ue_routing"].setdefault("src_subnets", [])
+                    ret["ue_routing"]["src_subnets"].append(prefix.data.prefix)
+
+                if (
+                    not ret["ue_routing"].get("snat_addr")
+                    and "fab" in prefix.data.description
+                ):
+                    for interface in self.interfaces.values():
+                        for address in interface["addresses"]:
+                            if address in netaddr.IPSet([prefix.subnet]):
+                                ret["ue_routing"]["snat_addr"] = str(
+                                    netaddr.IPNetwork(address).ip
+                                )
+                                break
+
+        return ret
+
+    def generate_extra_config(self):
+        """
+        Generate the extra configs which need in management server configuration
+        This function should only be called when the device role is "Router"
+        """
+
+        if self.extra_config:
+            return self.extra_config
+
+        primary_ip = self.data.primary_ip.address if self.data.primary_ip else None
+
+        service_names = list(map(lambda x: x.name, self.services))
+
+        if "dns" in service_names:
+            unbound_listen_ips = []
+            unbound_allow_ips = []
+
+            for interface in self.interfaces.values():
+                if not interface["isPrimary"] and not interface["mgmtOnly"]:
+                    for address in interface["addresses"]:
+                        unbound_listen_ips.append(address)
+
+            for prefix in PrefixContainer().all():
+                if prefix.data.description:
+                    unbound_allow_ips.append(prefix.data.prefix)
+
+            if unbound_listen_ips:
+                self.extra_config["unbound_listen_ips"] = unbound_listen_ips
+
+            if unbound_allow_ips:
+                self.extra_config["unbound_allow_ips"] = unbound_allow_ips
+
+        if "ntp" in service_names:
+            ntp_client_allow = []
+
+            for prefix in PrefixContainer().all():
+                if prefix.data.description:
+                    ntp_client_allow.append(prefix.data.prefix)
+
+            if ntp_client_allow:
+                self.extra_config["ntp_client_allow"] = ntp_client_allow
+
+        return self.extra_config
+
+
+class Device(AssignedObject):
+    """
+    Wraps a single Netbox device
+    Also caches all known devices in a class variable (devs)
+    """
+
+    def __init__(self, data):
+
+        super().__init__(data)
+        DeviceContainer().add(self.id, self)
+
+    @property
+    def type(self):
+        return "Device"
+
+    def get_interfaces(self):
+        if not self.interfaces:
+            self.interfaces = self.nbapi.dcim.interfaces.filter(device_id=self.id)
+
+        return self.interfaces
+
+
+class VirtualMachine(AssignedObject):
+    """
+    VM equivalent of Device
+    """
+
+    def __init__(self, data):
+
+        super().__init__(data)
+        VirtualMachineContainer().add(self.id, self)
+
+    @property
+    def type(self):
+        return "VirtualMachine"
+
+    def get_interfaces(self):
+        if not self.interfaces:
+            self.interfaces = self.nbapi.virtualization.interfaces.filter(
+                virtual_machine_id=self.id
+            )
+
+        return self.interfaces
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")],
+                    }
+                )
diff --git a/scripts/nbhelper/service.py b/scripts/nbhelper/service.py
new file mode 100644
index 0000000..d84f0cb
--- /dev/null
+++ b/scripts/nbhelper/service.py
@@ -0,0 +1,182 @@
+#!/usr/bin/env python3
+
+# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+# service.py
+#
+
+import re
+import netaddr
+
+from .utils import logger, AttrDict
+from .container import ServiceInfoContainer
+
+
+def getIPaddress(addressWithMask):
+    return str(netaddr.IPNetwork(addressWithMask).ip)
+
+
+def dhcpSubnetConfigGenerator():
+    dhcpSubnetConfigs = list()
+
+    serviceInfoContainer = ServiceInfoContainer()
+    serviceInfoContainer.initialize()
+
+    for domainName, domain in serviceInfoContainer.all():
+        subnetConfig = {
+            "dns_search": [domainName],
+            "dns_servers": [domain["dnsServer"]["address"]],
+            "ntp_servers": [domain["ntpServer"]["address"]],
+            "tftp_servers": domain["dhcpServer"]["address"],
+            "range": domain["dhcprange"],
+            "subnet": domain["subnet"],
+            "routers": [{"ip": domain["router"]}],
+            "hosts": list(),
+        }
+
+        for address, host in domain["hosts"].items():
+            subnetConfig["hosts"].append(
+                {
+                    "ip_addr": getIPaddress(address),
+                    "mac_addr": host["macaddr"],
+                    "name": host["hostname"],
+                }
+            )
+
+        subnetConfig["hosts"] = sorted(
+            subnetConfig["hosts"], key=lambda x: int(x["ip_addr"].split(".")[-1])
+        )
+        dhcpSubnetConfigs.append(subnetConfig)
+
+    return dhcpSubnetConfigs
+
+
+def dnsFowardZoneConfigGenerator():
+    def getDomainNameByIP(ip_address):
+        """
+        getDomainNameByIP will return the corresponding domain name of an IP address
+        In the ntpServer, dhcpServer, dnsServer we only have the IP addresses of them,
+        But we can use the dhcp subnet configuration to find the FQDN
+        """
+        dhcpSubnetConfigs = dhcpSubnetConfigGenerator()
+
+        for domain in dhcpSubnetConfigs:
+            domainName = domain["dns_search"][0]
+            for host in domain["hosts"]:
+                if ip_address == host["ip_addr"]:
+                    return f"{host['name']}.{domainName}."
+
+
+    dnsForwardZoneConfigs = dict()
+
+    serviceInfoContainer = ServiceInfoContainer()
+    serviceInfoContainer.initialize()
+
+    for domainName, domain in serviceInfoContainer.all():
+        forwardZoneConfig = {
+            "cname": dict(),
+            "a": dict(),
+            "ns": list(),
+            "srv": dict(),
+            "txt": dict(),
+        }
+
+        # Get the services set to this Tenant network
+        ntpServer = domain["ntpServer"] or None
+        dhcpServer = domain["dhcpServer"] or None
+        dnsServer = domain["dnsServer"] or None
+
+        # If service exists, set the FQDN to CNAME records
+        if ntpServer:
+            forwardZoneConfig["cname"]["dns"] = getDomainNameByIP(ntpServer["address"])
+        if dhcpServer:
+            forwardZoneConfig["cname"]["tftp"] = getDomainNameByIP(dhcpServer["address"])
+        if dnsServer:
+            forwardZoneConfig["cname"]["dns"] = getDomainNameByIP(dnsServer["address"])
+            forwardZoneConfig["ns"].append(getDomainNameByIP(dnsServer["address"]))
+
+        for address, host in domain["hosts"].items():
+            # Add exist IP address into dnsReverseZoneConfigs,
+            hostname = host["hostname"]
+            forwardZoneConfig["a"][hostname] = address
+
+        for address in netaddr.IPSet(domain["dhcprange"]):
+            # If address exists in ServiceInfoContainer's host dictionary,
+            # Use the pre-generated hostname as A record's name
+            hostname = "dhcp%03d" % address.words[-1]
+            forwardZoneConfig["a"][hostname] = str(address)
+
+        dnsForwardZoneConfigs[domainName] = forwardZoneConfig
+
+    return dnsForwardZoneConfigs
+
+
+def dnsReverseZoneConfigGenerator():
+    def canonicalize_rfc1918_prefix(prefix):
+        """
+        RFC1918 prefixes need to be expanded to their widest canonical range to
+        group all reverse lookup domains together for reverse DNS with NSD/Unbound.
+        """
+
+        pnet = netaddr.IPNetwork(prefix)
+        (o1, o2, o3, o4) = pnet.network.words  # Split ipv4 octets
+        cidr_plen = pnet.prefixlen
+
+        if o1 == 10:
+            o2 = o3 = o4 = 0
+            cidr_plen = 8
+        elif (o1 == 172 and o2 >= 16 and o2 <= 31) or (o1 == 192 and o2 == 168):
+            o3 = o4 = 0
+            cidr_plen = 16
+
+        return "%s/%d" % (".".join(map(str, [o1, o2, o3, o4])), cidr_plen)
+
+    serviceInfoContainer = ServiceInfoContainer()
+    serviceInfoContainer.initialize()
+
+    # dnsReverseZoneConfigs contains all reverse zone records.
+    dnsReverseZoneConfigs = dict()
+    widedomain = None
+
+    for domainName, domain in serviceInfoContainer.all():
+
+        # Expand network range to group all tenant domains
+        widedomain = widedomain or canonicalize_rfc1918_prefix(domain["subnet"])
+
+        # Create the basic structure of reverse zone config
+        # {"10.0.0.0/8": {"ns": list(), "ptr": dict()}}
+        dnsReverseZoneConfigs.setdefault(widedomain, dict())
+        dnsReverseZoneConfigs[widedomain].setdefault("ns", list())
+        dnsReverseZoneConfigs[widedomain].setdefault("ptr", dict())
+
+        # Get the DNS services set to this Tenant network
+        dnsServer = domain["dnsServer"]["name"] if domain["dnsServer"] else None
+
+        # If service exists, set the FQDN to CNAME records
+        if dnsServer:
+            dnsReverseZoneConfigs[widedomain]["ns"].append(f"{domainName}.{dnsServer}.")
+
+        for address, host in domain["hosts"].items():
+            # Add exist IP address into dnsReverseZoneConfigs,
+            hostname = host["hostname"]
+            dnsReverseZoneConfigs[widedomain]["ptr"][
+                address
+            ] = f"{hostname}.{domainName}."
+
+        for address in netaddr.IPSet(domain["dhcprange"]):
+            # Add DHCP range IP address into dnsReverseZoneConfigs,
+            # Use the pre-generated hostname as A record's name
+            hostname = "dhcp%03d" % address.words[3]
+            dnsReverseZoneConfigs[widedomain]["ptr"][
+                str(address)
+            ] = f"{hostname}.{domainName}."
+
+    dnsReverseZoneConfigs[widedomain]["ptr"] = dict(
+        sorted(
+            dnsReverseZoneConfigs[widedomain]["ptr"].items(),
+            key=lambda x: (int(x[0].split(".")[-2]), int(x[0].split(".")[-1])),
+        )
+    )
+
+    return dnsReverseZoneConfigs
diff --git a/scripts/nbhelper/tenant.py b/scripts/nbhelper/tenant.py
new file mode 100644
index 0000000..4d529a7
--- /dev/null
+++ b/scripts/nbhelper/tenant.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python3
+
+# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+# tenant.py
+# The tenant abstract object of Netbox Object - Tenant
+
+from .utils import logger, netboxapi
+from .device import Device, VirtualMachine
+from .network import Prefix
+
+
+class Tenant:
+    def __init__(self):
+
+        from .utils import netboxapi, netbox_config
+
+        self.nbapi = netboxapi
+        self.name = netbox_config["tenant_name"]
+        self.name_segments = netbox_config.get("prefix_segments", 1)
+
+        self.tenant = self.nbapi.tenancy.tenants.get(name=self.name)
+
+        # Tenant only keep the resources which owns by it
+        self.devices = list()
+        self.vms = list()
+        self.prefixes = dict()
+
+        # Get the Device and Virtual Machines from Netbox API
+        for device_data in self.nbapi.dcim.devices.filter(tenant=self.tenant.slug):
+            device = Device(device_data)
+            device.tenant = self
+            self.devices.append(device)
+
+        for vm_data in self.nbapi.virtualization.virtual_machines.filter(
+            tenant=self.tenant.slug
+        ):
+            vm = VirtualMachine(vm_data)
+            vm.tenant = self
+            self.vms.append(vm)
+
+        vrf = self.nbapi.ipam.vrfs.get(tenant=self.tenant.slug)
+        for prefix_data in self.nbapi.ipam.prefixes.filter(vrf_id=vrf.id):
+            prefix = Prefix(prefix_data, self.name_segments)
+            if prefix_data.description:
+                self.prefixes[prefix_data.prefix] = prefix
+
+    def get_prefixes(self):
+        """Get the IP Prefixes owns by current tenant"""
+
+        return self.prefixes
+
+    def get_device_by_name(self, name):
+        """
+        Find the device or VM which belongs to this Tenant,
+        If the name wasn't specified, return the management server
+        """
+
+        for machine in self.devices + self.vms:
+            if name and machine.name == name:
+                return machine
+            elif machine.data["device_role"]["name"] == "Router":
+                return machine
+
+        ret_msg = (
+            "The name '%s' wasn't found in this tenant, "
+            + "or can't found any Router in this tenant"
+        )
+
+        logger.error(ret_msg, name)
+        sys.exit(1)
+
+    def get_devices(self, device_types=["server", "router"]):
+        """
+        Get all devices (Router + Server) belong to this Tenant
+        """
+
+        if not device_types:
+            return self.devices + self.vms
+
+        ret = []
+
+        for machine in self.devices:
+            if machine.data.device_role.slug in device_types:
+                ret.append(machine)
+
+        for vm in self.vms:
+            if vm.data.role.slug in device_types:
+                ret.append(vm)
+
+        return ret
diff --git a/scripts/nbhelper/utils.py b/scripts/nbhelper/utils.py
new file mode 100644
index 0000000..5614ba9
--- /dev/null
+++ b/scripts/nbhelper/utils.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+
+# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+# utils.py
+# The utility functions shared among nbhelper objects
+
+import re
+import logging
+import argparse
+import pynetbox
+import requests
+
+from ruamel import yaml
+
+# Initialize module-level variables
+netboxapi = None
+netbox_config = None
+netbox_version = None
+
+# create shared logger
+logging.basicConfig()
+logger = logging.getLogger("nbh")
+
+
+def initialize(extra_args):
+    """
+    Initialize the NBHelper module, the extra_args is required, it contains the
+    NetBox API url, API token, and the name of site
+    """
+    global netboxapi, netbox_config, netbox_version
+
+    args = parse_cli_args(extra_args)
+    netbox_config = yaml.safe_load(args.settings.read())
+
+    for require_args in ["api_endpoint", "token", "tenant_name"]:
+        if not netbox_config.get(require_args):
+            logger.error("The require argument: %s was not set. Stop." % require_args)
+            sys.exit(1)
+
+    netboxapi = pynetbox.api(
+        netbox_config["api_endpoint"], token=netbox_config["token"], threading=True,
+    )
+
+    if not netbox_config.get("validate_certs", True):
+        session = requests.Session()
+        session.verify = False
+        netboxapi.http_session = session
+
+    netbox_version = netboxapi.version
+
+    return args
+
+
+def parse_cli_args(extra_args={}):
+    """
+    parse CLI arguments.  Can add extra arguments with a option:kwargs dict
+    """
+
+    parser = argparse.ArgumentParser(description="Netbox")
+
+    # Positional args
+    parser.add_argument(
+        "settings",
+        type=argparse.FileType("r"),
+        help="YAML Ansible inventory file w/NetBox API token",
+    )
+
+    parser.add_argument(
+        "--debug", action="store_true", help="Print additional debugging information"
+    )
+
+    for ename, ekwargs in extra_args.items():
+        parser.add_argument(ename, **ekwargs)
+
+    args = parser.parse_args()
+    log_level = logging.DEBUG if args.debug else logging.INFO
+    logger.setLevel(log_level)
+
+    return args
+
+
+def check_name_dns(name):
+
+    badchars = re.search("[^a-z0-9.-]", name.lower(), re.ASCII)
+
+    if badchars:
+        logger.error(
+            "DNS name '%s' has one or more invalid characters: '%s'",
+            name,
+            badchars.group(0),
+        )
+        sys.exit(1)
+
+    return name.lower()
+
+
+def clean_name_dns(name):
+    return re.sub("[^a-z0-9.-]", "-", name.lower(), 0, re.ASCII)
+
+
+def apply_as_router(output_yaml):
+    """ Add the router-specific value for output structure """
+
+    output_yaml.setdefault("netprep_router", True)
+    output_yaml.setdefault("tftpd_files", ["undionly.kpxe"])
+    output_yaml.setdefault(
+        "vhosts", [{"name": "default", "default_server": True, "autoindex": True}]
+    )
+    output_yaml.setdefault("acme_username", "www-data")
+
+    return output_yaml
+
+
+class AttrDict(dict):
+    def __init__(self, *args, **kwargs):
+        super(AttrDict, self).__init__(*args, **kwargs)
+        self.__dict__ = self
