Overview
This chapter provides an overview and installation information needed to use the Python application programming interface (API) support on Cisco Nexus 3000 Series switches.
Information About the Python API
Python is an easy-to-learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python’s elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms.
The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the Python website:
http://www.python.org/
The same site also distributes and points to many free third-party Python modules, programs and tools, and additional documentation.
The Cisco Nexus 3000 Series switches support all the features available in Python v2.7.5.
The Python scripting capability on the Cisco Nexus 3000 Series switches allows you to perform the following tasks:
- Running a script to verify configuration on switch bootup.
- Backing up a configuration.
- Proactive congestion management by monitoring and responding to buffer utilization characteristics.
- Integration with the Power-On Auto Provisioning or EEM modules.
- Ability to perform a job at a specific time interval (such as Port Auto Description).
- Programmatic access to the switch command-line interface (CLI) to perform various tasks.
Python can also be accessed from the Bash shell.
Installing Python
The Python interpreter is available by default in the Cisco NX-OS software.You can invoke Python by entering the python command, and you can write scripts to access Cisco NX-OS APIs by importing the cisco.py module using the import cisco command.
Cisco Python Package
Cisco NX-OS provides a Cisco Python package that enables access to many core network device modules, such as interfaces, VLANs, VRFs, ACLs and routes. You can display the details of the Cisco Python package by using the help() command. To obtain additional information about the classes and methods in a module, you can run the help command for a specific module. For example, help(cisco.interface) displays the properties of the cisco.interface module.
The following is an example of how to display information about the Cisco python package:
/isan/python/scripts/cisco/__init__.py
Installing Third Party Pure Python Packages
You can install the third-party pure Python package by copying mypkg.tgz on your server. Perform the following steps to extract and install the third-party package:
- Secure-copy the tar file by executing the copy scp://user@server/path/to/mypkg.tgz bootflash:mypkg.tgz vrf management command.
- Untar the mypkg.tgz file by using the tar extract bootflash:mypkg.tgz command.
- Move the extracted file to bootflash by using the move bootflash:mypkg-1.2/* bootflash: command.
- You can install the package by using the python setup.py install command.
- Remove the copied file from bootflash.
- You can use the third-party package in scripts or in the Python shell.
Note You will be able to install the third-party packages using the easy_install command in future releases.
Using Python
This section describes how to write and execute Python scripts by passing parameters and includes the following topics:
Entering the Python Shell
You can enter the Python shell by using the python command without any parameters.
Note The Python interpreter is designated with the ">>>" or "…" prompt.
Python 2.7.5 (default, May 16 2014, 10:58:01)
Type "help", "copyright", "credits" or "license" for more information.
Executing Scripts
You can execute a Python script by using the python filename command.
Passing Parameters to the Script
You can execute a Python script by using the python filename [arg1, arg2, arg3, ...] command.
switch# python test.py abc xyz 1 2
['/bootflash/test.py', 'abc', 'xyz', '1', '2']
Using the CLI Command APIs
The Python programming language uses three APIs that can execute CLI commands. These APIs are available within the Python Cisco Package and are listed in the following table. The arguments for these APIs are strings of CLI commands. To execute a CLI command through the Python interpreter, you must type the CLI command as an argument string of one of the following APIs:
Table 1-1 CLI Command APIs
|
|
cli() Example: Status, output = cli (“cli-command”) |
Returns the raw output and error code of CLI commands, including control/special characters. Status 0 means that the CLI cmd ran successfully.
Note The interactive Python interpreter prints control/special characters 'escaped'. A carriage return is printed as '\n' and gives results that might be difficult to read. The clip() API gives results that are more readable.
|
clid() Example: json_string = clid (“cli-command”) |
For CLI commands that support XML, this API returns JSON output.
Note An exception is thrown when XML is not used.
This API can be useful when searching the output of show commands. |
clip() Example: clip (“cli-command”) |
Prints the output of the CLI command directly to stdout and returns nothing to Python.
Note clip (“cli-command”) is equivalent to r=cli(“cli-command”) print r
|
When two or more commands are run individually, the state is not persistent from one command to subsequent commands.
In the following example, the second command fails because the state from the first command does not persist for the second command:
>>> cli("interface eth4/1")
When two or more commands are run together, the state is persistent from one command to subsequent commands.
In the following example, the second command is successful because the state persists for the second and third commands:
>>> cli("conf t ; interface eth4/1 ; shut")
Note Commands are separated with " ; " as shown in the example. (The ; must be surrounded with single blank characters.)
Display Formats
The following examples show various display formats by using the Python APIs:
Example 1
>>> cli('conf t ; interface Eth1/1 ; description +from-Python+')
>>> clip('show running int eth 1/1')
!Command: show running-config interface Ethernet1/1
!Time: Mon Jul 28 08:56:14 2014
description +from-Python+
Example 2
>>> cli('show run int eth 1/1')
(0, '\n!Command: show running-config interface Ethernet1/1\n!Time: Mon Jul 28 08:57:28 2014\n\nversion 6.0(2)U4(1)\n\ninterface Ethernet1/1\n description +from-Python+\n\n')
Example 3
>>> from cisco.cli import clid
>>> out=json.loads(clid('show version'))
... print "%30s = %s" % (k, out[k])
kick_file_name = bootflash:///EI-828.k
module_id = 32x40G Supervisor
kick_tmstmp = 07/25/2014 21:15:22
isan_file_name = bootflash:///EI-828.s
sys_ver_str = 6.0(2)U4(1) [build 6.0(2)U4(0.828)]
kickstart_ver_str = 6.0(2)U4(1) [build 6.0(2)U4(0.828)]
kick_cmpl_time = 7/25/2014 13:00:00
chassis_id = Nexus 3132 Chassis
proc_board_id = FOC170170JK
cpu_name = Intel(R) Core(TM) i3- CPU @ 2.00GHz
bios_cmpl_time = 10/15/2013
isan_tmstmp = 07/26/2014 15:43:16
rr_reason = Reset Requested by CLI command reload
rr_ctime = Sun Jul 27 17:26:11 2014
header_str = Cisco Nexus Operating System (NX-OS) Software
TAC support: http://www.cisco.com/tac
Documents: http://www.cisco.com/en/US/products/ps9372/tsd_products_support_series_home.html
Copyright (c) 2002-2014, Cisco Systems, Inc. All rights reserved.
The copyrights to certain works contained herein are owned by
other third parties and are used and distributed under license.
Some parts of this software are covered under the GNU Public
License. A copy of the license is available at
http://www.gnu.org/licenses/gpl.html.
isan_cmpl_time = 7/25/2014 13:00:00
power_seq_ver_str = Module 1: version v2.1
Embedded Event Manager Support
Embedded Event Manager (EEM) supports the invocation of Python scripts based on events. Syslog for events can be passed to a Python script by using the variable $ command.
The following example shows EEM invoking a python script for an IF_DOWN event.
EEM configuration:
switch(config)# event manager applet if-mon
switch(config-applet)# event syslog pattern "*IF_DOWN.*"
Configuration accepted successfully
switch(config-applet)# action 1.0 cli python if-mon.py eth1/1 $command
switch(config-applet)# end
Python script:
x = re.compile ('[Ee]thernet\d+\/\d+')
print 'Starting my script.. args:'
print 'Detected shut on interface %s' % intf
print ('---------show run int %s---------\n%s\n' % (intf, i.show().raw_output))
print ('----------------------\n%s\n' % o)
print 'Restoring interface %s' % intf
i.set_description ('++dont shut++')
print ('----------------------\n%s\n' % o)
print ('---------show run int %s---------\n%s\n' % (intf, i.show().raw_output))
Python Integration with Cisco NX-OS Network Interfaces
On Cisco Nexus 3000 Series devices, Python is integrated with the underlying Cisco NX-OS network interfaces. You can switch from one virtual routing context to another by setting up a context through the cisco.vrf.set_global_vrf() API.
The following example shows how to retrieve an HTML document over the management interface of a Cisco Nexus 3000 Series device. You can also establish a connection to an external entity over the inband interface by switching to a desired virtual routing context.
Python 2.7.5 (default, May 16 2014, 10:58:01)
Type "help", "copyright", "credits" or "license" for more information.
>>> set_global_vrf('management')
>>> page=urllib2.urlopen('http://172.23.40.211:8000/welcome.html')
>>> help(cisco.vrf.set_global_vrf)
Help on function set global vrf in module cisco.vrf:
Sets the global vrf. Any new sockets that are created (using socket.socket)
will automatically get set to this vrf (including sockets used by other
vrf: VRF name (string) or the VRF ID (int).
Cisco NX-OS Security with Python
Cisco NX-OS resources are protected by the Cisco NX-OS Sandbox layer of software and by the CLI role-based access control (RBAC).
All users associated with a Cisco NX-OS network-admin or dev-ops role are privileged users. Users who are granted access to Python with a custom role are regarded as non-privileged users. Non-privileged users have a limited access to Cisco NX-OS resources, such as file system and Bash commands. Privileged users have greater access to all the resources of Cisco NX-OS.
Examples of Security and User Authority
RBAC controls CLI access based on the login user privileges. A login user's identity is given to Python that is invoked from the CLI shell or from Bash. Python passes the login user's identity to any subprocess that is invoked from Python.
The following is an example for a privileged user:
'11:28:53.845 AM UTC Sun May 08 2011\n'
>>> cli('configure terminal ; vrf context myvrf')
>>> clip('show running-config l3vm')
!Command: show running-config l3vm
!Time: Sun May 8 11:29:40 2011
The following is an example for a non-privileged user:
'11:18:47.482 AM UTC Sun May 08 2011\n'
>>> cli('configure terminal ; vrf context myvrf2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/isan/python/scripts/cli.py", line 20, in cli
raise cmd_exec_error(msg)
errors.cmd_exec_error: '% Permission denied for the role\n\nCmd exec error.\n'
The following example shows an RBAC configuration:
switch# show user-account
this user account has no expiry date
this user account has no expiry date
roles:network-operator python-role
switch# show role name python-role
Description: Python show role
vsan policy: permit(default)
Vlan policy: permit(default)
Interface policy: permit(default)
Vrf policy: permit(default)
-------------------------------------------------------------------
Rule Perm Type Scope Entity
-------------------------------------------------------------------
2 permit command python *
Example of Running Script with Scheduler
The following example shows a Python script that is running the script with the scheduler feature:
switchname = cli("show switchname")
user = os.environ['USER']
msg = user + " ran " + __file__ + " on : " + switchname
# Save this script in bootflash:///scripts
Enter configuration commands, one per line. End with CNTL/Z.
switch(config)# feature scheduler
switch(config)# scheduler job name testplan
switch(config-job)# python bootflash:///scripts/testplan.py
switch(config)# scheduler schedule name testplan
switch(config-schedule)# job name testplan
switch(config-schedule)# time start now repeat 0:0:4
Schedule starts from Mon Mar 14 16:40:03 2011
switch(config-schedule)# end
2011 Mar 14 16:38:03 switch %VSHD-5-VSHD_SYSLOG_CONFIG_I: Configured from vty by admin on 10.19.68.246@pts/2
switch# show scheduler schedule
------------------------------
Schedule Type : Run every 0 Days 0 Hrs 4 Mins
Start Time : Mon Mar 14 16:40:03 2011
Last Execution Time : Yet to be executed
-----------------------------------------------
Job Name Last Execution Status
-----------------------------------------------
==============================================================================
switch# 2011 Mar 14 16:40:04 switch %USER-1-SYSTEM_MSG: No user ran /bootflash/scripts/testplan.py on : switch - nxpython
2011 Mar 14 16:44:04 switch last message repeated 1 time
Calculating MD5 Checksum
Every time you make a change to the configuration script, ensure that you recalculate the MD5 checksum. The following example shows the script to be run in a bash shell to recalculate the MD5 checksum:
#md5sum="13f71ffebe16cc6143a6af2186b40948"
# If any changes to this script file are made, please run the below command
# in bash after modifications.
# The above is the (embedded) md5sum of this file taken without this line,
# can be # created this way if using a bash shell:
# f=poap_fabric.py ; cat $f | sed '/^#md5sum/d' > $f.md5 ; sed -i "s/^#md5sum=.*/#md5sum=\"$(md5sum $f.md5 | sed 's/ .*//')\"/" $f
# This way this script's integrity can be checked in case you do not trust
# tftp's ip checksum. This integrity check is done by /isan/bin/poap.bin).
# The integrity of the files downloaded later (images, config) is checked
# by downloading the corresponding file with the .md5 extension and is
# done by this script itself.