No Rest for SuzieQ

To be clear, it is true that SuzieQ never rests but it is also true that SuzieQ always RESTS, that is, the SuzieQ REST API is available to answer your network questions and help automate your network workflows.

In my previous post about SuzieQ we focused on getting started and asking questions about our network via the Command Line Interface (CLI).
If you followed along with the previous post you should now have a working open source SuzieQ server.  This means you have everything you need to launch the SuzieQ REST API.

In this post we will configure and run the SuzieQ REST API and use it to automate a fairly common networking use case, changing the vlan on an access port.

Out of the box you can interact with SuzieQ via its CLI, GUI, or REST interfaces and there is a python module as well.

The Open Source GUI is fairly basic so I am not going to spend too much time on it. Having said that, I've been lucky enough to work with the Enterprise version and the Enterprise GUI is streamlined and powerful. It is a big hit with those who prefer to work in a GUI. Since I can never pass up an opportunity to encourage network operators to stop documenting their current network topology with a drawing tool, the Enterprise GUI offers on demand and usable topology maps across various contexts including LLDP/CDP, OSPF, and VRF. If you want to dump your aging, inaccurate topology Visios this is the place to start!

What are we trying to do?

We want to provide our users with a little self service.

Under certain conditions it should be pretty safe to let a user move their device over to a new vlan. Put another way, allowing a user to change the vlan on their port can generally only result in self inflicted pain 🤞🏽.

Today we are going to build a little specialized Web App you can run (locally or on a server) that will let a user query the network about a particular device by its DNS name and find out if we can move it to an existing vlan of their choosing.

We will use this fairly typical use case to showcase the power of the data SuzieQ gathers for us and how we can interact with it via the REST API to build a workflow.

Such a simple ask, right?

I need to move my system to this network.

How hard can that be?

Network Engineer: "What switch and port is your system on?"
User: "Uh...XY123"

Network Engineer: "That is not a switch or a port number!"
User: "Uh...its the label on the little box on the wall"

Network Engineer: "That is the jack! OK..give me your MAC address."
User: "Uh...what?"

Network Engineer: "OK give me...."
User: "Uh..."

You get the idea. In fact, its worse because you will probably get.. "I need to move it to the IoT network"
Which means you have to figure out which Vlan that is, is it available at that location, and determine if it is configured and working on the switch the user is connected to (once you find that out).

All the information we need to determine if we should move a device to a new vlan (including the list of vlans available at the location) will come from SuzieQ via REST calls.

At no time during the "reconnaissance" are we directly accessing the involved network devices. SuzieQ is saving state so that when we need information we can ask things like:

✅ Where is the device (what is its location)?

✅ Is the device on the network now?

✅ What is its MAC?

✅ What is the Vendor OUI of the MAC?

✅ What is its current vlan?

✅ What switch is it on?

✅ What user port is it on?

✅ Has it been on that port for the last 30 days or has it moved around?

✅ What is the new vlan?

✅ Is the new vlan configured on the switch?

Assumptions

  • The user knows and can provide the DNS name of the device.
  • The device is on the network and we are moving it "in place". That is, we are re-configuring its current network interface to a new vlan. With SuzieQ we could see where it has been and if its been connected to the same switch interface consistently for some amount of time we could proceed with the change. SuzieQ gives us that information but for our simple example, if the device is not on the network now we will not make any changes to the network.
  • The user has authority to make the change (oh boy!).

Approach

We know users are comfortable with web pages so we are going to present our App as a web page. We also know asking anyone to type anything is fraught with problems, so we are going to use pulldowns with validated data wherever possible. About the only thing we should ask our user to enter is the DNS name of the device they want to move.

We will use Streamlit for our web front end.

Once the user enters the device name, we will take our user through a series of button clicks which will run Python and take them through:

  • resolving the name to an IP address,
  • locating the device (based on IP and then MAC)
  • determining which vlan they want to move to (based on the available vlans at the location)
  • determining if it is safe to move the device (because the vlan is configured on the switch)
  • change the vlan on the port if all the checks pass

We will query our SuzieQ data via its REST API using the Python Requests module.

We will use Netmiko to push the configuration changes needed to move the device to its new vlan (once we confirm it is available on the switch).

Configuring the SuzieQ REST Service

The SuzieQ configuration file we are using (suzieq-cfg.yml) is in the home sq directory if you have been following along. Probably something like /home/<your username>/sq.

It actually comes with a simple HTTP only configuration to get you started quickly (although not at all recommended for a production environment).

For this simple proof of concept, we are taking all the defaults (No HTTPS and using the example API_KEY provided).

claudia@sqos:~/sq$ cat suzieq-cfg.yml
data-directory: /home/claudia/sq/parquet
temp-directory: /tmp/

rest:
  # Uncomment these lines if you're using your own files for the REST server
  # The certificates listed below are provided purely to get started, In any
  # secure deployment, these must be generated specifically for the site and
  # these lines uncommented and containing the location of the site-specific file.
  # rest-certfile: /secrets/cert.pem
  # rest-keyfile: /secrets/key.pem
  #
  API_KEY: 386157e6e759ef7f3d6ecb24a6f6d847b334gg4f
  logging-level: DEBUG
  address: 10.1.10.47
  port: 8000
  no-https: True
  logfile: /tmp/sq-rest-server.log
  # logsize is in bytes
  # logsize: 10000000
  # log-stdout: True

poller:

# <snip>

Starting the REST server

Now that we have the configuration, we just need to start the service.

Here I am starting the rest server sq-rest-server and giving it the configuration file I want to use and disabling https.

If you are new to Linux (please take a class.. you won't regret it!) the final "&" tells the Linux operating system to run this command in the background and immediately return your prompt (while continuing to run the command in the background).

Tip:
I've put my SuzieQ installation in my home directory (represented by ~ in Linux), in the sq directory. Within that sq directory I created my Python virtual environment and called it venv_sq.

~/sq/venv_sq/bin/sq-rest-server -c ~/sq/suzieq-cfg.yml --no-https &

Lets break it down:

~/sq/venv_sq/bin/sq-rest-server explicitly calls the sq-rest-server script (which you got when you pip installed suzieq) in its location.  For my system it translates to /home/claudia/sq/venv_sq/bin/sq-rest-server.

We are passing two arguments to  the sq-rest-server script:

  • -C expects the location of the SuzieQ configuration file you want to use.  In this case its in my home directory, in the sq directory, and its called suzieq-cfg.yml
  • --no-https disables https so the server will be reachable via http://<ip of your server>:<port>
  • & tells the operating system to run the command in the background

Note: This approach is great for labs but not at all suitable for production. In a production environment you want to disable http and only use https. You also want to use a more robust approach to running the process. The enterprise version comes with systemd all set up for you. Since this is just a little proof of concept we are not going worry too much about that.

How do I know its running?

Using the Linux ps -ef command which displays process status (ps) with the -ef "flags" which gives you all the process with additional details. "Piping" the output of that command to grep filters the output to just what you want to see ps -ef | grep sq-rest-server

The first entry 18191 tells you that the rest server is running and shows you how it was started (notice that its essentially the command above without the ~ shortcut for your home directory).

The second entry 18247 tells you that I am also running a process to look at the rest server log continually tail -f /tmp/sq-rest-server.log

This is really handy for troubleshooting.

The third line is basically what we are doing now (grepping the output of ps) and can be ignored.

claudia@sqos:~/sq$ ps -ef | grep sq-rest-server
claudia    18191    1822  0 May18 pts/1    00:03:07 /home/claudia/sq/venv_sq/bin/python /home/claudia/sq/venv_sq/bin/sq-rest-server -c /home/claudia/sq/suzieq-cfg.yml --no-https
claudia    18247    5574  0 May18 pts/2    00:00:00 tail -f /tmp/sq-rest-server.log
claudia    23125   15050  0 16:47 pts/4    00:00:00 grep --color=auto sq-rest-server
claudia@sqos:~/sq$

Testing the REST Server with Swagger

The SuzieQ REST server comes with a Swagger interface that lets you quickly and easily test your server and develop the format you will need to follow to ask your network questions via REST.

Authorizing to Swagger

  1. Go to your SuzieQ Swagger URL (http://10.1.10.47:8000/api/docs)
  2. Click on Authorize
  3. Enter your API Token to authorize your session (In this example I am using the default one that comes with SuzieQ)
  4. Click on Authorize again once you have entered your API Token

Launching the Dial-a-Vlan App

Clone or download the repository.

Make sure you have a virtual environment created for this repository.
python -m venv venv_norest4sq

Activate your virtual environment
source venv_sq/bin/activate

Note where you are in the directory structure and also note that your prompt changes once your virtual environment has been activated.  Use the deactivate command to deactivate your virtual environment.

Make sure you have installed all the necessary modules (requests, netaddr, pandas, streamlit, netmiko, python-dotenv) once you have activated your virtual environment.  Until you do this, your virtual environment is basically just a copy of your Python installation.

pip install -r requirements.com

Start the App

You will find one Python script in the repository, DialAVlan_App.py. While it is entirely in Python it is intended to be launched by Streamlit.

Change directory into your repository. You should already be there if you created your virtual environment within the repository directory.
streamlit run DialAVlan_App.py

% streamlit run DialAVlan_App.py

You can now view your Streamlit app in your browser.

Local URL: http://localhost:8501
Network URL: http://10.1.10.35:8501

Streamlit will, by default, open up your web browser and display the App.


What is the code doing?

You will find one Python script in the repository, DialAVlan_App.py which has the business logic along with some supporting functions.

The main() function presents a Streamlit form that offers a button for each stage. Its a workflow so subsequent stages are offered based on the results of the checks.
1. Given the device DNS (Fully Qualified Domain Name or FQDN) name find its IP and anything else we can find in SuzieQ
2. If we found the device, the next step is to get a list of the valid vlans at the devices' location and ask the user to pick which one to move the device to
3. With this information in hand we can now do the final checks to make sure that if we move the device it will work. Is the vlan configured on the switch? If so, push the change to the interface configuration and perform some validation.

The try_sq_rest_call

This function acts as the base function for all REST calls to the SuzieQ REST API.  It assembles the request, sends it to the SuzieQ REST API, and returns the data.

It sets default values for variables for the protocol, port, access token, and server ip and requires two arguments to be passed to it, uri_path and uri_options.

These two variables, uri_path and uri_options, will change based on the query.

For example, if I want to find an IP on the network I use SuzieQ's network find feature in the CLI:

Using the Swagger interface for the equivalent query, I get something like this in the Request URL section. This really tells us all we need to know.

Now looking at the function network_find, you can see that I paste that Request URL in there as a comment.  I used it a guide to craft the two variables I need to send to the try_sq_rest_call.

The URI path is nothing more than the URL after the server ip and port number. It maps exactly to what I typed in the CLI network find.

The URI options represent the details of the query. In this case the IP address we are looking for and in its simplest form we ask for the latest information. The optional view variable defaults to "latest" but if you call the function with view="all" then you will get all the information for that ip that SuzieQ has captured ever since it started monitoring.

Network Changes

The App uses Netmiko to log in to the switch, pull a few show commands, and make the vlan change if all the checks pass.

So that you are not hardcoding network device passwords into your code, we use python-dotenv to load configuration variables which are then used by the scripts.

Notice that there is a .env_sample file in the repository.  Copy that file and rename it to .env (if you are Windows user make sure an extension does not get applied to that file, it must be .env not .env.txt).

Once you have your .env file, you can update it with your credentials.  Below is an example of mine.

SQ_API_TOKEN="bearer token"
INET_USR="cisco"
INET_PWD="cisco"
INET_SEC="cisco"

On a Linux or Linux based host, you can lock this file down so no one can open it but you.

For more information on handling credentials this post may give you some ideas.

How Network Engineers Can Manage Credentials and Keys More Securely in Python


Lets see the App in action

The device was not found on the network

In this situation, the workflow cannot proceed and ends with an error.  While we have historical information about when the device has been on the network and where, our first criteria for making a change is that the device be on the network now.

The device is on the network but its interface or port cannot be determined

In this case the device has been seen on the network but the interface its connected to cannot be determined.

All checks passed

In this case we found the device, it is on the network now and we know exactly where it is. We've presented the user with a list of vlans available at that location. They selected the new vlan and we made sure it is available on the switch.

In this situation, all our criteria for proceeding with the change have been met and it is safe to move the device change the configuration of the port to the new vlan.


What is missing?

Handy little App but in a production environment it would look a little different.

- User Authentication (and some business rules around who can use this self serve feature, anyone or maybe authorized individuals at a location?)
- Using HTTPS
- Robust web site with certificate (this can be done with Streamlit and NGINX)
- Using SuzieQ Enterprise for RBAC
- Using SuzieQ Enterprise for Spanning Tree analysis
- Using SuzieQ Enterprise to determine how the device obtains its IP (ARP and DHCP snooping)
- Using SuzieQ Enterprise for its speed
- a robust implementation for running the SuzieQ server and it services (systemd, etc.)

In addition, the App should have much more error checking!

What I didn't check in this example.

Is the vlan functional?

Checking to make sure the vlan is configured on the relevant switch is necessary but not sufficient.

It is also important to make sure the the vlan is actually working.

In a production environment with SuzieQ Enterprise, I do a REST call to check STP and make sure it has root.

Since that feature is not in the open source, I would make sure its trunked on the uplink (finding the uplink can be challenging) and I might look to see if other access ports are on that vlan and maybe "infer" that the vlan is working.

Since we have netmiko already I could also send a "show spanning-tree vlan {new_vlan}", parse out the results and check myself.

How is the users device getting its new IP Address?

It is an option to limit this "self service" to devices that use DHCP but how can you tell that from the network side of things?

If you use DHCP snooping then you could look up the IP. If you find it in the DHCP snooping output then it uses DHCP otherwise you can infer that its configured statically on the device.

With the open source you will need to run those queries yourself and parse out the output. SuzieQ Enterprise captures this information (if its configured on the network).

Even assuming that there is a DHCP scope for that subnet can be dangerous and should be verified!  Presumably, since one of our "rules" was to only present vlans already configured at the location we can assume that this has already been taken care of but you know what they say about assumptions.


Conclusion

This little exercise is another example of the value network observability brings to network operations.   Network engineers are not going away.  It is the network engineer working with the business that will define the conditions under which network changes can be made in an automated manner. Observability tools like SuzieQ are making it easy to make sure the state is as you expect (now or in the past) so that changes can be pushed safely and the expected outcome tested.  These tools ensure steps are not skipped due to inattention, assumption, urgency, and/or lack of time.

The ability to automate these checks makes automation in brownfield environments without the latest and greatest equipment possible!

Having this rich set of network state over time at our fingertips, ready for programmatic access, is the missing piece of the puzzle for automating network workflows.

One final point in closing.  I try to make sure I leave you with examples that are free (well, not counting your time!). I've mentioned the Enterprise version of SuzieQ a number of times here because its value is so great.

Can we do all those checks manually (get commands, parse them out, do my checks)? Yes but looking at the network state in the past is a challenge without tools like SuzieQ.

I hope this little example has sparked some ideas for your next network automation project!


https://elsewhere.scdn3.secure.raxcdn.com/images/v95000/articles/No10UppingStcover.jpg

In case you missed the B.A.D reference (Dial a Hitman Music)


Python Module Use

  • suzieq
    • Network Observability
  • netaddr
    • Obtain MAC Vendor OUI
  • streamlit
    • Web Framework for the User Interface
  • requests
    • Used to send HTTP requests to the SuzieQ REST API
  • pandas
    • Used to format tables more easily
  • python-dotenv
    • Used to load credentials from environment variables

Additional Information

SuzieQ (v0.22) tip if getting errors from ciscoconfparse
pip install ciscoconfparse==1.7.24
* after installing the virtual environment modules from requirements.txt

More on ps -ef
https://linuxhandbook.com/ps-ef-examples/

More on Linux &
https://bashitout.com/2013/05/18/Ampersands-on-the-command-line.html