├── .gitignore ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── __pycache__ └── user_env.cpython-36.pyc ├── add_line.py ├── list_subscribers_and_phones.py └── user_env.template /.gitignore: -------------------------------------------------------------------------------- 1 | /user_env.py 2 | __py_cache__/ 3 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: Current File", 9 | "type": "python", 10 | "request": "launch", 11 | "program": "${file}" 12 | }, 13 | { 14 | "name": "Python: Attach", 15 | "type": "python", 16 | "request": "attach", 17 | "localRoot": "${workspaceFolder}", 18 | "remoteRoot": "${workspaceFolder}", 19 | "port": 3000, 20 | "secret": "my_secret", 21 | "host": "localhost" 22 | }, 23 | { 24 | "name": "Python: Terminal (integrated)", 25 | "type": "python", 26 | "request": "launch", 27 | "program": "${file}", 28 | "console": "integratedTerminal" 29 | }, 30 | { 31 | "name": "Python: Terminal (external)", 32 | "type": "python", 33 | "request": "launch", 34 | "program": "${file}", 35 | "console": "externalTerminal" 36 | }, 37 | { 38 | "name": "Python: Django", 39 | "type": "python", 40 | "request": "launch", 41 | "program": "${workspaceFolder}/manage.py", 42 | "args": [ 43 | "runserver", 44 | "--noreload", 45 | "--nothreading" 46 | ], 47 | "debugOptions": [ 48 | "RedirectOutput", 49 | "Django" 50 | ] 51 | }, 52 | { 53 | "name": "Python: Flask (0.11.x or later)", 54 | "type": "python", 55 | "request": "launch", 56 | "module": "flask", 57 | "env": { 58 | "FLASK_APP": "app.py" 59 | }, 60 | "args": [ 61 | "run", 62 | "--no-debugger", 63 | "--no-reload" 64 | ] 65 | }, 66 | { 67 | "name": "Python: Module", 68 | "type": "python", 69 | "request": "launch", 70 | "module": "module.name" 71 | }, 72 | { 73 | "name": "Python: Pyramid", 74 | "type": "python", 75 | "request": "launch", 76 | "args": [ 77 | "${workspaceFolder}/development.ini" 78 | ], 79 | "debugOptions": [ 80 | "RedirectOutput", 81 | "Pyramid" 82 | ] 83 | }, 84 | { 85 | "name": "Python: Watson", 86 | "type": "python", 87 | "request": "launch", 88 | "program": "${workspaceFolder}/console.py", 89 | "args": [ 90 | "dev", 91 | "runserver", 92 | "--noreload=True" 93 | ] 94 | }, 95 | { 96 | "name": "Python: All debug Options", 97 | "type": "python", 98 | "request": "launch", 99 | "pythonPath": "${config:python.pythonPath}", 100 | "program": "${file}", 101 | "module": "module.name", 102 | "env": { 103 | "VAR1": "1", 104 | "VAR2": "2" 105 | }, 106 | "envFile": "${workspaceFolder}/.env", 107 | "args": [ 108 | "arg1", 109 | "arg2" 110 | ], 111 | "debugOptions": [ 112 | "RedirectOutput" 113 | ] 114 | } 115 | ] 116 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cisco and/or its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # axl-python-suds-sample 2 | 3 | Sample apps demonstrating usage of the Administrative XML Layer (AXL) API for Cisco Unified Communications Manager 4 | 5 | ## Getting started 6 | 7 | * Copy `user_env.template` to `user_env.py` 8 | * Edit `user_env.py` and add your CUCM environment and user details 9 | * Install the `suds-jurko` Python3 library 10 | * Run one of the `.py` sample scripts 11 | -------------------------------------------------------------------------------- /__pycache__/user_env.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/axl-python-suds-sample/342368e09383cd0b5c52b983ff21f78596d25a4b/__pycache__/user_env.cpython-36.pyc -------------------------------------------------------------------------------- /add_line.py: -------------------------------------------------------------------------------- 1 | """AXL sample script, using the SUDS-Jurko library 2 | 3 | Script Dependencies: 4 | suds 5 | logging (optional) 6 | 7 | Depencency Installation: 8 | $ pip install suds-jurko 9 | 10 | Copyright (c) 2018 Cisco and/or its affiliates 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | """ 28 | 29 | # Installing a root/CA Certificate 30 | # (Tested on Ubuntu Linux 18.04) 31 | 32 | # Retrieve certificate from target CUCM host 33 | # - openssl s_client -showcerts -connect cucm-node.example.com:443 /dev/null|openssl x509 >cucm-node.example.com.crt 34 | # Store certificate on the client 35 | # - Create a directory for extra CA certificates in /usr/share/ca-certificates: 36 | # sudo mkdir /usr/share/ca-certificates/extra 37 | # - Copy the CA .crt file to this directory: 38 | # sudo cp foo.crt /usr/share/ca-certificates/extra/foo.crt 39 | # - Append the certificate path (relative to /usr/share/ca-certificates) to /etc/ca-certificates.conf 40 | # sudo dpkg-reconfigure ca-certificates 41 | # 42 | # In case of a .pem file, it must first be converted to a .crt file: 43 | # openssl x509 -in foo.pem -inform PEM -out foo.crt 44 | 45 | import os 46 | import sys 47 | 48 | # Get the absolute path for the project root 49 | project_root = os.path.abspath(os.path.dirname(__file__)) 50 | 51 | # Extend the system path to include the project root and import the env file 52 | sys.path.insert(0, project_root) 53 | import user_env 54 | 55 | # Uncomment the next 3 lines to enable detailed logging 56 | # import logging 57 | # logging.basicConfig(level=logging.INFO) 58 | # logging.getLogger("suds.transport").setLevel(logging.DEBUG) 59 | 60 | from suds.client import Client 61 | 62 | client = Client("file://"+user_env.WSDL_PATH, 63 | location="https://"+user_env.CUCM_LOCATION+"/axl/", 64 | username=user_env.CUCM_USER, 65 | password=user_env.CUCM_PASSWORD) 66 | 67 | newLine = { 68 | "pattern": "5555", 69 | "routePartitionName": "" 70 | } 71 | 72 | result = client.service.addLine(newLine) 73 | 74 | ean = { 75 | "numMask": "8XXXX", 76 | "isUrgent": True, 77 | "addLocalRoutePartition": True, 78 | "routePartition": "testPartition" 79 | } 80 | 81 | cfa = { 82 | "callingSearchSpaceName": "Test_CSS", 83 | "secondaryCallingSearchSpaceName": None, 84 | "destination": "9999" 85 | } 86 | 87 | result = client.service.updateLine( 88 | pattern = "5555", 89 | routePartitionName = "", 90 | description = "test description", 91 | useEnterpriseAltNum = True, 92 | enterpriseAltNum = ean, 93 | callForwardAll = cfa 94 | ) 95 | 96 | print(result) 97 | -------------------------------------------------------------------------------- /list_subscribers_and_phones.py: -------------------------------------------------------------------------------- 1 | """AXL and sample script, using the SUDS-Jurko library 2 | 3 | Script Dependencies: 4 | suds 5 | logging (optional) 6 | 7 | Depencency Installation: 8 | $ pip install suds-jurko 9 | 10 | Copyright (c) 2018 Cisco and/or its affiliates. 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | The above copyright notice and this permission notice shall be included in all 19 | copies or substantial portions of the Software. 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | """ 28 | 29 | import pathlib 30 | # import pydash 31 | import ssl 32 | from suds.client import Client 33 | from suds.xsd.doctor import Import 34 | from suds.xsd.doctor import ImportDoctor 35 | 36 | import os 37 | import sys 38 | 39 | # Get the absolute path for the project root 40 | project_root = os.path.abspath(os.path.dirname(__file__)) 41 | 42 | # Extend the system path to include the project root and import the env file 43 | sys.path.insert(0, project_root) 44 | import user_env 45 | 46 | #Disable HTTPS certificate validation check - not recommended for production 47 | if hasattr(ssl, '_create_unverified_context'): 48 | ssl._create_default_https_context = ssl._create_unverified_context 49 | 50 | tns = 'http://schemas.cisco.com/ast/soap/' 51 | imp = Import('http://schemas.xmlsoap.org/soap/encoding/') 52 | imp.filter.add(tns) 53 | 54 | axl = Client("file://"+user_env.WSDL_PATH, 55 | location="https://"+user_env.CUCM_LOCATION+"/axl/", 56 | faults=False,plugins=[ImportDoctor(imp)], 57 | username=user_env.CUCM_USER, 58 | password=user_env.CUCM_PASSWORD) 59 | 60 | def getSubs(): 61 | res = axl.service.listProcessNode({'name': '%', 'processNodeRole': 'CUCM Voice/Video'}, returnedTags={'name': ''}) 62 | subs = res[1]['return']['processNode'] 63 | for sub in subs: 64 | if sub.name != 'EnterpriseWideData': 65 | print(sub.name) 66 | 67 | def listPhones(): 68 | res = axl.service.listPhone({'name': '%'}, returnedTags={'name': ''}) 69 | if res[1]['return']: 70 | phones = res[1]['return']['phone'] 71 | for phone in phones: 72 | if phone.name.startswith('SEP'): 73 | print(phone.name) 74 | 75 | getSubs() 76 | listPhones() 77 | -------------------------------------------------------------------------------- /user_env.template: -------------------------------------------------------------------------------- 1 | """Set your Environment Information once, not many times. 2 | 3 | The provided sample code in this repository will reference this file to get the 4 | needed information about users and environment context to run the sample. You 5 | provide this info here once and the scripts in this repository will access it 6 | as needed. 7 | 8 | TODO: To setup your `env_user.py` copy this file then edit and save your info 9 | 10 | $ cp env_user.template env_user.py 11 | 12 | 13 | Copyright (c) 2018 Cisco and/or its affiliates. 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | """ 33 | 34 | # User Input 35 | 36 | WSDL_PATH = "" 37 | CUCM_LOCATION = "" 38 | CUCM_USER = "" 39 | CUCM_PASSWORD = "" 40 | 41 | # End User Input --------------------------------------------------------------------------------