NSOT (Network Source Of Truth)

NSoT is an API-first application that provides a REST API and a web application front-end for managing IP addresses (IPAM), network devices, and network interfaces. This open- source application can be incorporated into both automated on-prem and cloud builds to manage and assign IP addresses.

Step-by-step guide: Set up your own NSOT Docker Container

(Guide assumes you have Ubuntu 16.04 running)

1. If you do not have docker already installed:

sudo apt install docker.io

2. Run the following docker commands to pull down the latest NSOT docker image, run the image, and create a super user account within nsot which is required.

sudo docker run -p 8990:8990 -d –name=nsot nsot/nsot start –noinput

sudo docker exec -it nsot bash (you are now in the nsot container after running this command)

nsot-server –config=/etc/nsot/nsot.conf.py createsuperuser (you will be prompted to create a superuser name/password) exit (exit out of the container)

3. After completing step 2 you have a working nsot server running as a container with a sql-lite

4. Install pynsot on your local Ubuntu instance which is the nsot cli/api client for interacting with nsot if python pip is not installed, run

sudo apt install python-pip pip install pynsot

5. Once the client is installed, create a .pynsotrc file in your local home directory

vi ~/.pynsotrc


url = auth_header = X-NSoT-Email default_domain = localhost

email = <enter the email you used for the nsot superuseraccount in step2> default_site = 1

auth_method = auth_header

6. Once the pynsot client is installed and your .pynsotrc file is created, create a default site 1 (we will go over sites, networks, etc shortly ) to verify everything is working properly

nce the pynsot client is insta

7. If successful, you should receive the output “[SUCCESS] Added site!” . Congratulations! you now have your own working nsot server to hack away

NSOT Basics

Now that you have created your very own NSOT server to hack away on, lets go over the basics of sites, networks, attributes, and resources:


A site is basically creating your own isolated section within nsot for any networks, attributes, and resources you create. Everything in NSOT must be related to a site. Depending on how you want to organize nsot, a site could represent a physical location, ex. Ashburn, an environment, ex. CustA-Prod, etc. One thing to keep in mind about sites is they allow for multiple instances of conflicting objects. For example, you could create network under site=Denver and network under site=CustA-Prod


NSOT is built around the python netaddr package which gives makes it a great tool for IP Address management and automated IP assignments. In our next example, you will see how to create a large CIDR Block (parent network) and how to assign own smaller networks (children) within the larger CIDR block. NSOT also has the ability to assign out next available network blocks as well as next available IP addresses. We will be using this functionality to create our AWS VPC CIDR block, subnets, as well as assign IP addresses to elastic network interfaces.


Think of attributes as the metadata/tags for NSOT. You can assign multiple attributes to Networks and resources, allowing you to filter what networks/resources are returned in a query of the NSOT database. For example , in an AWS VPC build scenario in the US-east1 region of AWS for CustA Prod, we could have the attributes CSP=AWS, region=us-east1, customer=custA, environment=prod applied to network which is a child network to (parent CIDR block) as shown below:

Attributes are very similar to Tags within AWS. They allow you to assign granular data to Networks and resources which allow for very fine grained NSOT queries and organization of our data.


Resources are something we really do not use within NSOT at this time. NSOT also has the ability to act as an asset/inventory management tool where a resource would be something like a Cisco CSR in the Denver DC or even ec2 instances within a given VPC. For more information on the NSOT data model, please refer

to http://nsot.readthedocs.io/en/latest/models.html#resources.

NSOT CLI (Pynsot) Let the Fun Begin:

The NSOT CLI is the easiest way I have found to interact with NSOT. You can add networks, sites, attributes, etc. through the web ui by simply logging in on your local nsot server at http: or through the python api which I am not going to get into with this article. Building off of everything we did in step 1, let create a new CIDR block (parent network) under site 1 by running the commands below:

nsot networks add -s 1 -c

nsot networks list

You should see network added to nsot as shown above.

Next, lets say we had a use case like the cosmos vRouter where we needed two networks out of this space. One network will only be used for core vRouters, and the other network will only be used for edge vRouters. First lets create some attributes:

nsot attributes add -s 1 -n core -r Network

nsot attributes add -s 1 -n edge -r Network

nsot attributes add -s 1 -n dhcp_scope -r Network

We created 3 new attributes above. Let’s break down the first command. we created a new attribute with a name of core (-n core), associated it site 1 (-s 1), and it can only be applied to a Network resource (-r Network). Now, list the attributes we just created:

nsot attributes list

As you can see from the output above, you can pass additional flags to make attributes required on a network resource, add a description of what they are, and even apply constraints if you want to lock down what values can actually be stored.

Now lets add the two networks. One for edge routers, and one for core routers. First, we will list the next available /24 network in the parent network, store it in a variable, and then add the network back into nsot with the attributes applied:

export CORENET=$(nsot networks list -s 1 -c next_network -p 24)

nsot networks add -s 1 -c $CORENET -a dhcp_scope=L2_VPN -a core=true

export EDGENET=$(nsot networks list -s 1 -c next_network -p 24)

nsot networks add -s 1 -c $EDGENET -a dhcp_scope=L2_VPN -a edge=true

nsot networks list

Lets breakdown what we did with pulling the next available network for the CORENET and then adding it back/reserving it in nsot. the output we stored in the CORENET var was from the following NSOT command:

# “This pulls the next available /24 network (next_network -p 24) out of the parent network (.-c in site 1 (. -s 1) nsot networks list -s 1 -c next_network -p 24

# “This adds the returned next available /24 network which is stored in the $CORENET env var back in to NSOT with two attributes, -a dhcp_sc nsot networks add -s 1 -c $CORENET -a dhcp_scope=L2_VPN -a core=true

We repeated the same process which pulled the next available /24 network for the edge vrouters and stored it back in to NSOT as allocated.

Now that we have two networks created with appropriate attributes associated, lets list the next available IP out of the Core network and then assign them back to NSOT as allocated.

#This queries the nsot server for the network in site 1 with attributes matching dhcp_scope=l2_VPN -q core=true export CORENET=$(nsot networks list -s 1 -q dhcp_scope=l2_VPN -q core=true –no-include-ips)

#pulls the next IP out of the network stored in the $CORENET var above export NEXTIP=$(nsot networks list -s 1 -c $CORENET next_address -n 1)

#add the IP back to nsot with the attributes dhcp_scope=L2_VPN -a core=true nsot networks add -s 1 -c $NEXTIP -a dhcp_scope=L2_VPN -a core=true

Now you will see the next available IP on the NSOT server as allocated. Think about what we just did there and how you can apply this logic. If these commands are run within a script on instances being turned up in AWS, in a terraform template assigning out CIDR blocks to VPCs, etc, you have essentially created an IPAM solution as well as a DHCP service for your environment! This is just scratching the surface of what this powerful tool can do. NSOT can be set up with an RDS/MySQL backend and you can have multiple NSOT app servers/containers running behind a load balancer, turning this into an easily deployable production ready solution. Happy Hacking!


NSOT has a REST API allowing you to add, delete, edit, and query NSOT using simple curl commands. Here is a list of useful curl requests that can be used to interact with NSOT:

add an attribute:

The curl below will post a new attribute under site_id 2 named env.

curl -H “Content-Type: application/json” –user username:password -vX POST http://prometheus-llc.io/api/attributes/ -d ‘{“multi”: “false”,”resource_name”:”Network”,”description”:””,”display”:”false”,”required”:”false”,”site_id”: “2”,”id”: “2”,”name”:”env”}’

You can also use a .json file to post the same data as shown below.

curl -H “Content-Type: application/json” –user username:password –data @f1.json -vX POST http://prometheus-llc.io/api/attributes/

Delete an attribute:

When an attribute is created, it is assigned a unique, sequential ID number. In the example below, the attribute we are going to delete has an ID of 5 which we will use in the DELETE request below.

curl -H “Content-Type: application/json” –user username:password -vX DELETE http://prometheus-llc.io:80/api/attributes/5/

Grab next available network:

The command below with grab the next available /22 in the network block that has id 1 and assign it to an environment variable net1. We will use this returned value stored in $net1 and post it back to NSOT to reserve the network with a set of attributes.

export net1=$(curl -H “Content-Type: application/json” –user username:password http://prometheus-llc.io/api/sites/1/networks/1/next_network/?prefix_length=22 | tr -d ‘[]”‘)

curl -H “Content-Type: application/json” –user username:password -vX POST http://prometheus-llc.io/api/networks -d ‘{“site_id”: “1”,”cidr”: “$net1″,”attributes”: {“customer”: “custA”, “environment”: “prod”}}’


Using jq, you can run granular queries to return specific information within the json data returned by NSOT.

curl -H “Content-Type: application/json” –user user:pass -X GET http://prometheus-llc.io/api/networks/ | jq ‘map(select(.attributes.type == “supernet” and

.attributes.environment == “dev”)) | .[].cidr’

Related articles


NSOT (Network Source Of Truth)