Automation
Automation

Using Python to script CoS on EX / QFX switches

by lacko on ‎08-24-2018 01:57 PM

The Challenge of Scripting

Have you ever been faced with the challenge of querying or changing the configuration of several hundreds or even thousands of devices on your network? Have you ever considered using Python language to create a script that analyses the current configuration and makes changes accordingly? If the answer is yes to any of these questions, you may be interested in reading this article.

 

I want to introduce you to the Pretty Good Terminal and its usage for large scale scripting deployment because I do believe it is an extremely powerful network automation tool, and all who face similar challenges might find it a good friend. Important to mention here, that the software and below mentioned functionality is completely free for personal use.

  

A Visual Script using Python

PGT has the concept of Visual Script, which is basically an active flowchart. Each element in the script can issue CLI commands and process the result, collecting information and store them in variables for later decisions.

 

The flow of execution will be determined by the connections between elements. Each connector will evaluate a logical expression, and in case it returns True, execution will continue with the connected element.

 

This flowchart is called the vScript and PGT will execute the vScript on a list of devices given by there ip address. Telnet / SSH and jump server connection management – including credential management - is fully controlled by the internal scripting engine, therefore the vScript itself will need to take care only device configuration.

 

For this example I will use Python, but the programming language behind the visual elements may also be C#.

 

Designing the script

Last time I was tasked to roll out a CoS configuration template to all EX and QFX series switches in the network, meaning some 500 devices.  Armed with the aforementioned tool-set, I transformed the requirements to a script flow shown below:

 

1.png

 

The script begins with some checks to see what device it will be operating on, then if all matches it will start the configuration.

 

For instance, the GetVersion element issues the CLI command "show version" and parses the result in order to determine the make and model of the device connected. The CLI command to send is static -always the same – therefore it is hard coded in this command element and is specified on the Commands tab:

 2.png

 

After the command gets executed, the text returned will be split line by line and presented as a list of strings in local variable called self.aCommandResult. The Main Code of the command element will parse this text to populate some attributes of the GetVersion  object:

 

3.png

 

The attributes of the GetVersion object are listed on the Attributes tab. The purpose of them is to make the information public for other objects in the script to make decisions or use them in any other way:

 

4.png

 

 

For instance,  script execution will only continue from “GetVersion” to “CheckVCMode” command if the “GetVersion_ChekVCMode” connector evaluates the below condition to True. And the condition is referencing the attributes of GetVersion command element that it has determined in previous step:

 

 

5.png

 

If the “GetVersion_ChekVCMode” connector is evaluated to False, execution would continue to the “Not Supported” STOP element and script would be finished. This is because that connector is set to always return True. To report the problem, the “Not Supported” element sets the Action Result script variable:

 

6.png

 

When all preliminary checks have passed, the configuration part commences:

 

 7.png

 

The key element here is the yellow “QoS config check” object. This object is a collection of methods wich can be called from several other command elements, hence it is not part of the logical flow of execution.

 

It also holds the predefined CoS template for EX and QFX switches to be configured on the devices and will perform a comparison of the current configuration to the template.

 

8.png

 

The object’s Python code contains a single function, called “CheckConfiguration”. Once called, it will execute the command “show configuration class-of-service | display set” and compare the result to the appropriate template. As this object is not a command element, there is no placeholder to define any CLI command, but rather it will use the Session global variable and its ExecCommand method to send the CLI command and collect the result:

 

9.png

 

The actualConfiguration (string list) variable will then be used to make the comparison, and the results are two Python sets:

 

  • MissingFromConfiguration : is a set of CoS commands that are missing from the actual configuraton;
  • InAdditionToTemplate : is list of CoS commands the device currently has beyond the template.

 10.png

 

These lists will be used to actualize the configuration :

  • Add the missing “set” commands;
  • Delete the unnecessary configuration;

 

When in the configuration block, the aforementioned sets are already holding the calculated elements because the CheckConfiguration method had been called by Check Configuration command element at the beginning of the script to decide what action to take.  Therefore, the “Configure QoS” element only has to execute commands contained in the list:

 

11.png

 

Should anything go wrong during the command execution, an exception would be generated setting the ExecError attribute to True and also the RollbackReason attribute to the exception message.

 

Developing the script

Of course, not any script would work correctly without first testing and debugging. For this reason a lightweight Python debugger was also built into PGT. As the script is started and elements get the focus in the execution path, the code will break at the breakpoints set and variable values can be examined or the code can be executed step-by-step:

 

12.png

 

Python script files

Above I illustrated the usage of Visual Scripts, but normal Python scripts files can also be created, debugged and deployed much the same way. In this context PGT can be considered a Python script manager that runs the scripts while providing advanced hosting services. When you write, or debug the script, the Python Interactive console will help you with context sensitive code-completion and quick watch of variables.

 

Deploying the script

Once you have created and tested a script, the time will come to deploy it on real devices. This can be a cumbersome task for many reasons, like some devices not available at a time, the connection fails for any reason or authentication fails. At the end of the day, you will need to find some way to keep records of what happened on which device.

 

But PGT will also support you in this effort. You can use the Scripting Project Manager plugin for all of the above steps, and it will also provide you charts on results:

 

13.png

 

It is beyond the scope of this article to describe how SPM works, but in case you are interested, you will find a good training video on the website explaining how to use this tool.

 

Why would you use PGT ?

The question is, why would you use Pretty Good Terminal to host and run Python scripts, when you could simply start a script with Python itself ?  What is the added value or benefit of using it ?

As PGT was originally developed for router/switch mass configuration, it's scripting engine was specifically designed for scripting thousands of devices by mastering Telnet and SSH connections over multiple hops of jump servers and collecting the script results in a sophisticated way. As a .NET based application written in C#, PGT can actually host Python scripts using IronPython. This way you can consider PGT as Python script manager providing advanced services for scripts, such as: 

 

  • Connection management: PGT will manage all Telnet / SSH connection to devices, even if a device is reachable through multiple jump servers.
  • Script result handling: The simple communication interface between PGT and the Python scripts make it very easy to capture and maintain the script results
  • Robust logging facility: The built-in LogManager will provide simple and yet thread safe logging services for scripts, even if the same script is run in multiple instances at the same time
  • Lightweight debugging: The built-in Python Interactive console will provide easy script debugging
  • Intelligent code editor: The Python Interactive console provides auto code-completion and intelli-sense feature to help you writing or editing Python sctips
  • Script repository: Python Scripts are assigned an alias name in the repository and PGT scripts (connection lists, if you like) can easily refer to them.

Should you have any questions you can reach me here, on LinkedIn, or via the contact form on PGT's website.