Extreme API with Python For Extreme Networks Products Part Number 9036931-00 Rev AA February 2021 Copyright © 2021 Extreme Networks, Inc. All rights reserved.
Table of Contents 1 Preface .......................................................................................... 5 1.1 References .................................................................................................................................... 5 1.2 Acknowledgements ....................................................................................................................... 5 2 Introduction ..............................................................................
2.6.2 Requests .............................................................................................................................. 20 2.6.3 Testing a REST API ............................................................................................................... 25 2.7 Webhooks ................................................................................................................................... 27 2.8 HTTPS with Python ..................................................
5.2.5 Add User Inputs................................................................................................................... 81 5.2.6 Automate Workflow Execution ........................................................................................... 83 5.2.7 Workflow Example .............................................................................................................. 88 5.3 NorthBound Interface API ......................................................................
Extreme API with Python Page |5 1 Preface This document is provided for information only, to share technical experience and knowledge. Do not use this document to validate designs, features, or scalability. 1.1 References The following references are used extensively in the preparation of this document: EXOS 30.6 User Guide EXOS 30.6 RestConf Developer Guide XMC 8.4.3 GraphQL API Configuring User Interfaces and Operating Systems for VOSS 8.1.
Extreme API with Python Page |6 2 Introduction This document provides an easy approach to the various APIs within Extreme Networks solutions. The programming language used here is Python 3, but other languages can also be used. The Python 3 was selected based on how easy it is for beginners to learn, and its wide use in the market. 2.1 Using Python At the time this document was written, Python had two major versions: Python 2.7 and Python 3.
Extreme API with Python Page |7 2.1.3 Virtual Environment The easiest way to manage multiple packages, modules and libraries is to work with virtual environments. If you do not use a virtual environment, every time you install a new package, module, or library, it is added into the global Python installation. This becomes problematic if you install packages with dependencies that may require older or more recent versions of modules you are already using.
Extreme API with Python Page |8 Note: If you need more information about a function, method or library, Python has a built-in help system. In the Python interactive shell, type help() or dir(. If you use an IDE, you can run code directly from the editor and, with more advanced IDEs, you can manage virtual environments and execute selected portions of code. Spyder and Jupyter are part of the Anaconda distribution, which is a typical environment for data science. 2.
Extreme API with Python Page |9 2.2.2 HTTP Status Codes When working with HTTP, it is important to understand the status code that is returned in a CALL. There are five status code categories: 1xx: informational response 2xx: successful 3xx: redirection 4xx: client error 5xx: server error You should see a 200 when everything is operating normally (OK). Error codes such as 403 (forbidden access) or 404 (not found) help identify issues.
Extreme API with Python P a g e | 10 Wen working with REST API, (and any API using HTTP), you will most likely need to manipulate the headers using the content-type, accept, authorization and x-auth-token commands. Note: The HTTP Archive site is an excellent resource for learning more about HTTP. This site monitors the top 1.3M web sites and extracts the HTTP information for analyses. This information, along with reports such as State of the Web , are accessible to the public. 2.2.4.
Extreme API with Python P a g e | 11 2.2.4.4 X-Auth-Token The X-Auth-Token is an unregistered header and is not subject to formal specification. Its presence and content are always tied to a respective application. It typically stores a token for authorization and can be considered as a shortcut of the bearer token defined in OAuth 2.0. For Extreme APIs, the X-Auth-Token will be used with EXOS and VOSS Restconf implementation. 2.2.
Extreme API with Python P a g e | 12 The result is shown below: C:\Extreme API with Python> headers-example.py Headers sent: {'User-Agent': 'python-requests/2.22.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'content-type': 'application/json', 'x-auth-token': 'c3RlZjpleHRyZW1l'} Headers received: {'Date': 'Sun, 14 Jun 2020 15:03:53 GMT', 'Content-Type': 'application/json', 'Content-Length': '390', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.
Extreme API with Python P a g e | 13 bearer scheme was created as part of OAuth 2.0 (rfc 6750), but is sometimes used alone. As the token must remain secret, the best practice is to use it only with HTTPS. 2.3.3 API Key API keys are common. This is what you would typically use when working with YouTube APIs, for example. The benefit of this method is that it uses a different set of identification credentials than those used for the account itself, (for example, what basic authentication doesn’t provide).
Extreme API with Python P a g e | 14 password = getpass.getpass() print("\nYou entered:\nUsername: {} Password: {}".format(username, password)) The result is shown below: C:\Extreme API with Python> auth-examples.py Username: Stef Password: You entered: Username: Stef Password: extreme If the application is running on a secure environment, another way to is to store passwords, keys, and tokens as environment variables that the application can access.
Extreme API with Python P a g e | 15 2.4 Understanding JSON JSON (JavaScript Object Notation) is an open standard file format, defined in RFC 8259 (HTTPS://tools.ietf.org/html/rfc8259), widely used to format the data transmitted and stored with modern APIs and tools. Despite its name, JSON is language-independent and is used with whatever programming language needed.
Extreme API with Python P a g e | 16 information that can be read by humans, JSON is currently the most efficient tool. Nevertheless, when you need to exchange a vast amount of information, performance and efficiency become more important and you can consider new standards. These alternatives are not yet used in external Extreme APIs, although binary formats, such as Protobuf, are becoming popular as well. JSON and Protobuf are expected to co-exist, serving different needs. 2.
Extreme API with Python P a g e | 17 import json json_sample = ''' { "whisky": [ { "name": "Hibiki", "type": "Blended", "age": 17 }, { "name": "Old Pulteney", "type": "Single Malt", "age": 21 } ], "stock": null, "alcohol": true } ''' data = json.loads(json_sample) print(type(data)) print(data) new_data = json.dumps(data) print(type(new_data)) print(new_data) This example imports the JSON module and manipulates a JSON entry in Python.
Extreme API with Python P a g e | 18 {"whisky": [{"name": "Hibiki", "type": "Blended", "age": 17}, {"name": "Old Pulteney", "type": "Single Malt", "age": 21}], "stock": null, "alcohol": true} In this example, a string is the source, but you could also have uploaded information from a file, and saved it back to a file using the json.load() and json.dump() commands. 2.
Extreme API with Python P a g e | 19 'ftpwrapper', 'getproxies', 'getproxies_environment', 'getproxies_registry', 'hashlib', 'http', 'install_opener', 'io', 'localhost', 'noheaders', 'os', 'parse_http_list', 'parse_keqv_list', 'pathname2url', 'posixpath', 'proxy_bypass', 'proxy_bypass_environment', 'proxy_bypass_registry', 'quote', 're', 'request_host', 'socket', 'splitattr', 'splithost', 'splitpasswd', 'splitport', 'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'ssl', 'string', 'sys', '
Extreme API with Python P a g e | 20 print(type(data)) print(len(data)) The result is shown below: 200 48959 48959 This example shows the success HTTP status code (200), and the amount of data returned in bytes. 2.6.2 Requests Although Urllib provides all the required tools to manipulate URLs and HTTP CALLs, a better package called Requests is commonly used. HTTPS://requests.readthedocs.io/en/master/ The best practice is to install Requests with PIP.
Extreme API with Python P a g e | 21 Downloading HTTPS://files.pythonhosted.org/packages/1a/70/1935c770cb3be6e3a8b78ced23d7e0f3b187f5cb fab4749523ed65d7c9b1/requests-2.23.0-py2.py3-none-any.whl (58kB) |████████████████████████████████| 61kB 1.9MB/s Collecting certifi>=2017.4.17 (from requests) Downloading HTTPS://files.pythonhosted.org/packages/57/2b/26e37a4b034800c960a00c4e1b3d9ca5d7014e98 3e6e729e33ea2f36426c/certifi-2020.4.5.1-py2.py3-none-any.whl (157kB) |████████████████████████████████| 163kB 6.
Extreme API with Python P a g e | 22 Make a REST CALL, using GET to retrieve data. This service lets you add parameters (arguments) to the URL in a query string, so that the server also returns this information . Requests has an integrated JSON function that you can use also, as shown below : import requests qstring = {"h2g2": 42, "elite": 1337} r = requests.get('HTTPS://httpbin.org/get', params=qstring) print(r.url) print(r.status_code) print(r.headers['content-type']) print(r.encoding) print(r.
Extreme API with Python P a g e | 23 https://httpbin.org/get?h2g2=42&elite=1337 200 application/json None { "args": { "elite": "1337", "h2g2": "42" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Host": "httpbin.org", "User-Agent": "python-requests/2.22.0", "X-Amzn-Trace-Id": "Root=1-5ed8c610-484d6854daf7112485a3b020" }, "origin": "109.13.132.180", "url": "https://httpbin.
Extreme API with Python P a g e | 24 print(type(data)) print(data) In the results, you can see that the URL no longer contains a query string, and in the JSON returned, there is a form entry with the data you sent. HTTPS://httpbin.org/post 200 application/json { "args": {}, "data": "", "files": {}, "form": { "elite": "1337", "h2g2": "42" }, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Content-Length": "17", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.
Extreme API with Python P a g e | 25 r = requests.get('HTTPS://httpbin.org/delay/4', timeout=3) Add a delay of 4 seconds for the answer with a timeout of 3 seconds. Running the script gives you a traceback: Traceback (most recent call last): […] raise ReadTimeout(e, request=request) requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='httpbin.org', port=443): Read timed out. (read timeout=3) You can also use a Python try/except, which provides a cleaner result without breaking code.
Extreme API with Python P a g e | 26 These sections are the Request builder, the Response window, and the Explorer window. In the Request builder, you create the HTTP CALL, specify the URL, add parameters, and set the authentication and headers. The Request and Response windows display requests and responses. Zoom into the Request builder, to see (in this example) an HTTP GET method, the URL for the API next to it, and several tabs where you can personalize the CALL.
Extreme API with Python P a g e | 27 In the response window, you can see the HTTP Status code, in this case an encouraging 200, and the data sent back in JSON by the API. You can now use this information in the application, as you can see the keys and value types returned. You can now write a Python application to interface with this API. import requests headers = {"Accept": "application/json"} try: r = requests.get('HTTPS://icanhazdadjoke.com/', headers=headers, timeout=3) except requests.exceptions.
Extreme API with Python P a g e | 28 2.8 HTTPS with Python Usually, when you work with an API that uses HTTP as the transfer protocol, such as REST API, you will be required to use HTTPS for obvious security reasons. If you are using self-signed certificates, you will see warnings and errors. To avoid this, in the code, add the disable_warnings method from Urllib3 and add the verify=False argument with requests. import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.
Extreme API with Python P a g e | 29 3 EXOS APIs EXOS offers several APIs for developers that support on-switch automation and external automation. The following sections describe these options. 3.1 On-Switch APIs EXOS has included automation and scripting since its original inception. The first scripting interface offered to the users, and still present today, is called CLI Scripting and uses TCL functions for advanced scripting.
Extreme API with Python P a g e | 30 3.1.1.3 Execute a Python Script There are two CLI commands you can use to execute an existing Python script from the CLI: - run script .py load script .py The first command was introduced specifically for executing Python script. The second one is the legacy command, used for CLI Scripting. 3.1.1.4 EXOS CLI Module You can use an EXOS module called exsh to execute a Python script on EXOS.
Extreme API with Python P a g e | 31 sw1.2 # run script createVlans.py sw1.3 # show vlan Untagged ports auto-move: Inform ----------------------------------------------------------------------------------------------Name VID Protocol Addr Flags Proto Ports Virtual Active router /Total ----------------------------------------------------------------------------------------------Default 1 --------------------------------T------------ANY 5 /5 VR-Default Mgmt 4095 192.168.56.
Extreme API with Python P a g e | 32 print "Missing arguments\nExpected arguments are Port and Action\nValid Actio ns are down and up" exit(0) if sys.argv[2] == "down": exsh.clicmd("delete vlan exsh.clicmd("config vlan else: exsh.clicmd("create vlan exsh.clicmd("config vlan 42") Default add port {}".format(sys.argv[1])) 42") 42 add port {}".format(sys.argv[1])) UPM config requires that you create a profile and a log filter to monitor the event you want associated with this profile.
Extreme API with Python P a g e | 33 sw1.
Extreme API with Python P a g e | 34 Default 1 --------------------------------T------------ANY 0 /0 VR-Default Mgmt 4095 192.168.56.121 /24 -------------------------ANY 1 /1 VR-Mgmt VLAN_0042 42 ---------------------------------------------ANY 1 /1 VR-Default -------------------------------------------------------------------------------------Flags : (B) BFD Enabled, (c) 802.1ad customer VLAN, (C) EAPS Control VLAN, […] Total number of VLAN(s) : 3.1.1.5.
Extreme API with Python P a g e | 35 sw1.1 # sh log 07/01/2020 00:51:44.26 User Admin just connected! 07/01/2020 00:51:44.26 Login passed for user admin through telnet (192.168.56.1) 07/01/2020 00:51:37.20 Administrative account (admin) logout from telnet (192.168.56.1) 07/01/2020 00:51:30.32 User admin: Cleared the log messages in memory-buffer. A total of 4 log messages were displayed.
Extreme API with Python P a g e | 36 ev.sub(event_cb) 3.1.2.1 Create a Process Enter the create process command and provide the necessary parameters: The process name The process creation (must be python-module) The name of the Python application, without the .py suffix The startup behavior, which can be either on-demand or auto The VR from which you want it to run. The default is VR-Mgmt The startup behavior, on-demand, runs once like a script would.
Extreme API with Python P a g e | 37 Your program with the logging capability should look like this: from exos import api import exos.api.throwapi as throwapi import logging logger = logging.getLogger('test') logger.setLevel(logging.DEBUG) logHandler = api.TraceBufferHandler("testbuf", 20480) logHandler.setLevel(logging.DEBUG) logHandler.setFormatter(logging.Formatter("%(levelname)s:%(name)s:%(funcName)s.%( lineno)s:: %(message)s")) logger.addHandler(logHandler) def event_cb(event, subs): logger.
Extreme API with Python P a g e | 38 06/07/2020 14:06:37.002965 [200] Begin trace buffer 06/07/2020 14:06:54.479653 [221] INFO:test:event_cb.15:: {'meta': {'action': 'create', 'timestamp': 1591538814.48, 'object': 'vlan', 'id': 'exos.vlan.create'}, 'data': {'vr_name': 'VR-Default', 'vlan_name': 'VLAN_0010'}} 06/07/2020 14:06:54.485521 [224] INFO:test:event_cb.15:: {'meta': {'action': 'create', 'timestamp': 1591538814.49, 'object': 'vlan', 'id': 'exos.vlan.
Extreme API with Python P a g e | 39 Raises: - CLICommandError(error_msg, cmd): A CLI command returned an error message. The error_msg attribute is the message received from the CLI and cmd is the command that was being run at the time CLITimeoutError: A CLI request timed out Note: You are presenting the synchronous CALL in this example, but asynchronous CALLs exist as well. Enhance your previous example by creating or deleting a VLAN is on the switch: from exos import api import exos.api.
Extreme API with Python P a g e | 40 # Subscribe to vlan events ev = throwapi.Subscription("vlan") ev.sub(event_cb) main() Note: When you need double quotes for a CLI command in a Python string, you can use a single quote to delimit the string. Another solution is to use double quote and escape the inner ones with a backslash “\”. Failing to this will result in an error. Your program reacts as expected on a switch. sw1.12 # create process test python-module test start auto creating test... * sw1.
Extreme API with Python P a g e | 41 3.2.1 RESTCONF API The latest API introduced with EXOS is the RESTConf, which follows the Openconfig model and works in conjunction with the Python module restconf.pyz. This module is available on Extreme Networks github: HTTPS://github.com/extremenetworks/EXOS_Apps/tree/master/REST Note: The RESTConf module is bundled in EXOS since release 22.4, but is backward compatible with EXOS 22.1, by adding the restconf.pyz module to the system. 3.2.1.
Extreme API with Python P a g e | 42 To access the Restconf server on a switch, RFC 8040 requires a common URL as the root. The root resource for EXOS is /rest/restconf/. The datastore is represented by a node named data. Note: All methods are supported on data. Enable HTTPS on EXOS To enable HTTPS on an EXOS switch, first enable SSL. The following example starts with a factory default switch (or VM): sw1.
Extreme API with Python P a g e | 43 You will also need to add the verify=False parameter to the request CALLs. EXOS allows you to install customer certificates that have been signed by trusted authorities. 3.2.1.4 Using Restconf with Python Use the restconf.py class available on Extreme Networks Github. At the time of writing of this document, the version of the class is 1.2.0.0. Note: The restconf.py class is compatible with Python 2.7 and 3.x.
Extreme API with Python P a g e | 44 # you make a GET API call for all the vlans info = rest.get('data/openconfig-vlan:vlans') data = info.json() vlans = data.get('openconfig-vlan:vlans').get('vlan') for vlan in vlans: print("Found VLAN {} with VID {}".format(vlan.get('state').get('name'), v lan.get('vlan-id'))) main() As a result, you can see all existing VLANs on the switch: C:\Extreme Found VLAN Found VLAN Found VLAN API with Python> rest_example.py -i 192.168.56.
Extreme API with Python P a g e | 45 Below your endpoint is a VLAN entry which is a list of the VLANs. For each entry in the list, you will see the element id (in this case, the VLAN id), a state container and a config container. The Openconfig data model is very consistent, which means that once you understand it, you can easily access any data: it always follows the same pattern. To create a VLAN, manipulate the config container following the same structure.
Extreme API with Python P a g e | 46 if args.username is None: # prompt for username args.username = input('Enter remote system username: ') # also get password args.password = getpass.getpass('Remote system password: ') # open a restconf session rest = Restconf(args.ip, args.username, args.
Extreme API with Python P a g e | 47 The result: C:\Extreme API with Python> rest_example.py -i 192.168.56.
Extreme API with Python P a g e | 48 # you list the existing vlans after to check again print("-"*42) list_vlans(rest) Adding this code results in re-creating VLAN “H2G2”, and then renaming it to Zaphod: C:\Extreme API with Python> rest_example.py -i 192.168.56.
Extreme API with Python P a g e | 49 Default 1 ---------------------------------------------ANY 0 /0 VR-Default interco 4094 10.1.1.2 /24 -f-----------------------ANY 1 /1 VR-Default Mgmt 4095 192.168.56.
Extreme API with Python P a g e | 50 3.2.2.3 Using JSON-RPC with Python As with the RESTCONF API, a Python class is proposed on the Extreme Networks github to facilitate its use. HTTPS://github.com/extremenetworks/EXOS_Apps/blob/master/JSONRPC/jsonrpc.py Note: At the time of writing of this document, the latest version of the JSON-RPC class is 2.0.0.4. The class uses different methods, depending on the use case. The most common method is using CLI commands.
Extreme API with Python P a g e | 51 parser.add_argument('-p', '--password', help='Login password for the remote system', default='') args = parser.parse_args() return args def main(): args = get_params() if args.username is None: # prompt for username args.username = input('Enter remote system username: ') # also get password args.password = getpass.getpass('Remote system password: ') with open(args.filename, "r") as f: cmds = f.read().
Extreme API with Python P a g e | 52 Name VID Protocol Addr Flags Proto Ports Virtual Active router /Total ----------------------------------------------------------------------------------------------interco 4094 10.1.1.
Extreme API with Python P a g e | 53 sw = {} sw['ip'] = ip sw['vlans'] = [] for vlan in response.get('result'): if vlan.get('status') in ["MORE", "SUCCESS"]: info = {} data = vlan.get('vlanProc') info['ip'] = data.get('ipAddress') info['netmask'] = data.get('maskForDisplay') info['name'] = data.get('name1') info['vid'] = data.get('tag') sw['vlans'].append(info) vlans.append(sw) for entry in vlans: print("\nSwitch {} has {} VLANs".format(entry.get('ip'), len(entry.
Extreme API with Python P a g e | 54 'netmask': 24, 'name': 'VLAN_0021', 'vid': 21}, {'ip': '0.0.0.0', 'netmask': 0, 'name': 'VLAN_0022', 'vid': 22}] The JSON output is a result of the EXOS CLI command shows the data structures that have been used to create this display on EXOS. It can be sometimes difficult to find the exact information for a given feature or protocol parameter. Note: JSON output is created with the cli2json.py embedded Python script in EXOS.
Extreme API with Python P a g e | 55 4 VOSS API VOSS offers a RESTCONF API using the Openconfig model. VOSS powers the VSP product family. Note: RESTCONF was added to VOSS starting with version 8.0. 4.1 VOSS RESTCONF Documentation The Configuring User Interfaces and Operating Systems for VOSS document is provided with any new release of the OS. This document uses VOSS 8.1.5 for the examples. The link to this document for VOSS 8.1.5 is: HTTPS://documentation.extremenetworks.
Extreme API with Python P a g e | 56 The way to use RESTCONF is identical to that of EXOS, and the endpoints follow the same logic. Be careful to use the default port used in VOSS for RESTCONF, which is 8080 for HTTP. It must be provided along with the IP address. The RESTCONF Python class is available on the Extreme Networks github: HTTPS://github.com/extremenetworks/ExtremeScripting/blob/master/VOSS/restconf.py Note: Starting with XMC 8.5, the restconf_voss.
Extreme API with Python P a g e | 57 print("Found VLAN {} with VID {}".format(vlan.get('state').get('name'), v lan.get('vlan-id'))) def main(): args = get_params() if args.username is None: # prompt for username args.username = input('Enter remote system username: ') # also get password args.password = getpass.getpass('Remote system password: ') # open a restconf session - you are assuming http rest = Restconf(args.ip + ':' + DEFAULT_TCP_PORT, args.username, args.
Extreme API with Python P a g e | 58 # you list the existing vlans after to check again print("-"*42) list_vlans(rest) main() The result: C:\Extreme API with Python> rest_voss.py -i 192.168.56.
Extreme API with Python P a g e | 59 5 XMC API XMC (Extreme Management Center) uses several APIs, and the focus in this section is on the most recent addition with GraphQL support. This is also referred to as the NBI API (NorthBound Interface), through the extensive use of the Python capability built into XMC. This API can be accessed either externally or internally via the Python Scripting Engine. Note: GraphQL is a query language developed by Facebook, before becoming public in 2015.
Extreme API with Python P a g e | 60 ship the latest revision of the modules. These are available on the Extreme Networks Github, and it is advisable to update them to the latest version available. Note: At the time of writing of this document, latest versions are v2.0.0.4 for jsonrpc.py, v1.2.0.0 for restconf.py and v1.0.0.1 for restconf_voss.py. 5.1.
Extreme API with Python P a g e | 61 for key,value in emc_vars.iteritems(): print key You can sort the output by category for easier reading, with explanations for the variable use.
Extreme API with Python P a g e | 62 jboss.http.port jboss.server.log.dir jboss.bind.address jboss.bind.address.management jboss.HTTPS.port STATUS USE_IPV6 extreme.hideLegacyDesktopApps The ports variable returns a string containing all the ports, separated by commas. 5.1.6.2 emc_cli.send() Another tool provided by XMC is the emc_cli.send() Python object. This object accepts several parameters.
Extreme API with Python P a g e | 63 Because the emc_cli object connects to the device using either Telnet or SSH, any device from any vendor is accessible, however login banners and sub-prompts can vary from one vendor to another. XMC has a list of CLI rules to access the device. Starting with XMC 8.1.2, you can customize the CLI rules or the regular expressions for prompt detection, by creating a file named myCLIRules.xml, located in the same directory as the CLIRules.xml file (names are case-sensitive).
Extreme API with Python P a g e | 64 # Remove echoed command and final prompt from output def cleanOutput(outputStr): lastLine = outputStr.splitlines()[-1:][0] if RegexPrompt.match(lastLine): lines = outputStr.splitlines()[1:-1] else: lines = outputStr.splitlines()[1:] return '\n'.join(lines) 5.1.6.3 Additional emc_cli Methods This section has covered the most common method used for the emc_cli Python object. However, there are several other methods that can be useful. Examples of these are shown below.
Extreme API with Python P a g e | 65 5.1.6.4 Add User-Input Variables to a Script As of XMC 8.0.4, the metadata used with TCL can still be used as is, even if the syntax is more TCLcentric than it is compliant with Python. Starting with XMC 8.1.2, the Metadata fields with Python scripting have evolved so that the name field and the value field can be referenced directly. Note: The legacy “set var name value” syntax is still supported for backward compatibility.
Extreme API with Python P a g e | 66 # Fabric node (VSP) is available (via OoB or else) # ################################################################################# #@DetailDescriptionEnd #@SectionStart (description = "Service Definition to create") # @VariableFieldLabel (description = "BVLAN 1", # type = string, # required = yes, # readOnly = no, # name = "bvlan1", # value = "4051" # ) # # # # # # # @VariableFieldLabel (description = "BVLAN 2", type = string, required = yes, readOnly = no, name =
Extreme API with Python P a g e | 67 # @VariableFieldLabel (description = "Multicast Enable", # type = string, # required = yes, # readOnly = no, # validValues = [yes,no], # name = "multicast", # value = "no" # ) #@SectionEnd #@SectionStart (description = "Device Specific Data") # @VariableFieldLabel (description = "NNI Fabric Port List", # type = string, # required = yes, # readOnly = no, # name = "portlist", # value = "1/1-1/3", # scope = device # ) # @VariableFieldLabel (description = "Nickname Custom",
Extreme API with Python P a g e | 68 if int(emc_vars["bvlan1"]) > 4094 or int(emc_vars["bvlan1"]) < 2: raise RuntimeError('BVLAN 1 Id is out of range') if int(emc_vars["bvlan2"]) > 4094 or int(emc_vars["bvlan2"]) < 2: raise RuntimeError('BVLAN 2 Id is out of range') if int(emc_vars["bvlan1"]) == int(emc_vars["bvlan2"]): raise RuntimeError('Error: BVLAN 1 Id is identical than BVLAN 2 Id') Writing a script from XMC is simple.
Extreme API with Python P a g e | 69 5.2 Workflow Engine The Workflow Engine, Introduced with XMC 8.2, enables you to create complex actions based on events or alarms or that can be manually triggered. These actions execute several tasks in a logical progression, depending on the result of the previous task. This improvement enables you to create custom features. The Workflow Engine relies on Python scripting, with some extra parameters and a few differences, which are described in the following sections.
Extreme API with Python P a g e | 70 workflowUpdatedBy workflowexecutionId workflowUpdatedDateTime workflowDescription workflowTimeout workflowNosIds workflowCreatedBy workflowName workflowVersion activityMessage activityDescription activityCustomId activityName activityNosIds scriptOwner scriptName scriptAssignment scriptTimeout scriptType abort_on_error javax.script.name javax.script.engine_version javax.script.language javax.script.engine output STATUS auditLogEnabled failFast extreme.
Extreme API with Python P a g e | 71 Not found: interSwitchPorts Not found: javax.script.
Extreme API with Python P a g e | 72 Note: You can also select an existing workflow and save it with a different name to use as a template for a new workflow. After you have created a new workflow, and entered a name and a description for it, you are ready to start editing it. Several windows are displayed. Next to the Menu bar, on the left side, you can see the Workflow List, the Palette, the Designer and finally the Details window.
Extreme API with Python P a g e | 73 - HTTP Activity Mail Activity CLI Activity Activity Group Gateways are objects that allow different execution paths. Inclusive Parallel Parallel Boundary is a timer object that can be executed if an activity does not complete during a specified time. This allows you to follow a given path in the Workflow if this happens. The Workflow Engine checks every 10 seconds and triggers a timer in a range of N to N+10 seconds.
Extreme API with Python P a g e | 74 If you select a Python script, the list expands to include the variables shown here: Part no.
Extreme API with Python P a g e | 75 These variables are from your emc_vars dictionary, and some are only significant in some situations, running with a given activity. To create a new variable, select the Add button at the top of the Details panel. You can set the default value, type, and scope. Part no.
Extreme API with Python P a g e | 76 When created, in this example as a string type, the variable becomes accessible from the Python Script through the emc_vars dictionary. Here’s a quick example, creating a Python Script in a workflow. You connect the script with the Start and End gateways, using the arrows from one object to the other, then you can click on the Run button to execute the workflow, after a save.
Extreme API with Python P a g e | 77 The output: Script Name: StefTest_Script_-_4 Date and Time: 2020-06-26T19:32:36.361 XMC User: root XMC User Domain: IP: extreme Extreme! Note: If an activity does not need to be run against a device, delete the devices variable so that the engine will not ask you to provide this input. 5.2.
Extreme API with Python P a g e | 78 With this method, you pass an argument variable as a string that you created previously in the activity, and its value, also as a string. You can test this value with gateways, and other activities. This is the correct way to change a variable value (if the variable has a scope of workflow). Note: You can also use this method to pass JSON data, using json.dumps(). emc_results.
Extreme API with Python P a g e | 79 After you have done this, the variable is accessible throughout the workflow. To test it with the inclusive parallel gateway, select one of the output links and set the condition. This dictates what must be met to follow this path. In your example, you defined two paths; one that checks if “My Variable” is equal to “OK”, and the other to “KO”. The resulting script prints the path has been followed. Part no.
Extreme API with Python P a g e | 80 The first script (Script-4) sets the value to the variable for the rest of the workflow, using emc_results.put(). print emc_vars['MyVariable'] emc_results.put("MyVariable", "KO") After you save and run your workflow, you can watch a visual representation of execution of the workflow. Every step that is completed successfully turns green, while failed steps appear red. Part no.
Extreme API with Python P a g e | 81 5.2.5 Add User Inputs Workflows also allows for users to be prompted for inputs. In the previous example, you replaced the hardcoded value of My Variable with a field to select the value you want to use and made sure only valid values are available. Select your script (Script-4) and select the Inputs tab in the Details panel. At the top of the Inputs tab, select the gear icon (Manage Inputs…).
Extreme API with Python P a g e | 82 Select a ComboBox with Valid Values of OK and KO. This is what you expect for your inclusive parallel gateway. Then select the correct variable (My Variable). Your script will no longer modify the variable. When you run your workflow, you must choose between OK and KO. The path that is followed depends on your choice. Part no.
Extreme API with Python P a g e | 83 The result: 5.2.6 Automate Workflow Execution As with Python scripting with EXOS, automation is important because it provides dynamic triggers, based on specific events, in a workflow.
Extreme API with Python P a g e | 84 For example, using XMC 8.4.
Extreme API with Python P a g e | 85 if emc_vars['family'] not in ["VSP Series", "Summit Series"]: print "This type of device is not supported by this workflow ({})".
Extreme API with Python P a g e | 86 From the Actions tab, add a new Task Action and select your workflow. Part no.
Extreme API with Python P a g e | 87 Select Save. As soon as a Device Down alarm is received by XMC, your workflow is executed. You can track it from the Workflow Dashboard. Double-click the workflow to see details and confirm the output of your script. Script Name: Alarm-Down_Script_-_6 Date and Time: 2020-06-28T15:01:56.478 Part no.
Extreme API with Python P a g e | 88 XMC User: NetSight Server XMC User Domain: IP: 192.168.56.121 You received an alarm that device IP Campus_08:00:27:35:2A:E4, with the IP 192.168.56.121 is SNMP Contact Lost: No SNMP reply from device 192.168.56.121 caused by SNMP Error: Timeout[4098], last uptime was 0 Days 00:02:56. 5.2.7 Workflow Example In this example, you will create a new workflow, using different resources for illustration. You will retrieve data from a web server and use it in a script.
Extreme API with Python P a g e | 89 Your script counts the number of IPs and, based on this, will trigger a different script. To make the workflow easier to read, enable the link edit mode to you can add a description to each test. Part no.
Extreme API with Python P a g e | 90 Your workflow should look like this: The simple Count IP script counts all the IPs in the file received, and removes the comment lines. Create a second variable called MyVar2 to test for path selection. received_blacklist = emc_vars['ip_blacklist'] blist = received_blacklist.splitlines() i = 0 for ip in blist: if ip.startswith("#"): Part no.
Extreme API with Python P a g e | 91 continue else: i += 1 if (i % 2): emc_results.put("MyVar2", "1") else: emc_results.put("MyVar2", "0") emc_results.put("IPCount", str(i)) The inclusive parallel gateway tests if the MyVar2 variable is equal to 0 or 1. The final scripts do the same thing, but for the purpose of this example, this is duplicated for each path. print "There are {} entries in the IP list".format(emc_vars["IPCount"]) Run your workflow to see the output: Part no.
Extreme API with Python P a g e | 92 Part no.
Extreme API with Python P a g e | 93 5.3 NorthBound Interface API The NBI API is based on GraphQL. Through the NBI, you can access data stored in the database of XMC, which means virtually everything that XMC manages in the network. XMC provides the emc_nbi Python object to interact with the NBI API. This NBI is accessible both internally through the Python Scripting Engine (and by extension the Workflow Engine), and externally to any authorized application requesting data.
Extreme API with Python P a g e | 94 5.3.1 emc_nbi The emc_nbi Python object includes several functions and methods. As of XMC 8.4.
Extreme API with Python P a g e | 95 A query is a read-only operation. This has been supported since XMC 8.1.2 as a beta feature and in 8.2 as GA code. A query is a string that can be formatted as a JSON object. The most important part of a query are the fields. Each field is defined in a schema that is dynamically created by the runtime. Some arguments may be used with some fields. Fields device(ip: “192.168.1.
Extreme API with Python P a g e | 96 You can access the GraphQL schema description as an IDL file or a JSON file, at the following URLs on an XMC server: HTTPS://:8443/nbi/graphql/schema.idl HTTPS://:8443/nbi/graphql/schema.json Using the GraphiQL interface, you can browse the fields available to us. Let’s have an example and say you want to retrieve the list of devices managed by XMC, and have their MAC address, firmware version and site location.
Extreme API with Python P a g e | 97 The Device field contains several sub-fields. Build your query in the Network input panel and include the fields you want to search between curly brackets. Some fields are mandatory, which is indicated by a !. Part no.
Extreme API with Python P a g e | 98 A query example is shown here: { } network { devices { baseMac firmware sitePath } } If you run your query from GraphiQL, you will see this (truncated) output from your XMC server: Note: The list for this device consists of VMs running on a PC, with XMC also running on the same PC along with a VM. This is a practical and safe way to test queries, workflows, and scripts. Part no.
Extreme API with Python P a g e | 99 This example clearly shows the GraphQL query syntax and the expected output to expect. The output is formatted in JSON in GraphiQL, but the data is returned as a Java hashmap within a script. This should be treated as a regular Python dictionary. From here, you have all the tools you need to include NBI CALLs within your Python scripts and workflows.
Extreme API with Python P a g e | 100 XMC User: root XMC User Domain: IP: 192.168.56.121 There are 5 devices in Extreme Fabric Connect site There are 9 devices in IP Campus site 5.3.3 GraphQL Mutation A mutation lets you add, delete, or modify content in the XMC database. This can be potentially risky, so be sure you are not deleting important data, or corrupting the database content. Note: GraphQL mutation is supported in XMC 8.3 and later.
Extreme API with Python P a g e | 101 else: print "\nSuccessfully created Site {}".format(SiteName) The string starts with the mutation field. Browse the GraphiQL interface to the createSite field. Enter the required arguments, such as the siteLocation (which is mandatory when creating a new site). Specify the output you want to receive from this action. Select from the GraphiQL list. Print the result to display the data returned, and print a comment depending on the outcome.
Extreme API with Python P a g e | 102 Data returned: {network: {createSite={status=ERROR, message=Site already exists 'NewSite', siteId=null}}} Cannot create Site /World/NewSite because Site already exists 'NewSite' 5.3.4 RBAC for API Usage Another feature of XMC is the ability to limit access to the API based on user requests. Administrators may have a root access, and thus all access privileges, but you can use XMC to create separate users and groups, with specific privileges.
Extreme API with Python P a g e | 103 Basic authorization is the standard approach, using the authorization header in HTTP or HTTPS. However, this simple access method is not very secure, as discussed in chapter 2.3. The OAuth 2.0 method is recommended when security is an important factor. This method requires you to create a client in the Client API Access tab in the Administration > Users menu. This generates a Client ID and a Client Secret that can be used for NBI CALLs only.
Extreme API with Python P a g e | 104 #!/usr/bin/env python import json import requests from requests import Request, Session from requests.auth import HTTPBasicAuth from requests.packages.urllib3.exceptions import InsecureRequestWarning import argparse import getpass def get_params(): parser = argparse.ArgumentParser(prog = 'nbi') parser.add_argument('-u', '--username', help='Login username for the remote system') parser.
Extreme API with Python P a g e | 105 session.verify = False session.timeout = 10 session.auth = (args.username, args.password) session.headers.update( { 'Accept': 'application/json', 'Content-type': 'application/json', 'Cache-Control': 'no-cache', } ) # define XMC-NBI query nbiQuery = '{ network{ devices { ip nickName } } }' # execute NBI call nbiUrl = 'HTTPS://' + args.ip + ':8443/nbi/graphql' response = session.post(nbiUrl, json= {'query': nbiQuery} ) if response.
Extreme API with Python P a g e | 106 192.168.56.123 192.168.56.127 192.168.56.128 192.168.56.11 192.168.56.141 192.168.56.122 IP Campus_08:00:27:C5:83:32 sw7 sw8 192.168.56.11 voss01 IP Campus_08:00:27:2A:B1:DF 5.3.6 Use NBI to Execute a Workflow So far, NBI examples have been created mostly from the network field. This example uses the workflows field. To execute a workflow from the NBI, you need to know the ID of the workflow you want to run, and you need to do a mutation.
Extreme API with Python P a g e | 107 from time import sleep idQuery = ''' { workflows { allWorkflows { id name } } } ''' exeMutation = ''' mutation { workflows { startWorkflow (input: { id: variables: { MyVariable: "" } } ) { status errorCode executionId message } } } ''' messageQuery = ''' { workflows { execution(executionId: ) { variables } } } Part no.
Extreme API with Python P a g e | 108 ''' WorkflowName = "StefWorkflow" WorkflowID = 0 Action = "OK" WAIT = 1 res = emc_nbi.query(idQuery) for workflow in res['workflows']['allWorkflows']: if workflow['name'] == WorkflowName: WorkflowID = workflow['id'] break exeMutation = exeMutation.replace("", str(WorkflowID)).replace("", Action) res = emc_nbi.
Extreme API with Python P a g e | 109 5.4 Axis API Prior to the NBI API, XMC offered the Axis API. The Axis API is also sometimes called XMC Web Services. The Axis API is a REST API, returning data formatted as XML. This API is still available, but not recommended for use anymore, with the exception of ExtremeAnalytics, because the NBI API does not provide an interface to ExtremeAnalytics. Note: The ExtremeAnalytics web service is called Purview, which was the original name of the solution.
Extreme API with Python P a g e | 110 Name Type Description name string Name of new location description string Location description masks string IP subnets and masks of location Returns: A string status. 5.4.1.2 addLocationGroup This function creates a new location group. Parameters: Name Type Description name string Name of new location group description string Description of location group Returns: A string status. 5.4.1.3 getAppliances Retrieve the list of Extreme Appliances.
Extreme API with Python P a g e | 111 Name Type Description target string The target to retrieve data from, available options are: application application_group location profile target_address client target source target_type datafamily user_data TopN specific targets: appsByClient server statistics string The statistic to retrieve, available options are: byte_count – total byte count flow_count – total flow count target_address – client/server IP address app_rsp_time – application response time tc
Extreme API with Python P a g e | 112 Name Type Description aggType string Aggregation type, available options are: SUM – sum AVG - average Returns: TableData with a structure defined by the following table. Name Type Description extraData anyType Additional data from the operation lastChange long Timestamp of last valid data noChange boolean True if the data is being stored success boolean True if operation is successful tableData string JSON data 5.4.1.
Extreme API with Python P a g e | 113 Name Type Description source string Extreme Analytics appliance IP address Returns: flow data in JSON format. 5.4.1.8 getVersion Retrieve Extreme Analytics version. Returns: Version as a string. 5.4.1.9 importLocationCSV This creates locations with a provided CSV string. Parameters: Name Type Description locationGroup string Location group name csv string CSV data, data must be in a format where line 1 contains “name,ipmask” without quotes.
Extreme API with Python P a g e | 114 payload = {'maxRows': 2, 'searchString': 'Extreme', 'source': '192.168.20.88'} getHeaders = {'Accept': 'application/json'} r = requests.get(url + 'getBidirectionalFlowsData', verify=False, auth=(login, passw), params=payload, headers=getHeaders) root = ET.fromstring(r.text) data = json.loads(root[0].text) print('json data: ', data) r = requests.get(url + 'getVersion', verify=False, auth=(login, passw), headers=getHeaders) root = ET.fromstring(r.text) print(root[0].
Extreme API with Python P a g e | 115 \nPublicKeySize=2048\nCertificateVersion=v3\nValidNotBefore=150111230000Z\ncommonName= Netsight.\nTLSServerName=extremecontrol\nIssuerCount=6\nSubjectOrganizationalUnitName= NetSight Server\nCertificateLength=798\nuuid=f7d61177\nHalfSession=0\nFlow_HostName=Netsight.\n ServerIP=192.168.20.80', 'fdip': '192.168.20.80', 'sc': '', 'sl': '/World/Extreme Networks France', 'ss': '192.168.254.1', 'st': 1590674777472, 'fda': 'xmc (192.168.20.80)', 'bps': 0.
Extreme API with Python P a g e | 116 6 ExtremeCloud IQ API ExtremeCloud IQ (XIQ) is a 4th generation cloud-based network management system. XIQ is entirely API driven internally, and offers an external API (xAPI) as an addition of the internal API to users. This is a REST API. The XIQ xAPI is made up of four APIs: - Identity Management Monitoring Configuration Presence and Location There are dozens of endpoints to choose from. Presence and Location require a streaming data service via a webhook. 6.
Extreme API with Python P a g e | 117 Create an app to obtain a client ID and a client secret. The Redirect URL is necessary regardless of the authentication method you use. XIQ offers two methods: Bearer Token (basic) and OAuth 2.0 (advanced). With Bearer Token, the URL you use does not need to be real, but it must use HTTPS, and must match the URL in the headers of your requests. Connect to your XIQ account: HTTPS://extremecloudiq.
Extreme API with Python P a g e | 118 By default, the token is valid for 30 days but can be extended up to 365 days. You should see two new tokens: - The Access token that you will use to authenticate for every request. This is the Bearer token. The Refresh token. Part no.
Extreme API with Python P a g e | 119 6.1.2 Headers for the xAPI Because XIQ uses a REST API, connections must be made via HTTPS. Specific headers are required when making a CALL to the xAPI. - X-AH-API-CLIENT-SECRET X-AH-API-CLIENT-ID X-AH-API-CLIENT-REDIRECT-URI Authorization The first three headers are proprietary, and the last one is the regular authorization header.
Extreme API with Python P a g e | 120 Swagger is easy to browse, and lists all URLs and the methods that are supported, including a brief description. Select an URL to expand it and see what type of data is expected and how the response will be displayed. Part no.
Extreme API with Python P a g e | 121 6.1.4 Parameters The information between curly brackets in the URL is optional, with the exception of the ownerId parameter, which is mandatory. This parameter is the VIQ ID in your XIQ account, in the “About ExtremeCloud IQ” menu. Part no.
Extreme API with Python P a g e | 122 Nearly every endpoint has a pageSize parameter. By default, XIQ sends data at a maximum of 100 entries at a time, on one return, which can be too small when collecting the clients list, for example. The pageSize parameter lets you change this value to better match your needs. The pagination entry in the data returned provides valuable information.
Extreme API with Python P a g e | 123 The clientId or deviceId optional parameters are unique IDs for each client or device. They are found when listing the appropriate data, and when they are added to the endpoint, where they point to more information. 6.2 Use Python with XIQ After you have created all the tokens necessary to connect to XIQ, you can write a Python script to interact with and provide information about your XIQ account.
Extreme API with Python P a g e | 124 except requests.exceptions.RequestException as e: print("There was an error accessing XIQ API") sys.exit(1) data = r.json() EXOSList = [] VSPList = [] for device in data.get('data'): entry = {} if device.get('simType') == "SIMULATED": continue entry['model'] = device.get('model') entry['ip'] = device.get('ip') entry['firmware'] = device.get('osVersion') entry['deviceID'] = device.get('deviceId') entry['connected'] = device.get('connected') if device.get('model').
Extreme API with Python P a g e | 125 except requests.exceptions.RequestException as e: print("There was an error accessing XIQ API") sys.exit(1) data = r.json() up = 0 down = 0 for port in data.get('data').get('ports'): if port.get('status') == "UP": up += 1 elif port.get('status') == "DOWN": down += 1 print("\t{} ports UP and {} ports DOWN".format(up, down)) if len(VSPList): print("\nVSP switches:") for vsp in VSPList: print('\t{} with IP {} running VOSS version {}'.
Extreme API with Python P a g e | 126 When sending JSON data, you must add two headers: - Content-Type Accept They both must be set to application/json. In this example, you assign a network policy to a device. You know the serial number and the policy name of this device, and the rest of the information is retrieved from the API. import import import import requests os sys json baseURL = "HTTPS://ie.extremecloudiq.com/" clientSecret = os.environ.get('clientSecret') clientId = os.environ.
Extreme API with Python P a g e | 127 sys.exit(1) except requests.exceptions.RequestException as e: print("There was an error accessing XIQ API") sys.exit(1) return r.json() data = restGet('xapi/v1/configuration/networkpolicy/policies') for policy in data.get('data'): if policy['name'] == POLICY: PolicyID = policy['id'] break data = restGet('xapi/v1/monitor/devices') for device in data.
Extreme API with Python P a g e | 128 print(r.json()) Run this script on your test XIQ account. The following information is returned: C:\Extreme API with Python> xiq2.py {'data': {'status': 200, 'successMessage': 'Network Policy 382247794480476 applied to devices successfully.'}} You have now successfully assigned a network policy to your EXOS switch. 6.2.
Extreme API with Python P a g e | 129 'X-AH-API-CLIENT-ID': clientId, 'X-AH-API-CLIENT-REDIRECT-URI': 'HTTPS://foo.com', 'Authorization': authToken, 'Accept': 'application/json', 'Content-type': 'application/json' } webhookurl = 'HTTPS://webhook.site/5b8f683d-e2e5-4373-aea8-9149a762357d' params = {'ownerId': int(ownerID), 'application': 'WebhookTest', 'url': webhookurl, ' secret': 'test', 'messageType': 'LOCATION_AP_CENTRIC', 'eventType': 'LOCATION'} params = json.dumps(params) try: r = requests.
Extreme API with Python P a g e | 130 Enable Presence Analytics in your network policy in the Additional Settings panel. The default trap interval is set to 60 seconds. Look at your webhook tester to see if you are receiving data every minute. Part no.
Extreme API with Python P a g e | 131 To stop the webhook, send a DELETE to the API endpoint, and specify the correct subscription ID. You can also list and modify all your webhooks. This example shows how to list your webhooks: import requests import os import sys baseURL = "HTTPS://ie.extremecloudiq.com/" clientSecret = os.environ.get('clientSecret') clientId = os.environ.get('clientId') redirectURI = 'HTTPS://foo.com' authToken = os.environ.get('authToken') ownerID = os.environ.
Extreme API with Python P a g e | 132 } params = {'ownerId': ownerID} def restGet(url): try: r = requests.get(baseURL + url, headers=requestHeaders, params=params) if r.status_code != 200: print("Connection failure! Unable to connect to API") print(r.content) sys.exit(1) except requests.exceptions.RequestException as e: print("There was an error accessing XIQ API") sys.exit(1) return r.
Extreme API with Python P a g e | 133 The result is shown here: C:\Extreme API with Python> webhookget.py {'data': [{'ownerId': 88999, 'application': 'WebhookTest', 'secret': 'test', 'url': 'HTTPS://webhook.site/5b8f683d-e2e5-4373-aea8-9149a762357d', 'messageType': 'LOCATION_AP_CENTRIC', 'createdAt': '2020-0703T07:22:46.230Z', 'id': 382247794480746}], 'pagination': {'offset': 0, 'countInPage': 1, 'totalCount': 1}} 200 Validate that the webhook subscription is no longer part of your XIQ configuration.
Extreme API with Python P a g e | 134 7 Extreme Campus Controller API Extreme Campus Controller is a wired and wireless management solution for campus and IoT networks. As with most Extreme Networks solutions, it also provides a REST API. It supports Bearer tokens and OAuth 2.0 for authentication and authorization.
Extreme API with Python P a g e | 135 "scopes" : { "site" : "RW", "network" : "RW", "deviceAp" : "RW", "deviceSwitch" : "RW", "eGuest" : "RW", "adoption" : "RW", "troubleshoot" : "RW", "onboardAaa" : "RW", "onboardCp" : "RW", "onboardGroupsAndRules" : "RW", "onboardGuestCp" : "RW", "platform" : "RW", "account" : "RW", "application" : "RW", "license" : "RW", "cliSupport" : "RW" } In return, the Extreme Campus Controller server issues a token. This is the Bearer token that you will use for REST API CALLs.
Extreme API with Python P a g e | 136 C:\Extreme API with Python> xcc.py { "access_token" : "eyJraWQiOiIxODI1RS1DMjYwMSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.
Extreme API with Python P a g e | 137 One way to obtain this information using Python is shown here: import os import requests import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) xcclogin = os.environ.get('xcclogin') xccpassw = os.environ.get('xccpassw') baseURL = 'HTTPS://192.168.20.90:5825' auth_url = baseURL + '/management/v1/oauth2/token' auth_body = {'grantType': 'password', 'userId': xcclogin, 'password': xccpassw} r = requests.
Extreme API with Python P a g e | 138 def restGet(endpoint): try: r = requests.get(baseURL + endpoint, verify=False, headers=myHeaders, timeout=5) except requests.exceptions.Timeout: print("Timeout!") return None if r.status_code != 200: print("Cannot access XCC REST API! Error code: {}".format(r.status_code)) print(r.content) return None return r.json() data = restGet('/management/v1/aps') if data: print(len(data)) Executing the script results in the following: C:\Extreme API with Python> xcc.
Extreme API with Python P a g e | 139 AP3935 3 AP410 3 AP510 3 AP3915 4 AP3916 4 AP505 4 SA201 8 7.3 Use POST The PUT or POST method is very similar to GET. The main difference is that you must pass the data structure you want to add or modify during the REST API CALL. For example, create a new role (for Policy) in Extreme Campus Controller. Name it Stef.
Extreme API with Python P a g e | 140 break if not found: role = {'name': 'Stef', 'defaultAction': 'allow', 'defaultCos': None} r = requests.post(baseURL + '/management/v3/roles', verify=False, headers=myHeaders, json=role) if r.status_code != 201: print("Cannot access XCC REST API! Error code: {}".format(r.status_code)) print(r.content) exit(0) The output should look like this: C:\Extreme API with Python> xcc.
Extreme API with Python P a g e | 141 7.4 Use PUT In this example, rename your newly created role. You must do a PUT on the role, using its ID in the endpoint, and sending the updated JSON data structure. Make a slight modification to your code: data = restGet('/management/v3/roles') if data: print("\nThere are {} roles".format(len(data))) found = False for name in data: if name.
Extreme API with Python P a g e | 142 if r.status_code != 201: print("Cannot access XCC REST API! Error code: {}".format(r.status_code)) print(r.content) exit(0) else: role['name'] = "H2G2" r = requests.put(baseURL + '/management/v3/roles/{}'.format(role['id']), verify=False, headers=myHeaders, json=role) if r.status_code != 200: print("Cannot access XCC REST API! Error code: {}".format(r.status_code)) print(r.content) else: print("Role name changed") The result: C:\Extreme API with Python> xcc.
Extreme API with Python P a g e | 143 7.5 Use DELETE This example shows you how to delete the role you just created using DELETE. Add the instruction at the end of your code, as shown below: data = restGet('/management/v3/roles') if data: for name in data: if name.get('name') in ["Stef", "H2G2"]: print("Deleting role {}".format(name.get('name'))) r = requests.delete(baseURL + '/management/v3/roles/{}'.format(name['id']), verify=False, headers=myHeaders) print(r.
Extreme API with Python P a g e | 144 {'model': 'AP3915', 'count': 4}, {'model': 'AP3916', 'count': 4}, {'model': 'AP505', 'count': 4}, {'model': 'SA201', 'count': 8}] There are 43 roles Deleting role H2G2 b'' Deleting role Stef b'' Because you executed the entire code, it created Stef again because Stef no longer existed after you renamed it to H2G2. The new piece of code found and deleted each new entry. Because this was a successful delete, no response was returned. Part no.