aruba / pyaoscx Goto Github PK
View Code? Open in Web Editor NEWPython modules for AOS-CX
License: Apache License 2.0
Python modules for AOS-CX
License: Apache License 2.0
I try to use pyaoscx (2.1.0) for update vlan information based on workflow.py script
i write the following script
from pyaoscx.session import Session
from pyaoscx.pyaoscx_factory import PyaoscxFactory
from pyaoscx.vlan import Vlan
from pyaoscx.interface import Interface
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# There are two approaches to workflows, both using the session.
version = '10.04'
switch_ip = '10.200.11.225'
s = Session(switch_ip, version)
s.open('admin', 'MyPassword')
try:
vlan100 = Vlan(s, 100)
vlan100.get()
print ("vlan100 {}".format(vlan100))
#update vlan 100 (voice and description)
vlan100.voice = True
vlan100.name = "My Vlan"
vlan100.description = "My description"
print ("vlan100 {}".format(vlan100))
vlan100.apply()
vlan100.get()
print ("vlan100 {}".format(vlan100))
# ===========================================================
# ===========================================================
# ===========================================================
except Exception as error:
print('Ran into exception: {}. Closing session.'.format(error))
finally:
# At the end, the session MUST be closed
s.close()
but don't work :
vlan100 Vlan, name: 'vlan100' ID: '100' and description: 'None'
vlan100 Vlan, name: 'My Vlan' ID: '100' and description: 'My description'
vlan100 Vlan, name: 'vlan100' ID: '100' and description: 'None'
Hello,
i found an issue with getting the MAC addresses if a VRRP is configured and i would consider this as a bug. This is also used in other modules for example when getting a VLAN via VLAN.get(session,vlan_id)
.
When there is a VRRP configured for a VLAN the variable mac['port']
equals None.
Line 214 in 648cfc7
As far is i know this is right as there is no logical or physical Port assigned to the virtual MAC address of the VRRP. Still this is leading to an error, because later on api.py tries to access the items of mac['port']
.
Before that the variable is handed over to interface.py as response_data
:
Lines 365 to 382 in 648cfc7
After this response_data
is handed over to api.py. Which finally tries to access the items of response_data
which then leads to the Error "Ran into exception: 'NoneType' object has no attribute 'items'. Closing session."
Lines 84 to 101 in 648cfc7
This happens because it is not checked at any point either if the current MAC address is a VRRP or if the port of the MAC address equals None. Those two points mentioned could also be a possible solution in my opinion which could be implemented via changing line 214 in mac.py to one of the following snippets:
Check if the port of the MAC address is None
if mac['port'] is not None:
mac_obj.port = Interface.from_response(session, mac["port"])
else:
mac_obj.port = None
Check if the given MAC address is configured via a VRRP
if 'vrrp' not in indices:
mac_obj.port = Interface.from_response(session, mac["port"])
else:
mac_obj.port = None
Those are just suggestions and i don't know if they are implemented in the right way to work for every usecase of pyaoscx.
Hi,
There is plan to adding TACACS/RADIUS Server support (and AAA Group) for configure RBAC of switches ?
The 6200 doesn't support BGP,
swagger on the 6200 shows the BGP method:
https://<ip of 6200>/rest/v10.04/system/vrfs/default/bgp_routers
However it returns a 404
unknown attribute for VRF: bgp_routers
In ansible aoscx_l3_interface on a 6200 (or 6100 which would be an issue anyway as the 6100 does not support Routed only ports) will throw an error as it's not handling this response, which is valid given the devices don't support it.
Traceback (most recent call last):
File "/home/wade/.ansible/tmp/ansible-local-24017e3clgz02/ansible-tmp-1642567562.535256-24022-51633859472383/AnsiballZ_aoscx_l3_interface.py", line 107, in <module>
_ansiballz_main()
File "/home/wade/.ansible/tmp/ansible-local-24017e3clgz02/ansible-tmp-1642567562.535256-24022-51633859472383/AnsiballZ_aoscx_l3_interface.py", line 99, in _ansiballz_main
invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
File "/home/wade/.ansible/tmp/ansible-local-24017e3clgz02/ansible-tmp-1642567562.535256-24022-51633859472383/AnsiballZ_aoscx_l3_interface.py", line 47, in invoke_module
runpy.run_module(mod_name='ansible_collections.arubanetworks.aoscx.plugins.modules.aoscx_l3_interface', init_globals=dict(_module_fqn='ansible_collections.arubanetworks.aoscx.plugins.modules.aoscx_l3_interface', _modlib_path=modlib_path),
File "/usr/lib64/python3.8/runpy.py", line 207, in run_module
return _run_module_code(code, init_globals, run_name, mod_spec)
File "/usr/lib64/python3.8/runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "/usr/lib64/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/tmp/ansible_aoscx_l3_interface_payload__jl9wziz/ansible_aoscx_l3_interface_payload.zip/ansible_collections/arubanetworks/aoscx/plugins/modules/aoscx_l3_interface.py", line 314, in <module>
File "/tmp/ansible_aoscx_l3_interface_payload__jl9wziz/ansible_aoscx_l3_interface_payload.zip/ansible_collections/arubanetworks/aoscx/plugins/modules/aoscx_l3_interface.py", line 217, in main
File "/home/wade/.local/lib/python3.8/site-packages/pyaoscx/pyaoscx_module.py", line 48, in is_materialized
return fnct(self, *args, **kwargs)
File "/home/wade/.local/lib/python3.8/site-packages/pyaoscx/interface.py", line 1114, in configure_l3
vrf_obj.get()
File "/home/wade/.local/lib/python3.8/site-packages/pyaoscx/pyaoscx_module.py", line 33, in ensure_connected
return fnct(self, *args, **kwargs)
File "/home/wade/.local/lib/python3.8/site-packages/pyaoscx/vrf.py", line 159, in get
BgpRouter.get_all(self.session, self)
File "/home/wade/.local/lib/python3.8/site-packages/pyaoscx/bgp_router.py", line 197, in get_all
raise GenericOperationError(response.text, response.status_code)
pyaoscx.exceptions.generic_op_error.GenericOperationError: GENERIC OPERATION ERROR: unknown attribute for VRF: bgp_routers
Code: 404
From the looks of it we need to either handle the unknown attribute for VRF: bgp_routers
and set to None or whatever we need to denote BGP is not configured, or ideally look at the model/capabilities of the switch and skip the API call entirely for the models that don't support it.
FYI: the 6200 supports Routed Only Ports, but only after setting system internal-vlan-range
I expect the l3_interface module doesn't check for that today, as it's quirk specific to the 6200.
Hello,
apologies if this is not the right location.
Using python 3.8 and latest pyaoscx in pip
I've been trying to use this library to get all the VLANs, their MAC addresses and which interface each MAC address is on.
https://github.com/aruba/pyaoscx/blob/master/pyaoscx/mac.py#L142 has a bit about port
is under get() - but it's not under get_all() so I'm thinking maybe it's not possible?
Do you have some suggestion for how one could get this piece of information with one API call? (My workaround right now is to make lots of API calls, one for each Mac address directly the REST API without using this library to get the information). Do you happen to know if there some way to run a command like show mac-address-table
?
Could I throw in the depth= parameter in some good place?
I created a gist with an example code that tries to print the port but it doesn't, it fails with
$ python example_mac.py
<class 'pyaoscx.mac.Mac'>
['_Mac__modified', '__abstractmethods__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', '_extract_missing_parameters_from', '_get_and_copy_data', '_get_data', '_is_replace_required', '_mac_path', '_original_attributes', '_parent_vlan', '_post_data', '_put_data', '_send_data', '_set_configuration_items', '_set_vlan', '_uri', 'apply', 'base_uri', 'config_attrs', 'connected', 'create', 'delete', 'deprecated', 'display_name', 'from_id', 'from_response', 'from_uri', 'get', 'get_all', 'get_info', 'get_info_format', 'get_uri', 'indices', 'info_format', 'mac_address', 'mac_format', 'materialized', 'modified', 'path', 'resource_uri_name', 'session', 'update', 'uri_path', 'was_modified']
Ran into exception: 'Mac' object has no attribute 'port'. Closing session.
Traceback (most recent call last):
File "example_mac.py", line 46, in get_aruba_macs
print(macs[mac].port)
AttributeError: 'Mac' object has no attribute 'port'
https://gist.github.com/martbhell/ffa751efd09f156bc6eb3d4ce7890460
get_chassis_info and get_product_info are giving 404 responses due to an extra '/' in the URI calls.
...
EDIT: I located the problem, see next post.
when will recent updates be pushed to pypi? I need the poe_interface capability, and it has not been push out...
This class is good, but appears to miss some features, such as interface lldp neighbors, and interface known/heard ethernet addresses (ie the switching table)? Will this be implemented at some point ?
I am trying to create a lookback using pyaoscx ver 2.1.0
my code is:
from pyaoscx.session import Session
from pyaoscx.pyaoscx_factory import PyaoscxFactory
import urllib3
import traceback
import logging
urllib3.disable_warnings()
host = "192.168.91.200"
version = "10.04"
s = Session(host, version)
s.open("admin", "admin")
try:
factory = PyaoscxFactory(s)
loopback_2 = factory.interface("loopback2")
loopback_2.configure_loopback("fred", ipv4=["7.7.7.7/32"], description=None)
except Exception as e:
logging.error(traceback.format_exc())
finally:
session.close()
The error I get is:
ERROR:root:Traceback (most recent call last):
File "create_lo2.py", line 32, in
loopback_2.configure_loopback("fred", ipv4=["7.7.7.7/32"], description=None)
File "C:\Users\user1\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyaoscx\interface.py", line 1430, in configure_loopback
return self.apply()
File "C:\Users\user1\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyaoscx\pyaoscx_module.py", line 33, in ensure_connected
return fnct(self, *args, **kwargs)
File "C:\Users\user1\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyaoscx\interface.py", line 534, in apply
modified = self.update()
File "C:\Users\user1\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyaoscx\pyaoscx_module.py", line 33, in ensure_connected
return fnct(self, *args, **kwargs)
File "C:\Users\user1\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyaoscx\interface.py", line 730, in update
raise GenericOperationError(
pyaoscx.exceptions.generic_op_error.GenericOperationError: GENERIC OPERATION ERROR
any assistance appreciated
Trying to connect to a device using and IPv6 Address fails with the error: raise LoginError("Cookies were not set correctly. Login failed")
I did encase the IP Address in square brackets like [2001:db8:1::25], as it is customary for URLs. Without the brackets, I got even more parsing errors.
In the file session.py:159 in method open(...): )
self.connected = (
hasattr(cookies, "_cookies") and self.ip in cookies._cookies
)
the check for connected fails, as for some reason unknown to me the switch returns the cookie with the address [2001:db8:1::25].local
. This extra .local at the end of the ip fails the test condition.
I tried to mitigate by also checking for .local, and that is a workaround for my development machine at the moment.
self.connected = hasattr(cookies, '_cookies') and (self.ip in cookies._cookies or "%s.local"% self.ip in cookies._cookies)
I would really appreciate a fix for this in the official pypi version (or in aos-cx, whatever is preferred), as plan to run this on ipv6-only networks, and newly deployed switches do not have dns entries yet.
If I need to push this via my SE or a support case, please tell me as that would be possible.
I can not find the guide about how to use pyaoscx for each module and the docs in the github are not readable.
Hello,
pyaoscx version 2.3.1
I tried to upload firmware but get an error:
pyaoscx.exceptions.response_error.ResponseError: "RESPONSE ERROR: Invalid URL 'firmware?image=secondary': No scheme supplied. Perhaps you meant http://firmware?image=secondary?: Response: POST"
I have a CX6300 switch, which serves PoE to a bunch of Aruba AP's. When I run the code snippet below, I get an error stating "UNSUPPORTED CAPABILITY, This device is not PoE capable.", for either 10.04 or 10.08 api.
I can get interfaces shutdown, enabled, vlan changes, and more, but not this.
Any ideas ? (I am using the latest github pull, with the recent mac() fixes)
Output:
Getting sesion for 10.112.1.75
Firmware = FL.10.08.1040
Platform = 6300
Getting interface list...
Interface 1/1/1:
poe.get() error - exception: 'UNSUPPORTED CAPABILITY, This device is not PoE capable.'
... (other interfaces removed for brevity)
My test code:
import sys
from pyaoscx.session import Session
from pyaoscx.device import Device
from pyaoscx.interface import Interface
from pyaoscx.poe_interface import PoEInterface
# disable unknown SSL cert warnings:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
switch_ip = '10.112.1.75'
username = '***'
password = '***'
API_VERSION = '10.08' # "10.04" or "10.08"
s = Session(ip_address=switch_ip, api=API_VERSION)
try:
print(f"Getting sesion for {switch_ip}")
s.open(username=username, password=password)
except Exception as error:
print('s.open() exception: {}. Cannot open session.'.format(error))
sys.exit()
device = Device(s)
device.get()
print(f"Firmware = {device.firmware_version}")
print(f"Platform = {device.platform_name}")
print("\nGetting interface list...")
interface_dict = Interface.get_facts(session=s)
for ifname in interface_dict:
print(f"Interface {ifname}:")
try:
# go get PoE info:
interface = Interface(session=s, name=ifname)
try:
poe = PoEInterface(session=s, parent_interface=interface)
try:
poe.get(selector='status')
print(" POE Exists!")
except Exception as error:
print(f" poe.get() error - exception: {format(error)}")
except Exception as error:
print(f" PoEInterface() error - exception: {format(error)}")
except Exception as error:
print(f" Interface() error - exception: {format(error)}")
s.close()
Running the test on Ubuntu 20.04 and testing with virtual Aruba CX
Version : Virtual.10.07.0010
Build Date :
Build ID : ArubaOS-CX:Virtual.10.07.0010:c075dcdbb1f5:202106100007
Build SHA : c075dcdbb1f5c2d88d501045bc6386f1dfa49bbc
Active Image :
Service OS Version :
BIOS Version :
My virtual environment:
(test) arne@linux:~/test$ pip list
Package Version
certifi 2021.5.30
charset-normalizer 2.0.6
idna 3.2
netaddr 0.8.0
pip 20.0.2
pkg-resources 0.0.0
pyaoscx 2.0.1
PyYAML 5.4.1
requests 2.26.0
setuptools 44.0.0
urllib3 1.26.6
My testscript:
(test) arne@linux:~/test$ cat sw01-int-down.py
from pyaoscx.session import Session
from pyaoscx.pyaoscx_factory import PyaoscxFactory
#from pyaoscx.vlan import Vlan
from pyaoscx.interface import Interface
version = '10.04'
switch_ip = 'sw01.ao-test.net'
s = Session(switch_ip, version)
s.open('admin', 'Pass0rd123!')
try:
#port_1_1_7 = Interface(s, '1/1/7')
#port_1_1_7.get()
#port_1_1_7.admin = 'down'
# Apply changes
#port_1_1_7.apply()
port_1_1_8 = Interface(s, '1/1/8')
port_1_1_8.get()
port_1_1_8.admin = 'down'
# Apply changes
port_1_1_8.apply()
#port_1_1_9 = Interface(s, '1/1/9')
#port_1_1_9.get()
#port_1_1_9.admin = 'down'
# Apply changes
#port_1_1_9.apply()
except Exception as error:
print('Ran into exception: {}. Closing session.'.format(error))
finally:
# At the end, the session MUST be closed
s.close()
Error message when changing 1/1/7 or 1/1/8
Ran into exception: RESPONSE ERROR in maximum recursion depth exceeded while calling a Python object: GET. Closing session.
Interface config:
interface 1/1/7
no shutdown
vrf attach transport
ip address 10.200.99.129/29
ip ospf 1 area 0.0.0.0
interface 1/1/8
no shutdown
vrf attach transport
ip address 10.200.99.145/29
ip ospf 1 area 0.0.0.0
interface 1/1/9
no shutdown
no routing
vlan trunk native 1
vlan trunk allowed all
like with 2.01, please push v2.1 to pypi (add tag, etc.)
Thank you,
Johan
Hi,
First of all, thanks for the module.
I was wondering if there're plans for supporting checkpoint management, rollback, etc.
Use the query parameter attributes=capabilities
to retrieve the list of system capabilities.
pyaoscx/pyaoscx/configuration.py
Line 39 in 49aa8e9
We'd like to use pyaoscx for the following workflow:
For this workflow we need a pyaoscx function that calls the "/configs/autocheckpoint" API endpoint with POST for enabling the autocheckpoint with a specific time in minutes and with PUT for acknowledging the checkpoint before the timer runs out. Would it be possible to implement this?
Please implement the Ruff linter and resolve issues. I suggest configuring Ruff with all rules enabled by default and then selectively disable problematic rules. Ruff covers a significant fraction of pylint's rules and those from many other linters. Ruff implements all or virtually all of flake8 rules - so, you could remove flake8. Ruff should be run under Github CI.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.