diff --git a/scripts/tenant_validator.py b/scripts/tenant_validator.py
new file mode 100644
index 0000000..baa4a79
--- /dev/null
+++ b/scripts/tenant_validator.py
@@ -0,0 +1,413 @@
+#!/usr/bin/env python3
+
+# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
+# SPDX-License-Identifier: Apache-2.0
+
+# tenant_validator.py
+# Grab the data from Tenant and check if the information is invalidate
+
+import re
+import yaml
+import logging
+import argparse
+import nbhelper
+import pynetbox
+import requests
+import netaddr
+
+
+logging.basicConfig()
+logger = logging.getLogger("TenentValidator")
+
+# The Global variable shared with different netbox api caller function
+netboxapi = None
+netbox_config = None
+misconfs = list()
+
+# The consistent variable should be same in every devices, prefixes of the deployment
+site_name = None
+deployment_name = None
+
+# A Regex rule to identify if device name is a valid domain
+fqdn_regex = re.compile(
+    "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
+)
+
+
+class Configuration(object):
+
+    mapping_dict = {
+        logging.ERROR: logger.error,
+        logging.WARN: logger.warn,
+        logging.INFO: logger.info,
+    }
+
+    def __init__(self, obj, message, level=logging.ERROR):
+        self.level = level
+        self.obj = obj
+        self.message = message
+
+        # self.mapping_dict[level](self)
+
+    def __repr__(self):
+        return "[%s] object %s: %s\nRef. %s" % (
+            "/".join(self.obj.url.split("/")[-4:-2]),
+            self.obj,
+            self.message,
+            self.obj.url.replace("10.76.28.11", "netbox.infra.onlab.us").replace(
+                "api/", ""
+            ),
+        )
+
+
+def get_object_type(obj):
+    return ("/".join(obj.url.split("/")[-4:-2]),)
+
+
+def validate_vlans(vlans=list()):
+    global misconfs
+
+    for vlan in vlans:
+        if not vlan.group:
+            misconfs.append(Configuration(vlan, "VLAN group isn't set"))
+        if not vlan.site:
+            misconfs.append(Configuration(vlan, "VLAN site isn't set"))
+        if not vlan.tenant:
+            misconfs.append(Configuration(vlan, "VLAN tenant isn't set"))
+
+
+def validate_prefixes(prefixes=list()):
+    global misconfs
+
+    tenant_dict = dict()
+
+    for prefix in prefixes:
+        netmask = prefix.prefix.split("/")[-1]
+
+        if not re.search(fqdn_regex, prefix.description):
+            misconfs.append(Configuration(prefix, "Description (FQDN) is invalid"))
+        else:
+            device = netboxapi.dcim.devices.filter(tenant_id=prefix.tenant.id)[0]
+            if device:
+                sitename = device.name.split(".")[-1]
+                if sitename not in prefix.description:
+                    misconfs.append(
+                        Configuration(prefix, "Site name should in the prefix FQDN")
+                    )
+
+        if not prefix.tenant:
+            misconfs.append(Configuration(prefix, "Tenant isn't set"))
+        else:
+            tenant_dict.setdefault(prefix.tenant, dict())
+            tenant_dict[prefix.tenant].setdefault(netmask, list())
+            tenant_dict[prefix.tenant][netmask].append(prefix)
+
+    # Assume prefixes in different tenants don't have the intersection
+    # So parent prefix only check if it has a DHCP sub-prefix in same tenant
+    for prefixes_by_tenant in tenant_dict.values():
+        for netmask, prefixes_by_netmask in prefixes_by_tenant.items():
+            for prefix in prefixes_by_netmask:
+                if int(netmask) < 26:
+                    children = [
+                        child
+                        for key, value in prefixes_by_tenant.items()
+                        if int(key) > int(netmask)
+                        for child in value
+                    ]
+
+                    children = [
+                        child
+                        for child in children
+                        if str(
+                            netaddr.IPNetwork(
+                                child.prefix.split("/")[0] + "/" + netmask
+                            ).cidr
+                        )
+                        == prefix.prefix
+                    ]
+                    if children:
+                        continue
+
+                    dhcp_addr = list(
+                        filter(
+                            lambda ip: ip.status.value == "dhcp",
+                            netboxapi.ipam.ip_addresses.filter(parent=prefix.prefix),
+                        )
+                    )
+
+                    if not dhcp_addr:
+                        misconfs.append(
+                            Configuration(prefix, "DHCP subnet not found in prefix")
+                        )
+                        continue
+
+                    if len(dhcp_addr) > 1:
+                        misconfs.append(
+                            Configuration(
+                                prefix, "Prefix should have exact 1 DHCP subnet"
+                            )
+                        )
+                        continue
+
+                    dhcp_range = dhcp_addr[0].address
+                    ip_addrs = netboxapi.ipam.ip_addresses.filter(parent=dhcp_range)
+                    ip_addrs = list(filter(lambda ip: ip != dhcp_addr[0], ip_addrs))
+                    if ip_addrs:
+                        misconfs.append(
+                            Configuration(
+                                prefix,
+                                "DHCP range %s contains other IP addresses: %s"
+                                % (dhcp_range, ip_addrs),
+                            )
+                        )
+
+
+def validate_ip_addresses(ip_addresses=list()):
+    global misconfs
+    prefix_dict = dict()
+
+    for ip_address in ip_addresses:
+
+        if netaddr.IPNetwork(ip_address.address).network.is_private():
+            if not ip_address.vrf:
+                misconfs.append(
+                    Configuration(ip_address, "VRF isn't set for this IP address")
+                )
+            else:
+                prefix = str(netaddr.IPNetwork(ip_address.address).cidr)
+                if prefix not in prefix_dict:
+                    prefix_dict[prefix] = netboxapi.ipam.prefixes.get(prefix=prefix)
+
+                if prefix_dict[prefix] and prefix_dict[prefix].vrf != ip_address.vrf:
+                    misconfs.append(
+                        Configuration(ip_address, "VRF isn't match with Prefix")
+                    )
+
+
+def validate_interfaces(interfaces=list()):
+    global misconfs
+
+    for interface in interfaces:
+        count_ips = 0
+
+        if get_object_type(interface) == "virtualization/interfaces":
+            count_ips = len(
+                netboxapi.ipam.ip_addresses.filter(vminterface_id=interface.id)
+            )
+        elif get_object_type(interface) == "dcim/interfaces":
+            count_ips = interface.count_ipaddresses
+
+        if count_ips > 0 and not interface.mac_address:
+            misconfs.append(
+                Configuration(
+                    interface,
+                    "VM Interface has IP address assigned but mac address isn't set",
+                )
+            )
+
+        if (
+            get_object_type(interface) == "dcim/interfaces"
+            and interface.type.value == "virtaul"
+            and (not interface.mgmt_only or not interface.tagged_vlans)
+        ):
+            misconfs.append(
+                Configuration(
+                    interface,
+                    "Virtual interface should be management only or VLAN interface",
+                )
+            )
+
+        if interface.tagged_vlans:
+            if len(interface.tagged_vlans) > 1:
+                misconfs.append(
+                    Configuration(interface, "Virtual Interface has multiple VLANs set")
+                )
+            elif str(interface.tagged_vlans[0].vid) not in interface.name:
+                misconfs.append(
+                    Configuration(
+                        interface, "Virtual Interface name not match to VLAN ID"
+                    )
+                )
+
+
+def validate_vrfs(vrfs=list()):
+    global misconfs
+
+    for vrf in vrfs:
+        if not vrf.enforce_unique:
+            misconfs.append(
+                Configuration(vrf, "VRF doesn't have enforce_unique set as True")
+            )
+
+        if not vrf.tenant:
+            misconfs.append(Configuration(vrf, "VRF doesn't have tenant set"))
+
+
+def validate_machines(machines=list()):
+    global misconfs
+
+    tenant_info = dict()
+
+    for machine in machines:
+        if not re.search(fqdn_regex, machine.name):
+            misconfs.append(
+                Configuration(
+                    machine, "Device/VM FQDN name %s is invalid" % machine.name
+                )
+            )
+
+        if not machine.tenant:
+            misconfs.append(Configuration(machine, "Device/VM doesn't have tenant set"))
+
+        segments = machine.name.split(".")
+        if len(segments) != 3:
+            misconfs.append(
+                Configuration(
+                    machine,
+                    "Device/VM FQDN should have 3 segments, found %d" % len(segments),
+                )
+            )
+        elif machine.tenant:
+            if machine.tenant not in tenant_info:
+                tenant_info.setdefault(
+                    machine.tenant, {"deployment": segments[1], "site": segments[2]}
+                )
+            else:
+                deployment = tenant_info[machine.tenant]["deployment"]
+                site = tenant_info[machine.tenant]["site"]
+                if deployment != segments[1] or site != segments[2]:
+                    misconfs.append(
+                        Configuration(
+                            machine,
+                            "Deployment or Site name is not consistent with other Device/VM",
+                        )
+                    )
+
+        if (
+            (
+                machine.__class__.__name__ == "Devices"
+                and machine.device_role.name in ["Router", "Switch", "Server"]
+            )
+            or machine.__class__.__name__ == "VirtualMachines"
+        ) and not machine.primary_ip:
+            misconfs.append(
+                Configuration(machine, "Primary IP must be set for this Device/VM")
+            )
+
+
+def validate_tenants(tenants=list()):
+    global misconfs
+
+    for tenant in tenants:
+        if tenant.device_count == 0:
+            misconfs.append(Configuration(tenant, "0 device was found for this tenant"))
+        if tenant.prefix_count == 0:
+            misconfs.append(Configuration(tenant, "0 prefix was found for this tenant"))
+        if tenant.vrf_count == 0:
+            misconfs.append(Configuration(tenant, "0 vrf was found for this tenant"))
+
+        devices = list(netboxapi.dcim.devices.filter(tenant_id=tenant.id))
+        mgmtserver = list(filter(lambda d: d.device_role.name == "Router", devices))
+        if len(mgmtserver) != 1:
+            misconfs.append(
+                Configuration(tenant, "Tenant must have exact 1 Router (mgmtserver)")
+            )
+
+
+def get_objects(tenant_name=""):
+    return_dict = dict()
+
+    tenants = list(netboxapi.tenancy.tenants.filter(name=tenant_name))
+    if len(tenants) == 0:
+        logger.critical("Tenant name %s wasn't found in Netbox" % tenant_name)
+        sys.exit(1)
+    tenant_id = None if len(tenants) != 1 else tenants[0].id
+
+    # If the tenant_id is None, then Netbox API will return all objects by default
+    devices = list(netboxapi.dcim.devices.filter(tenant_id=tenant_id))
+    virtual_machines = list(
+        netboxapi.virtualization.virtual_machines.filter(tenant_id=tenant_id)
+    )
+
+    physical_interfaces = list()
+    for device in devices:
+        physical_interfaces.extend(
+            list(netboxapi.dcim.interfaces.filter(device_id=device.id))
+        )
+
+    virtual_interfaces = list()
+    for virtual_machine in virtual_machines:
+        virtual_interfaces.extend(
+            list(
+                netboxapi.virtualization.interfaces.filter(
+                    virtual_machine_id=virtual_machine.id
+                )
+            )
+        )
+
+    vrfs = list(netboxapi.ipam.vrfs.filter(tenant_id=tenant_id))
+    vlans = list(netboxapi.ipam.vlans.filter(tenant_id=tenant_id))
+    ip_addresses = list(netboxapi.ipam.ip_addresses.filter(tenant_id=tenant_id))
+
+    prefixes = list()
+    for vrf in vrfs:
+        prefixes.extend(list(netboxapi.ipam.prefixes.filter(vrf_id=vrf.id)))
+
+    return_dict = {
+        "tenants": tenants,
+        "devices": devices,
+        "physical_interfaces": physical_interfaces,
+        "virtual_machines": virtual_machines,
+        "virtual_interfaces": virtual_interfaces,
+        "vrfs": vrfs,
+        "prefixes": prefixes,
+        "vlans": vlans,
+        "ip_addresses": ip_addresses,
+    }
+
+    return return_dict
+
+
+if __name__ == "__main__":
+
+    parser = argparse.ArgumentParser(description="Netbox Tenant Validator")
+    parser.add_argument(
+        "settings",
+        type=argparse.FileType("r"),
+        help="YAML Ansible inventory file w/NetBox API token",
+    )
+
+    args = parser.parse_args()
+    netbox_config = yaml.safe_load(args.settings.read())
+    netboxapi = pynetbox.api(
+        netbox_config["api_endpoint"], token=netbox_config["token"], threading=True
+    )
+
+    if not netbox_config.get("validate_certs", False):
+        session = requests.Session()
+        session.verify = False
+        netboxapi.http_session = session
+
+    mapping_func = {
+        "tenants": validate_tenants,
+        "devices": validate_machines,
+        "physical_interfaces": validate_interfaces,
+        "virtual_machines": validate_machines,
+        "virtual_interfaces": validate_interfaces,
+        "vrfs": validate_vrfs,
+        "vlans": validate_vlans,
+        "prefixes": validate_prefixes,
+        "ip_addresses": validate_ip_addresses,
+    }
+
+    netbox_data = get_objects(netbox_config.get("tenant_name", ""))
+
+    for key, validate_func in mapping_func.items():
+        if netbox_data[key]:
+            validate_func(netbox_data[key])
+
+    if not misconfs:
+        print("All checks passed.")
+    else:
+        for misconf in misconfs:
+            print(misconf)
