Using the pyaoscx Package
Using the pyaoscx package
For instructions on how to install the latest version of the pyaoscx
package follow the instructions in the Installing pyaoscx v2 guide.
pyaoscx
v2.0.0+ Package Structure
pyaoscx
v2.0.0+ Package Structurepyaoscx
│ README.md
│ CONTRIBUTING.md
│ ...
│
└───pyaoscx
│ │ CONTRIBUTING.md
│ │ DESIGN.md
│ │ acl.py
│ │ acl_entry.py
│ │ ...
│
└───docs
│ │ ...
│
└───workflows
│ workflow.py
The pyaoscx
package is a directory containing files and subdirectories. Contained directly within the top level pyaoscx
directory are informative files such as the readme, licensing information, contribution guidelines, and release notes. Also contained directly within the top level directory are the relevant code-containing directories pyaoscx
and workflows
.
Using pyaoscx
Modules
pyaoscx
ModulesThe pyaoscx
subfolder contains the AOS-CX Python modules which uses the object-oriented approach. Instead of having separate modules to perform specific operations, it connects several features together to represent the operational state of the switch. This allows users to keep track of the switch configuration in its objects and internal data structures.
Every single feature is represented in a class, classes may contain and depend on references on additional classes or features. For example, the Interface
represents a specific Interface, and it may contain references to other VLANs
, VRFs
, and depending on the use case, the VSF
or VSX
configuration. Detailed module documentation can be found on the pyaoscx
readthedocs.
Each module contains function definitions which either make a single REST API call or multiple REST API calls. Each function that makes multiple REST API calls is written as such to perform a small logical low-level process (e.g. one call creates a VLAN and the next creates a corresponding VLAN interface). The REST API calls are performed using the Python requests
library, which provides functions to make HTTP GET, PUT, POST, and DELETE requests. Information about the requests
library can be found here.
All module or feature creation is managed through a flag attribute materialized. This attribute will be True
if the module exists within the device, False
otherwise. This will be updated whenever a POST or GET call is executed.
Each pyaoscx Module has a list of important attributes besides materialized:
session
: used to make the HTTP requests, among other things.config_attrs
: list of attributes writable to each specific object- original_attributes: dictionary with object information and attributes right
after performing a GET request. modified
: Flag to verify if object was modified, in case it was not the PUT
request is not made.
Design document available
Our design document is available in our Github repository and outlines the structure of the
pyaoscx
package and how to use it.
Using the pyaoscx
Package
pyaoscx
PackageAfter installing the package, you'll be able to run and create your own workflows.
There's an example workflow available in the Github repository that you can pull and use as a template for custom workflows.
First clone the repository:
ubuntu-vm$ git clone https://github.com/aruba/pyaoscx.git
Change into the newly cloned repository and enter the /workflows/
directory to view the workflow.py
file:
ubuntu-vm$cd pyaoscx/
ubuntu-vm$cd workflows/
ubuntu-vm$pwd
/home/sandbox/pyaoscx/workflows
ubuntu-vm$ls
__init__.py workflow.py
In this object oriented approach there are two ways to configure the AOS-CX platform, the open granulated approach and the imperative factory approach. Both methods require a Session
object which is used as the primary connection source to the AOS-CX switch.
from pyaoscx.session import Session
version = "10.04"
switch_ip = "172.25.0.2"
s = Session(switch_ip, version)
s.open("admin", "admin")
Once you have your Session
object you can begin configuring features of the AOS-CX switch using Classes and functions. In the example workflow.py
file provided in the repository, it shows the two different approaches to configuring features using the pyaoscx
package:
from pyaoscx.session import Session
from pyaoscx.pyaoscx_factory import PyaoscxFactory
from pyaoscx.vlan import Vlan
from pyaoscx.interface import Interface
# There are two approaches to workflows, both using the session.
version = "10.04"
switch_ip = "172.25.0.2"
s = Session(switch_ip, version)
s.open("admin", "admin")
# Try block is used so that session closes even on error.
try:
# APPROACH 1: OPEN GRANULATED APPROACH
# VLAN
# Create Vlan object -- Not yet materialized
vlan100 = Vlan(s, 100, name="VLAN 100", voice=True)
# Since object is not materialized, performs
# a POST request -- This method internally
# makes a GET request right after the POST
# Obtaining all attributes VLAN related
vlan100.apply()
# Now let's create another object, that we know already exists
# inside of the Switch
vlan1 = Vlan(s, 1)
# Perform a GET request to obtain all data and materialize object
vlan1.get()
# Now, we are able to modify the objects internal attributes
vlan1.voice = True
# Apply changes
changed = vlan1.apply()
# If changed is True, a PUT request was done and object was modified
vlan100.description = "New description, changed via pyaoscx SDK"
vlan100.apply()
# Now vlan100 contains the description attribute
print("VLAN 100 description {0}".format(vlan100.description))
# ===========================================================
# ===========================================================
# ===========================================================
# APPROACH 2: IMPERATIVE FACTORY APPROACH
# VLAN
# Create Factory object, passing the Session Object
factory = PyaoscxFactory(s)
# Create Vlan object
# If vlan is non-existent, Factory instantly creates it
# inside the switch device
vlan200 = factory.vlan(200, "NAME200")
# Now the granulated approach could still be used.
# Or an imperative method too
# ===========================================================
# ===========================================================
# ===========================================================
# More complex example using the OPEN GRANULATED APPROACH
# Create an Interface object
lag = Interface(s, "lag1")
lag.apply()
# Create a Vlan object
vlan_1 = Vlan(s, 1)
# In this case, now that the VLAN exists within the Switch,
# a GET request is called to obtain the VLAN's information.
# The information is then added to the object as attributes.
vlan_1.get()
# Interfaces/Ports added to LAG
port_1_1_11 = Interface(s, "1/1/11")
port_1_1_11.get()
# Make changes to configure LAG as L2
lag.admin = "down"
lag.routing = False
lag.vlan_trunks = [vlan_1]
lag.lacp = "passive"
lag.other_config["mclag_enabled"] = False
lag.other_config["lacp-fallback"] = False
lag.vlan_mode = "native-untagged"
lag.vlan_tag = vlan_1
# Add port as LAG member
lag.interfaces.append(port_1_1_11)
# Apply changes
lag.apply()
# ===========================================================
# ===========================================================
# ===========================================================
# Same complex example using the IMPERATIVE FACTORY APPROACH
# PLUS USING IMPERATIVE METHODS
# Create the Interface object
lag2 = factory.interface("lag2")
modified = lag2.configure_l2(
description="Created using imperative method",
admin="up",
vlan_mode="native-untagged",
vlan_tag=1,
trunk_allowed_all=True,
native_vlan_tag=True,
)
# If modified is True, a PUT request was done and object was modified
except Exception as error:
print("Ran into exception: {0}. Closing session.".format(error))
finally:
# At the end, the session MUST be closed
s.close()
Creating Custom Workflows
Similar to the provided example, you'll need to create your Session
object in order to create a connection to the AOS-CX device. Alternatively, if you're hesitant in storing switch credentials in plaintext, you're able to use Python libraries to either get credentials at runtime or store them in an encrypted file using Vault.
Once you have your Session
object you can begin configuring features of the AOS-CX switch using Classes and functions. The below example creates a Device
object
In the below example you can see the Vlan
and Interface
Classes are used to create VLAN100 and configure an interface 1/1/14
with access to the newly created VLAN:
from pyaoscx.session import Session
from pyaoscx.vlan import Vlan
from pyaoscx.device import Device
from pyaoscx.interface import Interface
# OPTIONAL: Disable WARNINGS that occur when using insecure connection
# with self-signed cert
import urllib3
urllib3.disable_warnings()
# There are two approaches to workflows, both using the session.
version = "10.04"
switch_ip = "172.25.0.2"
s = Session(switch_ip, version)
# OPTIONAL: retrieve username & password through keyboard input
# at runtime, requires getpass4 python library
from getpass4 import getpass
username = input("Enter Username: ")
password = getpass('Password: ')
s.open(username, password)
switch = Device(s)
# Try block is used so that session closes even on error.
try:
vlan100 = switch.vlan(100)
# Example of creating an object and setting attributes to configure
vlan100.voice = True
# apply() must be called on the object to apply the configuration
# vlan100.materialized will be true if configuration exists on switch
# and application was successful
vlan100.apply()
interface = switch.interface('1/1/14')
interface.admin_state = "up"
interface.apply()
# using functions directly on an object will call apply() in the
# background and therefore not necessary
interface.configure_l2(
vlan_mode="access",
vlan_tag=int(vlan100.id)
)
except Exception as error:
print("Ran into exception: {0}. Closing session.".format(error))
finally:
# At the end, the session MUST be closed
s.close()
Updated about 2 months ago