I built this application as a demonstration of how a Source of Truth can drive network configuration by not only verifying that a network devices configuration matches the Source of Truth, but also implement changes when deviations are found.
Retrieving current status from device with pyATS
Looking up intended state for device from Netbox
Running tests to see if VLANs from Netbox are configured
❌ 11 MISSING from switch
❌ 12 MISSING from switch
❌ 13 MISSING from switch
✅ 21 (test-web) exists with correct name on switch
✅ 22 (test-app) exists with correct name on switch
✅ 23 (test-data) exists with correct name on switch
Running interface enabled test
✅ Ethernet1/1 was correctly found to be UP/UP on switch
✅ Ethernet1/2 was correctly found to be UP/UP on switch
✅ Ethernet1/3 was correctly found to be UP/UP on switch
✅ Ethernet1/4 was correctly found to be UP/UP on switch
✅ Ethernet1/5 was correctly found to be UP/UP on switch
✅ Mgmt0 was correctly found to be UP/UP on switch
Running interface description test
✅ Ethernet1/1 has the correct description configured on switch
✅ Ethernet1/2 has the correct description configured on switch
✅ Ethernet1/3 has the correct description configured on switch
✅ Ethernet1/4 has the correct description configured on switch
✅ Mgmt0 has the correct description configured on switch
Running interface mode test
✅ Ethernet1/2 is correctly configured as a trunk
✅ Ethernet1/3 is correctly configured as a trunk
✅ Ethernet1/4 is correctly configured as a trunk
✅ Ethernet1/5 is correctly configured as a trunk
Running interface vlan test
✅ Ethernet1/2 correctly is trunking ALL vlan ids.
❌❌ Vlan 11 is NOT configured on the switch.
❌❌ Vlan 12 is NOT configured on the switch.
❌❌ Vlan 13 is NOT configured on the switch.
✅ Ethernet1/6 correctly has 13 configured as the access vlan id
Creating 11 (production-web)
Creating 12 (production-app)
Creating 13 (production-data)
Updating Interface Ethernet1/4 mode to Tagged
Updating Interface Ethernet1/5 mode to Tagged
Updating Interface Ethernet1/3 mode to Tagged
The technologies used in this demonstration are:
Here are some videos that show the application in action:
This project is not intended to cover every aspect of the network configuration, at least not the initial version. Rather my goal was to tackle a few of the common areas I see from my own network and discussions with others that would be hugely valuable for a solution like this. Specifically this application tackles the following.
shut / no shut
state on the switchaccess / trunk
configuration as well as access, native, and trunked VLANs.If a deviation is found between Netbox and the device a ChatOps message is sent to a designated room within Webex Teams.
NOTE: Before using this code in your own environment, see the Caveats / Known Issues / Later Updates Section at the end of this README.
Also, this demo is provided as-is but with no gaurantees of any level of functionality, or that it won't cause problems in your own envirnoment. It's a DEMONSTRATION of a topic, offered as an example of a concept. I do NOT recommend taking this code as is and running in production, or in any environment where the potential for catastrophic failure isn't a comfortable result. YOU HAVE BEEN WARNED
So you'd like to see it in action, I mean, who wouldn't. There are options:
I'll do my best to detail out what you need to know to run this demo in the different forms, but a few things are assumed to be known or aware of already.
Furthermore, while all the code for the demo is in the repo, the demo instructions will not include a walkthrough and explaination of how it all works.
Further-furthermore, while not explicitly required, in order for the application to send Webex Teams messages for ChatOps, you'll need a Webex Teams account (you can get a free account), and setup a "Bot App" to use. You can find Learning Labs that cover Webex Teams APIs and Bots on DevNet. The key part for this demo is creating the "Bot" and retrieving it's Token. Also, you'll need to retrieve the roomId for where to send the alerts, more on this later.
The quickest way to see this demo in action is to use the resources from DevNet Sandbox. Specifically the Open NX-OS Always On Sandbox and a Demo Netbox Server setup for this demonstration (Netbox credentials: operator / DevNetSandboxForever
).
As noted above, you'll need to setup a new bot account in Webex Teams and retrieve the Bot Token to use for the application. There are several learning labs on DevNet that go into details on bots and Webex Teams, so please see them for more information.
To create the bot account, go to your "My Apps" section of developer.webex.com and set it up.
Now let's get the application running.
First, clone down this repository to your workstation.
While we will work up to running in Docker, we'll start more simply by running in a Python virtual-environment. Note: I recommend the latest version of Python 3.6 or 3.7.
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
This will install the Python requirements into your virtual environment.
Included in the repo is a file sandbox_env
. This is a file that has the necessary "secrets" for communicating to the DevNet Sandbox resources.
# Environment variables file running the demo using the DevNet Sandbox resources export NETBOX_URL="http://ec2-54-89-119-42.compute-1.amazonaws.com" export NETBOX_TOKEN="0123456789abcdef0123456789abcdef01234567"export SWITCH_HOSTNAME="sbx-n9kv-ao" export SWITCH_MGMT_IP="sbx-nxos-mgmt.cisco.com" export SWITCH_MGMT_PORT="8181" export SWITCH_USERNAME="admin" export SWITCH_PASSWORD="Admin_1234!"
# Uncomment these and add your Webex Teams Bot Token and RoomId # export TEAMS_TOKEN="" # export TEAMS_ROOMID=""
Open this file and add the token for your Teams Bot and target roomId for notifications. Some notes:
TEAMS_TOKEN
is the Bot token you will use for ChatOps. You were given this token when you created the Bot app.inspect@webex.bot
to a room and ask it it for the roomId
(case sensitive). It will then reply with the roomId for that room.
Note: if you do NOT provide the TEAMS info, the application will run fine, but no messages will be sent to a Chat room. You can monitor the status by looking at the standard output.
Now source
the sandbox_env
file to create environment variables in your terminal session.
source sandbox_env
You can now run the application.
python check_device.py
Retrieving current status from device with pyATS
Looking up intended state for device from Netbox
Running tests to see if VLANs from Netbox are configured
✅ 100 (mgmt) exists with correct name on switch
✅ 101 (prod) exists with correct name on switch
✅ 102 (dev) exists with correct name on switch
✅ 103 (test) exists with correct name on switch
✅ 104 (security) exists with correct name on switch
✅ 105 (iot) exists with correct name on switch
If there were any differences in the configuration and Netbox, you should see some lines like this in the output.
❌ 1999 MISSING from switch
.
.
Creating 1999 (quarantine)
And look for ChatOps messages like this in your Teams room.
You can further test the application by removing some configuration from the Always On NX-OS devices and watch as it's detected and restored.
Note: You can't add NEW configuration to Netbox because the operator account used for the shared demo is READ-ONLY
! Example: SSH to the Always On Sandbox and remove a VLAN
ssh -p 8181 admin@sbx-nxos-mgmt.cisco.com
config t
no vlan 1999
# Resulting Output
❌ 1999 MISSING from switch
.
.
Creating 1999 (quarantine)
Stop the application with Cntrl-C
Now you know the application works... let's container-ize it.
Build a container.
docker build -t nxos-netbox-sync:latest .
Note: If you have a Docker Hub account (or another registry), use that in the tag name so you can
push
it.
Run the container.
source sandbox_env
docker run --rm -it \
-e NETBOX_URL="${NETBOX_URL}" \
-e NETBOX_TOKEN="${NETBOX_TOKEN}" \
-e SWITCH_HOSTNAME="${SWITCH_HOSTNAME}" \
-e SWITCH_MGMT_IP="${SWITCH_MGMT_IP}" \
-e SWITCH_MGMT_PORT="${SWITCH_MGMT_PORT}" \
-e SWITCH_USERNAME="${SWITCH_USERNAME}" \
-e SWITCH_PASSWORD="${SWITCH_PASSWORD}" \
-e TEAMS_TOKEN="${TEAMS_TOKEN}" \
-e TEAMS_ROOMID="${TEAMS_ROOMID}" \
nxos-netbox-sync:latest
Note: If your switch uses a port other than 22 for SSH, you'll need to add an additional environment variable of
-e SWITCH_MGMT_PORT="${SWITCH_MGMT_PORT}"
to the command.
[Entrypoint] Starting pyATS Docker Image ...
[Entrypoint] Workspace Directory: /pyats
[Entrypoint] Activating workspace
[CMD] Starting NX-OS Netbox Sync ...
[CMD] Activating pyATS virtualenv
[CMD] Running check_device.py
Retrieving current status from device with pyATS
Looking up intended state for device from Netbox
Running tests to see if VLANs from Netbox are configured
✅ 100 (mgmt) exists with correct name on switch
✅ 101 (prod) exists with correct name on switch
✅ 102 (dev) exists with correct name on switch
✅ 103 (test) exists with correct name on switch
✅ 104 (security) exists with correct name on switch
✅ 105 (iot) exists with correct name on switch
Stop the container with Cntrl-C
I fully expect everyone to want to try this out with their own lab setup, it's just that cool. But before you jump in, I gotta repeat the warning from above.
NOTE: Before using this code in your own environment, see the Caveats / Known Issues / Later Updates Section at the end of this README.
Also, this demo is provided as-is but with no gaurantees of any level of functionality, or that it won't cause problems in your own envirnoment. It's a DEMONSTRATION of a topic, offered as an example of a concept. I do NOT recommend taking this code as is and running in production, or in any environment where the potential for catastrophic failure isn't a comfortable result. YOU HAVE BEEN WARNED
That out of they way, here's how you can set this up in your own lab.
First thing you'll need is to get a Netbox server up and running. If you have one, great. If not you can easily get one running quickly using the netbox-docker method available and well documented on GitHub.
Once you have Netbox running, you'll need to add the device to the DCIM inventory, configure it's interfaces, and create the VLANs desired.
Reminder.. if you're running this on a switch that already has some configuration on it that you want to make sure stays the same and isnt' damaged, you should configure Netbox to match the current state. Failure to do so could result in your switch loosing configuration.
For the basic use case of verifying and updating configuration on the switch with what is published in Netbox, just about any NX-OS switch will do. You'll just need to have the management IP address and credentials ready to provide the application. But if you'd like to run the application container ON THE SWITCH itself, you'll need to take a few steps to prepare it.
For full details on Docker on NX-OS see the product documentation.
Due to details on how the management VRF and namespaces operate on NX-OS you'll need to setup an "INBAND" management address to use to connect. This can be a loopback, vlan interface, or layer-3 physical interface, it just can't be the Mgmt 0
port on the switch itself. As en example...
interface Ethernet1/1
description Inband Management Interface
no switchport
ip address 10.10.20.59/24
Enable the bash-shell access on the switch and connect as root
feature bash-shell
run bash sudo su -
Before you start docker, you'll need to verify that enough disk space is allocated for containers. Edit /etc/sysconfig/docker
and make sure small_dockerstrg
it at least 900.
Start and verify Docker.
service docker start
chkconfig --add docker
verify
service docker status
Pull down the Docker image for the app onto the swich.
ip netns exec management docker pull hpreston/nxos-netbox-sync:latest
Note: This is pulling the container that I published to Docker Hub. You can also build your own image using the Dockerfile included in the repo as an alternative.
If you have problems connecting to the Docker to pull the image, verify that DNS is configured correctly, and that the switch has access to the Internet through the management interface. This is required not just to pull the image, but also to send messages to Webex Teams.
As noted above, you'll need to setup a new bot account in Webex Teams and retrieve the Bot Token to use for the application. There are several learning labs on DevNet that go into details on bots and Webex Teams, so please see them for more information.
To create the bot account, go to your "My Apps" section of developer.webex.com and set it up.
Now let's get the application running.
First, clone down this repository to your workstation.
While we will work up to running in Docker, we'll start more simply by running in a Python virtual-environment. Note: I recommend the latest version of Python 3.6 or 3.7.
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
This will install the Python requirements into your virtual environment.
Included in the repo is a file src_env.template
. This is a template file for you to use to create your own src_env
file that will hold all the "secrets" for the application.
# Sample environment variables file for storing key details for the application export NETBOX_URL="" export NETBOX_TOKEN=""export SWITCH_HOSTNAME="" export SWITCH_MGMT_IP="" # export SWITCH_MGMT_PORT="" # Specify SSH port if it is NOT 22 export SWITCH_USERNAME="" export SWITCH_PASSWORD=""
export TEAMS_TOKEN="" export TEAMS_ROOMID=""
Copy this file and name it src_env
. Fill in the details for each value for your implementation. Some notes:
SWITCH_HOSTNAME
is used to locate the device in Netbox, be sure it matches.TEAMS_TOKEN
is the Bot token you will use for ChatOps. You were given this token when you created the Bot app.inspect@webex.bot
to a room and ask it it for the roomId
(case sensitive). It will then reply with the roomId for that room.
Note: if you do NOT provide the TEAMS info, the application will run fine, but no messages will be sent to a Chat room. You can monitor the status by looking at the standard output.
Now source
the src_env
file to create environment variables in your terminal session.
source src_env
You can now run the application.
python check_device.py
Retrieving current status from device with pyATS
Looking up intended state for device from Netbox
Running tests to see if VLANs from Netbox are configured
✅ 100 (mgmt) exists with correct name on switch
✅ 101 (prod) exists with correct name on switch
✅ 102 (dev) exists with correct name on switch
✅ 103 (test) exists with correct name on switch
✅ 104 (security) exists with correct name on switch
✅ 105 (iot) exists with correct name on switch
If there were any differences in the configuration and Netbox, you should see some lines like this in the output.
❌ 1999 MISSING from switch
.
.
Creating 1999 (quarantine)
And look for ChatOps messages like this in your Teams room.
While the application is running, either remove some configuration from the switch, or add something new to Netbox to see the sync-tool in action!
Stop the application with Cntrl-C
Now you know the application works... let's container-ize it.
Build a container.
docker build -t nxos-netbox-sync:latest .
Note: If you have a Docker Hub account (or another registry), use that in the tag name so you can
push
it.
Run the container.
source src_env
docker run --rm -it \
-e NETBOX_URL="${NETBOX_URL}" \
-e NETBOX_TOKEN="${NETBOX_TOKEN}" \
-e SWITCH_HOSTNAME="${SWITCH_HOSTNAME}" \
-e SWITCH_MGMT_IP="${SWITCH_MGMT_IP}" \
-e SWITCH_USERNAME="${SWITCH_USERNAME}" \
-e SWITCH_PASSWORD="${SWITCH_PASSWORD}" \
-e TEAMS_TOKEN="${TEAMS_TOKEN}" \
-e TEAMS_ROOMID="${TEAMS_ROOMID}" \
nxos-netbox-sync:latest
Note: If your switch uses a port other than 22 for SSH, you'll need to add an additional environment variable of
-e SWITCH_MGMT_PORT="${SWITCH_MGMT_PORT}"
to the command.
[Entrypoint] Starting pyATS Docker Image ...
[Entrypoint] Workspace Directory: /pyats
[Entrypoint] Activating workspace
[CMD] Starting NX-OS Netbox Sync ...
[CMD] Activating pyATS virtualenv
[CMD] Running check_device.py
Retrieving current status from device with pyATS
Looking up intended state for device from Netbox
Running tests to see if VLANs from Netbox are configured
✅ 100 (mgmt) exists with correct name on switch
✅ 101 (prod) exists with correct name on switch
✅ 102 (dev) exists with correct name on switch
✅ 103 (test) exists with correct name on switch
✅ 104 (security) exists with correct name on switch
✅ 105 (iot) exists with correct name on switch
Stop the container with Cntrl-C
And the final step, running the container on the switch.
On your switch, jump into the bash shell
run bash sudo su -
If you pushed your Docker image to a repository, pull it down with a command like this. Note: this command pulls the image from my Docker account. It should work, but it isn't YOURS.
ip netns exec management docker pull hpreston/nxos-netbox-sync:latest
Create all the environment variables on the switch. It's simplest to just copy the contents of your src_env
file and paste into the switch.
Now run the container on the switch just like you did locally.
docker run --rm -it \
-e NETBOX_URL="${NETBOX_URL}" \
-e NETBOX_TOKEN="${NETBOX_TOKEN}" \
-e SWITCH_HOSTNAME="${SWITCH_HOSTNAME}" \
-e SWITCH_MGMT_IP="${SWITCH_MGMT_IP}" \
-e SWITCH_USERNAME="${SWITCH_USERNAME}" \
-e SWITCH_PASSWORD="${SWITCH_PASSWORD}" \
-e TEAMS_TOKEN="${TEAMS_TOKEN}" \
-e TEAMS_ROOMID="${TEAMS_ROOMID}" \
nxos-netbox-sync:latest
Note: If your switch uses a port other than 22 for SSH, you'll need to add an additional environment variable of
-e SWITCH_MGMT_PORT="${SWITCH_MGMT_PORT}"
to the command.
[Entrypoint] Starting pyATS Docker Image ...
[Entrypoint] Workspace Directory: /pyats
[Entrypoint] Activating workspace
[CMD] Starting NX-OS Netbox Sync ...
[CMD] Activating pyATS virtualenv
[CMD] Running check_device.py
Retrieving current status from device with pyATS
Looking up intended state for device from Netbox
Running tests to see if VLANs from Netbox are configured
✅ 100 (mgmt) exists with correct name on switch
✅ 101 (prod) exists with correct name on switch
✅ 102 (dev) exists with correct name on switch
✅ 103 (test) exists with correct name on switch
✅ 104 (security) exists with correct name on switch
✅ 105 (iot) exists with correct name on switch
A few things to be aware of should you look to leverage this code for something within your own environment.
I built this application as a demonstration of how a Source of Truth can drive network configuration by not only verifying that a network devices configuration matches the Source of Truth, but also implement changes when deviations are found.
This output is an example report from the application:
Retrieving current status from device with pyATSLooking up intended state for device from NetboxRunning tests to see if VLANs from Netbox are configured❌ 11 MISSING from switch❌ 12 MISSING from switch❌ 13 MISSING from switch✅ 21 (test-web) exists with correct name on switch✅ 22 (test-app) exists with correct name on switch✅ 23 (test-data) exists with correct name on switchRunning interface enabled test✅ Ethernet1/1 was correctly found to be UP/UP on switch✅ Ethernet1/2 was correctly found to be UP/UP on switch✅ Ethernet1/3 was correctly found to be UP/UP on switch✅ Ethernet1/4 was correctly found to be UP/UP on switch✅ Ethernet1/5 was correctly found to be UP/UP on switch✅ Mgmt0 was correctly found to be UP/UP on switchRunning interface description test✅ Ethernet1/1 has the correct description configured on switch✅ Ethernet1/2 has the correct description configured on switch✅ Ethernet1/3 has the correct description configured on switch✅ Ethernet1/4 has the correct description configured on switch✅ Mgmt0 has the correct description configured on switchRunning interface mode test✅ Ethernet1/2 is correctly configured as a trunk✅ Ethernet1/3 is correctly configured as a trunk✅ Ethernet1/4 is correctly configured as a trunk✅ Ethernet1/5 is correctly configured as a trunkRunning interface vlan test✅ Ethernet1/2 correctly is trunking ALL vlan ids.❌❌ Vlan 11 is NOT configured on the switch.❌❌ Vlan 12 is NOT configured on the switch.❌❌ Vlan 13 is NOT configured on the switch.✅ Ethernet1/6 correctly has 13 configured as the access vlan idCreating 11 (production-web)Creating 12 (production-app)Creating 13 (production-data)Updating Interface Ethernet1/4 mode to TaggedUpdating Interface Ethernet1/5 mode to TaggedUpdating Interface Ethernet1/3 mode to Tagged
This video, Cisco NX-OS Netbox Sync Demo1: In Action, shows the application in action.
Cisco NX-OS Netbox Sync Demo1: In Action
This project is not intended to cover every aspect of the network configuration, at least not the initial version. Rather my goal was to tackle a few of the common areas I see from my own network and discussions with others that would be hugely valuable for a solution like this. Specifically, this application tackles the following:
shut / no shut
state on the switch. access/trunk
configuration as well as access, native, and trunked VLANs.If a deviation is found between Netbox and the device, a ChatOps message is sent to a designated room within Webex Teams.
The technologies used in this demonstration are:
Code Exchange Community
Get help, share code, and collaborate with other developers in the Code Exchange community.View Community