├── .github ├── CODEOWNERS └── workflows │ └── run_tests.yml ├── .gitignore ├── DESCRIPTION.rst ├── MANIFEST.in ├── Makefile ├── README.md ├── docs ├── Makefile ├── README.md ├── apidoc │ ├── Makefile │ ├── conf.py │ ├── index.rst │ ├── make.bat │ ├── rest.connector.libs.rst │ ├── rest.connector.rst │ ├── rest.connector.tests.rst │ └── rest.rst ├── changelog │ ├── 2017 │ │ └── june.rst │ ├── 2018 │ │ └── november.rst │ ├── 2019 │ │ ├── august.rst │ │ ├── dec.rst │ │ ├── jul.rst │ │ ├── june.rst │ │ └── sept.rst │ ├── 2020 │ │ ├── april.rst │ │ ├── august.rst │ │ ├── december.rst │ │ ├── july.rst │ │ ├── june.rst │ │ ├── may.rst │ │ ├── october.rst │ │ └── september.rst │ ├── 2021 │ │ ├── april.rst │ │ ├── august.rst │ │ ├── december.rst │ │ ├── february.rst │ │ ├── january.rst │ │ ├── july.rst │ │ ├── june.rst │ │ ├── march.rst │ │ ├── may.rst │ │ └── september.rst │ ├── 2022 │ │ ├── april.rst │ │ ├── august.rst │ │ ├── february.rst │ │ ├── january.rst │ │ ├── july.rst │ │ ├── june.rst │ │ ├── march.rst │ │ ├── may.rst │ │ ├── november.rst │ │ ├── october.rst │ │ └── september.rst │ ├── 2023 │ │ ├── april.rst │ │ ├── august.rst │ │ ├── february.rst │ │ ├── january.rst │ │ ├── july.rst │ │ ├── june.rst │ │ ├── march.rst │ │ ├── may.rst │ │ ├── november.rst │ │ ├── october.rst │ │ └── september.rst │ ├── 2024 │ │ ├── September.rst │ │ ├── april.rst │ │ ├── august.rst │ │ ├── february.rst │ │ ├── january.rst │ │ ├── july.rst │ │ ├── june.rst │ │ ├── march.rst │ │ ├── may.rst │ │ ├── november.rst │ │ └── october.rst │ ├── 2025 │ │ ├── april.rst │ │ ├── february.rst │ │ ├── january.rst │ │ ├── march.rst │ │ └── may.rst │ ├── index.rst │ └── undistributed │ │ └── template.rst ├── conf.py ├── index.rst └── user_guide │ ├── index.rst │ ├── installation.rst │ ├── introduction.rst │ └── services │ ├── apic │ ├── aci_sdk.rst │ ├── index.rst │ └── rest.rst │ ├── bigip.rst │ ├── dcnm.rst │ ├── dnac.rst │ ├── elasticsearch.rst │ ├── generic.rst │ ├── index.rst │ ├── iosxe.rst │ ├── nd.rst │ ├── nso.rst │ ├── nxos.rst │ ├── viptela.rst │ ├── virl.rst │ └── webex.rst ├── setup.py ├── src └── rest │ └── connector │ ├── __init__.py │ ├── implementation.py │ ├── libs │ ├── __init__.py │ ├── apic │ │ ├── __init__.py │ │ ├── acisdk_implementation.py │ │ └── implementation.py │ ├── bigip │ │ ├── __init__.py │ │ └── implementation.py │ ├── dcnm │ │ ├── __init__.py │ │ └── implementation.py │ ├── dnac │ │ ├── __init__.py │ │ └── implementation.py │ ├── elasticsearch │ │ ├── __init__.py │ │ └── implementation.py │ ├── iosxe │ │ ├── __init__.py │ │ └── implementation.py │ ├── ise │ │ ├── __init__.py │ │ └── implementation.py │ ├── nd │ │ ├── __init__.py │ │ └── implementation.py │ ├── nexusdashboard │ │ ├── __init__.py │ │ └── implementation.py │ ├── nso │ │ ├── __init__.py │ │ └── implementation.py │ ├── nxos │ │ ├── __init__.py │ │ ├── aci │ │ │ ├── __init__.py │ │ │ └── implementation.py │ │ └── implementation.py │ ├── viptela │ │ ├── __init__.py │ │ └── implementation.py │ ├── virl │ │ ├── __init__.py │ │ └── implementation.py │ ├── vmware │ │ ├── __init__.py │ │ └── implementation.py │ ├── webex │ │ ├── __init__.py │ │ └── implementation.py │ └── xpresso │ │ ├── __init__.py │ │ └── implementation.py │ ├── tests │ ├── __init__.py │ ├── test_apic.py │ ├── test_apic_cobra.py │ ├── test_bigip.py │ ├── test_elasticsearch.py │ ├── test_iosxe.py │ ├── test_ise.py │ ├── test_nd.py │ ├── test_nso.py │ ├── test_nxos.py │ ├── test_viptela.py │ ├── test_webex.py │ ├── test_xpresso.py │ └── testbed.yaml │ └── utils.py └── tests /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @CiscoTestAutomation/pyats-genie-devs -------------------------------------------------------------------------------- /.github/workflows/run_tests.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python package 5 | 6 | on: 7 | - push 8 | - pull_request 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | strategy: 16 | matrix: 17 | python-version: ['3.9', '3.10', '3.11', '3.12'] 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Set up Python ${{ matrix.python-version }} 22 | uses: actions/setup-python@v1 23 | with: 24 | python-version: ${{ matrix.python-version }} 25 | - name: Install dependencies 26 | run: | 27 | python -m pip install --upgrade pip 28 | pip install pyats[full] 29 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 30 | - name: Test Unit Tests 31 | run: | 32 | make develop 33 | cd tests 34 | python -m unittest 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Python compiled files 2 | *.pyc 3 | *.pyo 4 | __pycache__/ 5 | *.log 6 | 7 | # Cython files 8 | *.c 9 | *.so 10 | 11 | # Developer files 12 | .project 13 | .pydevproject 14 | 15 | # Pycharm files 16 | .idea 17 | 18 | # Rope files 19 | .ropeproject 20 | 21 | # Swap files (VI) 22 | *.sw* 23 | 24 | # backup files 25 | *.bak 26 | 27 | # rope project files 28 | *.ropeproject 29 | 30 | # temp files 31 | *~ 32 | 33 | # build folder 34 | __build__/ 35 | build/ 36 | 37 | # Artifacts caused by "make develop" 38 | *.egg-info 39 | 40 | # coverage.py artifacts 41 | htmlcov/ 42 | .coverage* 43 | 44 | # filesystem stuff on Mac 45 | .DS_Store 46 | 47 | # unicon log file 48 | uni.log 49 | 50 | # Files resulting from a git meld merge 51 | *.orig 52 | 53 | # .vscode 54 | .vscode 55 | .history -------------------------------------------------------------------------------- /DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | pyATS REST connector package 2 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include DESCRIPTION.rst 2 | include README.md 3 | 4 | recursive-include tests *.yaml -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Rest Internal Makefile 3 | # 4 | # Author: 5 | # 6 | # Support: 7 | # pyats-support-ext@cisco.com 8 | # 9 | # Version: 10 | # v1.0.0 11 | # 12 | # Date: 13 | # May 2017 14 | # 15 | # About This File: 16 | # This script will build the Rest package for distribution in PyPI server 17 | # 18 | # Requirements: 19 | # 1. Module name is the same as package name. 20 | # 2. setup.py file is stored within the module folder 21 | ############################################################################### 22 | 23 | # Variables 24 | PKG_NAME = rest.connector 25 | BUILDDIR = $(shell pwd)/__build__ 26 | PYTHON = python3 27 | TESTCMD = $(PYTHON) -m unittest discover tests 28 | DISTDIR = $(BUILDDIR)/dist 29 | 30 | DEPENDENCIES = f5-icontrol-rest requests_mock requests dict2xml ciscoisesdk 31 | 32 | .PHONY: clean package distribute distribute_staging distribute_staging_external\ 33 | develop undevelop populate_dist_dir help docs pubdocs tests 34 | 35 | help: 36 | @echo "Please use 'make ' where is one of" 37 | @echo "" 38 | @echo "package : Build the package" 39 | @echo "test : Test the package" 40 | @echo "distribute : Distribute the package to PyPi server" 41 | @echo "distribute_staging : Distribute the package to staging area" 42 | @echo "distribute_staging_external : Distribute the package to external staging area" 43 | @echo "clean : Remove build artifacts" 44 | @echo "develop : Build and install development package" 45 | @echo "undevelop : Uninstall development package" 46 | @echo "docs : Build Sphinx documentation for this package" 47 | @echo "distribute_docs : Publish the Sphinx documentation to the official cisco-shared web server for all to see" 48 | 49 | docs: 50 | @echo "" 51 | @echo "--------------------------------------------------------------------" 52 | @echo "Building $(PKG_NAME) documentation" 53 | @echo "" 54 | 55 | @cd docs; make html 56 | 57 | @echo "Completed building docs for preview." 58 | @echo "" 59 | @echo "Done." 60 | @echo "" 61 | 62 | pubdocs: 63 | @echo "Not implemented yet." 64 | 65 | test: 66 | @$(TESTCMD) 67 | 68 | package: 69 | @echo "" 70 | @echo "--------------------------------------------------------------------" 71 | @echo "Building $(PKG_NAME) distributable: $@" 72 | @echo "" 73 | 74 | @mkdir -p $(DISTDIR) 75 | 76 | # NOTE : Only specify --universal if the package works for both py2 and py3 77 | # https://packaging.python.org/en/latest/distributing.html#universal-wheels 78 | @$(PYTHON) setup.py bdist_wheel --dist-dir=$(DISTDIR) 79 | @$(PYTHON) setup.py sdist --dist-dir=$(DISTDIR) 80 | 81 | @echo "" 82 | @echo "Completed building: $@" 83 | @echo "" 84 | @echo "Done." 85 | @echo "" 86 | 87 | develop: 88 | @echo "" 89 | @echo "--------------------------------------------------------------------" 90 | @echo "Building and installing $(PKG_NAME) development distributable: $@" 91 | @echo "" 92 | 93 | @pip uninstall -y rest.connector || true 94 | @pip install $(DEPENDENCIES) 95 | @$(PYTHON) setup.py develop --no-deps -q 96 | 97 | @echo "" 98 | @echo "Completed building and installing: $@" 99 | @echo "" 100 | @echo "Done." 101 | @echo "" 102 | 103 | undevelop: 104 | @echo "" 105 | @echo "--------------------------------------------------------------------" 106 | @echo "Uninstalling $(PKG_NAME) development distributable: $@" 107 | @echo "" 108 | 109 | @./setup.py develop --no-deps -q --uninstall 110 | 111 | @echo "" 112 | @echo "Completed uninstalling: $@" 113 | @echo "" 114 | @echo "Done." 115 | @echo "" 116 | 117 | clean: 118 | @echo "" 119 | @echo "--------------------------------------------------------------------" 120 | @echo "Removing make directory: $(BUILDDIR)" 121 | @rm -rf $(BUILDDIR) 122 | @echo "" 123 | @echo "Removing build artifacts ..." 124 | @./setup.py clean 125 | @echo "" 126 | @echo "Done." 127 | @echo "" 128 | 129 | distribute: 130 | @echo "" 131 | @echo "--------------------------------------------------------------------" 132 | @echo "Copying all distributable to $(PROD_PKGS)" 133 | @test -d $(DISTDIR) || { echo "Nothing to distribute! Exiting..."; exit 1; } 134 | @ssh -q $(PROD_USER) 'test -e $(PROD_PKGS)/$(PKG_NAME) || mkdir $(PROD_PKGS)/$(PKG_NAME)' 135 | @scp $(DISTDIR)/* $(PROD_USER):$(PROD_PKGS)/$(PKG_NAME)/ 136 | @echo "" 137 | @echo "Done." 138 | @echo "" 139 | 140 | distribute_staging: 141 | @echo "" 142 | @echo "--------------------------------------------------------------------" 143 | @echo "Copying all distributable to $(STAGING_PKGS)" 144 | @test -d $(DISTDIR) || { echo "Nothing to distribute! Exiting..."; exit 1; } 145 | @ssh -q $(PROD_USER) 'test -e $(STAGING_PKGS)/$(PKG_NAME) || mkdir $(STAGING_PKGS)/$(PKG_NAME)' 146 | @scp $(DISTDIR)/* $(PROD_USER):$(STAGING_PKGS)/$(PKG_NAME)/ 147 | @echo "" 148 | @echo "Done." 149 | @echo "" 150 | 151 | distribute_staging_external: 152 | @echo "" 153 | @echo "--------------------------------------------------------------------" 154 | @echo "Copying all distributable to $(STAGING_EXT_PKGS)" 155 | @test -d $(DISTDIR) || { echo "Nothing to distribute! Exiting..."; exit 1; } 156 | @ssh -q $(PROD_USER) 'test -e $(STAGING_EXT_PKGS)/$(PKG_NAME) || mkdir $(STAGING_EXT_PKGS)/$(PKG_NAME)' 157 | @scp $(DISTDIR)/* $(PROD_USER):$(STAGING_EXT_PKGS)/$(PKG_NAME)/ 158 | @echo "" 159 | @echo "Done." 160 | @echo "" 161 | 162 | changelogs: 163 | @echo "" 164 | @echo "--------------------------------------------------------------------" 165 | @echo "Generating changelog file" 166 | @echo "" 167 | @$(PYTHON) -c "from ciscodistutils.make_changelog import main; main('./docs/changelog/undistributed', './docs/changelog/undistributed.rst')" 168 | @echo "rest.connector changelog created..." 169 | @echo "" 170 | @echo "Done." 171 | @echo "" 172 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # REST API Connector 2 | 3 | This is a pyATS connection class implementation that allows scripts to connect 4 | to a device using REST via topology/YAML format. 5 | 6 | The `rest.connector` module is abstraction enabled and currently supports 7 | specific platforms. Please note that the custom abstraction keyword is required 8 | in the `testbed.yaml` file. 9 | 10 | This package is open sourced to [Cisco DevNet](https://developer.cisco.com/) 11 | in June 2019. 12 | 13 | 14 | # Installation 15 | 16 | Installation guide can be found on [our website]. 17 | 18 | [our website]: https://developer.cisco.com/pyats/ 19 | 20 | ``` 21 | $ pip install rest.connector 22 | ``` 23 | 24 | > Copyright (c) 2018 Cisco Systems, Inc. and/or its affiliates 25 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | # Replace later 6 | # `git status -- .`\n\n\ 7 | # `git log -n 1 --stat -- .`\n\n" | \ 8 | # "mail -s "$(HEADER) Documentation Updated by ${USER}" $(WATCHERS)" 9 | SPHINXOPTS = 10 | SPHINXBUILD = sphinx-build 11 | SPHINXAPI = sphinx-apidoc 12 | PAPER = letter 13 | BUILDDIR = $(shell pwd)/../__build__/documentation 14 | PROD_USER = pyadm@pyats-ci 15 | PROD_DIR = /auto/pyats/wwwin-pyats/cisco-shared/rest/ 16 | PROD_BKUP_DIR = /auto/pyats/wwwin-pyats/cisco-shared/rest/rest-backup/$(shell date +%d-%m-%y-%H:%M:%S) 17 | WATCHERS = jeaubin 18 | HEADER = [Rest Watchdog] 19 | HOSTNAME = `hostname` 20 | 21 | # Dependencies for building documentation 22 | DEPENDENCIES = Sphinx sphinxcontrib-napoleon sphinxcontrib-mockautodoc sphinx-rtd-theme 23 | 24 | 25 | # User-friendly check for sphinx-build 26 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 27 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 28 | endif 29 | 30 | # Internal variables. 31 | PAPEROPT_a4 = -D latex_paper_size=a4 32 | PAPEROPT_letter = -D latex_paper_size=letter 33 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 34 | # the i18n builder cannot share the environment and doctrees with the others 35 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 36 | 37 | .PHONY: distribute help clean docs html dirhtml singlehtml\ 38 | pickle json htmlhelp qthelp devhelp epub latex latexpdf text man\ 39 | changes linkcheck doctest gettext install_build_deps 40 | 41 | help: 42 | @echo "Please use 'make ' where is one of" 43 | @echo "" 44 | @echo " docs to make HTML, LaTeX and PDF documents" 45 | @echo " distribute to distribute to production host server" 46 | @echo "" 47 | @echo " --- default Sphinx targets ---" 48 | @echo "" 49 | @echo " html to make standalone HTML files" 50 | @echo "install_build_deps: Install build dependencies for docs (will be run in make docs)" 51 | @echo " serve to start a web server to serve generated html files" 52 | @echo " dirhtml to make HTML files named index.html in directories" 53 | @echo " singlehtml to make a single large HTML file" 54 | @echo " pickle to make pickle files" 55 | @echo " json to make JSON files" 56 | @echo " htmlhelp to make HTML files and a HTML help project" 57 | @echo " qthelp to make HTML files and a qthelp project" 58 | @echo " devhelp to make HTML files and a Devhelp project" 59 | @echo " epub to make an epub" 60 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 61 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 62 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 63 | @echo " text to make text files" 64 | @echo " man to make manual pages" 65 | @echo " texinfo to make Texinfo files" 66 | @echo " info to make Texinfo files and run them through makeinfo" 67 | @echo " gettext to make PO message catalogs" 68 | @echo " changes to make an overview of all changed/added/deprecated items" 69 | @echo " xml to make Docutils-native XML files" 70 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 71 | @echo " linkcheck to check all external links for integrity" 72 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 73 | 74 | install_build_deps: 75 | @echo "Installing build dependecies into your environment" 76 | @pip install $(DEPENDENCIES) 77 | @echo "" 78 | @echo "Done" 79 | 80 | clean: 81 | rm -rf $(BUILDDIR) 82 | 83 | serve: 84 | @echo "point your browser to http://$(HOSTNAME):8000" 85 | @cd $(BUILDDIR)/html && python -m http.server || echo Error: run \'make \ 86 | html\' before using \'make serve\' 87 | 88 | docs: html 89 | @echo "" 90 | @echo "Done." 91 | @echo "" 92 | 93 | distribute: 94 | @echo "" 95 | @echo "--------------------------------------------------------------------" 96 | @echo "Backing up existing docs to $(PROD_BKUP_DIR)" 97 | @ssh $(PROD_USER) "mkdir -p $(PROD_BKUP_DIR); mv -f $(PROD_DIR)/* $(PROD_BKUP_DIR)/" 98 | @echo "Copying all built documentation to $(PROD_DIR)" 99 | @test -d $(BUILDDIR) || { echo "Nothing to distribute! Exiting..."; exit 1; } 100 | @rsync -rtlv --progress --delete $(BUILDDIR)/ $(PROD_USER):$(PROD_DIR)/ 101 | @echo -e "Documentation updated by ${USER} to \ 102 | $(PROD_USER):$(PROD_DIR)/\n\n\ 103 | `find $(BUILDDIR)`\n\n\ 104 | -----------------------------------------------------------------------\n\n\ 105 | Distribution Environment:\n\n\ 106 | -----------------------------------------------\n\n\ 107 | @echo "" 108 | @echo "Done." 109 | @echo "" 110 | 111 | html: 112 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 113 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 114 | 115 | dirhtml: 116 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 117 | @echo 118 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 119 | 120 | singlehtml: 121 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 122 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 123 | @echo 124 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 125 | 126 | pickle: 127 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 128 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 129 | @echo 130 | @echo "Build finished; now you can process the pickle files." 131 | 132 | json: 133 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 134 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 135 | @echo 136 | @echo "Build finished; now you can process the JSON files." 137 | 138 | htmlhelp: 139 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 140 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 141 | @echo 142 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 143 | ".hhp project file in $(BUILDDIR)/htmlhelp." 144 | 145 | qthelp: 146 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 147 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 148 | @echo 149 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 150 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 151 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pyATS.qhcp" 152 | @echo "To view the help file:" 153 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pyATS.qhc" 154 | 155 | devhelp: 156 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 157 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 158 | @echo 159 | @echo "Build finished." 160 | @echo "To view the help file:" 161 | @echo "# mkdir -p $$HOME/.local/share/devhelp/pyATS" 162 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pyATS" 163 | @echo "# devhelp" 164 | 165 | epub: 166 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 167 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 168 | @echo 169 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 170 | 171 | latex: 172 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 173 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 174 | @echo 175 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 176 | @echo "Run 'make' in that directory to run these through (pdf)latex" \ 177 | "(use 'make latexpdf' here to do that automatically)." 178 | 179 | latexpdf: 180 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 181 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 182 | @echo "Running LaTeX files through pdflatex..." 183 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 184 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 185 | 186 | latexpdfja: 187 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 188 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 189 | @echo "Running LaTeX files through platex and dvipdfmx..." 190 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 191 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 192 | 193 | text: 194 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 195 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 196 | @echo 197 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 198 | 199 | man: 200 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 201 | @echo 202 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 203 | 204 | texinfo: 205 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 206 | @echo 207 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 208 | @echo "Run 'make' in that directory to run these through makeinfo" \ 209 | "(use 'make info' here to do that automatically)." 210 | 211 | info: 212 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 213 | @echo "Running Texinfo files through makeinfo..." 214 | make -C $(BUILDDIR)/texinfo info 215 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 216 | 217 | gettext: 218 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 219 | @echo 220 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 221 | 222 | changes: 223 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 224 | @echo 225 | @echo "The overview file is in $(BUILDDIR)/changes." 226 | 227 | linkcheck: 228 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 229 | @echo 230 | @echo "Link check complete; look for any errors in the above output " \ 231 | "or in $(BUILDDIR)/linkcheck/output.txt." 232 | 233 | doctest: 234 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 235 | @echo "Testing of doctests in the sources finished, look at the " \ 236 | "results in $(BUILDDIR)/doctest/output.txt." 237 | 238 | xml: 239 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 240 | @echo 241 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 242 | 243 | pseudoxml: 244 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 245 | @echo 246 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 247 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | #### Contribute to the documentation 2 | 3 | Documentation is made better when user can provide feedback and provide enhancement. pyATS strongly encourages community involvement in improving the documentation. 4 | 5 | To contribute, you need to fork the repository, do your modifications and create a new pull request. 6 | 7 | > :warning: **Make sure you have the full pyats package installed via ```pip install pyats[full]```.** 8 | 9 | To build the docs locally on your machine. Please follow the instructions below 10 | 11 | - On the top right corner, click ```Fork```. (see https://help.github.com/en/articles/fork-a-repo) 12 | 13 | Screen Shot 2020-12-21 at 2 37 19 PM 14 | 15 | - In your terminal, clone the repo using the command shown below: 16 | ```shell 17 | git clone https://github.com//rest.git 18 | ``` 19 | 20 | - ```cd rest/docs``` 21 | 22 | - Use ```make install_build_deps``` to install all of the build dependencies 23 | 24 | - Run ```make docs``` to generate documentation in HTML 25 | 26 | - Wait until you see ```Done``` in your terminal 27 | 28 | - The documentation is now built and stored under the directory 29 | ```rest/__build__``` 30 | 31 | - Run ```make serve``` to view the documentation on your browser or navigate to the repository. 32 | 33 | - Please create a PR after you have made your changes (see [commit your changes](https://pubhub.devnetcloud.com/media/pyats-development-guide/docs/contribute/contribute.html#commit-your-changes) & [open a PR](https://pubhub.devnetcloud.com/media/pyats-development-guide/docs/contribute/contribute.html#open-a-pull-request)) 34 | 35 | Here are a few examples that could be great pull request: 36 | 37 | - Fix Typos 38 | - Better wording, easier explanation 39 | - More details, examples 40 | - Anything else to enhance the documentation 41 | 42 | #### How to contribute to the pyATS community 43 | 44 | - For detail on contributing to pyATS, please follow the [contribution guidelines](https://pubhub.devnetcloud.com/media/pyats-development-guide/docs/contribute/contribute.html#) 45 | -------------------------------------------------------------------------------- /docs/apidoc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " applehelp to make an Apple Help Book" 34 | @echo " devhelp to make HTML files and a Devhelp project" 35 | @echo " epub to make an epub" 36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 37 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 39 | @echo " text to make text files" 40 | @echo " man to make manual pages" 41 | @echo " texinfo to make Texinfo files" 42 | @echo " info to make Texinfo files and run them through makeinfo" 43 | @echo " gettext to make PO message catalogs" 44 | @echo " changes to make an overview of all changed/added/deprecated items" 45 | @echo " xml to make Docutils-native XML files" 46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 47 | @echo " linkcheck to check all external links for integrity" 48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 49 | @echo " coverage to run coverage check of the documentation (if enabled)" 50 | 51 | clean: 52 | rm -rf $(BUILDDIR)/* 53 | 54 | html: 55 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 56 | @echo 57 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 58 | 59 | dirhtml: 60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 61 | @echo 62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 63 | 64 | singlehtml: 65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 66 | @echo 67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 68 | 69 | pickle: 70 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 71 | @echo 72 | @echo "Build finished; now you can process the pickle files." 73 | 74 | json: 75 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 76 | @echo 77 | @echo "Build finished; now you can process the JSON files." 78 | 79 | htmlhelp: 80 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 81 | @echo 82 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 83 | ".hhp project file in $(BUILDDIR)/htmlhelp." 84 | 85 | qthelp: 86 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 87 | @echo 88 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 89 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 90 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Restapidoc.qhcp" 91 | @echo "To view the help file:" 92 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Restapidoc.qhc" 93 | 94 | applehelp: 95 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 96 | @echo 97 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 98 | @echo "N.B. You won't be able to view it unless you put it in" \ 99 | "~/Library/Documentation/Help or install it in your application" \ 100 | "bundle." 101 | 102 | devhelp: 103 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 104 | @echo 105 | @echo "Build finished." 106 | @echo "To view the help file:" 107 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Restapidoc" 108 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Restapidoc" 109 | @echo "# devhelp" 110 | 111 | epub: 112 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 113 | @echo 114 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 115 | 116 | latex: 117 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 118 | @echo 119 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 120 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 121 | "(use \`make latexpdf' here to do that automatically)." 122 | 123 | latexpdf: 124 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 125 | @echo "Running LaTeX files through pdflatex..." 126 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 127 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 128 | 129 | latexpdfja: 130 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 131 | @echo "Running LaTeX files through platex and dvipdfmx..." 132 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 133 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 134 | 135 | text: 136 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 137 | @echo 138 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 139 | 140 | man: 141 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 142 | @echo 143 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 144 | 145 | texinfo: 146 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 147 | @echo 148 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 149 | @echo "Run \`make' in that directory to run these through makeinfo" \ 150 | "(use \`make info' here to do that automatically)." 151 | 152 | info: 153 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 154 | @echo "Running Texinfo files through makeinfo..." 155 | make -C $(BUILDDIR)/texinfo info 156 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 157 | 158 | gettext: 159 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 160 | @echo 161 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 162 | 163 | changes: 164 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 165 | @echo 166 | @echo "The overview file is in $(BUILDDIR)/changes." 167 | 168 | linkcheck: 169 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 170 | @echo 171 | @echo "Link check complete; look for any errors in the above output " \ 172 | "or in $(BUILDDIR)/linkcheck/output.txt." 173 | 174 | doctest: 175 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 176 | @echo "Testing of doctests in the sources finished, look at the " \ 177 | "results in $(BUILDDIR)/doctest/output.txt." 178 | 179 | coverage: 180 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 181 | @echo "Testing of coverage in the sources finished, look at the " \ 182 | "results in $(BUILDDIR)/coverage/python.txt." 183 | 184 | xml: 185 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 186 | @echo 187 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 188 | 189 | pseudoxml: 190 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 191 | @echo 192 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 193 | -------------------------------------------------------------------------------- /docs/apidoc/index.rst: -------------------------------------------------------------------------------- 1 | .. Rest apidoc documentation master file, created by 2 | sphinx-quickstart on Wed May 17 14:12:43 2017. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Apidoc 7 | ====== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 4 13 | 14 | rest 15 | 16 | -------------------------------------------------------------------------------- /docs/apidoc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | echo. coverage to run coverage check of the documentation if enabled 41 | goto end 42 | ) 43 | 44 | if "%1" == "clean" ( 45 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 46 | del /q /s %BUILDDIR%\* 47 | goto end 48 | ) 49 | 50 | 51 | REM Check if sphinx-build is available and fallback to Python version if any 52 | %SPHINXBUILD% 2> nul 53 | if errorlevel 9009 goto sphinx_python 54 | goto sphinx_ok 55 | 56 | :sphinx_python 57 | 58 | set SPHINXBUILD=python -m sphinx.__init__ 59 | %SPHINXBUILD% 2> nul 60 | if errorlevel 9009 ( 61 | echo. 62 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 63 | echo.installed, then set the SPHINXBUILD environment variable to point 64 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 65 | echo.may add the Sphinx directory to PATH. 66 | echo. 67 | echo.If you don't have Sphinx installed, grab it from 68 | echo.http://sphinx-doc.org/ 69 | exit /b 1 70 | ) 71 | 72 | :sphinx_ok 73 | 74 | 75 | if "%1" == "html" ( 76 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 77 | if errorlevel 1 exit /b 1 78 | echo. 79 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 80 | goto end 81 | ) 82 | 83 | if "%1" == "dirhtml" ( 84 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 85 | if errorlevel 1 exit /b 1 86 | echo. 87 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 88 | goto end 89 | ) 90 | 91 | if "%1" == "singlehtml" ( 92 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 93 | if errorlevel 1 exit /b 1 94 | echo. 95 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 96 | goto end 97 | ) 98 | 99 | if "%1" == "pickle" ( 100 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 101 | if errorlevel 1 exit /b 1 102 | echo. 103 | echo.Build finished; now you can process the pickle files. 104 | goto end 105 | ) 106 | 107 | if "%1" == "json" ( 108 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 109 | if errorlevel 1 exit /b 1 110 | echo. 111 | echo.Build finished; now you can process the JSON files. 112 | goto end 113 | ) 114 | 115 | if "%1" == "htmlhelp" ( 116 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 117 | if errorlevel 1 exit /b 1 118 | echo. 119 | echo.Build finished; now you can run HTML Help Workshop with the ^ 120 | .hhp project file in %BUILDDIR%/htmlhelp. 121 | goto end 122 | ) 123 | 124 | if "%1" == "qthelp" ( 125 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 129 | .qhcp project file in %BUILDDIR%/qthelp, like this: 130 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Restapidoc.qhcp 131 | echo.To view the help file: 132 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Restapidoc.ghc 133 | goto end 134 | ) 135 | 136 | if "%1" == "devhelp" ( 137 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 138 | if errorlevel 1 exit /b 1 139 | echo. 140 | echo.Build finished. 141 | goto end 142 | ) 143 | 144 | if "%1" == "epub" ( 145 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 146 | if errorlevel 1 exit /b 1 147 | echo. 148 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 149 | goto end 150 | ) 151 | 152 | if "%1" == "latex" ( 153 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 154 | if errorlevel 1 exit /b 1 155 | echo. 156 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 157 | goto end 158 | ) 159 | 160 | if "%1" == "latexpdf" ( 161 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 162 | cd %BUILDDIR%/latex 163 | make all-pdf 164 | cd %~dp0 165 | echo. 166 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 167 | goto end 168 | ) 169 | 170 | if "%1" == "latexpdfja" ( 171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 172 | cd %BUILDDIR%/latex 173 | make all-pdf-ja 174 | cd %~dp0 175 | echo. 176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 177 | goto end 178 | ) 179 | 180 | if "%1" == "text" ( 181 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 182 | if errorlevel 1 exit /b 1 183 | echo. 184 | echo.Build finished. The text files are in %BUILDDIR%/text. 185 | goto end 186 | ) 187 | 188 | if "%1" == "man" ( 189 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 190 | if errorlevel 1 exit /b 1 191 | echo. 192 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 193 | goto end 194 | ) 195 | 196 | if "%1" == "texinfo" ( 197 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 198 | if errorlevel 1 exit /b 1 199 | echo. 200 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 201 | goto end 202 | ) 203 | 204 | if "%1" == "gettext" ( 205 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 206 | if errorlevel 1 exit /b 1 207 | echo. 208 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 209 | goto end 210 | ) 211 | 212 | if "%1" == "changes" ( 213 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 214 | if errorlevel 1 exit /b 1 215 | echo. 216 | echo.The overview file is in %BUILDDIR%/changes. 217 | goto end 218 | ) 219 | 220 | if "%1" == "linkcheck" ( 221 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 222 | if errorlevel 1 exit /b 1 223 | echo. 224 | echo.Link check complete; look for any errors in the above output ^ 225 | or in %BUILDDIR%/linkcheck/output.txt. 226 | goto end 227 | ) 228 | 229 | if "%1" == "doctest" ( 230 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 231 | if errorlevel 1 exit /b 1 232 | echo. 233 | echo.Testing of doctests in the sources finished, look at the ^ 234 | results in %BUILDDIR%/doctest/output.txt. 235 | goto end 236 | ) 237 | 238 | if "%1" == "coverage" ( 239 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage 240 | if errorlevel 1 exit /b 1 241 | echo. 242 | echo.Testing of coverage in the sources finished, look at the ^ 243 | results in %BUILDDIR%/coverage/python.txt. 244 | goto end 245 | ) 246 | 247 | if "%1" == "xml" ( 248 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 249 | if errorlevel 1 exit /b 1 250 | echo. 251 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 252 | goto end 253 | ) 254 | 255 | if "%1" == "pseudoxml" ( 256 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 257 | if errorlevel 1 exit /b 1 258 | echo. 259 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 260 | goto end 261 | ) 262 | 263 | :end 264 | -------------------------------------------------------------------------------- /docs/apidoc/rest.connector.libs.rst: -------------------------------------------------------------------------------- 1 | rest.connector.libs package 2 | =========================== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | apic 8 | ^^^^ 9 | .. automodule:: rest.connector.libs.apic.implementation 10 | :members: 11 | :undoc-members: 12 | :show-inheritance: 13 | 14 | dnac 15 | ^^^^ 16 | .. automodule:: rest.connector.libs.dnac.implementation 17 | :members: 18 | :undoc-members: 19 | :show-inheritance: 20 | 21 | iosxe 22 | ^^^^ 23 | .. automodule:: rest.connector.libs.iosxe.implementation 24 | :members: 25 | :undoc-members: 26 | :show-inheritance: 27 | 28 | nd 29 | ^^^^ 30 | .. automodule:: rest.connector.libs.nd.implementation 31 | :members: 32 | :undoc-members: 33 | :show-inheritance: 34 | 35 | nso 36 | ^^^^ 37 | .. automodule:: rest.connector.libs.nso.implementation 38 | :members: 39 | :undoc-members: 40 | :show-inheritance: 41 | 42 | nxos 43 | ^^^^ 44 | .. automodule:: rest.connector.libs.nxos.implementation 45 | :members: 46 | :undoc-members: 47 | :show-inheritance: 48 | 49 | virl 50 | ^^^^ 51 | .. automodule:: rest.connector.libs.virl.implementation 52 | :members: 53 | :undoc-members: 54 | :show-inheritance: 55 | 56 | Module contents 57 | --------------- 58 | 59 | .. automodule:: rest.connector.libs 60 | :members: 61 | :undoc-members: 62 | :show-inheritance: 63 | -------------------------------------------------------------------------------- /docs/apidoc/rest.connector.rst: -------------------------------------------------------------------------------- 1 | rest.connector package 2 | ====================== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | rest.connector.tests 10 | rest.connector.libs 11 | 12 | Module contents 13 | --------------- 14 | 15 | .. automodule:: rest.connector 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | -------------------------------------------------------------------------------- /docs/apidoc/rest.connector.tests.rst: -------------------------------------------------------------------------------- 1 | rest.connector.tests package 2 | ============================ 3 | 4 | Module contents 5 | --------------- 6 | 7 | .. automodule:: rest.connector.tests 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | -------------------------------------------------------------------------------- /docs/apidoc/rest.rst: -------------------------------------------------------------------------------- 1 | rest package 2 | ============ 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | rest.connector 10 | 11 | Module contents 12 | --------------- 13 | 14 | .. automodule:: rest 15 | :members: 16 | :undoc-members: 17 | :show-inheritance: 18 | -------------------------------------------------------------------------------- /docs/changelog/2017/june.rst: -------------------------------------------------------------------------------- 1 | June 2017 2 | ========= 3 | 4 | June 6 5 | ------ 6 | 7 | .. csv-table:: Module Versions 8 | :header: "Modules", "Versions" 9 | 10 | ``rest.connector``, v1.0.0 11 | 12 | Features: 13 | ^^^^^^^^^ 14 | 15 | Initial introduction of ``REST`` package. 16 | 17 | -------------------------------------------------------------------------------- /docs/changelog/2018/november.rst: -------------------------------------------------------------------------------- 1 | November 2018 2 | ============= 3 | 4 | November 13 5 | ----------- 6 | 7 | .. csv-table:: Module Versions 8 | :header: "Modules", "Versions" 9 | 10 | ``rest.connector``, v1.0.3 11 | 12 | Bug fix: 13 | ^^^^^^^^^ 14 | 15 | Modification to rest.connector to support new abstract imports. 16 | 17 | -------------------------------------------------------------------------------- /docs/changelog/2019/august.rst: -------------------------------------------------------------------------------- 1 | August 2019 2 | =========== 3 | 4 | Aug 27, 2019 5 | ------------ 6 | 7 | .. csv-table:: Module Versions 8 | :header: "Modules", "Versions" 9 | 10 | ``rest.connector``, v19.8.1 11 | 12 | Changes 13 | ------- 14 | 15 | - Added VIRL REST Connector fix, by Takashi Higashimura (tahigash) 16 | 17 | 18 | .. csv-table:: Module Versions 19 | :header: "Modules", "Versions" 20 | 21 | ``rest.connector``, v19.8 22 | 23 | Changes 24 | ------- 25 | 26 | - Added proxies argument to iosxe plugin 27 | 28 | 29 | Aug 8, 2019 30 | ----------- 31 | 32 | 33 | .. csv-table:: Module Versions 34 | :header: "Modules", "Versions" 35 | 36 | ``rest.connector``, v19.7.1 37 | 38 | Changes 39 | ------- 40 | 41 | - Fix up for dependencies to genie.abstract 42 | -------------------------------------------------------------------------------- /docs/changelog/2019/dec.rst: -------------------------------------------------------------------------------- 1 | Dec 2019 2 | ======== 3 | 4 | .. csv-table:: Module Versions 5 | :header: "Modules", "Versions" 6 | 7 | ``rest.connector``, v19.12 8 | 9 | Changes 10 | ------- 11 | 12 | - Added F5 (BigIP) REST Connector implementation, by Mirza Waqas Ahmed (mirzawaqasahmed) 13 | 14 | -------------------------------------------------------------------------------- /docs/changelog/2019/jul.rst: -------------------------------------------------------------------------------- 1 | July 2019 2 | ========= 3 | 4 | .. csv-table:: Module Versions 5 | :header: "Modules", "Versions" 6 | 7 | ``rest.connector``, v19.7 8 | 9 | Changes 10 | ------- 11 | 12 | - Added NXOS REST Connector fix, by Saravanakumar Mariyappan (smariyap) 13 | - Integrated with pyATS credentials feature. 14 | -------------------------------------------------------------------------------- /docs/changelog/2019/june.rst: -------------------------------------------------------------------------------- 1 | June 2019 2 | ========= 3 | 4 | .. csv-table:: Module Versions 5 | :header: "Modules", "Versions" 6 | 7 | ``rest.connector``, v19.6.0 8 | 9 | Changes 10 | ------- 11 | 12 | - Added IOSXE REST Connector implementation, by Maaz Mashood Mohiuddin (mmashood) 13 | - Added DNAC REST Connector implementation 14 | -------------------------------------------------------------------------------- /docs/changelog/2019/sept.rst: -------------------------------------------------------------------------------- 1 | September 2019 2 | ============== 3 | 4 | Sept 24 5 | ------- 6 | 7 | .. csv-table:: Module Versions 8 | :header: "Modules", "Versions" 9 | 10 | ``rest.connector``, v19.9.0 11 | 12 | Changes 13 | ------- 14 | 15 | - modified dnac connector to prefer host instead of ip 16 | - dnac plugin now enforces header to application/json content-type -------------------------------------------------------------------------------- /docs/changelog/2020/april.rst: -------------------------------------------------------------------------------- 1 | April 2020 2 | ========== 3 | 4 | April 28 5 | -------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 20.4 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | 14 | Features: 15 | ^^^^^^^^^ 16 | 17 | * Fixed login_url on IOSXE (removed 'webui') -------------------------------------------------------------------------------- /docs/changelog/2020/august.rst: -------------------------------------------------------------------------------- 1 | August 2020 2 | ========== 3 | 4 | August 25 5 | -------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 20.8 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | 14 | Features: 15 | ^^^^^^^^^ 16 | 17 | * Fixed timeout issue in `connect()` 18 | * Fixed issue with nxos _request() method when using expected_return_code 19 | -------------------------------------------------------------------------------- /docs/changelog/2020/december.rst: -------------------------------------------------------------------------------- 1 | December 2020 2 | ============= 3 | 4 | December 15 5 | ----------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 20.12 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | 14 | Features: 15 | ^^^^^^^^^ 16 | 17 | * Added platform abstraction to REST 18 | * Moved APIC implementation into NXOS/ACI 19 | -------------------------------------------------------------------------------- /docs/changelog/2020/july.rst: -------------------------------------------------------------------------------- 1 | July 2020 2 | ========== 3 | 4 | July 28 5 | -------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 20.7 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | 14 | Features: 15 | ^^^^^^^^^ 16 | 17 | * nxos connector now accepts expected return code as argument 18 | -------------------------------------------------------------------------------- /docs/changelog/2020/june.rst: -------------------------------------------------------------------------------- 1 | June 2020 2 | ========== 3 | 4 | July 7 5 | -------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 20.6 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | 14 | Features: 15 | ^^^^^^^^^ 16 | 17 | * No new features -------------------------------------------------------------------------------- /docs/changelog/2020/may.rst: -------------------------------------------------------------------------------- 1 | May 2020 2 | ========== 3 | 4 | May 26 5 | -------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 20.5 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | 14 | Features: 15 | ^^^^^^^^^ 16 | 17 | * No new features -------------------------------------------------------------------------------- /docs/changelog/2020/october.rst: -------------------------------------------------------------------------------- 1 | October 2020 2 | ============ 3 | 4 | October 27 5 | ---------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector`` | 20.10 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | 14 | Features: 15 | ^^^^^^^^^ 16 | 17 | * No change 18 | -------------------------------------------------------------------------------- /docs/changelog/2020/september.rst: -------------------------------------------------------------------------------- 1 | September 2020 2 | ========== 3 | 4 | September 29 5 | -------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 20.9 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | 14 | Features: 15 | ^^^^^^^^^ 16 | 17 | * Added logging for nxos response 18 | * Added DCNM support 19 | -------------------------------------------------------------------------------- /docs/changelog/2021/april.rst: -------------------------------------------------------------------------------- 1 | April 2021 2 | ========== 3 | 4 | April 27 5 | -------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.4 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | 24 | * WebEx connector 25 | * Added elasticsearch connector implementation 26 | 27 | * Viptela connector 28 | * Fixed authentication check for vManage 29 | 30 | -------------------------------------------------------------------------------- /docs/changelog/2021/august.rst: -------------------------------------------------------------------------------- 1 | August 2021 2 | ========= 3 | 4 | August 31 5 | ------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.8 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | 24 | * APIC 25 | * Added XML payload option to push method 26 | * APIC 27 | * Added ACI SDK connector (based on APIC Cobra SDK libraries) 28 | * Nexus Dashboard (ND) 29 | * Added Nexus Dashboard (ND) rest connector 30 | -------------------------------------------------------------------------------- /docs/changelog/2021/december.rst: -------------------------------------------------------------------------------- 1 | December 2021 2 | ========== 3 | 4 | December 14 - Rest v21.12 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 21.12 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2021/february.rst: -------------------------------------------------------------------------------- 1 | February 2021 2 | ============ 3 | 4 | February 27 5 | ---------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.2 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | 24 | * Updated docs 25 | * Added port arguments -------------------------------------------------------------------------------- /docs/changelog/2021/january.rst: -------------------------------------------------------------------------------- 1 | January 2021 2 | ============ 3 | 4 | January 27 5 | ---------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.1 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | * Moved APIC implementation from NXOS/ACI to APIC 24 | 25 | * IOSXE 26 | * Added sshtunnel support 27 | * Added protocol key in testbed yaml. Default to https 28 | * NXOS 29 | * Added sshtunnel support 30 | * Added protocol key in testbed yaml. Default to https 31 | * VIRL 32 | * Added sshtunnel support 33 | * Added protocol key in testbed yaml. Default to http 34 | * DCNM 35 | * Added sshtunnel support 36 | * Added protocol key in testbed yaml. Default to https 37 | * NSO 38 | * Added sshtunnel support 39 | * Added protocol key in testbed yaml. Default to http 40 | * Viptela 41 | * Added sshtunnel support 42 | * Added protocol key in testbed yaml. Default to https 43 | * BIG-IP 44 | * Added sshtunnel support 45 | * Added protocol key in testbed yaml. Default to https 46 | -------------------------------------------------------------------------------- /docs/changelog/2021/july.rst: -------------------------------------------------------------------------------- 1 | July 2021 2 | ========= 3 | 4 | July 27 5 | ------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.7 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | 24 | No changes 25 | -------------------------------------------------------------------------------- /docs/changelog/2021/june.rst: -------------------------------------------------------------------------------- 1 | June 2021 2 | ========= 3 | 4 | June 29 5 | ------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.6 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | 24 | * NXOS 25 | * Added retry logic 26 | -------------------------------------------------------------------------------- /docs/changelog/2021/march.rst: -------------------------------------------------------------------------------- 1 | March 2021 2 | ========== 3 | 4 | March 30 5 | -------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.3 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | 24 | * WebEx connector 25 | * Added webex connector implementation 26 | -------------------------------------------------------------------------------- /docs/changelog/2021/may.rst: -------------------------------------------------------------------------------- 1 | May 2021 2 | ======== 3 | 4 | May 25 5 | ------ 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.5 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | 24 | No changes 25 | -------------------------------------------------------------------------------- /docs/changelog/2021/september.rst: -------------------------------------------------------------------------------- 1 | September 2021 2 | ========= 3 | 4 | September 28 5 | ------- 6 | 7 | +-------------------------------+-------------------------------+ 8 | | Module | Versions | 9 | +===============================+===============================+ 10 | | ``rest.connector `` | 21.9 | 11 | +-------------------------------+-------------------------------+ 12 | 13 | Upgrade Instructions 14 | ^^^^^^^^^^^^^^^^^^^^ 15 | 16 | .. code-block:: bash 17 | 18 | pip install --upgrade rest.connector 19 | 20 | 21 | Features: 22 | ^^^^^^^^^ 23 | 24 | No changes -------------------------------------------------------------------------------- /docs/changelog/2022/april.rst: -------------------------------------------------------------------------------- 1 | April 2022 2 | ========== 3 | 4 | April 25 - Rest v22.4 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.4 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2022/august.rst: -------------------------------------------------------------------------------- 1 | August 2022 2 | ========== 3 | 4 | August 26 - Rest v22.8 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.8 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- 28 | Fix 29 | -------------------------------------------------------------------------------- 30 | 31 | * nexus dashboard (nd) 32 | * Added content_type parameter to post and put api 33 | * Prevented an error from being raised if response does not contain a json, 34 | 35 | 36 | -------------------------------------------------------------------------------- /docs/changelog/2022/february.rst: -------------------------------------------------------------------------------- 1 | February 2022 2 | ============= 3 | 4 | February 24 - Rest v22.2 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.2 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2022/january.rst: -------------------------------------------------------------------------------- 1 | January 2022 2 | ========== 3 | 4 | January 25 - Rest v22.1 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.1 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | Features: 24 | ^^^^^^^^^ 25 | * APIC 26 | * Added order_by argument to GET operation -------------------------------------------------------------------------------- /docs/changelog/2022/july.rst: -------------------------------------------------------------------------------- 1 | July 2022 2 | ========== 3 | 4 | July 26 - Rest v22.7 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.7 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Features and Bug Fixes: 26 | ^^^^^^^^^^^^^^^^^^^^^^^ 27 | 28 | -------------------------------------------------------------------------------- 29 | Fix 30 | -------------------------------------------------------------------------------- 31 | * Playback 32 | * Modified _mock_helper: 33 | * Added dictionary to support IOSXR mock data generation -------------------------------------------------------------------------------- /docs/changelog/2022/june.rst: -------------------------------------------------------------------------------- 1 | June 2022 2 | ========== 3 | 4 | June 27 - Rest v22.6 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.6 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2022/march.rst: -------------------------------------------------------------------------------- 1 | March 2022 2 | ========== 3 | 4 | March 29 - Rest v22.3 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.3 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2022/may.rst: -------------------------------------------------------------------------------- 1 | May 2022 2 | ========== 3 | 4 | May 30 - Rest v22.5 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.5 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2022/november.rst: -------------------------------------------------------------------------------- 1 | November 2022 2 | ========== 3 | 4 | November 28 - Rest v22.11 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.11 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2022/october.rst: -------------------------------------------------------------------------------- 1 | October 2022 2 | ========== 3 | 4 | October 25 - Rest v22.10 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.10 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2022/september.rst: -------------------------------------------------------------------------------- 1 | September 2022 2 | ========== 3 | 4 | September 23 - Rest v22.9 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 22.9 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/april.rst: -------------------------------------------------------------------------------- 1 | April 2023 2 | ========== 3 | 4 | April 25 - Rest v23.4 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.4 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/august.rst: -------------------------------------------------------------------------------- 1 | August 2023 2 | ========== 3 | 4 | August 29 - Rest v23.8 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.8 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/february.rst: -------------------------------------------------------------------------------- 1 | February 2023 2 | ========== 3 | 4 | February 28 - Rest v23.2 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.2 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/january.rst: -------------------------------------------------------------------------------- 1 | January 2023 2 | ========== 3 | 4 | January 31 - Rest v23.1 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.1 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/july.rst: -------------------------------------------------------------------------------- 1 | July 2023 2 | ========== 3 | 4 | July 25 - Rest v23.7 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.7 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/june.rst: -------------------------------------------------------------------------------- 1 | June 2023 2 | ========== 3 | 4 | June 27 - Rest v23.6 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.6 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/march.rst: -------------------------------------------------------------------------------- 1 | March 2023 2 | ========== 3 | 4 | March 28 - Rest v23.3 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.3 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/may.rst: -------------------------------------------------------------------------------- 1 | May 2023 2 | ========== 3 | 4 | May 30 - Rest v23.5 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.5 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/november.rst: -------------------------------------------------------------------------------- 1 | November 2023 2 | ========== 3 | 4 | November 27 - Rest v23.11 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.11 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/october.rst: -------------------------------------------------------------------------------- 1 | October 2023 2 | ========== 3 | 4 | October 31 - Rest v23.10 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.10 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2023/september.rst: -------------------------------------------------------------------------------- 1 | September 2023 2 | ========== 3 | 4 | September 26 - Rest v23.9 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 23.9 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- 28 | Fix 29 | -------------------------------------------------------------------------------- 30 | 31 | * rest 32 | * Updated IOSXE Implimentation 33 | * Changed "connect" method 34 | * Send a GET request to a common "well-known" IOS-XE YANG model (path /Cisco-IOS-XE-nativenative/version) 35 | * Debug output to include the received data from the device 36 | * Content-Type header is not used (default_content_type parameter) 37 | 38 | 39 | -------------------------------------------------------------------------------- /docs/changelog/2024/September.rst: -------------------------------------------------------------------------------- 1 | September 2024 2 | ========== 3 | 4 | September 24 - Rest v24.9 5 | ------------------------ 6 | 7 | 8 | 9 | .. csv-table:: New Module Versions 10 | :header: "Modules", "Version" 11 | 12 | ``rest.connector``, v24.9 13 | 14 | 15 | 16 | 17 | Changelogs 18 | ^^^^^^^^^^ 19 | -------------------------------------------------------------------------------- /docs/changelog/2024/april.rst: -------------------------------------------------------------------------------- 1 | April 2024 2 | ========== 3 | 4 | - Rest v24.4 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 24.4 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/august.rst: -------------------------------------------------------------------------------- 1 | August 2024 2 | ========== 3 | 4 | August 27 - Rest v24.8 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 24.8 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/february.rst: -------------------------------------------------------------------------------- 1 | February 2024 2 | ========== 3 | 4 | February 27 - Rest v24.2 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 24.2 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/january.rst: -------------------------------------------------------------------------------- 1 | January 2024 2 | ========== 3 | 4 | 30 - Rest v24.1 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 24.1 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/july.rst: -------------------------------------------------------------------------------- 1 | July 2024 2 | ========== 3 | 4 | July 30 - Rest v24.7 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 24.7 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/june.rst: -------------------------------------------------------------------------------- 1 | June 2024 2 | ========== 3 | 4 | - Rest v24.6 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 24.6 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/march.rst: -------------------------------------------------------------------------------- 1 | March 2024 2 | ========== 3 | 4 | - Rest v24.3 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 24.3 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/may.rst: -------------------------------------------------------------------------------- 1 | May 2024 2 | ========== 3 | 4 | May 28 - Rest v24.5 5 | ------------------------ 6 | 7 | 8 | 9 | +-------------------------------+-------------------------------+ 10 | | Module | Versions | 11 | +===============================+===============================+ 12 | | ``rest.connector `` | 24.5 | 13 | +-------------------------------+-------------------------------+ 14 | 15 | Upgrade Instructions 16 | ^^^^^^^^^^^^^^^^^^^^ 17 | 18 | .. code-block:: bash 19 | 20 | pip install --upgrade rest.connector 21 | 22 | 23 | 24 | 25 | Changelogs 26 | ^^^^^^^^^^ 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/november.rst: -------------------------------------------------------------------------------- 1 | November 2024 2 | ========== 3 | 4 | November 26 - Rest v24.11 5 | ------------------------ 6 | 7 | 8 | 9 | .. csv-table:: New Module Versions 10 | :header: "Modules", "Version" 11 | 12 | ``rest.connector``, v24.11 13 | 14 | 15 | 16 | 17 | Changelogs 18 | ^^^^^^^^^^ 19 | -------------------------------------------------------------------------------- 20 | New 21 | -------------------------------------------------------------------------------- 22 | 23 | * connector 24 | * Add ISE connector base implementation 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/changelog/2024/october.rst: -------------------------------------------------------------------------------- 1 | October 2024 2 | ========== 3 | 4 | October 29 - Rest v24.10 5 | ------------------------ 6 | 7 | 8 | 9 | .. csv-table:: New Module Versions 10 | :header: "Modules", "Version" 11 | 12 | ``rest.connector``, v24.10 13 | 14 | 15 | 16 | 17 | Changelogs 18 | ^^^^^^^^^^ 19 | -------------------------------------------------------------------------------- /docs/changelog/2025/april.rst: -------------------------------------------------------------------------------- 1 | April 2025 2 | ========== 3 | 4 | April 29 - Rest v25.4 5 | ------------------------ 6 | 7 | 8 | 9 | .. csv-table:: New Module Versions 10 | :header: "Modules", "Version" 11 | 12 | ``rest.connector``, v25.4 13 | 14 | 15 | 16 | 17 | Changelogs 18 | ^^^^^^^^^^ 19 | -------------------------------------------------------------------------------- 20 | New 21 | -------------------------------------------------------------------------------- 22 | 23 | * ise 24 | * Modified connect 25 | * added better logging for ise. 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/changelog/2025/february.rst: -------------------------------------------------------------------------------- 1 | February 2025 2 | ========== 3 | 4 | February 25 - Rest v25.2 5 | ------------------------ 6 | 7 | 8 | 9 | .. csv-table:: New Module Versions 10 | :header: "Modules", "Version" 11 | 12 | ``rest.connector``, v25.2 13 | 14 | 15 | 16 | 17 | Changelogs 18 | ^^^^^^^^^^ 19 | -------------------------------------------------------------------------------- /docs/changelog/2025/january.rst: -------------------------------------------------------------------------------- 1 | January 2025 2 | ========== 3 | 4 | - Rest v25.1 5 | ------------------------ 6 | 7 | 8 | 9 | .. csv-table:: New Module Versions 10 | :header: "Modules", "Version" 11 | 12 | ``rest.connector``, v25.1 13 | 14 | 15 | 16 | 17 | Changelogs 18 | ^^^^^^^^^^ 19 | -------------------------------------------------------------------------------- 20 | Fix 21 | -------------------------------------------------------------------------------- 22 | 23 | * connector 24 | * NXOS 25 | * Set session wide SSL verification to False for HTTPS URLs 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/changelog/2025/march.rst: -------------------------------------------------------------------------------- 1 | March 2025 2 | ========== 3 | 4 | March 25 - Rest v25.3 5 | ------------------------ 6 | 7 | 8 | 9 | .. csv-table:: New Module Versions 10 | :header: "Modules", "Version" 11 | 12 | ``rest.connector``, v25.3 13 | 14 | 15 | 16 | 17 | Changelogs 18 | ^^^^^^^^^^ 19 | -------------------------------------------------------------------------------- /docs/changelog/2025/may.rst: -------------------------------------------------------------------------------- 1 | May 2025 2 | ========== 3 | 4 | - Rest v25.5 5 | ------------------------ 6 | 7 | 8 | 9 | .. csv-table:: New Module Versions 10 | :header: "Modules", "Version" 11 | 12 | ``rest.connector``, v25.5 13 | 14 | 15 | 16 | 17 | Changelogs 18 | ^^^^^^^^^^ 19 | -------------------------------------------------------------------------------- /docs/changelog/index.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | 2025/may 8 | 2025/april 9 | 2025/march 10 | 2025/february 11 | 2025/january 12 | 2024/november 13 | 2024/october 14 | 2024/September 15 | 2024/august 16 | 2024/july 17 | 2024/june 18 | 2024/may 19 | 2024/april 20 | 2024/march 21 | 2024/february 22 | 2024/january 23 | 2023/november 24 | 2023/october 25 | 2023/september 26 | 2023/august 27 | 2023/july 28 | 2023/june 29 | 2023/may 30 | 2023/april 31 | 2023/march 32 | 2023/february 33 | 2023/january 34 | 2022/november 35 | 2022/october 36 | 2022/september 37 | 2022/august 38 | 2022/july 39 | 2022/june 40 | 2022/may 41 | 2022/april 42 | 2022/march 43 | 2022/february 44 | 2022/january 45 | 2021/december 46 | 2021/october 47 | 2021/september 48 | 2021/august 49 | 2021/july 50 | 2021/june 51 | 2021/may 52 | 2021/april 53 | 2021/march 54 | 2021/february 55 | 2021/january 56 | 2020/october 57 | 2020/september 58 | 2020/august 59 | 2020/july 60 | 2020/june 61 | 2020/may 62 | 2020/april 63 | 2019/dec 64 | 2019/sept 65 | 2019/august 66 | 2019/jul 67 | 2019/june 68 | 2018/november 69 | 2017/june 70 | -------------------------------------------------------------------------------- /docs/changelog/undistributed/template.rst: -------------------------------------------------------------------------------- 1 | Only one changelog file per pull request. Combine these two templates where applicable. 2 | 3 | Templates 4 | ========= 5 | 6 | -------------------------------------------------------------------------------- 7 | New 8 | -------------------------------------------------------------------------------- 9 | * 10 | * : 11 | * 12 | 13 | -------------------------------------------------------------------------------- 14 | Fix 15 | -------------------------------------------------------------------------------- 16 | * 17 | * : 18 | * 19 | 20 | Examples 21 | ======== 22 | 23 | -------------------------------------------------------------------------------- 24 | New 25 | -------------------------------------------------------------------------------- 26 | * feature 27 | * Modified Connect: 28 | * Change var to variable 29 | * Updated regex pattern to accommodate various outputs. 30 | * Added keys , into the schema. -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Rest documentation build configuration file, created by 4 | # sphinx-quickstart on Tue Sep 29 09:59:47 2015. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | from datetime import datetime 18 | import sphinx_rtd_theme 19 | 20 | # If extensions (or modules to document with autodoc) are in another directory, 21 | # add these directories to sys.path here. If the directory is relative to the 22 | # documentation root, use os.path.abspath to make it absolute, like shown here. 23 | sys.path.insert(0, os.path.abspath('../')) 24 | 25 | # -- General configuration ------------------------------------------------ 26 | 27 | # If your documentation needs a minimal Sphinx version, state it here. 28 | #needs_sphinx = '1.0' 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [ 34 | 'sphinx.ext.autodoc', 35 | 'sphinx.ext.intersphinx', 36 | 'sphinx.ext.napoleon', 37 | ] 38 | 39 | 40 | # Add any paths that contain templates here, relative to this directory. 41 | templates_path = [] 42 | 43 | # The suffix of source filenames. 44 | source_suffix = '.rst' 45 | 46 | # The encoding of source files. 47 | #source_encoding = 'utf-8-sig' 48 | 49 | # The master toctree document. 50 | master_doc = 'index' 51 | 52 | # General information about the project. 53 | project = 'Rest' 54 | copyright = '%s, Cisco Systems Inc' % datetime.now().year 55 | 56 | # The version info for the project you're documenting, acts as replacement for 57 | # |version| and |release|, also used in various other places throughout the 58 | # built documents. 59 | # 60 | # The short X.Y version. 61 | version = '1.0' 62 | # The full version, including alpha/beta/rc tags. 63 | release = '1.1.1' 64 | 65 | # The language for content autogenerated by Sphinx. Refer to documentation 66 | # for a list of supported languages. 67 | #language = None 68 | 69 | # There are two options for replacing |today|: either, you set today to some 70 | # non-false value, then it is used: 71 | #today = '' 72 | # Else, today_fmt is used as the format for a strftime call. 73 | #today_fmt = '%B %d, %Y' 74 | 75 | # List of patterns, relative to source directory, that match files and 76 | # directories to ignore when looking for source files. 77 | exclude_patterns = ['_build'] 78 | 79 | # The reST default role (used for this markup: `text`) to use for all 80 | # documents. 81 | default_role = 'py:obj' 82 | 83 | # If true, '()' will be appended to :func: etc. cross-reference text. 84 | #add_function_parentheses = True 85 | 86 | # If true, the current module name will be prepended to all description 87 | # unit titles (such as .. function::). 88 | #add_module_names = True 89 | 90 | # If true, sectionauthor and moduleauthor directives will be shown in the 91 | # output. They are ignored by default. 92 | show_authors = True 93 | 94 | # The name of the Pygments (syntax highlighting) style to use. 95 | pygments_style = 'colorful' 96 | 97 | # A list of ignored prefixes for module index sorting. 98 | #modindex_common_prefix = [] 99 | 100 | # If true, keep warnings as "system message" paragraphs in the built documents. 101 | #keep_warnings = False 102 | 103 | 104 | # -- Options for HTML output ---------------------------------------------- 105 | 106 | # The theme to use for HTML and HTML Help pages. See the documentation for 107 | # a list of builtin themes. 108 | html_theme = 'sphinx_rtd_theme' 109 | 110 | #html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 111 | #html_theme = 'basicstrap' 112 | # 113 | # Theme options are theme-specific and customize the look and feel of a theme 114 | # further. For a list of options available for each theme, see the 115 | # documentation. 116 | #html_theme_options = {} 117 | 118 | # Add any paths that contain custom themes here, relative to this directory. 119 | 120 | # The name for this set of Sphinx documents. If None, it defaults to 121 | # " v documentation". 122 | html_title = 'Rest Documentation' 123 | 124 | # A shorter title for the navigation bar. Default is the same as html_title. 125 | html_short_title = 'Rest User Guide' 126 | 127 | # The name of an image file (relative to this directory) to place at the top 128 | # of the sidebar. 129 | #html_logo = None 130 | 131 | # The name of an image file (within the static path) to use as favicon of the 132 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 133 | # pixels large. 134 | #html_favicon = 'genie_ico.ico' 135 | 136 | # Add any paths that contain custom static files (such as style sheets) here, 137 | # relative to this directory. They are copied after the builtin static files, 138 | # so a file named "default.css" will overwrite the builtin "default.css". 139 | html_static_path = [] 140 | 141 | # Add any extra paths that contain custom files (such as robots.txt or 142 | # .htaccess) here, relative to this directory. These files are copied 143 | # directly to the root of the documentation. 144 | #html_extra_path = [] 145 | 146 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 147 | # using the given strftime format. 148 | html_last_updated_fmt = '%b %d, %Y' 149 | 150 | # If true, SmartyPants will be used to convert quotes and dashes to 151 | # typographically correct entities. 152 | #html_use_smartypants = True 153 | 154 | # Custom sidebar templates, maps document names to template names. 155 | #html_sidebars = {} 156 | 157 | # Additional templates that should be rendered to pages, maps page names to 158 | # template names. 159 | #html_additional_pages = {} 160 | 161 | # If false, no module index is generated. 162 | html_domain_indices = True 163 | 164 | # If false, no index is generated. 165 | html_use_index = True 166 | 167 | # If true, the index is split into individual pages for each letter. 168 | html_split_index = False 169 | 170 | # If true, links to the reST sources are added to the pages. 171 | html_show_sourcelink = False 172 | 173 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 174 | html_show_sphinx = False 175 | 176 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 177 | html_show_copyright = True 178 | 179 | # If true, an OpenSearch description file will be output, and all pages will 180 | # contain a tag referring to it. The value of this option must be the 181 | # base URL from which the finished HTML is served. 182 | #html_use_opensearch = '' 183 | 184 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 185 | #html_file_suffix = None 186 | 187 | # Output file base name for HTML help builder. 188 | htmlhelp_basename = 'RestDoc' 189 | 190 | 191 | # -- Options for LaTeX output --------------------------------------------- 192 | 193 | latex_elements = { 194 | # The paper size ('letterpaper' or 'a4paper'). 195 | #'papersize': 'letterpaper', 196 | 197 | # The font size ('10pt', '11pt' or '12pt'). 198 | #'pointsize': '10pt', 199 | 200 | # Additional stuff for the LaTeX preamble. 201 | #'preamble': '', 202 | } 203 | 204 | # Grouping the document tree into LaTeX files. List of tuples 205 | # (source start file, target name, title, 206 | # author, documentclass [howto, manual, or own class]). 207 | latex_documents = [ 208 | ('index', 'Rest.tex', 'Rest Documentation', 209 | 'pyats-support', 'manual'), 210 | ] 211 | 212 | # The name of an image file (relative to this directory) to place at the top of 213 | # the title page. 214 | #latex_logo = None 215 | 216 | # For "manual" documents, if this is true, then toplevel headings are parts, 217 | # not chapters. 218 | #latex_use_parts = False 219 | 220 | # If true, show page references after internal links. 221 | #latex_show_pagerefs = False 222 | 223 | # If true, show URL addresses after external links. 224 | #latex_show_urls = False 225 | 226 | # Documents to append as an appendix to all manuals. 227 | #latex_appendices = [] 228 | 229 | # If false, no module index is generated. 230 | #latex_domain_indices = True 231 | 232 | 233 | # -- Options for manual page output --------------------------------------- 234 | 235 | # One entry per manual page. List of tuples 236 | # (source start file, name, description, authors, manual section). 237 | man_pages = [ 238 | ('index', 'Rest', 'Rest Documentation', 239 | ['pyats-support'], 1) 240 | ] 241 | 242 | # If true, show URL addresses after external links. 243 | #man_show_urls = False 244 | 245 | 246 | # -- Options for Texinfo output ------------------------------------------- 247 | 248 | # Grouping the document tree into Texinfo files. List of tuples 249 | # (source start file, target name, title, author, 250 | # dir menu entry, description, category) 251 | texinfo_documents = [ 252 | ('index', 'Rest', 'Rest Documentation', 253 | 'pyats-support', 'Rest', 'Rest', 254 | 'Miscellaneous'), 255 | ] 256 | 257 | # Documents to append as an appendix to all manuals. 258 | #texinfo_appendices = [] 259 | 260 | # If false, no module index is generated. 261 | #texinfo_domain_indices = True 262 | 263 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 264 | #texinfo_show_urls = 'footnote' 265 | 266 | # If true, do not generate a @detailmenu in the "Top" node's menu. 267 | #texinfo_no_detailmenu = False 268 | 269 | 270 | # Example configuration for intersphinx: refer to the Python standard library. 271 | #intersphinx_mapping = {'http://docs.python.org/': None} 272 | 273 | # Napoleon config 274 | napoleon_use_admonition_for_examples = True 275 | 276 | ## Make sure that __init__ are printed in the doc 277 | #def skip(app, what, name, obj, skip, options): 278 | # if name == "__init__": 279 | # return False 280 | # return skip 281 | # 282 | #def setup(app): 283 | # app.connect("autodoc-skip-member", skip) 284 | # 285 | #autodoc_default_flags = ['members', 'private-members', 'special-members', 286 | # #'undoc-members', 287 | # 'show-inheritance'] 288 | autodoc_default_flags = ['inherited-members'] 289 | # 290 | # if name in exclusions: 291 | # return True 292 | # else: 293 | # return False 294 | # 295 | #def setup(app): 296 | # app.connect('autodoc-skip-member', autodoc_skip_member) 297 | 298 | autodoc_member_order = 'bysource' 299 | autoclass_content = 'both' 300 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | REST 2 | ==== 3 | 4 | `Rest` is a package containing a pyATS connection class implementation that 5 | allows pyATS scripts to connect to the device via `REST` using topology/YAML 6 | format. 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | 11 | user_guide/index 12 | apidoc/index 13 | changelog/index 14 | 15 | .. sectionauthor:: Jean-Benoit Aubin 16 | -------------------------------------------------------------------------------- /docs/user_guide/index.rst: -------------------------------------------------------------------------------- 1 | User Guide 2 | ========== 3 | 4 | This user guide explains installation, setup and usage of `rest.connector` 5 | library. 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | 10 | introduction 11 | installation 12 | services/index 13 | 14 | .. sectionauthor:: ATS Team 15 | -------------------------------------------------------------------------------- /docs/user_guide/installation.rst: -------------------------------------------------------------------------------- 1 | .. _installation: 2 | 3 | Installation 4 | ============ 5 | 6 | Installation & Upgrade 7 | ---------------------- 8 | 9 | The ``Rest`` package can be installed via `pip`. 10 | 11 | .. code-block:: bash 12 | 13 | pip install rest.connector 14 | 15 | -------------------------------------------------------------------------------- /docs/user_guide/introduction.rst: -------------------------------------------------------------------------------- 1 | 2 | Introduction 3 | ============ 4 | 5 | ``Rest`` is a pyATS connection class implementation that allows scripts to 6 | connect to a device using REST via topology/YAML format. 7 | 8 | The ``rest.connector`` module is abstraction enabled and currently supports 9 | only specific platforms. Please note that the custom abstraction keyword is 10 | required in the testbed.yaml file. 11 | 12 | 13 | Supported platforms 14 | ------------------- 15 | 16 | 17 | At the moment `rest.connector` supports the following platforms: 18 | 19 | .. csv-table:: Rest connector supported platforms 20 | :header: "OS", "OWNER", "CONTACT" 21 | 22 | ``nxos``, Jean-Benoit Aubin, pyats-support-ext@cisco.com 23 | ``dnac``, Jean-Benoit Aubin, pyats-support-ext@cisco.com 24 | ``nso``, Dave Wapstra, dwapstra@cisco.com 25 | ``iosxe``, Maaz Mashood Mohiuddin, mmashood@cisco.com 26 | ``apic``, Takashi Higashimura, pyats-support-ext@cisco.com 27 | ``virl``, Takashi Higashimura, pyats-support-ext@cisco.com 28 | ``webex``, Takashi Higashimura, pyats-support-ext@cisco.com 29 | ``nd``, Romel Tolos, rtolos@cisco.com 30 | 31 | 32 | Example use 33 | ----------- 34 | 35 | 36 | To specify a ``Rest`` connection for your device, add the ``rest.connector.Rest`` class 37 | to the connection for your devices in the testbed YAML file: 38 | 39 | .. code-block:: yaml 40 | 41 | # Example 42 | # ------- 43 | # 44 | # pyATS testbed yaml example for defining a REST connection 45 | 46 | testbed: 47 | name: myTestbed 48 | 49 | devices: 50 | PE1: 51 | os: # This must be set to select the rest connector plugin to use. 52 | # The following values are supported : 53 | # nso, nxos, dnac, apic, iosxe 54 | custom: 55 | abstraction: 56 | order: [os] 57 | os: # This must be set to select the rest connector plugin to use. 58 | # The following values are supported : 59 | # nso, nxos, dnac, apic, iosxe 60 | type: router 61 | 62 | connections: 63 | # Console 64 | a: 65 | ip: 1.2.3.4 66 | port: 10001 67 | protocol: telnet 68 | rest: 69 | # specify the rest connector class 70 | class: rest.connector.Rest 71 | ip: 1.2.3.4 72 | credentials: 73 | rest: 74 | username: my_username 75 | password: my_password 76 | 77 | 78 | With the above, the testbed loader can then load this YAML into object form. 79 | After connecting using the ``rest`` connection, you can execute REST API services. 80 | Please refer to the `services`_ section for details on supported services. 81 | 82 | .. _services: services/index.html 83 | 84 | 85 | .. code-block:: python 86 | 87 | # Example 88 | # ------- 89 | # 90 | # loading & using REST testbed yaml file in pyATS 91 | 92 | # import the topology module 93 | from pyats import topology 94 | 95 | # load the above testbed file containing REST device 96 | testbed = topology.loader.load('/path/to/rest/testbed.yaml') 97 | 98 | # get device by name 99 | device = testbed.devices['PE1'] 100 | 101 | # connect to it 102 | device.connect(via='rest') 103 | 104 | # get information of a particular DN 105 | url = '/api/mo/sys/bgp/inst/dom-default/af-ipv4-mvpn.json' 106 | output = device.rest.get(url) 107 | 108 | -------------------------------------------------------------------------------- /docs/user_guide/services/apic/aci_sdk.rst: -------------------------------------------------------------------------------- 1 | APIC SDK 2 | ========= 3 | 4 | The following services are supported by the SDK (Cobra) connector for APIC. 5 | 6 | 7 | query 8 | ----- 9 | 10 | Mimics same-name function from MoDirectory class (cobra.mit.access) 11 | 12 | .. list-table:: QUERY arguments 13 | :widths: 30 50 20 14 | :header-rows: 1 15 | 16 | * - Argument 17 | - Description 18 | - Default 19 | * - queryObject (obj) 20 | - A query object 21 | - Mandatory 22 | 23 | For more information please visit the `Cisco APIC Python API `_ 24 | 25 | commit 26 | ------ 27 | 28 | Mimics same-name function from MoDirectory class (cobra.mit.access) 29 | 30 | .. list-table:: COMMIT arguments 31 | :widths: 30 50 20 32 | :header-rows: 1 33 | 34 | * - Argument 35 | - Description 36 | - Default 37 | * - configObject (obj) 38 | - The configuration request to commit 39 | - Mandatory 40 | 41 | For more information please visit the `Cisco APIC Python API `_ 42 | 43 | lookupByDn 44 | ---------- 45 | 46 | Mimics same-name function from MoDirectory class (cobra.mit.access) 47 | 48 | .. list-table:: LOOKUPBYDN arguments 49 | :widths: 30 50 20 50 | :header-rows: 1 51 | 52 | * - Argument 53 | - Description 54 | - Default 55 | * - dnStrOrDn (obj|str) 56 | - DN of the object to lookup 57 | - Mandatory 58 | * - queryParams (dict) 59 | - Dictionary containing additional filters 60 | - Optional 61 | 62 | For more information please visit the `Cisco APIC Python API `_ 63 | 64 | lookupByClass 65 | ------------- 66 | 67 | Mimics same-name function from MoDirectory class (cobra.mit.access) 68 | 69 | .. list-table:: LOOKUPBYCLASS arguments 70 | :widths: 30 50 20 71 | :header-rows: 1 72 | 73 | * - Argument 74 | - Description 75 | - Default 76 | * - classNames (str|list) 77 | - Class name or list of classes 78 | - Mandatory 79 | * - parentDn (obj|str) 80 | - DN of the parent object 81 | - None 82 | * - kwargs (dict) 83 | - Dictionary containing additional filters 84 | - Optional 85 | 86 | For more information please visit the `Cisco APIC Python API `_ 87 | 88 | exists 89 | ------ 90 | 91 | Mimics same-name function from MoDirectory class (cobra.mit.access) 92 | 93 | .. list-table:: EXISTS arguments 94 | :widths: 30 50 20 95 | :header-rows: 1 96 | 97 | * - Argument 98 | - Description 99 | - Default 100 | * - dnStrOrDn (obj|str) 101 | - DN of the object to check 102 | - Mandatory 103 | 104 | get_model 105 | --------- 106 | 107 | Automatically import the required library and return the model class 108 | 109 | .. list-table:: GET_MODEL arguments 110 | :widths: 30 50 20 111 | :header-rows: 1 112 | 113 | * - Argument 114 | - Description 115 | - Default 116 | * - model (str) 117 | - Unique identifier of the module and class (eg. fv.Tenant) 118 | - Mandatory 119 | 120 | .. code-block:: python 121 | 122 | # Assuming the device is already connected 123 | tenant_class = device.cobra.get_model(model='fv.Tenant') 124 | 125 | create 126 | ------ 127 | 128 | Automatically import the required library and instantiate the model object 129 | 130 | .. list-table:: CREATE arguments 131 | :widths: 30 50 20 132 | :header-rows: 1 133 | 134 | * - Argument 135 | - Description 136 | - Default 137 | * - model (str) 138 | - Unique identifier of the module and class (eg. "fv.Tenant") 139 | - Mandatory 140 | * - parent_mo_or_dn (obj|str) 141 | - The parent MO or DN 142 | - Mandatory 143 | * - extra_parms (dict) 144 | - Dictionary containing additional attributes for the object 145 | - Optional 146 | 147 | .. code-block:: python 148 | 149 | # Assuming the device is already connected 150 | tenant = device.cobra.create(model='fv.Tenant', 151 | parent_mo_or_dn='uni', 152 | name='test') 153 | 154 | config_and_commit 155 | ----------------- 156 | 157 | Add MO to ConfigRequest and push it to device 158 | 159 | .. list-table:: CONFIG_AND_COMMIT arguments 160 | :widths: 30 50 20 161 | :header-rows: 1 162 | 163 | * - Argument 164 | - Description 165 | - Default 166 | * - mo (obj) 167 | - Object to be committed 168 | - Mandatory 169 | * - expected_status_code (int) 170 | - Expected result 171 | - 200 172 | 173 | .. code-block:: python 174 | 175 | # Assuming the device is already connected 176 | # and tenant object is created (create function) 177 | tenant = device.cobra.config_and_commit(mo=tenant) 178 | 179 | 180 | Additional info on the Cobra SDK can be found on the `Cisco APIC Python API `_ 181 | 182 | 183 | .. sectionauthor:: Romel Tolos 184 | -------------------------------------------------------------------------------- /docs/user_guide/services/apic/index.rst: -------------------------------------------------------------------------------- 1 | APIC 2 | ======== 3 | 4 | Services supported by rest.connector on APIC. 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | rest 10 | aci_sdk 11 | -------------------------------------------------------------------------------- /docs/user_guide/services/apic/rest.rst: -------------------------------------------------------------------------------- 1 | REST 2 | ==== 3 | 4 | The following services are supported by the REST connector for APIC. 5 | 6 | 7 | get 8 | --- 9 | 10 | API to send GET command to the device. 11 | 12 | .. list-table:: GET arguments 13 | :widths: 30 50 20 14 | :header-rows: 1 15 | 16 | * - Argument 17 | - Description 18 | - Default 19 | * - dn 20 | - Unique distinguished name describes the object and its place in the tree 21 | - Mandatory 22 | * - query_target {self|children|subtree} 23 | - | 'self': (default) MO itself 24 | | 'children': just the MO's child objects 25 | | 'subtree': MO and its child objects 26 | - self 27 | * - rsp_subtree {no|children|full} 28 | - | Specifies child object level included in the response 29 | | 'no': (default) the response does not include any children 30 | | 'children': return only the child objects 31 | | 'full': includes the full tree structure 32 | - no 33 | * - rsp_prop_include {all|naming-only|config-only} 34 | - | 'all': all properties of the objects 35 | | 'naming-only': only the naming properties 36 | | 'config-only': only configurable properties 37 | - all 38 | * - rsp_subtree_include (string) 39 | - specify additional contained objects or options to be included 40 | - None 41 | * - rsp_subtree_class (string) 42 | - specify classes 43 | - None 44 | * - query_target_filter (string) 45 | - filter expression 46 | - None 47 | * - target_subtree_class (string) 48 | - specify class 49 | - None 50 | * - order_by (string) 51 | - sort the query response by one or more properties of a class 52 | - None 53 | * - expected_status_code (int) 54 | - Expected result 55 | - None 56 | * - timeout 57 | - Maximum time it can take to disconnect to the device 58 | - 30 seconds 59 | 60 | .. code-block:: python 61 | 62 | # Assuming the device is already connected 63 | url = 'api/node/class/fvTenant.json' 64 | output = device.get(url, query_target='self', rsp_subtree='no', 65 | query_target_filter='', rsp_prop_include='all') 66 | 67 | post 68 | ---- 69 | 70 | API to send POST command to the device. 71 | 72 | .. list-table:: POST arguments 73 | :widths: 30 50 20 74 | :header-rows: 1 75 | 76 | * - Argument 77 | - Description 78 | - Default 79 | * - dn 80 | - Unique distinguished name describes the object and its place in the tree 81 | - Mandatory 82 | * - payload (dict|string) 83 | - Information to send via the post command 84 | - Mandatory 85 | * - xml_payload (bool) 86 | - Set to True if payload is in XML format 87 | - False 88 | * - expected_status_code (int) 89 | - Expected result 90 | - 200 91 | * - timeout (int) 92 | - Maximum time it can take to disconnect to the device 93 | - 30 seconds 94 | 95 | .. code-block:: python 96 | 97 | # Assuming the device is already connected 98 | payload = """ 99 | { 100 | "fvTenant": { 101 | "attributes": { 102 | "dn": "uni/tn-test", 103 | "name": "test", 104 | "rn": "tn-test", 105 | "status": "created" 106 | }, 107 | "children": [] 108 | } 109 | """ 110 | 111 | url = 'api/node/mo/uni/tn-test.json' 112 | device.rest.post(url, payload) 113 | 114 | delete 115 | ------ 116 | 117 | API to send DELETE command to the device. 118 | 119 | .. list-table:: DELETE arguments 120 | :widths: 30 50 20 121 | :header-rows: 1 122 | 123 | * - Argument 124 | - Description 125 | - Default 126 | * - dn (string) 127 | - Unique distinguished name describes the object and its place in the tree 128 | - Mandatory 129 | * - expected_status_code (int) 130 | - Expected result 131 | - 200 132 | * - timeout (int) 133 | - Maximum time it can take to disconnect to the device 134 | - 30 seconds 135 | 136 | .. code-block:: python 137 | 138 | # Assuming the device is already connected 139 | url = 'api/v1/schema/583c7c482501002501061985' 140 | output = device.delete(url) 141 | 142 | 143 | .. sectionauthor:: Takashi Higashimura 144 | -------------------------------------------------------------------------------- /docs/user_guide/services/bigip.rst: -------------------------------------------------------------------------------- 1 | BigIP 2 | ===== 3 | 4 | The following services are supported by the REST connector for F5 (BigIP). 5 | 6 | 7 | connect 8 | ------- 9 | 10 | API to connect to the device. 11 | 12 | The BigIP REST implementation supports specifying the port to connect to 13 | and allows to specify the username and password in the testbed YAML file. 14 | Under the hood its using token authentication to communicate with BigIP. 15 | 16 | .. code-block:: yaml 17 | 18 | # Example 19 | # ------- 20 | # 21 | # pyATS testbed yaml example for defining a REST connection 22 | 23 | testbed: 24 | name: myTestbed 25 | 26 | devices: 27 | bigip01.lab.local: 28 | alias: 'bigip01' 29 | type: 'bigip' 30 | os: 'bigip' 31 | custom: 32 | abstraction: 33 | order: [os] 34 | connections: 35 | rest: 36 | class: rest.connector.Rest 37 | ip: 1.2.3.4 38 | port: 443 39 | protocol: http 40 | credentials: 41 | rest: 42 | username: admin 43 | password: admin 44 | 45 | 46 | If no port is specified, the default of `443` is used. 47 | If verify is provided and is True, it will verify the SSL certificate. 48 | If protocol is not provided, the default is `http`. 49 | 50 | 51 | .. code-block:: python 52 | 53 | device = testbed.devices['bigip01'] 54 | device.connect(alias='rest', via='rest') 55 | device.rest.connected 56 | 57 | 58 | disconnect 59 | ---------- 60 | 61 | Will delete the current API Token in use. 62 | 63 | 64 | GET 65 | --- 66 | 67 | API to GET from the device. 68 | 69 | .. csv-table:: GET arguments 70 | :header: Argument, Description, Default 71 | 72 | ``api_url``, API url string (required), 73 | ``timeout``, timeout in seconds (optional), 30 74 | 75 | .. code-block:: python 76 | 77 | url = '/mgmt/tm/ltm/node' 78 | nodes = device.rest.get(url) 79 | 80 | 81 | POST 82 | ---- 83 | 84 | API to POST data to the device. 85 | 86 | .. csv-table:: POST arguments 87 | :header: Argument, Description, Default 88 | 89 | ``api_url``, API url string (required), 90 | ``payload``, Payload to be sent (required), 91 | ``timeout``, timeout in seconds (optional), 30 92 | 93 | .. code-block:: python 94 | 95 | url = '/mgmt/tm/ltm/node/' 96 | data = {"name":"wa12","partition":"Common","address":"119.119.192.193"} 97 | node = device.rest.post(url, data) 98 | 99 | url = '/mgmt/tm/ltm/node/' 100 | data = {"name":"wa13","partition":"Common","address":"119.119.192.195"} 101 | node = device.rest.post(url, data) 102 | 103 | url = '/mgmt/tm/ltm/pool/' 104 | data = {"name":"wa12","partition":"Common","members":"wa12:80"} 105 | pool = device.rest.post(url, data) 106 | 107 | 108 | PATCH 109 | ----- 110 | 111 | API to PATCH data on the device. 112 | 113 | .. csv-table:: PATCH arguments 114 | :header: Argument, Description, Default 115 | 116 | ``api_url``, API url string (required), 117 | ``payload``, Payload to be sent (required), 118 | ``timeout``, timeout in seconds (optional), 30 119 | 120 | .. code-block:: python 121 | 122 | url = '/mgmt/tm/ltm/node/~Common~wa12' 123 | data = {"session":"user-disabled"} 124 | node = device.rest.patch(url, data) 125 | 126 | 127 | PUT 128 | --- 129 | 130 | API to PUT data on the device. 131 | 132 | .. csv-table:: PUT arguments 133 | :header: Argument, Description, Default 134 | 135 | ``api_url``, API url string (required), 136 | ``payload``, Payload to be sent (required), 137 | ``timeout``, timeout in seconds (optional), 30 138 | 139 | .. code-block:: python 140 | 141 | url = '/mgmt/tm/ltm/pool/wa12' 142 | data = {"members":"wa13:80"} 143 | pool = device.rest.put(url, data) 144 | 145 | 146 | DELETE 147 | ------ 148 | 149 | API to DELETE data on the device. 150 | 151 | .. csv-table:: DELETE arguments 152 | :header: Argument, Description, Default 153 | 154 | ``api_url``, API url string (required), 155 | ``timeout``, timeout in seconds (optional), 30 156 | 157 | .. code-block:: python 158 | 159 | url = '/mgmt/tm/ltm/node/wa12' 160 | node = device.rest.delete(url) 161 | 162 | url = '/mgmt/tm/ltm/pool/wa12' 163 | pool = device.rest.delete(url) 164 | 165 | url = '/mgmt/tm/ltm/node/wa13' 166 | node = device.rest.delete(url) 167 | 168 | .. sectionauthor:: Mirza Waqas Ahmed 169 | 170 | -------------------------------------------------------------------------------- /docs/user_guide/services/dcnm.rst: -------------------------------------------------------------------------------- 1 | DCNM 2 | ==== 3 | 4 | The following services are supported by the REST connector for DCNM. 5 | 6 | 7 | get 8 | --- 9 | 10 | API to send GET command to the device. 11 | 12 | .. csv-table:: 13 | :header: Argument, Description, Default 14 | :widths: 30, 50, 20 15 | 16 | ``api_url``, "Unique distinguished name describes the place in the tree", "Mandatory" 17 | ``headers``, "Headers to send with the GET command", "None" 18 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 19 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 20 | 21 | .. code-block:: python 22 | 23 | # Assuming the device is already connected, and the fabric name is single_leaf_demo 24 | url = '/rest/top-down/fabrics/single_leaf_demo/vrfs' 25 | output = device.rest.get(url) 26 | 27 | post 28 | ---- 29 | 30 | API to send POST command to the device. 31 | 32 | .. csv-table:: 33 | :header: Argument, Description, Default 34 | :widths: 30, 50, 20 35 | 36 | ``api_url``, "Unique distinguished name describes the place in the tree", "Mandatory" 37 | ``payload``, "Payload to send to the device", "Mandatory" 38 | ``headers``, "Headers to send with the GET command", "None" 39 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 40 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 41 | 42 | .. code-block:: python 43 | 44 | # Assuming the device is already connected 45 | payload = """ 46 | { 47 | "fabric": "single_leaf_demo", 48 | "networkName": "MyNetwork_10000", 49 | "serialNumber": "FDO22230J8W", 50 | "vlan": "1000", 51 | "dot1QVlan": 1, 52 | "untagged": False, 53 | "detachSwitchPorts": "Ethernet1/5", 54 | "switchPorts": "", 55 | "deployment": False 56 | } 57 | """ 58 | # Assuming single_leaf_demo fabric is already created 59 | url = '/rest/top-down/fabrics/single_leaf_demo/networks/MyNetwork_10000/attachments/' 60 | device.rest.post(url, payload) 61 | 62 | delete 63 | ------ 64 | 65 | API to send DELETE command to the device. 66 | 67 | .. csv-table:: 68 | :header: Argument, Description, Default 69 | :widths: 30, 50, 20 70 | 71 | ``api_url``, "Unique distinguished name describes the place in the tree", "Mandatory" 72 | ``headers``, "Headers to send with the GET command", "None" 73 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 74 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 75 | 76 | .. code-block:: python 77 | 78 | # Assuming the device is already connected 79 | url = '/rest/top-down/fabrics/single_leaf_demo/networks/MyNetwork_10000' 80 | output = device.rest.delete(url) 81 | 82 | patch 83 | ----- 84 | 85 | API to send PATCH command to the device. 86 | 87 | .. csv-table:: 88 | :header: Argument, Description, Default 89 | :widths: 30, 50, 20 90 | 91 | ``api_url``, "Unique distinguished name describes the place in the tree", "Mandatory" 92 | ``payload``, "Payload to send to the device", "Mandatory" 93 | ``headers``, "Headers to send with the GET command", "None" 94 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 95 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 96 | 97 | .. code-block:: python 98 | 99 | # Assuming the device is already connected 100 | payload = """ 101 | { 102 | "fabric": "single_leaf_demo", 103 | "networkName": "MyNetwork_10000", 104 | "serialNumber": "FDO22230J8W", 105 | "vlan": "1000", 106 | "dot1QVlan": 1, 107 | "untagged": False, 108 | "detachSwitchPorts": "Ethernet1/6", 109 | "switchPorts": "", 110 | "deployment": False 111 | } 112 | """ 113 | # Assuming single_leaf_demo fabric is already created 114 | url = '/rest/top-down/fabrics/single_leaf_demo/networks/MyNetwork_10000' 115 | output = device.rest.patch(url) 116 | 117 | put 118 | --- 119 | 120 | API to send PUT command to the device. 121 | 122 | .. csv-table:: 123 | :header: Argument, Description, Default 124 | :widths: 30, 50, 20 125 | 126 | ``api_url``, "Unique distinguished name describes the place in the tree", "Mandatory" 127 | ``payload``, "Payload to send to the device", "Mandatory" 128 | ``headers``, "Headers to send with the GET command", "None" 129 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 130 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 131 | 132 | .. code-block:: python 133 | 134 | # Assuming the device is already connected 135 | payload = """ 136 | { 137 | "fabric": "single_leaf_demo", 138 | "networkName": "MyNetwork_10000", 139 | "serialNumber": "FDO22230J8W", 140 | "vlan": "1000", 141 | "dot1QVlan": 1, 142 | "untagged": False, 143 | "detachSwitchPorts": "Ethernet1/7", 144 | "switchPorts": "", 145 | "deployment": False 146 | } 147 | """ 148 | # Assuming single_leaf_demo fabric is already created 149 | url = '/rest/top-down/fabrics/single_leaf_demo/networks/MyNetwork_10000' 150 | output = device.rest.put(url) 151 | 152 | .. sectionauthor:: Sukanya Kalluri 153 | 154 | -------------------------------------------------------------------------------- /docs/user_guide/services/dnac.rst: -------------------------------------------------------------------------------- 1 | DNAC 2 | ==== 3 | 4 | The following services are supported by the REST connector for DNAC. 5 | 6 | 7 | connect 8 | ------- 9 | 10 | API to connect to the device. 11 | 12 | The DNAC REST implementation supports specifying the port to connect to 13 | and allows to specify the username and password in the testbed YAML file. 14 | 15 | .. code-block:: yaml 16 | 17 | # Example 18 | # ------- 19 | # 20 | # pyATS testbed yaml example for defining a REST connection 21 | 22 | testbed: 23 | name: myTestbed 24 | 25 | devices: 26 | dnac: 27 | custom: 28 | abstraction: 29 | order: [os] 30 | connections: 31 | rest: 32 | # Rest connector class 33 | class: rest.connector.Rest 34 | ip: 1.2.3.4 35 | port: 8080 36 | verify: False 37 | credentials: 38 | rest: 39 | username: admin 40 | password: admin 41 | 42 | 43 | 44 | If no port is specified, the default of `443` is used. If verify is provided 45 | and is False, it wont verify the SSL certificate. 46 | 47 | .. csv-table:: GET arguments 48 | :header: Argument, Description, Default 49 | 50 | ``timeout``, Maximum time it can take to connect to the device. (optional), 30 51 | 52 | 53 | disconnect 54 | ---------- 55 | 56 | same as the `generic`_ implementation. 57 | 58 | .. _generic: generic.html#disconnect 59 | 60 | 61 | get 62 | --- 63 | 64 | API to send GET command to the device. 65 | 66 | .. csv-table:: GET arguments 67 | :header: Argument, Description, Default 68 | 69 | ``api_url``, API url string (required), 70 | ``timeout``, timeout in seconds (optional), 30 71 | 72 | .. code-block:: python 73 | 74 | url = '/dna/intent/api/v1/interface' 75 | output = device.rest.get(url) 76 | 77 | .. sectionauthor:: Jean-Benoit Aubin 78 | 79 | -------------------------------------------------------------------------------- /docs/user_guide/services/elasticsearch.rst: -------------------------------------------------------------------------------- 1 | Elasticsearch 2 | ============= 3 | 4 | The following services are supported by the REST connector for Elasticsearch. 5 | 6 | 7 | get 8 | --- 9 | 10 | API to send GET command to the device. 11 | 12 | .. csv-table:: 13 | :header: Argument, Description, Default 14 | :widths: 30, 50, 20 15 | 16 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 17 | ``headers``, "Headers to send with the GET command", "{Authorization: Bearer }" 18 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 19 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 20 | 21 | .. code-block:: python 22 | 23 | # Assuming the device is already connected 24 | url = '/index_name/_search' 25 | output = device.rest.get(url) 26 | 27 | post 28 | ---- 29 | 30 | API to send POST command to the device. 31 | 32 | .. csv-table:: 33 | :header: Argument, Description, Default 34 | :widths: 30, 50, 20 35 | 36 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 37 | ``payload``, "Payload to send to the device", "Mandatory" 38 | ``headers``, "Headers to send with the GET command", "{Authorization: Bearer }" 39 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 40 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 41 | 42 | .. code-block:: python 43 | 44 | # Assuming the device is already connected 45 | payload = """ 46 | { 47 | "banana": 100, 48 | "apple": 200 49 | } 50 | """ 51 | 52 | url = 'index_store' 53 | device.rest.post(url, payload) 54 | 55 | delete 56 | ------ 57 | 58 | API to send DELETE command to the device. 59 | 60 | .. csv-table:: 61 | :header: Argument, Description, Default 62 | :widths: 30, 50, 20 63 | 64 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 65 | ``headers``, "Headers to send with the GET command", "{Authorization: Bearer }" 66 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 67 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 68 | 69 | .. code-block:: python 70 | 71 | # Assuming the device is already connected 72 | url = 'index_store/doc_id' 73 | device.rest.delete(url) 74 | 75 | put 76 | --- 77 | 78 | API to send PUT command to the device. 79 | 80 | .. csv-table:: 81 | :header: Argument, Description, Default 82 | :widths: 30, 50, 20 83 | 84 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 85 | ``payload``, "Payload to send to the device", "Mandatory" 86 | ``headers``, "Headers to send with the GET command", "{Authorization: Bearer }" 87 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 88 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 89 | 90 | .. code-block:: python 91 | 92 | # Assuming the device is already connected 93 | payload = """ 94 | { 95 | "banana": 100, 96 | "apple": 200 97 | } 98 | """ 99 | 100 | url = 'index_store' 101 | output = device.rest.put(url, payload) 102 | 103 | .. sectionauthor:: Takashi Higashimura 104 | 105 | -------------------------------------------------------------------------------- /docs/user_guide/services/generic.rst: -------------------------------------------------------------------------------- 1 | Generic 2 | ======= 3 | 4 | The following generic services are supported by all implementations. 5 | 6 | 7 | connect 8 | ------- 9 | 10 | API to connect to the device. 11 | 12 | .. csv-table:: connect arguments 13 | :header: Argument, Description, Default 14 | :widths: 30, 50, 20 15 | 16 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 17 | ``port``, "Port number for protocol.", "443 (IOSXE, NXOS, DCNM, BIG-IP), 8443 (Viptela), 8080 (NSO), 19399 (VIRL)" 18 | ``protocol``, "Protocol to use.", "https (IOSXE, NXOS, DCNM, Viptela, BIG-IP), http (NSO, VIRL)" 19 | 20 | .. code-block:: python 21 | 22 | # Example 23 | # ------- 24 | # 25 | # loading & using REST testbed yaml file in pyATS 26 | 27 | # import the topology module 28 | from pyats import topology 29 | 30 | # load the above testbed file containing REST device 31 | testbed = topology.loader.load('/path/to/rest/testbed.yaml') 32 | 33 | # get device by name 34 | device = testbed.devices['PE1'] 35 | 36 | # connect to it 37 | device.connect(via='rest') 38 | 39 | disconnect 40 | ---------- 41 | 42 | API to disconnect from the device. 43 | 44 | .. csv-table:: disconnect arguments 45 | :header: Argument, Description, Default 46 | :widths: 30, 50, 20 47 | 48 | ``timeout``, "Maximum time it can take to disconnect from the device.", "30 seconds" 49 | 50 | .. code-block:: python 51 | 52 | # Example 53 | # ------- 54 | # 55 | # loading & using REST testbed yaml file in pyATS 56 | 57 | # import the topology module 58 | from pyats import topology 59 | 60 | # load the above testbed file containing REST device 61 | testbed = topology.loader.load('/path/to/rest/testbed.yaml') 62 | 63 | # get device by name 64 | device = testbed.devices['PE1'] 65 | 66 | # connect to it 67 | device.connect(via='rest') 68 | 69 | # disconnect rest connection 70 | device.rest.disconnect() 71 | 72 | -------------------------------------------------------------------------------- /docs/user_guide/services/index.rst: -------------------------------------------------------------------------------- 1 | Services 2 | ======== 3 | 4 | This part of the document covers all the services supported by rest.connector. 5 | 6 | .. toctree:: 7 | :maxdepth: 3 8 | 9 | generic 10 | nxos 11 | nso 12 | dnac 13 | iosxe 14 | apic/index 15 | virl 16 | bigip 17 | viptela 18 | dcnm 19 | nd 20 | -------------------------------------------------------------------------------- /docs/user_guide/services/iosxe.rst: -------------------------------------------------------------------------------- 1 | IOS-XE 2 | ====== 3 | 4 | The following services are supported by the REST connector for IOS-XE. 5 | 6 | 7 | connect 8 | ------- 9 | 10 | API to connect to the device. 11 | 12 | The IOS-XE REST implementation supports specifying the port to connect to 13 | and allows to specify the username and password in the testbed YAML file. 14 | 15 | .. code-block:: yaml 16 | 17 | # Example 18 | # ------- 19 | # 20 | # pyATS testbed yaml example for defining a REST connection 21 | 22 | testbed: 23 | name: myTestbed 24 | 25 | devices: 26 | eWLC: 27 | custom: 28 | abstraction: 29 | order: [os] 30 | os: iosxe 31 | type: router 32 | connections: 33 | rest: 34 | # Rest connector class 35 | class: rest.connector.Rest 36 | ip: 1.2.3.4 37 | port: 443 38 | credentials: 39 | rest: 40 | username: admin 41 | password: admin 42 | 43 | 44 | 45 | If no port is specified, he default of `443` is used. 46 | If no username or password is specified, the default of `admin` is used. 47 | 48 | When connecting to this device, an optional proxies argument may be specified. 49 | If not specified, proxies are loaded from the environment if they have been 50 | set. 51 | 52 | .. code-block:: python 53 | 54 | # Example 55 | # ------- 56 | # 57 | # loading & using REST testbed yaml file in pyATS 58 | 59 | # import the topology module 60 | from pyats import topology 61 | 62 | # load the above testbed file containing REST device 63 | testbed = topology.loader.load('/path/to/rest/testbed.yaml') 64 | 65 | # get device by name 66 | device = testbed.devices['PE1'] 67 | 68 | # connect to it 69 | device.connect(via='rest', proxies={ 70 | 'http': 'http://proxy.domain.com:80/', 71 | 'https': 'http://proxy.domain.com:80/', 72 | 'ftp': 'http://proxy.domain.com:80/', 73 | 'no': '.mydomain.com', 74 | } 75 | ) 76 | 77 | # Get information 78 | device.rest.get(url) 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | .. csv-table:: GET arguments 87 | :header: Argument, Description, Default 88 | 89 | ``default_content_type``, "Default content type for GET requests, json or xml", json 90 | ``timeout``, Maximum time it can take to disconnect to the device. (optional), 30 91 | 92 | 93 | disconnect 94 | ---------- 95 | 96 | same as the `generic`_ implementation. 97 | 98 | .. _generic: generic.html#disconnect 99 | 100 | 101 | get 102 | --- 103 | 104 | API to send GET command to the device. 105 | 106 | .. csv-table:: GET arguments 107 | :header: Argument, Description, Default 108 | 109 | ``api_url``, API url string (required), 110 | ``content_type``, Content type to be returned (xml or json) (optional), json 111 | ``headers``, Dictionary of headers (optional), 112 | ``expected_status_codes``, List of expected status codes (optional), 200 113 | ``timeout``, timeout in seconds (optional), 30 114 | 115 | .. code-block:: python 116 | 117 | url = '/restconf/data/site-cfg-data/' 118 | output = device.rest.get(url) 119 | 120 | 121 | post 122 | ---- 123 | 124 | API to send POST command with optional payload to the device. 125 | 126 | .. csv-table:: POST arguments 127 | :header: Argument, Description, Default 128 | 129 | ``api_url``, API url string (required), 130 | ``payload``, "payload to sent, can be string or dict (optional)", 131 | ``content_type``, content type to be returned (xml or json) (optional), 132 | ``headers``, dictionary of HTTP headers (optional), 133 | ``expected_status_codes``, list of expected result codes (optional), "200, 201, 204" 134 | ``timeout``, timeout in seconds (optional), 30 135 | .. 136 | 137 | If the content_type option is not passed, the script will try to detect 138 | if the payload is XML, otherwise it will assume JSON. The content-type and accept 139 | headers will be set based on the detected payload or on the passed content-type. 140 | 141 | If you pass a `dict()` object as payload, a conversion will be done to JSON or XML string. 142 | 143 | .. code-block:: python 144 | 145 | url = '/restconf/data/site-cfg-data/ap-cfg-profiles/' 146 | output = device.rest.post(url) 147 | 148 | 149 | patch 150 | ----- 151 | 152 | API to send POST command with payload to the device. 153 | 154 | .. csv-table:: PATCH arguments 155 | :header: Argument, Description, Default 156 | 157 | ``api_url``, API url string (required) 158 | ``payload``, "payload to sent, can be string or dict (required)" 159 | ``content_type``, content type to be returned (xml or json) (optional), 160 | ``headers``, dictionary of HTTP headers (optional) 161 | ``expected_status_codes``, list of expected result codes (optional), "200, 201, 204" 162 | ``timeout``, timeout in seconds (optional), 30 163 | .. 164 | 165 | If the content_type option is not passed, the script will try to detect 166 | if the payload is XML, otherwise it will assume JSON. The content-type and accept 167 | headers will be set based on the detected payload or on the passed content-type. 168 | 169 | If you pass a `dict()` object as payload, a conversion will be done to JSON or XML string. 170 | 171 | 172 | .. code-block:: python 173 | 174 | hyperlocation_enable = """ 175 | "Cisco-IOS-XE-wireless-site-cfg:ap-cfg-profile": { 176 | "hyperlocation": { 177 | "hyperlocation-enable": true, 178 | } 179 | } 180 | """ 181 | output = device.rest.patch("/restconf/data/site-cfg-data/ap-cfg-profiles/ap-cfg-profile=default-ap-profile", payload=hyperlocation_enable) 182 | 183 | 184 | put 185 | --- 186 | 187 | API to send PUT command with payload to the device. 188 | 189 | .. csv-table:: PUT arguments 190 | :header: Argument, Description, Default 191 | 192 | ``api_url``, API url string (required) 193 | ``payload``, "payload to sent, can be string or dict (required)" 194 | ``content_type``, content type to be returned (xml or json) (optional), 195 | ``headers``, dictionary of HTTP headers (optional) 196 | ``expected_status_codes``, list of expected result codes (optional), "200, 201, 204" 197 | ``timeout``, timeout in seconds (optional), 30 198 | .. 199 | 200 | If the content_type option is not passed, the script will try to detect 201 | if the payload is XML, otherwise it will assume JSON. The content-type and accept 202 | headers will be set based on the detected payload or on the passed content-type. 203 | 204 | If you pass a `dict()` object as payload, a conversion will be done to JSON or XML string. 205 | 206 | .. code-block:: python 207 | 208 | hyperlocation_enable = """ 209 | "Cisco-IOS-XE-wireless-site-cfg:ap-cfg-profile": { 210 | "hyperlocation": { 211 | "hyperlocation-enable": true, 212 | } 213 | } 214 | """ 215 | output = device.rest.put("/restconf/data/site-cfg-data/ap-cfg-profiles/ap-cfg-profile=default-ap-profile", payload=hyperlocation_enable) 216 | 217 | 218 | delete 219 | ------ 220 | 221 | API to send DELETE command with payload to the device. 222 | 223 | .. csv-table:: DELETE arguments 224 | :header: Argument, Description, Default 225 | 226 | ``api_url``, API url string (required) 227 | ``content_type``, content type to be returned (xml or json), 228 | ``headers``, dictionary of HTTP headers (optional), 229 | ``expected_status_codes``, list of expected result codes, "200, 201, 204" 230 | ``timeout``, timeout in seconds (optional), 30 231 | 232 | .. code-block:: python 233 | 234 | device.rest.delete('/restconf/data/site-cfg-data/ap-cfg-profiles/ap-cfg-profile=test-profile') 235 | 236 | 237 | .. sectionauthor:: Maaz Mashood Mohiuddin 238 | 239 | -------------------------------------------------------------------------------- /docs/user_guide/services/nd.rst: -------------------------------------------------------------------------------- 1 | Nexus Dashboard (ND) 2 | ==== 3 | 4 | The following services are supported by the REST connector for Nexus Dashboard (ND). 5 | 6 | 7 | get 8 | --- 9 | 10 | API to send GET command to the device. 11 | 12 | .. list-table:: GET arguments 13 | :widths: 30 50 20 14 | :header-rows: 1 15 | 16 | * - Argument 17 | - Description 18 | - Default 19 | * - api_url (string) 20 | - API url (subdirectory part of the url) string 21 | - Mandatory 22 | * - expected_status_code (int) 23 | - Expected result 24 | - 200 25 | * - timeout (int) 26 | - Maximum time it can take to disconnect to the device 27 | - 30 seconds 28 | * - retries (int) 29 | - Number of retries in case of transmission error 30 | - 3 times 31 | * - retry_wait (int) 32 | - Seconds to wait between retries 33 | - 10 seconds 34 | 35 | .. code-block:: python 36 | 37 | # Assuming the device is already connected 38 | url = '/api/config/class/localusers/' 39 | output = device.get(url) 40 | 41 | post 42 | ---- 43 | 44 | API to send POST command to the device. 45 | 46 | .. list-table:: POST arguments 47 | :widths: 30 50 20 48 | :header-rows: 1 49 | 50 | * - Argument 51 | - Description 52 | - Default 53 | * - api_url (string) 54 | - API url (subdirectory part of the url) string 55 | - Mandatory 56 | * - payload (dict) 57 | - Dictionary containing the information to send via the post 58 | - Mandatory 59 | * - expected_status_code (int) 60 | - Expected result 61 | - 200 62 | * - content_type 63 | - (json / xml / form) Information about the type of request 64 | - json 65 | * - timeout (int) 66 | - Maximum time it can take to disconnect to the device 67 | - 30 seconds 68 | * - retries (int) 69 | - Number of retries in case of transmission error 70 | - 3 times 71 | * - retry_wait (int) 72 | - Seconds to wait between retries 73 | - 10 seconds 74 | 75 | .. code-block:: python 76 | 77 | # Assuming the device is already connected 78 | payload = """ 79 | { 80 | "loginID": "test", 81 | "loginPasswd: "cisco!123" 82 | } 83 | """ 84 | 85 | url = 'api/config/localusers/test' 86 | device.rest.post(url, payload) 87 | 88 | put 89 | ---- 90 | 91 | API to send PUT command to the device. 92 | 93 | .. list-table:: PUT arguments 94 | :widths: 30 50 20 95 | :header-rows: 1 96 | 97 | * - Argument 98 | - Description 99 | - Default 100 | * - api_url (string) 101 | - API url (subdirectory part of the url) string 102 | - Mandatory 103 | * - payload (dict) 104 | - Dictionary containing the information to send via the post 105 | - None 106 | * - expected_status_code (int) 107 | - Expected result 108 | - 200 109 | * - content_type 110 | - (json / xml / form) Information about the type of request 111 | - json 112 | * - timeout (int) 113 | - Maximum time it can take to disconnect to the device 114 | - 30 seconds 115 | * - retries (int) 116 | - Number of retries in case of transmission error 117 | - 3 times 118 | * - retry_wait (int) 119 | - Seconds to wait between retries 120 | - 10 seconds 121 | 122 | delete 123 | ------ 124 | 125 | API to send DELETE command to the device. 126 | 127 | .. list-table:: DELETE arguments 128 | :widths: 30 50 20 129 | :header-rows: 1 130 | 131 | * - Argument 132 | - Description 133 | - Default 134 | * - api_url (string) 135 | - API url (subdirectory part of the url) string 136 | - Mandatory 137 | * - expected_status_code (int) 138 | - Expected result 139 | - 200 140 | * - timeout (int) 141 | - Maximum time it can take to disconnect to the device 142 | - 30 seconds 143 | * - retries (int) 144 | - Number of retries in case of transmission error 145 | - 3 times 146 | * - retry_wait (int) 147 | - Seconds to wait between retries 148 | - 10 seconds 149 | 150 | .. code-block:: python 151 | 152 | # Assuming the device is already connected 153 | url = 'api/config/localusers/test' 154 | device.delete(url) 155 | 156 | 157 | .. sectionauthor:: Romel Tolos 158 | -------------------------------------------------------------------------------- /docs/user_guide/services/nso.rst: -------------------------------------------------------------------------------- 1 | NSO 2 | === 3 | 4 | The following services are supported by the REST connector for NSO. 5 | 6 | 7 | connect 8 | ------- 9 | 10 | API to connect to the device. 11 | 12 | The NSO REST implementation supports specifying the port to connect to 13 | and allows to specify the username and password in the testbed YAML file. 14 | 15 | .. code-block:: yaml 16 | 17 | # Example 18 | # ------- 19 | # 20 | # pyATS testbed yaml example for defining a REST connection 21 | 22 | testbed: 23 | name: myTestbed 24 | 25 | devices: 26 | PE1: 27 | custom: 28 | abstraction: 29 | order: [os] 30 | connections: 31 | rest: 32 | # Rest connector class 33 | class: rest.connector.Rest 34 | ip: 1.2.3.4 35 | port: 8080 36 | credentials: 37 | rest: 38 | username: admin 39 | password: admin 40 | 41 | 42 | If no port is specified, he default of `8080` is used. 43 | If no username or password is specified, the default of `admin` is used. 44 | 45 | 46 | .. csv-table:: GET arguments 47 | :header: Argument, Description, Default 48 | 49 | ``default_content_type``, "Default content type for GET requests, json or xml", json 50 | ``timeout``, Maximum time it can take to disconnect to the device. (optional), 30 51 | 52 | 53 | disconnect 54 | ---------- 55 | 56 | same as the `generic`_ implementation. 57 | 58 | .. _generic: generic.html#disconnect 59 | 60 | 61 | get 62 | --- 63 | 64 | API to send GET command to the device. 65 | 66 | .. csv-table:: GET arguments 67 | :header: Argument, Description, Default 68 | 69 | ``api_url``, API url string (required), 70 | ``content_type``, Content type to be returned (xml or json) (optional), json 71 | ``headers``, Dictionary of headers (optional), 72 | ``expected_status_codes``, List of expected status codes (optional), 200 73 | ``timeout``, timeout in seconds (optional), 30 74 | 75 | .. code-block:: python 76 | 77 | url = '/api/running/devices' 78 | output = device.rest.get(url) 79 | 80 | 81 | post 82 | ---- 83 | 84 | API to send POST command with optional payload to the device. 85 | 86 | .. csv-table:: POST arguments 87 | :header: Argument, Description, Default 88 | 89 | ``api_url``, API url string (required), 90 | ``payload``, "payload to sent, can be string or dict (optional)", 91 | ``content_type``, content type to be returned (xml or json) (optional), 92 | ``headers``, dictionary of HTTP headers (optional), 93 | ``expected_status_codes``, list of expected result codes (optional), "200, 201, 204" 94 | ``timeout``, timeout in seconds (optional), 30 95 | .. 96 | 97 | If the content_type option is not passed, the script will try to detect 98 | if the payload is XML, otherwise it will assume JSON. The content-type and accept 99 | headers will be set based on the detected payload or on the passed content-type. 100 | 101 | If you pass a `dict()` object as payload, a conversion will be done to JSON or XML string. 102 | 103 | .. code-block:: python 104 | 105 | url = '/api/running/devices/device/R1/_operations/check-sync' 106 | output = device.rest.post(url) 107 | 108 | 109 | patch 110 | ----- 111 | 112 | API to send POST command with payload to the device. 113 | 114 | .. csv-table:: PATCH arguments 115 | :header: Argument, Description, Default 116 | 117 | ``api_url``, API url string (required) 118 | ``payload``, "payload to sent, can be string or dict (required)" 119 | ``content_type``, content type to be returned (xml or json) (optional), 120 | ``headers``, dictionary of HTTP headers (optional) 121 | ``expected_status_codes``, list of expected result codes (optional), "200, 201, 204" 122 | ``timeout``, timeout in seconds (optional), 30 123 | .. 124 | 125 | If the content_type option is not passed, the script will try to detect 126 | if the payload is XML, otherwise it will assume JSON. The content-type and accept 127 | headers will be set based on the detected payload or on the passed content-type. 128 | 129 | If you pass a `dict()` object as payload, a conversion will be done to JSON or XML string. 130 | 131 | 132 | .. code-block:: python 133 | 134 | config_routes = """ 135 | { 136 | "tailf-ned-cisco-ios:route": { 137 | "ip-route-forwarding-list": [ 138 | { 139 | "prefix": "10.6.1.0", 140 | "mask": "255.255.255.0", 141 | "forwarding-address": "10.2.2.2" 142 | } 143 | ] 144 | } 145 | } 146 | """ 147 | output = device.rest.patch("/api/running/devices/device/R1/config/ios:ip/route", payload=config_routes) 148 | 149 | 150 | put 151 | --- 152 | 153 | API to send PUT command with payload to the device. 154 | 155 | .. csv-table:: PUT arguments 156 | :header: Argument, Description, Default 157 | 158 | ``api_url``, API url string (required) 159 | ``payload``, "payload to sent, can be string or dict (required)" 160 | ``content_type``, content type to be returned (xml or json) (optional), 161 | ``headers``, dictionary of HTTP headers (optional) 162 | ``expected_status_codes``, list of expected result codes (optional), "200, 201, 204" 163 | ``timeout``, timeout in seconds (optional), 30 164 | .. 165 | 166 | If the content_type option is not passed, the script will try to detect 167 | if the payload is XML, otherwise it will assume JSON. The content-type and accept 168 | headers will be set based on the detected payload or on the passed content-type. 169 | 170 | If you pass a `dict()` object as payload, a conversion will be done to JSON or XML string. 171 | 172 | .. code-block:: python 173 | 174 | config_routes = """ 175 | { 176 | "tailf-ned-cisco-ios:route": { 177 | "ip-route-forwarding-list": [ 178 | { 179 | "prefix": "10.1.1.0", 180 | "mask": "255.255.255.0", 181 | "forwarding-address": "10.2.2.2" 182 | }, 183 | { 184 | "prefix": "10.2.1.0", 185 | "mask": "255.255.255.0", 186 | "forwarding-address": "10.2.2.2" 187 | } 188 | ] 189 | } 190 | } 191 | """ 192 | 193 | output = device.rest.put("/api/running/devices/device/R1/config/ios:ip/route", payload=config_routes) 194 | 195 | 196 | delete 197 | ------ 198 | 199 | API to send DELETE command with payload to the device. 200 | 201 | .. csv-table:: DELETE arguments 202 | :header: Argument, Description, Default 203 | 204 | ``api_url``, API url string (required) 205 | ``content_type``, content type to be returned (xml or json), 206 | ``headers``, dictionary of HTTP headers (optional), 207 | ``expected_status_codes``, list of expected result codes, "200, 201, 204" 208 | ``timeout``, timeout in seconds (optional), 30 209 | 210 | .. code-block:: python 211 | 212 | device.rest.delete('/api/running/devices/device/R1/config/ios:ip/route') 213 | 214 | 215 | .. sectionauthor:: Dave Wapstra 216 | 217 | -------------------------------------------------------------------------------- /docs/user_guide/services/nxos.rst: -------------------------------------------------------------------------------- 1 | NXOS 2 | ==== 3 | 4 | The following services are supported by the REST connector for NXOS. 5 | 6 | 7 | get 8 | --- 9 | 10 | API to send GET command to the device. 11 | 12 | .. csv-table:: 13 | :header: Argument, Description, Default 14 | :widths: 30, 50, 20 15 | 16 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 17 | ``headers``, "Headers to send with the GET command", "None" 18 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 19 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 20 | 21 | .. code-block:: python 22 | 23 | # Assuming the device is already connected 24 | url = '/api/mo/sys/bgp/inst/dom-default/af-ipv4-mvpn.json' 25 | output = device.rest.get(url) 26 | 27 | post 28 | ---- 29 | 30 | API to send POST command to the device. 31 | 32 | .. csv-table:: 33 | :header: Argument, Description, Default 34 | :widths: 30, 50, 20 35 | 36 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 37 | ``payload``, "Payload to send to the device", "Mandatory" 38 | ``headers``, "Headers to send with the GET command", "None" 39 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 40 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 41 | 42 | .. code-block:: python 43 | 44 | # Assuming the device is already connected 45 | payload = """ 46 | { 47 | "bgpInst": { 48 | "attributes": { 49 | "isolate": "disabled", 50 | "adminSt": "enabled", 51 | "fabricSoo": "unknown:unknown:0:0", 52 | "ctrl": "fastExtFallover", 53 | "medDampIntvl": "0", 54 | "affGrpActv": "0", 55 | "disPolBatch": "disabled", 56 | "flushRoutes": "disabled" 57 | }, 58 | "children": [ 59 | { 60 | "bgpDom": { 61 | "attributes": { 62 | "name": "default", 63 | "pfxPeerTimeout": "30", 64 | "pfxPeerWaitTime": "90", 65 | "clusterId": "", 66 | "maxAsLimit": "0", 67 | "reConnIntvl": "60", 68 | "rtrId": "0.0.0.0" 69 | }, 70 | "children": [ 71 | { 72 | "bgpRtCtrl": { 73 | "attributes": { 74 | "logNeighborChanges": "disabled", 75 | "enforceFirstAs": "enabled", 76 | "fibAccelerate": "disabled", 77 | "supprRt": "enabled" 78 | } 79 | } 80 | }, 81 | { 82 | "bgpPathCtrl": { 83 | "attributes": { 84 | "alwaysCompMed": "disabled", 85 | "asPathMultipathRelax": "disabled", 86 | "compNbrId": "disabled", 87 | "compRtrId": "disabled", 88 | "costCommunityIgnore": "disabled", 89 | "medConfed": "disabled", 90 | "medMissingAsWorst": "disabled", 91 | "medNonDeter": "disabled" 92 | } 93 | } 94 | } 95 | ] 96 | } 97 | } 98 | ] 99 | } 100 | } 101 | """ 102 | 103 | url = 'api/mo/sys/bgp/inst.json' 104 | device.rest.post(url, payload) 105 | 106 | delete 107 | ------ 108 | 109 | API to send DELETE command to the device. 110 | 111 | .. csv-table:: 112 | :header: Argument, Description, Default 113 | :widths: 30, 50, 20 114 | 115 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 116 | ``headers``, "Headers to send with the GET command", "None" 117 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 118 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 119 | 120 | .. code-block:: python 121 | 122 | # Assuming the device is already connected 123 | url = '/api/mo/sys/bgp/inst/dom-default/af-ipv4-mvpn.json' 124 | output = device.rest.delete(url) 125 | 126 | patch 127 | ----- 128 | 129 | API to send PATCH command to the device. 130 | 131 | .. csv-table:: 132 | :header: Argument, Description, Default 133 | :widths: 30, 50, 20 134 | 135 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 136 | ``payload``, "Payload to send to the device", "Mandatory" 137 | ``headers``, "Headers to send with the GET command", "None" 138 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 139 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 140 | 141 | .. code-block:: python 142 | 143 | # Assuming the device is already connected 144 | payload = """{ 145 | "intf-items": { 146 | "phys-items": { 147 | "PhysIf-list": [ 148 | { 149 | "adminSt": "down", 150 | "id": "eth1/2", 151 | "userCfgdFlags": "admin_layer,admin_state" 152 | } 153 | ] 154 | } 155 | } 156 | } 157 | """ 158 | url = '/api/mo/sys/bgp/inst/dom-default/af-ipv4-mvpn.json' 159 | output = device.rest.patch(url, payload) 160 | 161 | put 162 | --- 163 | 164 | API to send PUT command to the device. 165 | 166 | .. csv-table:: 167 | :header: Argument, Description, Default 168 | :widths: 30, 50, 20 169 | 170 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 171 | ``payload``, "Payload to send to the device", "Mandatory" 172 | ``headers``, "Headers to send with the GET command", "None" 173 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 174 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 175 | 176 | .. code-block:: python 177 | 178 | # Assuming the device is already connected 179 | payload = """{ 180 | "intf-items": { 181 | "phys-items": { 182 | "PhysIf-list": [ 183 | { 184 | "adminSt": "down", 185 | "id": "eth1/2", 186 | "userCfgdFlags": "admin_layer,admin_state" 187 | } 188 | ] 189 | } 190 | } 191 | } 192 | """ 193 | url = '/api/mo/sys/bgp/inst/dom-default/af-ipv4-mvpn.json' 194 | output = device.rest.put(url, payload) 195 | 196 | .. sectionauthor:: Jean-Benoit Aubin 197 | 198 | -------------------------------------------------------------------------------- /docs/user_guide/services/viptela.rst: -------------------------------------------------------------------------------- 1 | viptela/vManage 2 | =============== 3 | 4 | The following services are supported by the REST connector for viptela/vManage. 5 | 6 | 7 | connect 8 | ------- 9 | 10 | API to connect to the device. 11 | 12 | The vManage REST implementation supports specifying the port to connect to 13 | and allows to specify the username and password in the testbed YAML file. 14 | 15 | .. code-block:: yaml 16 | 17 | # Example 18 | # ------- 19 | # 20 | # pyATS testbed yaml example for defining a REST connection 21 | 22 | testbed: 23 | name: myTestbed 24 | 25 | devices: 26 | vmanage: 27 | os: viptela 28 | type: vmanage 29 | custom: 30 | abstraction: 31 | order: [os] 32 | connections: 33 | rest: 34 | class: rest.connector.Rest 35 | ip : "2.3.4.5" 36 | port: 8443 37 | verify: False 38 | credentials: 39 | rest: 40 | username: admin 41 | password: admin 42 | 43 | 44 | If no port is specified, the default of `8443` is used. If verify is provided 45 | and is False, it wont verify the SSL certificate. 46 | 47 | .. csv-table:: GET arguments 48 | :header: Argument, Description, Default 49 | 50 | ``timeout``, Maximum time it can take to connect to the device. (optional), 30 51 | 52 | 53 | get 54 | --- 55 | 56 | API to send GET command to the device. 57 | 58 | .. list-table:: GET arguments 59 | :widths: 30 50 20 60 | :header-rows: 1 61 | 62 | * - Argument 63 | - Description 64 | - Default 65 | * - mount_point 66 | - API url string 67 | - | string 68 | | Required 69 | * - headers 70 | - Additional headers dictionary 71 | - | dict 72 | | Optional 73 | * - timeout 74 | - Maximum time it can take to disconnect to the device 75 | - | default 30 seconds 76 | | Optional 77 | 78 | 79 | .. code-block:: python 80 | 81 | # Assuming the device is already connected 82 | mount_point = 'dataservice/device' 83 | output = device.get(mount_point=mount_point) 84 | 85 | post 86 | ---- 87 | 88 | API to send POST command to the device. 89 | 90 | .. list-table:: POST arguments 91 | :widths: 30 50 20 92 | :header-rows: 1 93 | 94 | * - Argument 95 | - Description 96 | - Default 97 | * - mount_point 98 | - API url string 99 | - | string 100 | | Required 101 | * - payload 102 | - payload dictionary 103 | - | dict 104 | | Required 105 | * - headers 106 | - Additional headers dictionary 107 | - | dict 108 | | Optional 109 | * - timeout 110 | - Maximum time it can take to disconnect to the device 111 | - | default 30 seconds 112 | | Optional 113 | 114 | .. code-block:: python 115 | 116 | # Assuming the device is already connected 117 | mount_point = "dataservice/template/feature/" 118 | payload = {"templateName":"cli-add-stp", 119 | "templateDescription":"cli-add-stp", 120 | "templateType":"cli-template", 121 | "deviceType":["vedge-ISR-4451-X"], 122 | "templateMinVersion":"15.0.0", 123 | "templateDefinition":{"config":{"vipObjectType":"object", 124 | "vipType":"constant", 125 | "vipValue":"spanning-tree mode rapid-pvst"}}, 126 | "factoryDefault":false} 127 | 128 | device.rest.post(mount_point=mount_point, 129 | payload=payload) 130 | 131 | 132 | put 133 | --- 134 | 135 | API to send PUT command to the device. 136 | 137 | .. list-table:: PUT arguments 138 | :widths: 30 50 20 139 | :header-rows: 1 140 | 141 | * - Argument 142 | - Description 143 | - Default 144 | * - mount_point 145 | - API url string 146 | - | string 147 | | Required 148 | * - payload 149 | - payload dictionary 150 | - | dict 151 | | Required 152 | * - headers 153 | - Additional headers dictionary 154 | - | dict 155 | | Optional 156 | * - timeout 157 | - Maximum time it can take to disconnect to the device 158 | - | default 30 seconds 159 | | Optional 160 | 161 | .. code-block:: python 162 | 163 | # Assuming the device is already connected 164 | mount_point = "dataservice/template/feature/3e322401-c965-4394-b539-216e57020404" 165 | payload = {"templateName":"cli-add-stp", 166 | "templateDescription":"cli-add-stp", 167 | "templateType":"cli-template", 168 | "deviceType":["vedge-ISR-4451-X"], 169 | "templateMinVersion":"15.0.0", 170 | "templateDefinition":{"config":{"vipObjectType":"object", 171 | "vipType":"constant", 172 | "vipValue":"spanning-tree mode rapid-pvst"}}, 173 | "factoryDefault":false} 174 | 175 | device.rest.put(mount_point=mount_point, 176 | payload=payload) 177 | 178 | delete 179 | ------ 180 | 181 | API to send DELETE command to the device. 182 | 183 | .. list-table:: DELETE arguments 184 | :widths: 30 50 20 185 | :header-rows: 1 186 | 187 | * - Argument 188 | - Description 189 | - Default 190 | * - mount_point 191 | - API url string 192 | - | string 193 | | Required 194 | * - headers 195 | - Additional headers dictionary 196 | - | dict 197 | | Optional 198 | * - timeout 199 | - Maximum time it can take to disconnect to the device 200 | - | default 30 seconds 201 | | Optional 202 | 203 | .. code-block:: python 204 | 205 | # Assuming the device is already connected 206 | mount_point = "dataservice/device/unreachable/" 207 | device.rest.delete(mount_point=mount_point) 208 | 209 | 210 | .. sectionauthor:: Vanda Wang 211 | -------------------------------------------------------------------------------- /docs/user_guide/services/virl.rst: -------------------------------------------------------------------------------- 1 | VIRL 2 | ==== 3 | 4 | The following services are supported by the REST connector for VIRL. 5 | 6 | 7 | get 8 | --- 9 | 10 | API to send GET command to the device. 11 | 12 | .. csv-table:: GET arguments 13 | :header: Argument, Description, Default 14 | :widths: 30, 50, 20 15 | 16 | ``url``, "REST API url", "Mandatory" 17 | ``expected_status_code``, "Expected result", "200" 18 | 19 | .. code-block:: python 20 | 21 | # Assuming the device is already connected 22 | url = '/simengine/rest/list' 23 | output = device.get(url) 24 | 25 | post 26 | ---- 27 | 28 | API to send POST command to the device. 29 | 30 | .. csv-table:: POST arguments 31 | :header: Argument, Description, Default 32 | :widths: 30, 50, 20 33 | 34 | ``url``, "REST API url", "Mandatory" 35 | ``payload``, "JSON data of VIRL config", "Mandatory" 36 | ``expected_status_code``, "Expected result", "200" 37 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 38 | 39 | .. code-block:: python 40 | 41 | # Assuming the device is already connected 42 | payload = """ 43 | { 44 | (VIRL Config) 45 | } 46 | """ 47 | 48 | url = '/simengine/rest/launch' 49 | device.post(url, payload) 50 | 51 | delete 52 | ------ 53 | 54 | API to send DELETE command to the device. 55 | 56 | .. csv-table:: DELETE arguments 57 | :header: Argument, Description, Default 58 | :widths: 30, 50, 20 59 | 60 | ``url``, "REST API url", "Mandatory" 61 | ``expected_status_code``, "Expected result", "200" 62 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 63 | 64 | .. code-block:: python 65 | 66 | # Assuming the device is already connected 67 | url = '/simengine/rest/tracking/{tracking_id}' 68 | output = device.delete(url) 69 | 70 | 71 | .. sectionauthor:: Takashi Higashimura 72 | -------------------------------------------------------------------------------- /docs/user_guide/services/webex.rst: -------------------------------------------------------------------------------- 1 | Webex 2 | ===== 3 | 4 | The following services are supported by the REST connector for Webex. 5 | 6 | 7 | get 8 | --- 9 | 10 | API to send GET command to the device. 11 | 12 | .. csv-table:: 13 | :header: Argument, Description, Default 14 | :widths: 30, 50, 20 15 | 16 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 17 | ``headers``, "Headers to send with the GET command", "{Authorization: Bearer }" 18 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 19 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 20 | 21 | .. code-block:: python 22 | 23 | # Assuming the device is already connected 24 | url = '/v1/people/me' 25 | output = device.rest.get(url) 26 | 27 | post 28 | ---- 29 | 30 | API to send POST command to the device. 31 | 32 | .. csv-table:: 33 | :header: Argument, Description, Default 34 | :widths: 30, 50, 20 35 | 36 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 37 | ``payload``, "Payload to send to the device", "Mandatory" 38 | ``headers``, "Headers to send with the GET command", "{Authorization: Bearer }" 39 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 40 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 41 | 42 | .. code-block:: python 43 | 44 | # Assuming the device is already connected 45 | payload = """ 46 | { 47 | "toPersonId": "", 48 | "text": "hello" 49 | } 50 | """ 51 | 52 | url = 'v1/messages/' 53 | device.rest.post(url, payload) 54 | 55 | delete 56 | ------ 57 | 58 | API to send DELETE command to the device. 59 | 60 | .. csv-table:: 61 | :header: Argument, Description, Default 62 | :widths: 30, 50, 20 63 | 64 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 65 | ``headers``, "Headers to send with the GET command", "{Authorization: Bearer }" 66 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 67 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 68 | 69 | .. code-block:: python 70 | 71 | # Assuming the device is already connected 72 | url = 'v1/messages/' 73 | device.rest.delete(url) 74 | 75 | put 76 | --- 77 | 78 | API to send PUT command to the device. 79 | 80 | .. csv-table:: 81 | :header: Argument, Description, Default 82 | :widths: 30, 50, 20 83 | 84 | ``dn``, "Unique distinguished name describes the place in the tree", "Mandatory" 85 | ``payload``, "Payload to send to the device", "Mandatory" 86 | ``headers``, "Headers to send with the GET command", "{Authorization: Bearer }" 87 | ``timeout``, "Maximum time it can take to disconnect to the device.", "30 seconds" 88 | ``expected_return_code``, "Return code that is expected.", "None (Any good result)" 89 | 90 | .. code-block:: python 91 | 92 | # Assuming the device is already connected 93 | payload = """{ 94 | "roomId": "", 95 | "text": "hello again!" 96 | } 97 | """ 98 | url = 'v1/messages/' 99 | output = device.rest.put(url, payload) 100 | 101 | .. sectionauthor:: Takashi Higashimura 102 | 103 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | """Setup file for rest package 4 | 5 | See: 6 | https://packaging.python.org/en/latest/distributing.html 7 | """ 8 | 9 | import os 10 | import re 11 | import sys 12 | import shlex 13 | import unittest 14 | import subprocess 15 | from setuptools import setup, Command, find_namespace_packages 16 | from setuptools.command.test import test 17 | 18 | pkg_name = 'rest.connector' 19 | pkg_path = '/'.join(pkg_name.split('.')) 20 | 21 | 22 | class CleanCommand(Command): 23 | '''Custom clean command 24 | 25 | cleanup current directory: 26 | - removes build/ 27 | - removes src/*.egg-info 28 | - removes *.pyc and __pycache__ recursively 29 | 30 | Example 31 | ------- 32 | python setup.py clean 33 | 34 | ''' 35 | 36 | user_options = [] 37 | description = 'CISCO SHARED : Clean all build artifacts' 38 | 39 | def initialize_options(self): 40 | pass 41 | 42 | def finalize_options(self): 43 | pass 44 | 45 | def run(self): 46 | os.system('rm -vrf ./build ./dist ./src/*.egg-info') 47 | os.system('find . -type f -name "*.pyc" | xargs rm -vrf') 48 | os.system('find . -type d -name "__pycache__" | xargs rm -vrf') 49 | 50 | 51 | class TestCommand(Command): 52 | user_options = [] 53 | description = 'CISCO SHARED : Run unit tests against this package' 54 | 55 | def initialize_options(self): 56 | pass 57 | 58 | def finalize_options(self): 59 | pass 60 | 61 | def run(self): 62 | # where the tests are (relative to here) 63 | tests = os.path.join('src', pkg_path, 'tests') 64 | 65 | # call unittests 66 | sys.exit(unittest.main( 67 | module=None, 68 | argv=['python -m unittest', 'discover', tests], 69 | failfast=True)) 70 | 71 | 72 | def read(*paths): 73 | '''read and return txt content of file''' 74 | with open(os.path.join(os.path.dirname(__file__), *paths)) as fp: 75 | return fp.read() 76 | 77 | 78 | def find_version(*paths): 79 | '''reads a file and returns the defined __version__ value''' 80 | version_match = re.search(r"^__version__ ?= ?['\"]([^'\"]*)['\"]", 81 | read(*paths), re.M) 82 | if version_match: 83 | return version_match.group(1) 84 | raise RuntimeError("Unable to find version string.") 85 | 86 | 87 | # launch setup 88 | setup( 89 | name=pkg_name, 90 | version=find_version('src', pkg_path, '__init__.py'), 91 | 92 | # descriptions 93 | description='pyATS REST connection package', 94 | long_description=read('DESCRIPTION.rst'), 95 | 96 | # the package's documentation page. 97 | url='https://developer.cisco.com/docs/rest-connector/', 98 | 99 | # author details 100 | author='Cisco Systems Inc.', 101 | author_email='jeaubin@cisco.com', 102 | maintainer_email='pyats-support-ext@cisco.com', 103 | 104 | # project licensing 105 | license='Apache 2.0', 106 | 107 | platforms=['Linux', 'macOS'], 108 | 109 | # see https://pypi.python.org/pypi?%3Aaction=list_classifiers 110 | classifiers=[ 111 | 'Development Status :: 6 - Mature', 112 | 'Development Status :: 5 - Production/Stable', 113 | 'Environment :: Console', 114 | 'Intended Audience :: Developers', 115 | 'Intended Audience :: Telecommunications Industry', 116 | 'Intended Audience :: Information Technology', 117 | 'Intended Audience :: System Administrators', 118 | 'License :: OSI Approved :: Apache Software License', 119 | 'Operating System :: MacOS', 120 | 'Operating System :: POSIX :: Linux', 121 | 'Programming Language :: Python :: 3.7', 122 | 'Programming Language :: Python :: 3.6', 123 | 'Programming Language :: Python :: 3.5', 124 | 'Programming Language :: Python :: 3 :: Only', 125 | 'Programming Language :: Python :: Implementation :: CPython', 126 | 'Topic :: Software Development :: Testing', 127 | 'Topic :: Software Development :: Build Tools', 128 | 'Topic :: Software Development :: Libraries', 129 | 'Topic :: Software Development :: Libraries :: Python Modules', 130 | ], 131 | 132 | # project keywords 133 | keywords='pyats cisco-shared', 134 | 135 | # project packages 136 | packages=find_namespace_packages(where='src'), 137 | 138 | # project directory 139 | package_dir={ 140 | '': 'src', 141 | }, 142 | 143 | # additional package data files that goes into the package itself 144 | package_data={'': ['README.md', 145 | 'tests/testbed.yaml', 146 | ] 147 | }, 148 | 149 | # Standalone scripts 150 | scripts=[ 151 | ], 152 | 153 | # console entry point 154 | entry_points={ 155 | }, 156 | 157 | # package dependencies 158 | install_requires=[ 159 | 'requests >= 1.15.1', 160 | 'dict2xml', 161 | 'f5-icontrol-rest', 162 | 'ciscoisesdk' 163 | ], 164 | 165 | # any additional groups of dependencies. 166 | # install using: $ pip install -e .[dev] 167 | extras_require={ 168 | 'dev': ['coverage', 169 | 'restview', 170 | 'Sphinx', 171 | 'sphinx-rtd-theme', 172 | 'requests-mock'], 173 | }, 174 | 175 | # any data files placed outside this package. 176 | # See: http://docs.python.org/3.4/distutils/setupscript.html 177 | # format: 178 | # [('target', ['list', 'of', 'files'])] 179 | # where target is sys.prefix/ 180 | data_files=[], 181 | 182 | # custom commands for setup.py 183 | cmdclass={ 184 | 'clean': CleanCommand, 185 | 'test': TestCommand, 186 | }, 187 | 188 | # non zip-safe (never tested it) 189 | zip_safe=False, 190 | ) 191 | -------------------------------------------------------------------------------- /src/rest/connector/__init__.py: -------------------------------------------------------------------------------- 1 | """rest.connector module defines a connection implementation to communicate to 2 | the device via REST api""" 3 | 4 | # metadata 5 | __version__ = "25.5" 6 | __author__ = ['Jean-Benoit Aubin ', 7 | 'Takashi Higashimura (tahigash) '] 8 | 9 | __contact__ = 'pyats-support@cisco.com' 10 | __copyright__ = 'Cisco Systems, Inc. Cisco Confidential' 11 | 12 | 13 | from pyats.connections import BaseConnection 14 | 15 | # For abstract 16 | from genie.abstract import Lookup 17 | import rest.connector.libs 18 | 19 | # Ease of use (rest.connector.Acisdk) 20 | from rest.connector.libs.apic.acisdk_implementation import AciCobra 21 | 22 | 23 | class Rest(BaseConnection): 24 | '''Rest 25 | 26 | Used for picking the right abstraction of REST implementatin based on the 27 | device, via abstraction 28 | 29 | It also overwrittes __getattribute__ to go look in the right abstracted 30 | class 31 | ''' 32 | 33 | def __init__(self, *args, **kwargs): 34 | '''__init__ instantiates a single connection instance.''' 35 | 36 | super().__init__(*args, **kwargs) 37 | 38 | # Get the device platform, must be grabbed from the device dict as 39 | # platform can be populated from type if platform is not defined. 40 | # device_platform = self.device._to_dict().get('platform') 41 | if hasattr(self.device, 'platform') and self.device.platform: 42 | abstraction_tokens = ['os', 'platform'] 43 | else: 44 | abstraction_tokens = ['os'] 45 | 46 | # Set up abstraction for this device 47 | lookup = Lookup.from_device(self.device, default_tokens=abstraction_tokens) 48 | _implementation = lookup.libs.implementation.Implementation 49 | self._implementation = _implementation(*args, **kwargs) 50 | 51 | def __getattribute__(self, name): 52 | '''Redirect specific name of function to the specific implementation''' 53 | 54 | # Selector of methods/attributes to pick from abstracted 55 | # Can't use __getattr__ as BaseConnection is abstract and some already 56 | # exists 57 | if name in ['api', 'get', 'post', 'put', 'patch', 'delete', 58 | 'connect', 'disconnect', 'connected']: 59 | return getattr(self._implementation, name) 60 | 61 | # Send the rest to normal __getattribute__ 62 | return super().__getattribute__(name) 63 | 64 | 65 | class Acisdk(AciCobra): 66 | def __init__(self, *args, **kwargs): 67 | super().__init__(*args, **kwargs) 68 | -------------------------------------------------------------------------------- /src/rest/connector/implementation.py: -------------------------------------------------------------------------------- 1 | from pyats.connections import BaseConnection 2 | 3 | 4 | class Implementation(BaseConnection): 5 | '''Rest BaseClass 6 | 7 | Baseclass for Rest connection implementation 8 | 9 | YAML Example 10 | ------------ 11 | 12 | devices: 13 | PE1: 14 | credentials: 15 | rest: 16 | username: admin 17 | password: cisco123 18 | connections: 19 | a: 20 | protocol: telnet 21 | ip: "1.2.3.4" 22 | port: 2004 23 | vty: 24 | protocol : telnet 25 | ip : "2.3.4.5" 26 | rest: 27 | class: rest.connector.Rest 28 | ip : "2.3.4.5" 29 | port: "443" 30 | protocol: https 31 | credentials: 32 | rest: 33 | username: admin 34 | password: cisco123 35 | 36 | Example 37 | ------- 38 | 39 | >>> from pyats.topology import loader 40 | >>> testbed = loader.load('/users/xxx/xxx/asr22.yaml') 41 | >>> device = testbed.devices['PE1'] 42 | >>> device.connect(alias='rest', via='rest') 43 | >>> device.rest.connected 44 | True 45 | ''' 46 | 47 | def __init__(self, *args, **kwargs): 48 | '''__init__ instantiates a single connection instance.''' 49 | 50 | # instanciate BaseConnection 51 | # (could use super...) 52 | BaseConnection.__init__(self, *args, **kwargs) 53 | self._is_connected = False 54 | 55 | @property 56 | def connected(self): 57 | '''Is a device connected''' 58 | return self._is_connected 59 | 60 | def connect(self, *args, **kwargs): 61 | '''connect to the device via REST''' 62 | 63 | raise NotImplementedError 64 | 65 | def disconnect(self): 66 | '''disconnect the device for this particular alias''' 67 | 68 | raise NotImplementedError 69 | 70 | def get(self, *args, **kwargs): 71 | '''GET REST Command to retrieve information from the device''' 72 | 73 | raise NotImplementedError 74 | 75 | def post(self, *args, **kwargs): 76 | '''POST REST Command to configure information from the device''' 77 | 78 | raise NotImplementedError 79 | 80 | def put(self, *args, **kwargs): 81 | '''PUT REST Command to update information on the device''' 82 | 83 | raise NotImplementedError 84 | 85 | def patch(self, *args, **kwargs): 86 | '''PATCH REST Command to update information on the device''' 87 | 88 | raise NotImplementedError 89 | 90 | def delete(self, *args, **kwargs): 91 | '''DELETE REST Command to delete information from the device''' 92 | 93 | raise NotImplementedError 94 | 95 | def configure(self, *args, **kwargs): 96 | '''configure - Not implemented for REST''' 97 | raise NotImplementedError('configure is not a supported method for REST. ' 98 | 'post is probably what you are looking for') 99 | 100 | def execute(self, *args, **kwargs): 101 | '''execute - Not implemented for REST''' 102 | raise NotImplementedError('execute is not a supported method for REST. ' 103 | 'get is probably what you are looking for.') 104 | -------------------------------------------------------------------------------- /src/rest/connector/libs/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction; This is the root package. 2 | from genie import abstract 3 | abstract.declare_package(__name__) 4 | -------------------------------------------------------------------------------- /src/rest/connector/libs/apic/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='apic') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/bigip/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='bigip') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/dcnm/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # Enable abstraction using this directory name as the abstraction token 3 | try: 4 | from genie import abstract 5 | abstract.declare_token(os='dcnm') 6 | except Exception as e: 7 | import warnings 8 | warnings.warn('Could not declare abstraction token: ' + str(e)) 9 | -------------------------------------------------------------------------------- /src/rest/connector/libs/dnac/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='dnac') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/dnac/implementation.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | import requests 4 | from requests.auth import HTTPBasicAuth 5 | from requests.exceptions import RequestException 6 | 7 | from pyats.connections import BaseConnection 8 | from rest.connector.implementation import Implementation 9 | from rest.connector.utils import get_username_password 10 | 11 | # create a logger for this module 12 | log = logging.getLogger(__name__) 13 | 14 | STD_HEADER = {'Content-type': 'application/json'} 15 | 16 | class Implementation(Implementation): 17 | '''Rest Implementation for DNAC 18 | 19 | Implementation of Rest connection to devices based on pyATS BaseConnection 20 | for DNAC 21 | 22 | YAML Example 23 | ------------ 24 | 25 | devices: 26 | dnac1: 27 | connections: 28 | rest: 29 | class: rest.connector.Rest 30 | ip : "2.3.4.5" 31 | port: 443 32 | verify: False 33 | credentials: 34 | rest: 35 | username: admin 36 | password: cisco123 37 | 38 | Code Example 39 | ------------ 40 | 41 | >>> from pyats.topology import loader 42 | >>> testbed = loader.load('/users/xxx/xxx/dna.yaml') 43 | >>> device = testbed.devices['dnac1'] 44 | >>> device.connect(alias='rest', via='rest') 45 | >>> device.rest.connected 46 | True 47 | ''' 48 | 49 | @BaseConnection.locked 50 | def connect(self, timeout=30): 51 | '''connect to the device via REST 52 | 53 | Arguments 54 | --------- 55 | 56 | timeout (int): Timeout value 57 | 58 | Raises 59 | ------ 60 | 61 | Exception 62 | --------- 63 | 64 | If the connection did not go well 65 | 66 | Note 67 | ---- 68 | 69 | There is no return from this method. If something goes wrong, an 70 | exception will be raised. 71 | ''' 72 | 73 | if self.connected: 74 | return 75 | 76 | # Building out Auth request. 77 | # prefer host instead of ip address directly 78 | try: 79 | host = self.connection_info['host'] 80 | except KeyError: 81 | host = self.connection_info['ip'].exploded 82 | 83 | port = self.connection_info.get('port', 443) 84 | self.verify = self.connection_info.get('verify', True) 85 | 86 | username, password = get_username_password(self) 87 | 88 | self.base_url = 'https://{host}:{port}'.format(host=host, port=port) 89 | 90 | auth_url = '{url}/dna/system/api/v1/auth/token'.format(url=self.base_url) 91 | resp = requests.post(auth_url, headers = STD_HEADER, 92 | auth=HTTPBasicAuth(username, password), 93 | verify=self.verify) 94 | 95 | self.token = resp.json()['Token'] # Retrieve the Token from the returned JSONhahhah 96 | 97 | self._is_connected = True 98 | log.info("Connected successfully to '{d}'".format(d=self.device.name)) 99 | 100 | @BaseConnection.locked 101 | def disconnect(self): 102 | '''disconnect the device for this particular alias''' 103 | 104 | log.info("Disconnecting from '{d}' with " 105 | "alias '{a}'".format(d=self.device.name, a=self.alias)) 106 | self._is_connected = False 107 | log.info("Disconnected successfully from " 108 | "'{d}'".format(d=self.device.name)) 109 | 110 | @BaseConnection.locked 111 | def get(self, api_url, timeout=30, **kwargs): 112 | '''GET REST Command to retrieve information from the device 113 | 114 | Arguments 115 | --------- 116 | 117 | api_url (string): API url string 118 | timeout: timeout in seconds (default: 30) 119 | **kwargs: keyword arguments supported in requests.get method 120 | ''' 121 | if not self.connected: 122 | raise Exception("'{d}' is not connected for " 123 | "alias '{a}'".format(d=self.device.name, 124 | a=self.alias)) 125 | full_url = '{url}{api_url}'.format(url=self.base_url, 126 | api_url=api_url) 127 | 128 | log.debug("Sending GET command to '{d}':"\ 129 | "\nDN: {furl}".format(d=self.device.name, furl=full_url)) 130 | 131 | hdr = {'x-auth-token': self.token, 'content-type' : 'application/json'} 132 | response = requests.get(full_url, headers=hdr, 133 | verify=self.verify, timeout=timeout, **kwargs) 134 | log.info("Output received:\n{response}".format(response=response)) 135 | 136 | return response 137 | 138 | @BaseConnection.locked 139 | def put(self, api_url, timeout=30, **kwargs): 140 | '''GET REST Command to retrieve information from the device 141 | 142 | Arguments 143 | --------- 144 | 145 | api_url (string): API url string 146 | timeout: timeout in seconds (default: 30) 147 | ''' 148 | if not self.connected: 149 | raise Exception("'{d}' is not connected for " 150 | "alias '{a}'".format(d=self.device.name, 151 | a=self.alias)) 152 | full_url = '{url}{api_url}'.format(url=self.base_url, 153 | api_url=api_url) 154 | 155 | log.debug("Sending PUT command to '{d}':"\ 156 | "\nDN: {furl}".format(d=self.device.name, furl=full_url)) 157 | 158 | hdr = {'x-auth-token': self.token, 'content-type' : 'application/json'} 159 | response = requests.put(full_url, headers=hdr, 160 | verify=self.verify, timeout=timeout, **kwargs) 161 | log.info("Output received:\n{response}".format(response=response.text)) 162 | 163 | return response 164 | 165 | @BaseConnection.locked 166 | def post(self, api_url, timeout=30, **kwargs): 167 | '''GET REST Command to POST information to the device 168 | 169 | Arguments 170 | --------- 171 | 172 | api_url (string): API url string 173 | timeout: timeout in seconds (default: 30) 174 | **kwargs are the same keyword arguments for the requests lib 175 | ''' 176 | if not self.connected: 177 | raise Exception("'{d}' is not connected for " 178 | "alias '{a}'".format(d=self.device.name, 179 | a=self.alias)) 180 | full_url = '{url}{api_url}'.format(url=self.base_url, 181 | api_url=api_url) 182 | 183 | log.info("Sending POST command to '{d}':"\ 184 | "\nDN: {furl}".format(d=self.device.name, furl=full_url)) 185 | 186 | hdr = {'x-auth-token': self.token, 'content-type' : 'application/json'} 187 | response = requests.post(full_url, headers=hdr, 188 | verify=self.verify, timeout=timeout, **kwargs) 189 | log.info("Output received:\n{response}".format(response=response)) 190 | 191 | return response 192 | -------------------------------------------------------------------------------- /src/rest/connector/libs/elasticsearch/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='elasticsearch') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/iosxe/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='iosxe') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/ise/__init__.py: -------------------------------------------------------------------------------- 1 | from genie import abstract 2 | abstract.declare_token(os='ise') 3 | -------------------------------------------------------------------------------- /src/rest/connector/libs/ise/implementation.py: -------------------------------------------------------------------------------- 1 | 2 | import logging 3 | import urllib.request 4 | from requests.exceptions import RequestException 5 | 6 | from pyats.connections import BaseConnection 7 | from rest.connector.utils import get_username_password 8 | from rest.connector.implementation import Implementation as RestImplementation 9 | 10 | from ciscoisesdk import IdentityServicesEngineAPI 11 | 12 | # create a logger for this module 13 | log = logging.getLogger(__name__) 14 | 15 | 16 | class Implementation(RestImplementation): 17 | '''Rest Implementation for ISE 18 | 19 | Implementation of Rest connection to ISE servers 20 | 21 | YAML Example 22 | ------------ 23 | 24 | devices: 25 | ise: 26 | os: ise 27 | connections: 28 | rest: 29 | class: rest.connector.Rest 30 | ip: 127.0.0.1 31 | port: "443" 32 | protocol: https 33 | credentials: 34 | rest: 35 | username: admin 36 | password: admin 37 | 38 | Code Example 39 | ------------ 40 | 41 | >>> from pyats.topology import loader 42 | >>> testbed = loader.load('topology.yaml') 43 | >>> device = testbed.devices['ise'] 44 | >>> device.connect(alias='rest', via='rest') 45 | >>> device.rest.connected 46 | True 47 | ''' 48 | 49 | def __init__(self, *args, **kwargs): 50 | super().__init__(*args, **kwargs) 51 | if 'proxies' not in kwargs: 52 | self.proxies = urllib.request.getproxies() 53 | 54 | @BaseConnection.locked 55 | def connect(self, 56 | timeout=30, 57 | verbose=False, 58 | port="443", 59 | protocol='https', 60 | debug=False, 61 | **kwargs): 62 | '''connect to the device via REST 63 | 64 | Arguments 65 | --------- 66 | 67 | timeout (int): Timeout value 68 | 69 | Raises 70 | ------ 71 | 72 | Exception 73 | --------- 74 | 75 | If the connection did not go well 76 | 77 | ''' 78 | if self.connected: 79 | log.info(f'{self} already connected') 80 | return 81 | 82 | # support sshtunnel 83 | if 'sshtunnel' in self.connection_info: 84 | try: 85 | from unicon.sshutils import sshtunnel 86 | except ImportError: 87 | raise ImportError( 88 | '`unicon` is not installed for `sshtunnel`. Please install by `pip install unicon`.' 89 | ) 90 | try: 91 | tunnel_port = sshtunnel.auto_tunnel_add(self.device, self.via) 92 | if tunnel_port: 93 | ip = self.device.connections[self.via].sshtunnel.tunnel_ip 94 | port = tunnel_port 95 | except AttributeError as e: 96 | raise AttributeError( 97 | "Cannot add ssh tunnel. Connection %s may not have ip/host or port.\n%s" 98 | % (self.via, e)) 99 | else: 100 | ip = self.connection_info.ip.exploded 101 | port = self.connection_info.get('port', port) 102 | 103 | if 'protocol' in self.connection_info: 104 | protocol = self.connection_info['protocol'] 105 | 106 | self.base_url = '{protocol}://{ip}:{port}'.format(protocol=protocol, 107 | ip=ip, 108 | port=port) 109 | 110 | username, password = get_username_password(self) 111 | 112 | self.api = IdentityServicesEngineAPI( 113 | username=username, password=password, 114 | base_url=self.base_url, uses_api_gateway=True, 115 | verify=False, debug=debug) 116 | 117 | version_request = self.api.version_and_patch.get_ise_version_and_patch() 118 | if version_request.status_code == 200: 119 | version_info = version_request.response 120 | # {'OperationResult': {'resultValue': [ 121 | # {'value': '3.3.0.430', 'name': 'version'}, {'value': '0', 'name': 'patch information'}]}} 122 | # Check if version_info is a dictionary 123 | if isinstance(version_info, dict): 124 | # Proceed with accessing the version information 125 | version_info_list = version_info.get('OperationResult', {}).get('resultValue', []) 126 | else: 127 | # Raise an appropriate error if version_info is not a dictionary 128 | raise TypeError(f"Expected version_info to be a dictionary, but received {version_info}") 129 | version_message_list = [] 130 | for version_nv in version_info_list: 131 | name = version_nv.get('name') 132 | value = version_nv.get('value') 133 | if name and value: 134 | version_message_list.append(f'{name}: {value}') 135 | if version_message_list: 136 | version_message = ' '.join(version_message_list) 137 | log.info(version_message) 138 | self._is_connected = True 139 | log.info("Connected successfully to '{d}'".format(d=self.device.name)) 140 | else: 141 | raise ConnectionError('Unable to connect to ISE server') 142 | 143 | return self.api 144 | 145 | @BaseConnection.locked 146 | def disconnect(self): 147 | """ 148 | """ 149 | self._is_connected = False 150 | return 151 | -------------------------------------------------------------------------------- /src/rest/connector/libs/nd/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='nd') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/nexusdashboard/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='nexusdashboard') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/nso/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='nso') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/nxos/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='nxos') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/nxos/aci/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(platform='aci') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/viptela/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='viptela') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/virl/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='virl') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/vmware/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='vmware') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/webex/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='webex') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/libs/xpresso/__init__.py: -------------------------------------------------------------------------------- 1 | # Enable abstraction using this directory name as the abstraction token 2 | try: 3 | from genie import abstract 4 | abstract.declare_token(os='xpresso') 5 | except Exception as e: 6 | import warnings 7 | warnings.warn('Could not declare abstraction token: ' + str(e)) 8 | -------------------------------------------------------------------------------- /src/rest/connector/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoTestAutomation/rest/995f7f7e9a1b54cb204f9f38b62a2d4fd78cd929/src/rest/connector/tests/__init__.py -------------------------------------------------------------------------------- /src/rest/connector/tests/test_ise.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | """ Unit tests for the rest.connector cisco-shared package. """ 3 | import os 4 | import unittest 5 | from requests.models import Response 6 | from unittest.mock import patch, MagicMock 7 | 8 | from pyats.topology import loader 9 | 10 | from rest.connector import Rest 11 | HERE = os.path.dirname(__file__) 12 | 13 | 14 | class test_rest_connector(unittest.TestCase): 15 | def setUp(self): 16 | self.testbed = loader.load(os.path.join(HERE, 'testbed.yaml')) 17 | self.device = self.testbed.devices['ise'] 18 | 19 | def test_init(self): 20 | connection = Rest(device=self.device, alias='rest', via='rest') 21 | self.assertEqual(connection.device, self.device) 22 | 23 | with self.assertRaises(NotImplementedError): 24 | self.assertRaises(connection.execute()) 25 | with self.assertRaises(NotImplementedError): 26 | self.assertRaises(connection.configure()) 27 | 28 | def test_connection(self): 29 | connection = Rest(device=self.device, alias='rest', via='rest') 30 | self.assertEqual(connection.connected, False) 31 | 32 | with patch('requests.session') as req: 33 | resp = Response() 34 | resp.headers['Content-type'] = 'application/json' 35 | resp.status_code = 200 36 | resp._content = b'{"OperationResult": {"resultValue": [{"value": "3.3.0.430",' + \ 37 | b' "name": "version"}, {"value": "0", "name": "patch information"}]}}' 38 | req().request.return_value = resp 39 | connection.connect() 40 | self.assertEqual(connection.connected, True) 41 | connection.connect() 42 | self.assertEqual(connection.connected, True) 43 | 44 | # Now disconnect 45 | with patch('requests.session') as req: 46 | connection.disconnect() 47 | self.assertEqual(connection.connected, False) 48 | 49 | -------------------------------------------------------------------------------- /src/rest/connector/tests/test_viptela.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | """ Unit tests for viptela/vManage rest.connector """ 3 | 4 | import os 5 | import unittest 6 | from requests.models import Response 7 | from unittest.mock import patch, MagicMock 8 | from requests.exceptions import RequestException 9 | 10 | from pyats.topology import loader 11 | 12 | from rest.connector import Rest 13 | HERE = os.path.dirname(__file__) 14 | 15 | 16 | class test_rest_connector(unittest.TestCase): 17 | 18 | def setUp(self): 19 | self.testbed = loader.load(os.path.join(HERE, 'testbed.yaml')) 20 | self.device = self.testbed.devices['vmanage'] 21 | 22 | def test_init(self): 23 | connection = Rest(device=self.device, alias='rest', via='rest') 24 | self.assertEqual(connection.device, self.device) 25 | 26 | with self.assertRaises(NotImplementedError): 27 | self.assertRaises(connection.execute()) 28 | with self.assertRaises(NotImplementedError): 29 | self.assertRaises(connection.configure()) 30 | 31 | def test_connection(self): 32 | connection = Rest(device=self.device, alias='rest', via='rest') 33 | self.assertEqual(connection.connected, False) 34 | 35 | with patch('requests.session') as req: 36 | resp = Response() 37 | resp.status_code = 200 38 | req().post.return_value = resp 39 | req().get.return_value = resp 40 | connection.connect() 41 | self.assertEqual(connection.connected, True) 42 | connection.connect() 43 | self.assertEqual(connection.connected, True) 44 | 45 | # Now disconnect 46 | with patch('requests.session') as req: 47 | connection.disconnect() 48 | self.assertEqual(connection.connected, False) 49 | 50 | def test_post_not_connected(self): 51 | connection = Rest(device=self.device, alias='rest', via='rest') 52 | with self.assertRaises(Exception): 53 | connection.post(mount_point='temp', 54 | payload={'payload': 'something'}) 55 | 56 | def test_connection_wrong_code(self): 57 | connection = Rest(device=self.device, alias='rest', via='rest') 58 | self.assertEqual(connection.connected, False) 59 | 60 | with patch('requests.session') as req: 61 | resp = Response() 62 | resp.status_code = 404 63 | req().post.return_value = resp 64 | req().get.return_value = resp 65 | 66 | with self.assertRaises(RequestException): 67 | connection.connect() 68 | 69 | self.assertEqual(connection.connected, False) 70 | 71 | # Now disconnect 72 | with patch('requests.session') as req: 73 | connection.disconnect() 74 | self.assertEqual(connection.connected, False) 75 | 76 | def test_post_connected(self): 77 | connection = Rest(device=self.device, alias='rest', via='rest') 78 | self.assertEqual(connection.connected, False) 79 | 80 | with patch('requests.session') as req: 81 | resp = Response() 82 | resp.raw = MagicMock() 83 | resp.status_code = 200 84 | req().post.return_value = resp 85 | req().get.return_value = resp 86 | connection.connect() 87 | resp.json = MagicMock(return_value={'imdata': []}) 88 | connection.post(mount_point='temp', 89 | payload={'payload': 'something'}) 90 | connection.disconnect() 91 | self.assertEqual(connection.connected, False) 92 | 93 | def test_get_not_connected(self): 94 | connection = Rest(device=self.device, alias='rest', via='rest') 95 | with self.assertRaises(Exception): 96 | connection.get(mount_point='temp') 97 | 98 | def test_get_connected(self): 99 | connection = Rest(device=self.device, alias='rest', via='rest') 100 | self.assertEqual(connection.connected, False) 101 | 102 | with patch('requests.session') as req: 103 | resp = Response() 104 | resp.raw = MagicMock() 105 | resp.status_code = 200 106 | req().post.return_value = resp 107 | req().get.return_value = resp 108 | connection.connect() 109 | resp.json = MagicMock(return_value={'imdata': []}) 110 | connection.get(mount_point='temp') 111 | connection.disconnect() 112 | self.assertEqual(connection.connected, False) 113 | 114 | def test_get_connected_change_expected(self): 115 | connection = Rest(device=self.device, alias='rest', via='rest') 116 | self.assertEqual(connection.connected, False) 117 | 118 | with patch('requests.session') as req: 119 | resp = Response() 120 | resp.raw = MagicMock() 121 | resp.status_code = 200 122 | resp2 = Response() 123 | resp2.raw = MagicMock() 124 | resp2.status_code = 300 125 | req().get.side_effect = [resp, resp2] 126 | req().post.side_effect = [resp, resp, resp2] 127 | 128 | connection.connect() 129 | resp.json = MagicMock(return_value={'imdata': []}) 130 | resp2.json = MagicMock(return_value={'imdata': []}) 131 | 132 | connection.get(mount_point='temp') 133 | self.assertEqual(connection.connected, True) 134 | connection.disconnect() 135 | self.assertEqual(connection.connected, False) 136 | 137 | def test_delete_not_connected(self): 138 | connection = Rest(device=self.device, alias='rest', via='rest') 139 | with self.assertRaises(Exception): 140 | connection.delete(mount_point='temp') 141 | 142 | def test_delete_connected(self): 143 | connection = Rest(device=self.device, alias='rest', via='rest') 144 | self.assertEqual(connection.connected, False) 145 | 146 | with patch('requests.session') as req: 147 | resp = Response() 148 | resp.raw = MagicMock() 149 | resp.status_code = 200 150 | req().post.return_value = resp 151 | req().get.return_value = resp 152 | req().delete.return_value = resp 153 | connection.connect() 154 | resp.json = MagicMock(return_value={'imdata': []}) 155 | connection.delete(mount_point='temp') 156 | connection.disconnect() 157 | self.assertEqual(connection.connected, False) 158 | 159 | def test_delete_connected_change_expected(self): 160 | connection = Rest(device=self.device, alias='rest', via='rest') 161 | self.assertEqual(connection.connected, False) 162 | 163 | with patch('requests.session') as req: 164 | resp = Response() 165 | resp.raw = MagicMock() 166 | resp.status_code = 200 167 | resp2 = Response() 168 | resp2.raw = MagicMock() 169 | resp2.status_code = 300 170 | req().delete.return_value = resp2 171 | req().post.side_effect = [resp, resp, resp2] 172 | req().get.return_value = resp 173 | connection.connect() 174 | resp.json = MagicMock(return_value={'imdata': []}) 175 | resp2.json = MagicMock(return_value={'imdata': []}) 176 | connection.delete(mount_point='temp') 177 | self.assertEqual(connection.connected, True) 178 | connection.disconnect() 179 | 180 | self.assertEqual(connection.connected, False) 181 | 182 | 183 | if __name__ == '__main__': 184 | unittest.main() 185 | -------------------------------------------------------------------------------- /src/rest/connector/tests/testbed.yaml: -------------------------------------------------------------------------------- 1 | 2 | devices: 3 | PE1: 4 | os: nxos 5 | type: router 6 | custom: 7 | abstraction: 8 | order: [os] 9 | connections: 10 | rest: 11 | class: rest.connector.Rest 12 | ip: 198.51.100.1 13 | ncs: 14 | os: nso 15 | type: nso 16 | custom: 17 | abstraction: 18 | order: [os] 19 | connections: 20 | rest: 21 | class: rest.connector.Rest 22 | protocol: http 23 | ip: 198.51.100.2 24 | port: 8080 25 | username: cisco 26 | password: cisco 27 | eWLC: 28 | os: iosxe 29 | type: eWLC 30 | custom: 31 | abstraction: 32 | order: [os] 33 | connections: 34 | rest: 35 | class: rest.connector.Rest 36 | protocol: https 37 | ip: 198.51.100.3 38 | port: 443 39 | username: cisco 40 | password: cisco 41 | apic: 42 | os: apic 43 | type: apic 44 | custom: 45 | abstraction: 46 | order: [os] 47 | connections: 48 | rest: 49 | class: rest.connector.Rest 50 | protocol: http 51 | ip: 198.51.100.4 52 | username: cisco 53 | password: cisco 54 | cobra: 55 | class: rest.connector.Acisdk 56 | ip: 198.51.100.5 57 | username: cisco 58 | password: cisco 59 | nd: 60 | os: nd 61 | type: linux 62 | custom: 63 | abstraction: 64 | order: [os] 65 | connections: 66 | rest: 67 | class: rest.connector.Rest 68 | protocol: http 69 | ip: 198.51.100.6 70 | username: cisco 71 | password: cisco 72 | bigip01.lab.local: 73 | alias: 'bigip01' 74 | type: 'bigip' 75 | os: 'bigip' 76 | custom: 77 | abstraction: 78 | order: [os] 79 | connections: 80 | rest: 81 | class: rest.connector.Rest 82 | protocol: https 83 | ip: 198.51.100.7 84 | credentials: 85 | rest: 86 | username: admin 87 | password: admin 88 | vmanage: 89 | os: viptela 90 | type: vmanage 91 | custom: 92 | abstraction: 93 | order: [os] 94 | connections: 95 | rest: 96 | class: rest.connector.Rest 97 | protocol: http 98 | ip: 198.51.100.8 99 | credentials: 100 | rest: 101 | username: admin 102 | password: admin 103 | webex: 104 | os: webex 105 | type: webex 106 | custom: 107 | abstraction: 108 | order: [os] 109 | connections: 110 | rest: 111 | class: rest.connector.Rest 112 | protocol: http 113 | ip: 198.51.100.9 114 | credentials: 115 | rest: 116 | token: webexaccesstoken 117 | xpresso: 118 | os: xpresso 119 | type: xpresso 120 | custom: 121 | abstraction: 122 | order: [os] 123 | connections: 124 | rest: 125 | class: rest.connector.Rest 126 | protocol: http 127 | host: xpresso-staging.cisco.com 128 | credentials: 129 | rest: 130 | token: xpressoaccesstoken 131 | elasticsearch: 132 | os: elasticsearch 133 | type: elasticsearch 134 | connections: 135 | defaults: 136 | via: rest 137 | rest: 138 | class: rest.connector.Rest 139 | ip: 198.51.100.10 140 | port: 9200 141 | protocol: http 142 | ise: 143 | os: ise 144 | connections: 145 | defaults: 146 | via: rest 147 | rest: 148 | class: rest.connector.Rest 149 | ip: 127.0.0.2 150 | port: 9000 151 | protocol: http 152 | 153 | -------------------------------------------------------------------------------- /src/rest/connector/utils.py: -------------------------------------------------------------------------------- 1 | """ Utilities shared by all plugin libraries. """ 2 | from pkg_resources import get_distribution, DistributionNotFound 3 | import re 4 | import requests 5 | import subprocess 6 | 7 | try: 8 | from pyats.utils.secret_strings import to_plaintext 9 | except ImportError: 10 | def to_plaintext(string): 11 | return(str(string)) 12 | 13 | 14 | def get_username_password(connection): 15 | username = password = None 16 | if connection.connection_info.get('credentials'): 17 | try: 18 | username = str( 19 | connection.connection_info['credentials']['rest']['username']) 20 | password = to_plaintext( 21 | connection.connection_info['credentials']['rest']['password']) 22 | except Exception: 23 | pass 24 | 25 | if not username: 26 | username = connection.connection_info.get('username', \ 27 | connection.device.tacacs.username \ 28 | if connection.device.tacacs.username \ 29 | else 'admin') 30 | 31 | if not password: 32 | password = connection.connection_info.get('password', \ 33 | connection.device.passwords.tacacs \ 34 | if connection.device.passwords.tacacs \ 35 | else 'admin') 36 | 37 | return (username, password) 38 | 39 | 40 | def get_token(connection): 41 | token = None 42 | if connection.connection_info.get('credentials'): 43 | try: 44 | token = str( 45 | connection.connection_info['credentials']['rest']['token']) 46 | except Exception: 47 | pass 48 | 49 | return token 50 | 51 | 52 | def get_apic_sdk_version(ip): 53 | """ 54 | :param ip: IP or hostname of the APIC controller 55 | :return: version of the APIC software as noted in the /cisco page 56 | """ 57 | version = None 58 | url = f'https://{ip}/cobra' 59 | 60 | response = requests.get(url, verify=False) 61 | 62 | if response.status_code == requests.codes.ok: 63 | match = re.search(r'.*\s([\d.]+)\s.*', response.text) 64 | if match: 65 | version = match.groups()[0] 66 | 67 | return version 68 | 69 | 70 | def get_installed_lib_versions(packages=('acicobra', 'acimodel')): 71 | """ 72 | :param packages: (tuple) a list of packages to be checked 73 | :return: dictionary with packages as keys and versions as values 74 | """ 75 | if not isinstance(packages, tuple) and not isinstance(packages, list): 76 | packages = [packages] 77 | versions = {} 78 | for package in packages: 79 | try: 80 | versions[package] = get_distribution(package).version 81 | except DistributionNotFound: 82 | versions[package] = None 83 | 84 | return versions 85 | 86 | 87 | def get_file_links(ip, packages=('acicobra', 'acimodel')): 88 | """ 89 | :param ip: IP or hostname of the APIC controller 90 | :param packages: (tuple) a list of packages to be downloaded 91 | :return: dictionary containing package names as keys and full path to files 92 | """ 93 | if not isinstance(packages, list): 94 | packages = [packages] 95 | url = f'https://{ip}/cobra/_downloads' 96 | links_dict = {} 97 | 98 | r = requests.get(url, verify=False) 99 | files = re.findall(r'', r.text) 100 | 101 | for package in packages: 102 | for file in files: 103 | if package in file: 104 | links_dict[package] = f'{url}/{file}' 105 | 106 | return links_dict 107 | 108 | 109 | def pip_install_from_link(ip, link=''): 110 | """ 111 | :param ip: IP or hostname of the APIC controller 112 | :param link: link to file (https://{ip}/cobra/_downloads/{file_name}) 113 | :return: True if install succeeded, False otherwise 114 | """ 115 | params = ['pip', 'install', f'--trusted-host={ip}', link] 116 | 117 | r = subprocess.run(params) 118 | if r.returncode: 119 | return False 120 | return True 121 | 122 | 123 | def verify_apic_version(ip): 124 | apic_version = get_apic_sdk_version(ip=ip) 125 | installed = get_installed_lib_versions(packages=['acicobra', 'acimodel']) 126 | 127 | if apic_version and any(map(lambda x: x != apic_version, installed)): 128 | links_dict = get_file_links(ip=ip, packages=[k for k, v in 129 | installed.items() 130 | if v != apic_version]) 131 | for package in links_dict: 132 | if not pip_install_from_link(ip=ip, link=links_dict[package]): 133 | raise RuntimeError('There seems to be a problem with the ' 134 | f'{package} automated installation.\n' 135 | 'Please install packages manually from APIC') 136 | -------------------------------------------------------------------------------- /tests: -------------------------------------------------------------------------------- 1 | src/rest/connector/tests/ --------------------------------------------------------------------------------