diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
commit | a453ac31f3428614cceb99027f8efbdb9258a40b (patch) | |
tree | f61f87408f32a8511cbd91799f9cececb53e0374 /collections-debian-merged/ansible_collections/mellanox | |
parent | Initial commit. (diff) | |
download | ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.tar.xz ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.zip |
Adding upstream version 2.10.7+merged+base+2.10.8+dfsg.upstream/2.10.7+merged+base+2.10.8+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'collections-debian-merged/ansible_collections/mellanox')
165 files changed, 22122 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.github/workflows/ansible-test.yml b/collections-debian-merged/ansible_collections/mellanox/onyx/.github/workflows/ansible-test.yml new file mode 100644 index 00000000..642de805 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.github/workflows/ansible-test.yml @@ -0,0 +1,56 @@ +name: CI +on: +- pull_request + +jobs: + sanity: + runs-on: ubuntu-latest + steps: + + - name: Check out code + uses: actions/checkout@v1 + with: + path: ansible_collections/mellanox/onyx + + - name: Set up Python 3.6 + uses: actions/setup-python@v1 + with: + python-version: 3.6 + + - name: Install ansible-base (devel) + run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check + + - name: Install ansible.netcommon + run: ansible-galaxy collection install ansible.netcommon -p ../../ + + - name: Run sanity tests + run: ansible-test sanity --docker -v --color --python 3.6 + + units: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v1 + with: + path: ansible_collections/mellanox/onyx + + - name: Set up Python 3.6 + uses: actions/setup-python@v1 + with: + python-version: 3.6 + + - name: Install ansible-base (devel) + run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check + + - name: Install ansible.netcommon + run: ansible-galaxy collection install ansible.netcommon -p ../../ + + - name: Run unit tests + run: ansible-test units --docker -v --color --python 3.6 --coverage + + - name: Generate coverage report. + run: ansible-test coverage xml -v --requirements --group-by command --group-by version + + - uses: codecov/codecov-action@v1 + with: + fail_ci_if_error: false diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.project b/collections-debian-merged/ansible_collections/mellanox/onyx/.project new file mode 100644 index 00000000..5c2c01ec --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>mellanox.onyx</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.python.pydev.PyDevBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.python.pydev.pythonNature</nature> + </natures> +</projectDescription> diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.pydevproject b/collections-debian-merged/ansible_collections/mellanox/onyx/.pydevproject new file mode 100644 index 00000000..2345b37c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.pydevproject @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?eclipse-pydev version="1.0"?><pydev_project> +<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">python3</pydev_property> +<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python interpreter</pydev_property> +</pydev_project> diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/.gitignore b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/.gitignore new file mode 100644 index 00000000..bc1a1f61 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/.gitignore @@ -0,0 +1,2 @@ +# Created by pytest automatically. +* diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/CACHEDIR.TAG b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/CACHEDIR.TAG new file mode 100644 index 00000000..381f03a5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/CACHEDIR.TAG @@ -0,0 +1,4 @@ +Signature: 8a477f597d28d172789f06886806bc55 +# This file is a cache directory tag created by pytest. +# For information about cache directory tags, see: +# http://www.bford.info/cachedir/spec.html diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/README.md b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/README.md new file mode 100644 index 00000000..bb78ba07 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/README.md @@ -0,0 +1,8 @@ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/latest/cache.html) for more information. diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/lastfailed b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/lastfailed new file mode 100644 index 00000000..4bd353fa --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/lastfailed @@ -0,0 +1,3 @@ +{ + "tests/unit/modules/test_onyx_aaa.py": true +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/nodeids b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/nodeids new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/nodeids @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/stepwise b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/stepwise new file mode 100644 index 00000000..0637a088 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.pytest_cache/v/cache/stepwise @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/.settings/org.eclipse.core.resources.prefs b/collections-debian-merged/ansible_collections/mellanox/onyx/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..5c4793c1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +encoding//plugins/doc_fragments/onyx.py=utf-8 +encoding//plugins/module_utils/network/onyx/onyx.py=utf-8 diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/FILES.json b/collections-debian-merged/ansible_collections/mellanox/onyx/FILES.json new file mode 100644 index 00000000..f7afc278 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/FILES.json @@ -0,0 +1,1300 @@ +{ + "files": [ + { + "name": ".", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0f49f7b26633926d9a1780dc0f7b0af0c77662d34111474dc612f7b973bf82ee", + "format": 1 + }, + { + "name": "plugins", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/modules", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/modules/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/modules/onyx_aaa.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "629f049095a377270c6f262564da8b845605eb750bdaafa9078267ffc0f7f9f8", + "format": 1 + }, + { + "name": "plugins/modules/onyx_bfd.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b75975f341d3eb8efa35b22efcc9eb007c9eb9aa2c04a03f18959edc85ce6a71", + "format": 1 + }, + { + "name": "plugins/modules/onyx_bgp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "fabd2ab9e6e5b3b2f05a941e421f1c8500dbeaf723a28c147ebfa660bba4cf7c", + "format": 1 + }, + { + "name": "plugins/modules/onyx_buffer_pool.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e6a46c03354ac3e94c940170b39ec9799018a46043a1a06ba783ea2abc93602c", + "format": 1 + }, + { + "name": "plugins/modules/onyx_command.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ac0f12e0945b73fa43bd42d947ccf80060bb89cdd56e1c4b8e32fcedda93ba5b", + "format": 1 + }, + { + "name": "plugins/modules/onyx_config.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9c3e9e8c709d7a52c53e8e7ac147c6e209042ee99340ed5504b9f412b86689c0", + "format": 1 + }, + { + "name": "plugins/modules/onyx_facts.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "875a040b48ebeede540b2422e32aba41015a4007318e39e4ec6cbb641a50d6a2", + "format": 1 + }, + { + "name": "plugins/modules/onyx_igmp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "be76d82e6f048412a86bf186158741a9da8291954ca56ecb4c51ab37e6b928d2", + "format": 1 + }, + { + "name": "plugins/modules/onyx_igmp_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f54aefb8460b3eebb258a8e40ad58b29956116ae67cfd055fd18b28719b69954", + "format": 1 + }, + { + "name": "plugins/modules/onyx_igmp_vlan.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "519a6adc5004d0db8bfd826a684c3ea111466fa8d3dd6f31bc7623d568504a5f", + "format": 1 + }, + { + "name": "plugins/modules/onyx_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2fc59485131339e439974199bb2ed75dc3456841159497922d0fd1d886128396", + "format": 1 + }, + { + "name": "plugins/modules/onyx_l2_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f95a193486f6a88094e2262cadbe9aeb24630e33fe8930152a705cb347716743", + "format": 1 + }, + { + "name": "plugins/modules/onyx_l3_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6d0d608b4e0b3aa857bcee050bf5522215242bd951d239883b48239c89febb6c", + "format": 1 + }, + { + "name": "plugins/modules/onyx_linkagg.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "35ba811473689d34fb53b3b451d19937a913ea0d778d2d2a47ce8e17ef715ba8", + "format": 1 + }, + { + "name": "plugins/modules/onyx_lldp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "20de334248f9f96d88147dc5e2579e07b9be1d586ef68da54007d2008f6e0a0d", + "format": 1 + }, + { + "name": "plugins/modules/onyx_lldp_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "39cf9b0f15f327a3fbc1a002b974706b62c95afe8e83f799d5fbef4a16f39852", + "format": 1 + }, + { + "name": "plugins/modules/onyx_magp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "64738fa8135be4b15f297fff0ef9dd9ce9a98ee034cb697754faf58821db195d", + "format": 1 + }, + { + "name": "plugins/modules/onyx_mlag_ipl.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "01062fd41d755bfb5f8f95e8304609fb1095fe7ad9f1c0ff6d9db64b6813bf8f", + "format": 1 + }, + { + "name": "plugins/modules/onyx_mlag_vip.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6d49c2e58257076cb8fa29924229ba68d4bc7f42c7b7ce50247de90e0c1cc849", + "format": 1 + }, + { + "name": "plugins/modules/onyx_ntp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5c282185b9601b3e664d2140586f2bd7951875bc74d7d0560ff8b1869f843d98", + "format": 1 + }, + { + "name": "plugins/modules/onyx_ntp_servers_peers.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e125f533cd1db0597f12a6d2ccc688425ef920f8534548701cb9419959a27b91", + "format": 1 + }, + { + "name": "plugins/modules/onyx_ospf.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "45b9dca0c9e28346f389c6be5fd0fc9559ff7aeaca2f752ab962b1a8cf809b3b", + "format": 1 + }, + { + "name": "plugins/modules/onyx_pfc_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9221a5bbf783d2fec348962adbfd78514bf1181a1a2327a10d40e10f9070c649", + "format": 1 + }, + { + "name": "plugins/modules/onyx_protocol.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c00b34ed6b29bbbfba99a255dcfe1c243e5074934ee87a559325a2a8db67a06e", + "format": 1 + }, + { + "name": "plugins/modules/onyx_ptp_global.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "44c5278ef34e8b98a4f14348414df60555f7a7780595c82f8718d47fcfac9dee", + "format": 1 + }, + { + "name": "plugins/modules/onyx_ptp_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "06bd95a884e83fd221635121ac11fab3a1723979d63c3d888eabf98e7630e44f", + "format": 1 + }, + { + "name": "plugins/modules/onyx_qos.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "294914e34e5898b789242dd7def4aebc302882cdcda8a83ea8ce59d6ae843feb", + "format": 1 + }, + { + "name": "plugins/modules/onyx_snmp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4fcf6879e3b6bb43961acafb0c22d5f42d6e56d8b642362e70bcff6ab201165c", + "format": 1 + }, + { + "name": "plugins/modules/onyx_snmp_hosts.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "59b1c73a197837a103f7a8876f330f9d86cb181329507632a672be08a15a696a", + "format": 1 + }, + { + "name": "plugins/modules/onyx_snmp_users.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5e91aa45ec19a4046b14b5dca3e6de003a8b24cb049e54551b846074fbd8439c", + "format": 1 + }, + { + "name": "plugins/modules/onyx_syslog_files.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "451ce423f39dfc21730c472efca3f814a619e93cbaab1e5afaefc57769c1421b", + "format": 1 + }, + { + "name": "plugins/modules/onyx_syslog_remote.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1570c399140b8a8196da86f8a3a8ea2c4894204d77d695a395f83c75a6e8b450", + "format": 1 + }, + { + "name": "plugins/modules/onyx_traffic_class.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c89635cf36ca7c57aa364d30ba9343550e7c900a02ac9d09177e5531b1c8d4ea", + "format": 1 + }, + { + "name": "plugins/modules/onyx_username.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "996836f7826f5de12abeb6a6ef9389ce771bd4a3270b0f3be46c5b4a4fd5a5f9", + "format": 1 + }, + { + "name": "plugins/modules/onyx_vlan.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b6f81eb262674ae0adf5e36016aa956bf0d49c968c2a8f13a370b1a6804771a0", + "format": 1 + }, + { + "name": "plugins/modules/onyx_vxlan.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "eddbae29ca5329ebcb4b5c2a012882ba97b83518b015f48cf0689432d895e6da", + "format": 1 + }, + { + "name": "plugins/modules/onyx_wjh.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "98e4d690100302025e7e330a7183bec21020307309d1906299047da549c59279", + "format": 1 + }, + { + "name": "plugins/terminal", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/terminal/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/terminal/onyx.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8b7e6370342562fbc94ea28de398daa27ac885baa31627e65bbbba71cd74f9d9", + "format": 1 + }, + { + "name": "plugins/cliconf", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/cliconf/onyx.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7c7208532cc8d93e2447839fff018d0886bfc083c74157ac9a3f941011ba1659", + "format": 1 + }, + { + "name": "plugins/cliconf/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/module_utils", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/module_utils/network", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/module_utils/network/onyx", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/module_utils/network/onyx/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/module_utils/network/onyx/onyx.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "87c8b00a4bd1db7d15a772ad3b75e9f74404acf6f8b53531332c195a5cbe3543", + "format": 1 + }, + { + "name": "plugins/module_utils/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/doc_fragments", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/doc_fragments/onyx.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2afe0a1681acab781eca3df1e57915a4703b6bbc5f117fc7007bd87c47f66617", + "format": 1 + }, + { + "name": "plugins/doc_fragments/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/action", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "plugins/action/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "plugins/action/onyx_config.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c72de4088c810b90f0629d814d0c3367b2bea7833e8a0fba26e57980e6e07b1c", + "format": 1 + }, + { + "name": "LICENSE", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8b1ba204bb69a0ade2bfcf65ef294a920f6bb361b317dba43c7ef29d96332b9b", + "format": 1 + }, + { + "name": "tests", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit/modules", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit/modules/__init__.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_bgp_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f64a9f972648b9c172a682917cc42e8cb4a790923fd0351c3345d8d83a03defd", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_buffer_pool.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bd36256e89df30c5684e1c4f1f283df74e76d2f790aeb6115c93e298d08fbfe2", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_command_show_version.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "041af8c3fc42e405b2402c0a101677e57f531a69faedaf7042ce3475afa1677c", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_config_config.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "51948129ebba0dcbcf92ccc8991f701101baeb019089040d99ba65b2e279cbc5", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_config_src.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ce0ee2063018bc9a3a5d9d5b47b6c0f60785b30316c743e75aff2510b02891ec", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_facts_show_interfaces_ethernet.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "aab6eb1b5ed587d0cad4ac2706cc15252fb5fb7d8cd06610e787624787894918", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_facts_show_module.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "da1956a8cad7c28645ea693211754a3d8b09fe5131a5b8420ebcc6eea9d21cca", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_facts_show_version.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4685296d162493d5e72d390fed1974b0444b29ce5786923df062219e3e22ae6f", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_igmp_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d6507c9bfd68ab7f90d29cd3f8e806b14922e54f49950e9948061c212a703eef", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_interfaces_rates.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7ee52361332e0b79f4d519764dcda5e5e7732f70301e57366d6f426b77f9ab1e", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_interfaces_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4f58a14b32e4335b0cb48eaab92e562944ae1715fc4a845f3d5f253bfccd9709", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_interfaces_status.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1859533c5040557306de876d88939666be7fdafd7b90a50c473778503f21cb8a", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_l2_interface_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "fcb91dbec22b011c2b68de8b9e1ad0939f9a31e99ecd637a87215292068c41f3", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_l3_interface_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "cefff7617098ada6b1ba9ed19037ef8e6959392eca3db8130c023f22a6fee514", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_l3_vlan_interface_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8237f23c168d80b1fba744d6b6106c5339c770096a310dae907fc10bd8d2e94b", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_lldp_interface_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8045235f5fc40f7cdc9566b65b883fa6b4e4bc45e44ee0017f91ba5520e6dff9", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_lldp_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5e56a2082a1682f7273f77de466d12b7f98a553c472d83e6a76e935c93a41180", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_logging_config_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a3b92c403e9c64605adefe451098b9c3f6a98ee0ea58525e791e1b1ac6268ceb", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_logging_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "386aeb1627cd59060af26df1213752eb53462b2ced62a763e38c87515b77be16", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_magp_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1f05d59bf9e8df405c81ce64c0f7ac4df4c70c0ea6e86d7cc4c4f430283dccbb", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_mlag_ipl_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d840f6d58caa763fdc24ae019638c024e3ceef3bdb900a403eacfdea77cc7355", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_mlag_port_channel_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "874019279d6ae1a5cf1e56180f3480714bdd7ecc9a75fbf950c71d04ac523604", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_mlag_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e7c1032e02d815edf80457e0444d4e87781315b0a6efad9b6010facdae210077", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_mlag_vip_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e137882ab76eebdaaa310036a350373a5f1ac4152389b4e357a640d57c78fd9b", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_ntp_servers_peers_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "13ab86f2c316d8fb7e49424a9af53794c4202eb16998dbe5cc67fea5a4a857b7", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_ntp_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "45a5b7b1835db6a0dfc928b0676d429f4894d9f84cea7bffdf0cc27bceced7ab", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_ospf_interfaces_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ac8f57ccb8a8b8d8bef40c35d63a2985530a933883ca83b0ee9c643b0d8870ce", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_ospf_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3c676ad0ac16373da91d4cf47af49f14b4adad3dac15e0b812a320fecf0df9aa", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_pfc_interface_disabled.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8291024a45a1faf5708ee24f52a1edfcceb1ce74d86bbe776df5f3a7d2b375e1", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_pfc_interface_enabled.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "43963b7a27061da877abd063797cfa7b865c1a225d935d5ccbe0baf5d577ad68", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_port_channel_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "26773a9e482baae148eefdcd47a6bc5de4f1327d83453ce289ae156167cc4322", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_protocols_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9963eb040e5d33e67fd7a557fdc696793f5775648e0c223af8e8d4f23294b7eb", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_aaa.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1b3c5a439c1738d2821995ebe33379bbfeb4a17df0851096490b496567e4a78b", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_bfd.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ad41d06446c79f15b18f2f30ba4f85b079b88caa49ac7b3f0b05d21fc80e1fb6", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_dcb_ets_interface.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6b6f9e32821643073ec37fdfbdacfcd796cdec46deb8fc937e60abc3996cd3ef", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_igmp_interfaces.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "01534c119bfe24ff42bb469ad7ffecaa229da49fb1a789396ff8a3298147e6df", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_interface_congestion_control.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6f13de6107e169fa05f65bbdc292359217a070c3c261cdc05d36847df7e9dd5f", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_interfaces_nve.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3851f9aae2bce34abf87128974f4cde628fe612ee9b149131ecffa82eda97f07", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_interfaces_nve_detail.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2aa144c9ee3347bf617171e1abc626875818f4a789f1040b26850a408f55c8a7", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4333c6bbd0dd9691a56aa35f84412d8b69c2bfd6b5468c94dd0ed2886d108ab1", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping_groups.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b11df1fe25e08de2b124930abedd83173e5c2d403d3d85867e6657a962010c9f", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping_querier.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "338839199acd4ed78a16ead7778ae8f23d3b832e13565f58cdafd752329029eb", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_ntp_configured.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b2228b4691d7c86f27d9a729e9adcff23d9ba68429dfa7ce6418237595e7a614", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_ptp_clock.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "652fd200b906bf1daff41039d45bb6c088b9373e8131a05a0fd6c475bf29afed", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_ptp_interface.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ff67f363d9c5c4f82e390097c1150a6437bbe0134e99232a9886741400d92e27", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_snmp_hosts.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ec9f7f2862121ca5cab947b2f4205accd9fb1a3769d137f5aa2b17aefcf9ffc3", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_show_snmp_users.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "d276b092c20a6f99ecd5e618d443a80fb1369d9d7b4ab7d8103838092e58faa3", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_snmp_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "09e652d9ef5ae7dc7dc37d6c38112efc5eb73af7399de5547b34509e034b6ef1", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_username_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "24c771ce0eb3bd2bb4b1699cde75b8bb0ed46fa6350bdd090883eb17d4017b9c", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_vlan_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "16883d414fc3ae1005ed16900574e218e8cba09f575b87c26fbfed521222845d", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/onyx_wjh_show.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "56a0d9201b4bafd61a5046b490e6a4ba3e57a48af55d27a33c26c0f4371ca13f", + "format": 1 + }, + { + "name": "tests/unit/modules/fixtures/show_qos_interface_ethernet.cfg", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "358db5d82748dcfb58d335820a472d380c848e2fe17850a56fcf29515c80dde5", + "format": 1 + }, + { + "name": "tests/unit/modules/onyx_module.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1430eb72e7ddc71508804a4281db83f2abb433755d9ab608a2fd43cc914fa73d", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_aaa.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1675c39c13969acdb1a3c50eb0dfa2b503aa74032895f6a241906775789c9457", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_bfd.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "67b992e621bcd5cc23192bf615826340f404190d9ea7fd08400239ada8b595bd", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_bgp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "18195136264725d0bfe92f73af717e4e628b3475c18b60b8154e1efb79d30b5a", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_buffer_pool.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4f2754cd85aff1020953a07d66a102099058f39012010b5ea579913e8a1fa5ce", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_command.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5f8b68112c2daef660bc84b0b046c8ac500ef5b5eafafd1ea9e06a697586dd94", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_config.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "e2855472a5deb149614901533ad3ed44f7493467e2840936a8f3b5fc4302c502", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_facts.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "90b1cd197d0cc8fd5b01a08ab4ab93aaddcedec15dc731e56a92a7ff81f4cf75", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_igmp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b38a86a050e743716297b6cb7a6beb02eca4d662dc5c60787abb90ddf9336c18", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_igmp_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4dfdda60944cedd0da4ca8666e5a313ca48902d51b65472f3ffda8c2fc8ba2d2", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_igmp_vlan.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "102ab7694a413065db7c8128227c04a05250ea4724ac93e9292005328e70d6e1", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "5f1a11c3e4bf0e10f03a0854fa3b051ecc93f0e458b614ed290c5d6ad0ee31bc", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_l2_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6e34c29c2003dccbd6af40ad64ef1dec11e197ecd747681cb4ddaec727201ca8", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_l3_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "c6a910b1fc50e0350e715650d1e99323d8a09b618b96399c1e1fb030c9dbc130", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_linkagg.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "086f05c66ecd80bd2f3492c55d8eda9235d9fb0d0a50d63d60db49012b60741c", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_lldp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "bc8f1f0f1b7b80ad2280b8d72cc2ebb77f134d46435c9bef5f52f0411c0af469", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_lldp_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6c29596f1210de10c521f5af16bf666d13f8df3131ded096f04c6b72fd5fc461", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_magp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "951497794e085b8d9d1422dd14f05ec1cfaf664c4e29f48c9c4c731c79dd7a43", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_mlag_ipl.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "b710c4454dbaf620ae0d30c6b5c88d1f68f373c25d0f42323892c100892981fb", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_mlag_vip.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7140226660a2db5938177da8149fc3e107c493bc64c5cddbd884d1d6bf0fd3fd", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_ntp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "005847aa9d5a857d8ce9febd991fe9e556b5959e3d325034ce96945807b8e8bd", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_ntp_servers_peers.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6b397003c7d1b8cfff0582f74401b54e637f7839a4e0faddb0074284cb20c511", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_ospf.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1482b4f52ad805524d1a9bde2dd3fa7db636d287472fcebe50acd51c63379078", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_pfc_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8f392b6a05823d61c132d18ec95964d6005c6760bd05991115e9526dc2565388", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_protocol.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "12ebef6e3c92d134630a266d5f14486fd154085b65bfa8fbc0e4668fc55f9ada", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_protocols.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "8a9bbe8d5840060ce0fde8ba0cdce0b8153bdd977a10cb5bf710e39371f02bd8", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_ptp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "663704f6a2bb01e2ebf4239733bb7cc5fbe0460a71a859177486b3eda092cd4e", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_ptp_global.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "663704f6a2bb01e2ebf4239733bb7cc5fbe0460a71a859177486b3eda092cd4e", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_ptp_interface.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "836e5b6f2f14a7e3fb6c3c62c3bc9a302e5533a54db6cb1e8b32f0e1063b42eb", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_qos.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "facb4f10eb147ca2248c06dfe2c8263cb7e421f77b4aaa6b12a1eae98aee69fe", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_snmp.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "dbe332e1261ef4ffe098b2d88866ef40eeef61e5f6dc1350efc8ba7bf2cdb013", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_snmp_hosts.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f703403454f9633f34f565222f9bd1a46820163ffa47235eb231a6cb3bad6cab", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_snmp_users.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2fe7f4aff915dfab34302ef3f99073d4c6770a73b15e44244de9b2f63ab11202", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_syslog_files.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3a4279a53d947b4ee1a93f21273585980725fb4e4135b07b9f0c648a9c469dbf", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_syslog_remote.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "27ad344642fcdbd0b03532c6f03bcdada9cf356b32fd1383063748fb68a70b83", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_traffic_class.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f904ce0adf40090a9d0bbb23687df73d60fc55eaee3564bdf5e3c9c96e6bd452", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_username.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "eb5b1759c49179bf9a6e00640e3a3f74431f2a1780618f3e5478ef5e5c5ded66", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_vlan.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0e6bb32056797b05ac525fa90975dcacbb7a93f8e7a2e6396eb70d9ac6aac592", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_vxlan.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "7969df8bfa013566f41cb0adcbad913da53d884f6f346385d6b473df5e906249", + "format": 1 + }, + { + "name": "tests/unit/modules/test_onyx_wjh.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ce6df683eccdf27ecd829d4e8936096919b92720ceb69ef4a5aed39544a99cac", + "format": 1 + }, + { + "name": "tests/unit/modules/utils.py", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "2606e99a7f9ab3073b25eb5f62cc0e3c38865d71407d4ecedc322d841a9c9a96", + "format": 1 + }, + { + "name": "tests/sanity", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.11.txt.orig", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "59721ff65165a9f024cba20d77eb9efe417191fef3cce4b36108afbd50642bcc", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.10.txt.orig", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "59721ff65165a9f024cba20d77eb9efe417191fef3cce4b36108afbd50642bcc", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.10.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1b65adccd5532b55506d5b6e7a714efbf7d834c573cb316e229cd92204fd0cb5", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.11.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "1b65adccd5532b55506d5b6e7a714efbf7d834c573cb316e229cd92204fd0cb5", + "format": 1 + }, + { + "name": "tests/sanity/ignore-2.9.txt", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "760a94025f8e48badb326837664885ad00b21b98b0d7e4dbb0d953fd7456b1a4", + "format": 1 + }, + { + "name": ".project", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a722f26cb57e64fe6bdc4431bb812e6c81aed792642b0fcd64c75bf399fe3d20", + "format": 1 + }, + { + "name": ".pydevproject", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "f46f7b154c652a68a38271ff28a2142aef25b5cbba20a560cc79f97db326d217", + "format": 1 + }, + { + "name": ".settings", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".settings/org.eclipse.core.resources.prefs", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "66e4beef443308869fb0a3114fdda32e233b5df1cefa2889577742f2a421cb9f", + "format": 1 + }, + { + "name": ".github", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".github/workflows", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".github/workflows/ansible-test.yml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "a8a55a94e8c05b3a5770ce3bf9ce1e5e5ae829c05c00538aa04adbf8974f94eb", + "format": 1 + }, + { + "name": ".pytest_cache", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".pytest_cache/v", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".pytest_cache/v/cache", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": ".pytest_cache/v/cache/stepwise", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", + "format": 1 + }, + { + "name": ".pytest_cache/v/cache/nodeids", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945", + "format": 1 + }, + { + "name": ".pytest_cache/v/cache/lastfailed", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "0b692620c0fdc89c27d63c0c272a72b1e1b8555d0b8de5d61b1ab647cbb3c81c", + "format": 1 + }, + { + "name": ".pytest_cache/README.md", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "9ee98c319ffd02d3e46d299a846cbd43908c88fdcf9df6d7311712003c5c5b76", + "format": 1 + }, + { + "name": ".pytest_cache/.gitignore", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "3ed731b65d06150c138e2dadb0be0697550888a6b47eb8c45ecc9adba8b8e9bd", + "format": 1 + }, + { + "name": ".pytest_cache/CACHEDIR.TAG", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "ffacb1561d9688b9d9b5e06f3ffa10814a03c2a6f892d7bea3e7fef62599eb23", + "format": 1 + }, + { + "name": "changelogs", + "ftype": "dir", + "chksum_type": null, + "chksum_sha256": null, + "format": 1 + }, + { + "name": "changelogs/changelog.yaml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "17d2b2a93fc4776ccb784ef084770afe811df50d5291f5d24411fb4c7d9c0f51", + "format": 1 + }, + { + "name": "changelogs/CHANGELOG.rst", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "67b6f00abfd57b8a85636956a6f06238d338e792cf353bab43ee5052ba98d56c", + "format": 1 + }, + { + "name": "changelogs/config.yaml", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "6588437ad6c3775823fddb38c41b68d4066da8ecb28276d335d465ab6184c811", + "format": 1 + } + ], + "format": 1 +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/LICENSE b/collections-debian-merged/ansible_collections/mellanox/onyx/LICENSE new file mode 100644 index 00000000..e72bfdda --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<https://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<https://www.gnu.org/licenses/why-not-lgpl.html>.
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/MANIFEST.json b/collections-debian-merged/ansible_collections/mellanox/onyx/MANIFEST.json new file mode 100644 index 00000000..2ceb8031 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/MANIFEST.json @@ -0,0 +1,35 @@ +{ + "collection_info": { + "namespace": "mellanox", + "name": "onyx", + "version": "1.0.0", + "authors": [ + "Samer Deeb (@samerd)" + ], + "readme": "README.md", + "tags": [ + "mellanox", + "onyx", + "cliconf", + "network" + ], + "description": "Collection for managing Mellanox onyx devices", + "license": [], + "license_file": "LICENSE", + "dependencies": { + "ansible.netcommon": "*" + }, + "repository": "https://github.com/ansible-collections/mellanox.onyx", + "documentation": "https://github.com/ansible-collections/mellanox.onyx", + "homepage": "https://github.com/ansible-collections/mellanox.onyx", + "issues": "https://github.com/ansible-collections/mellanox.onyx/issues" + }, + "file_manifest_file": { + "name": "FILES.json", + "ftype": "file", + "chksum_type": "sha256", + "chksum_sha256": "fac96af46248f3a578d39cf52221470de642fe112dae19ea88bad1111c0d8fe0", + "format": 1 + }, + "format": 1 +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/README.md b/collections-debian-merged/ansible_collections/mellanox/onyx/README.md new file mode 100644 index 00000000..65cdbd9a --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/README.md @@ -0,0 +1,87 @@ +# Mellanox Onyx Collection +<!--[![CI](https://zuul-ci.org/gated.svg)]--> +<!-- Add CI infornmntiom--> + +The Ansible Mellanox Onyx collection includes a list of Ansible modules for managing and automating Mellanox Onyx network devices. + +This collection has been tested against ONYX 3.6.8130 and above. + +### Supported connections +The Mellanox Onyx collection supports ``network_cli`` connections. + +## Included content + +Click the ``Content`` button to see the list of content included in this collection. + +## Installing this collection + +You can install the Mellanox Onyx collection with the Ansible Galaxy CLI: + + ansible-galaxy collection install mellanox.onyx + +You can also include it in a `requirements.yml` file and install it with `ansible-galaxy collection install -r requirements.yml`, using the format: + +```yaml +--- +collections: + - name: mellanox.onyx + version: 1.0.0 +``` +## Using this collection + +### Using modules from the Mellanox Onyx collection in your playbooks + +You can call modules by their Fully Qualified Collection Namespace (FQCN), such as `mellanox.onyx.onyx_interfaces`. + +The following example task configures a network interface speed and MTU on a Mellanox Onyx network device, using the FQCN: + +```yaml +--- +- name: configure interface + mellanox.onyx.onyx_interface: + name: Eth1/2 + speed: 100G + mtu: 512 +``` + +Another option is to call modules by their short name if you list the `mellanox.onyx` collection in the playbook's `collections`, in the follwoing example we are creating a link aggration interface: + +```yaml +--- +- hosts: onyx-hosts + gather_facts: false + connection: network_cli + + collections: + - mellanox.onyx + + tasks: + - name: configure link aggregation group + onyx_linkagg: + name: Po1 + members: + - Eth1/1 + - Eth1/2 +``` + + +## Changelogs +<!--Add a link to a changelog.md file or an external docsite to cover this information. --> + +## Roadmap + +<!-- Optional. Include the roadmap for this collection, and the proposed release/versioning strategy so users can anticipate the upgrade/update cycle. --> + +## More information + +- [Ansible network resources](https://docs.ansible.com/ansible/latest/network/getting_started/network_resources.html) +- [Ansible Collection overview](https://github.com/ansible-collections/overview) +- [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html) +- [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html) +- [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html) + +## Licensing + +GNU General Public License v3.0 or later. + +See [LICENSE](https://www.gnu.org/licenses/gpl-3.0.txt) to see the full text. diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/CHANGELOG.rst b/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/CHANGELOG.rst new file mode 100644 index 00000000..f5f9a154 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/CHANGELOG.rst @@ -0,0 +1,23 @@ +======================================== +Mellanox Onyx Collection Release Notes +======================================== + +.. contents:: Topics + + +v1.0.0 +====== + +Release Summary +--------------- + +This is the first proper release of the ``mellanox.onyx`` collection. +This changelog contains all changes to the modules in this collection that were added after the release of Ansible 2.9.0. +There were no additions to the Mellanox Onyx Collection in this release. + + +Minor Changes +------------- + +Bugfixes +-------- diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/changelog.yaml b/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/changelog.yaml new file mode 100644 index 00000000..5ef7e6a4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/changelog.yaml @@ -0,0 +1,16 @@ +ancestor: null +releases: + 1.0.0: + changes: + bugfixes: + minor_changes: + release_summary: 'This is the first proper release of the ``mellanox.onyx`` + collection. + + This changelog contains all changes to the modules in this collection that + were added after the release of Ansible 2.9.0. + There were no additions to the Mellanox Onyx Collection in this release. + + ' + fragments: + release_date: '2020-08-17'
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/config.yaml b/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/config.yaml new file mode 100644 index 00000000..56d1e2a6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/changelogs/config.yaml @@ -0,0 +1,29 @@ +changelog_filename_template: CHANGELOG.rst +changelog_filename_version_depth: 0 +changes_file: changelog.yaml +changes_format: combined +keep_fragments: false +mention_ancestor: true +new_plugins_after_name: removed_features +notesdir: fragments +prelude_section_name: release_summary +prelude_section_title: Release Summary +sections: +- - major_changes + - Major Changes +- - minor_changes + - Minor Changes +- - breaking_changes + - Breaking Changes / Porting Guide +- - deprecated_features + - Deprecated Features +- - removed_features + - Removed Features (previously deprecated) +- - security_fixes + - Security Fixes +- - bugfixes + - Bugfixes +- - known_issues + - Known Issues +title: Mellanox Onyx Collection +trivial_section_name: trivial
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/action/__init__.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/action/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/action/__init__.py diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/action/onyx_config.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/action/onyx_config.py new file mode 100644 index 00000000..4de62452 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/action/onyx_config.py @@ -0,0 +1,31 @@ +# +# (c) 2017, Red Hat, Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. +# +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.action.network import ActionModule as ActionNetworkModule + + +class ActionModule(ActionNetworkModule): + + def run(self, tmp=None, task_vars=None): + del tmp # tmp no longer has any effect + + self._config_module = True + return super(ActionModule, self).run(task_vars=task_vars) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/cliconf/__init__.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/cliconf/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/cliconf/__init__.py diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/cliconf/onyx.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/cliconf/onyx.py new file mode 100644 index 00000000..b5a66b14 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/cliconf/onyx.py @@ -0,0 +1,78 @@ +# +# (c) 2017 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. +# +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = """ +--- +cliconf: onyx +short_description: Use onyx cliconf to run command on Mellanox ONYX platform +description: + - This onyx plugin provides low level abstraction apis for + sending and receiving CLI commands from Mellanox ONYX network devices. +version_added: "2.5" +""" + +import json + +from itertools import chain + +from ansible.module_utils._text import to_text +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list +from ansible.plugins.cliconf import CliconfBase, enable_mode + + +class Cliconf(CliconfBase): + + def get_device_info(self): + device_info = {} + + reply = self.get('show version | json-print') + data = json.loads(reply) + device_info['network_os'] = data['Product name'] + device_info['network_os_version'] = data['Product release'] + device_info['network_os_version_summary'] = data['Version summary'] + device_info['network_os_model'] = data['Product model'] + + reply = self.get('show hosts | include Hostname') + data = to_text(reply, errors='surrogate_or_strict').strip() + hostname = data.split(':')[1] + hostname = hostname.strip() + device_info['network_os_hostname'] = hostname + + return device_info + + @enable_mode + def get_config(self, source='running', format='text', flags=None): + if source not in ('running',): + return self.invalid_params("fetching configuration from %s is not supported" % source) + cmd = 'show running-config' + return self.send_command(cmd) + + @enable_mode + def edit_config(self, command): + for cmd in chain(['configure terminal'], to_list(command), ['exit']): + self.send_command(cmd) + + def get(self, command, prompt=None, answer=None, sendonly=False, newline=True, check_all=False): + return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, newline=newline, check_all=check_all) + + def get_capabilities(self): + result = super(Cliconf, self).get_capabilities() + return json.dumps(result) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/doc_fragments/__init__.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/doc_fragments/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/doc_fragments/__init__.py diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/doc_fragments/onyx.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/doc_fragments/onyx.py new file mode 100644 index 00000000..9cf51f92 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/doc_fragments/onyx.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + + +class ModuleDocFragment(object): + + # Standard files documentation fragment + DOCUMENTATION = r''' +options: + provider: + description: + - A dict object containing connection details. + type: dict + suboptions: + host: + description: + - Specifies the DNS host name or address for connecting to the remote + device over the specified transport. The value of host is used as + the destination address for the transport. + type: str + required: true + port: + description: + - Specifies the port to use when building the connection to the remote device. + type: int + default: 22 + username: + description: + - Configures the username to use to authenticate the connection to + the remote device. This value is used to authenticate + the SSH session. If the value is not specified in the task, the + value of environment variable C(ANSIBLE_NET_USERNAME) will be used instead. + type: str + password: + description: + - Specifies the password to use to authenticate the connection to + the remote device. This value is used to authenticate + the SSH session. If the value is not specified in the task, the + value of environment variable C(ANSIBLE_NET_PASSWORD) will be used instead. + type: str + timeout: + description: + - Specifies the timeout in seconds for communicating with the network device + for either connecting or sending commands. If the timeout is + exceeded before the operation is completed, the module will error. + type: int + default: 10 + ssh_keyfile: + description: + - Specifies the SSH key to use to authenticate the connection to + the remote device. This value is the path to the + key used to authenticate the SSH session. If the value is not specified + in the task, the value of environment variable C(ANSIBLE_NET_SSH_KEYFILE) + will be used instead. + type: path + authorize: + description: + - Instructs the module to enter privileged mode on the remote device + before sending any commands. If not specified, the device will + attempt to execute all commands in non-privileged mode. If the value + is not specified in the task, the value of environment variable + C(ANSIBLE_NET_AUTHORIZE) will be used instead. + type: bool + default: no + auth_pass: + description: + - Specifies the password to use if required to enter privileged mode + on the remote device. If I(authorize) is false, then this argument + does nothing. If the value is not specified in the task, the value of + environment variable C(ANSIBLE_NET_AUTH_PASS) will be used instead. + type: str +''' diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/__init__.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/__init__.py diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/network/onyx/__init__.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/network/onyx/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/network/onyx/__init__.py diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/network/onyx/onyx.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/network/onyx/onyx.py new file mode 100644 index 00000000..41dc3366 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/module_utils/network/onyx/onyx.py @@ -0,0 +1,264 @@ +# -*- coding: utf-8 -*- +# +# (c) 2017, Ansible by Red Hat, inc +# +# This file is part of Ansible by Red Hat +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. +# +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from ansible.module_utils._text import to_text +from ansible.module_utils.connection import Connection, ConnectionError +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list, EntityCollection + +_DEVICE_CONFIGS = {} +_CONNECTION = None + +_COMMAND_SPEC = { + 'command': dict(key=True), + 'prompt': dict(), + 'answer': dict() +} + + +def get_connection(module): + global _CONNECTION + if _CONNECTION: + return _CONNECTION + _CONNECTION = Connection(module._socket_path) + return _CONNECTION + + +def to_commands(module, commands): + if not isinstance(commands, list): + raise AssertionError('argument must be of type <list>') + + transform = EntityCollection(module, _COMMAND_SPEC) + commands = transform(commands) + return commands + + +def run_commands(module, commands, check_rc=True): + connection = get_connection(module) + + commands = to_commands(module, to_list(commands)) + + responses = list() + + for cmd in commands: + out = connection.get(**cmd) + responses.append(to_text(out, errors='surrogate_then_replace')) + + return responses + + +def get_config(module, source='running'): + conn = get_connection(module) + out = conn.get_config(source) + cfg = to_text(out, errors='surrogate_then_replace').strip() + return cfg + + +def load_config(module, config): + try: + conn = get_connection(module) + conn.edit_config(config) + except ConnectionError as exc: + module.fail_json(msg=to_text(exc)) + + +def _parse_json_output(out): + out_list = out.split('\n') + first_index = 0 + opening_char = None + lines_count = len(out_list) + while first_index < lines_count: + first_line = out_list[first_index].strip() + if not first_line or first_line[0] not in ("[", "{"): + first_index += 1 + continue + opening_char = first_line[0] + break + if not opening_char: + return "null" + closing_char = ']' if opening_char == '[' else '}' + last_index = lines_count - 1 + found = False + while last_index > first_index: + last_line = out_list[last_index].strip() + if not last_line or last_line[0] != closing_char: + last_index -= 1 + continue + found = True + break + if not found: + return opening_char + closing_char + return "".join(out_list[first_index:last_index + 1]) + + +def show_cmd(module, cmd, json_fmt=True, fail_on_error=True): + if json_fmt: + cmd += " | json-print" + conn = get_connection(module) + command_obj = to_commands(module, to_list(cmd))[0] + try: + out = conn.get(**command_obj) + except ConnectionError: + if fail_on_error: + raise + return None + if json_fmt: + out = _parse_json_output(out) + try: + cfg = json.loads(out) + except ValueError: + module.fail_json( + msg="got invalid json", + stderr=to_text(out, errors='surrogate_then_replace')) + else: + cfg = to_text(out, errors='surrogate_then_replace').strip() + return cfg + + +def get_interfaces_config(module, interface_type, flags=None, json_fmt=True): + cmd = "show interfaces %s" % interface_type + if flags: + cmd += " %s" % flags + return show_cmd(module, cmd, json_fmt) + + +def get_bgp_summary(module): + cmd = "show running-config protocol bgp" + return show_cmd(module, cmd, json_fmt=False, fail_on_error=False) + + +def get_capabilities(module): + """Returns platform info of the remove device + """ + if hasattr(module, '_capabilities'): + return module._capabilities + + connection = get_connection(module) + try: + capabilities = connection.get_capabilities() + except ConnectionError as exc: + module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) + + module._capabilities = json.loads(capabilities) + return module._capabilities + + +class BaseOnyxModule(object): + ONYX_API_VERSION = "3.6.6000" + + def __init__(self): + self._module = None + self._commands = list() + self._current_config = None + self._required_config = None + self._os_version = None + + def init_module(self): + pass + + def load_current_config(self): + pass + + def get_required_config(self): + pass + + def _get_os_version(self): + capabilities = get_capabilities(self._module) + device_info = capabilities['device_info'] + return device_info['network_os_version'] + + # pylint: disable=unused-argument + def check_declarative_intent_params(self, result): + return None + + def _validate_key(self, param, key): + validator = getattr(self, 'validate_%s' % key) + if callable(validator): + validator(param.get(key)) + + def validate_param_values(self, obj, param=None): + if param is None: + param = self._module.params + for key in obj: + # validate the param value (if validator func exists) + try: + self._validate_key(param, key) + except AttributeError: + pass + + @classmethod + def get_config_attr(cls, item, arg): + return item.get(arg) + + @classmethod + def get_mtu(cls, item): + mtu = cls.get_config_attr(item, "MTU") + mtu_parts = mtu.split() + try: + return int(mtu_parts[0]) + except ValueError: + return None + + def _validate_range(self, attr_name, min_val, max_val, value): + if value is None: + return True + if not min_val <= int(value) <= max_val: + msg = '%s must be between %s and %s' % ( + attr_name, min_val, max_val) + self._module.fail_json(msg=msg) + + def validate_mtu(self, value): + self._validate_range('mtu', 1500, 9612, value) + + def generate_commands(self): + pass + + def run(self): + self.init_module() + + result = {'changed': False} + + self.get_required_config() + self.load_current_config() + + self.generate_commands() + result['commands'] = self._commands + + if self._commands: + if not self._module.check_mode: + load_config(self._module, self._commands) + result['changed'] = True + + failed_conditions = self.check_declarative_intent_params(result) + + if failed_conditions: + msg = 'One or more conditional statements have not been satisfied' + self._module.fail_json(msg=msg, + failed_conditions=failed_conditions) + + self._module.exit_json(**result) + + @classmethod + def main(cls): + app = cls() + app.run() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/__init__.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/__init__.py diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_aaa.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_aaa.py new file mode 100644 index 00000000..e1f1b37c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_aaa.py @@ -0,0 +1,157 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_aaa +version_added: '0.2.0' +author: "Sara Touqan (@sarato)" +short_description: Configures AAA parameters +description: + - This module provides declarative management of AAA protocol params + on Mellanox ONYX network devices. +options: + tacacs_accounting_enabled: + description: + - Configures accounting settings. + type: bool + auth_default_user: + description: + - Sets local user default mapping. + type: str + choices: ['admin', 'monitor'] + auth_order: + description: + - Sets the order on how to handle remote to local user mappings. + type: str + choices: ['local-only', 'remote-first', 'remote-only'] + auth_fallback_enabled: + description: + - Enables/Disables fallback server-err option. + type: bool +''' + +EXAMPLES = """ +- name: Configures aaa + onyx_aaa: + tacacs_accounting_enabled: yes + auth_default_user: monitor + auth_order: local-only + auth_fallback_enabled: false +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - aaa accounting changes default stop-only tacacs+ + - no aaa accounting changes default stop-only tacacs+ + - aaa authorization map default-user <user> + - aaa authorization map order <order> + - aaa authorization map fallback server-err + - no aaa authorization map fallback server-err +""" + +import re + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxAAAModule(BaseOnyxModule): + + def init_module(self): + """ initialize module + """ + element_spec = dict( + tacacs_accounting_enabled=dict(type='bool'), + auth_default_user=dict(type='str', choices=['admin', 'monitor']), + auth_order=dict(type='str', choices=['local-only', 'remote-first', 'remote-only']), + auth_fallback_enabled=dict(type='bool') + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def _set_aaa_config(self, all_aaa_config): + aaa_config = all_aaa_config[0] + self._current_config['auth_default_user'] = aaa_config.get("Default User") + self._current_config['auth_order'] = aaa_config.get("Map Order") + auth_fallback_enabled = aaa_config.get("Fallback on server-err") + if auth_fallback_enabled == "yes": + self._current_config['auth_fallback_enabled'] = True + else: + self._current_config['auth_fallback_enabled'] = False + aaa_config_2 = all_aaa_config[2] + accounting_message = aaa_config_2.get("message") + if accounting_message == "No accounting methods configured.": + self._current_config['tacacs_accounting_enabled'] = False + else: + self._current_config['tacacs_accounting_enabled'] = True + + def _show_aaa_config(self): + cmd = "show aaa" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + aaa_config = self._show_aaa_config() + if aaa_config: + self._set_aaa_config(aaa_config) + + def generate_commands(self): + tacacs_accounting_enabled = self._required_config.get("tacacs_accounting_enabled") + if tacacs_accounting_enabled is not None: + current_accounting_enabled = self._current_config.get("tacacs_accounting_enabled") + if current_accounting_enabled != tacacs_accounting_enabled: + if tacacs_accounting_enabled is True: + self._commands.append('aaa accounting changes default stop-only tacacs+') + else: + self._commands.append('no aaa accounting changes default stop-only tacacs+') + + auth_default_user = self._required_config.get("auth_default_user") + if auth_default_user is not None: + current_user = self._current_config.get("auth_default_user") + if current_user != auth_default_user: + self._commands.append('aaa authorization map default-user {0}' .format(auth_default_user)) + + auth_order = self._required_config.get("auth_order") + if auth_order is not None: + current_order = self._current_config.get("auth_order") + if current_order != auth_order: + self._commands.append('aaa authorization map order {0}' .format(auth_order)) + + auth_fallback_enabled = self._required_config.get("auth_fallback_enabled") + if auth_fallback_enabled is not None: + current_fallback = self._current_config.get("auth_fallback_enabled") + if current_fallback != auth_fallback_enabled: + if auth_fallback_enabled is True: + self._commands.append('aaa authorization map fallback server-err') + else: + self._commands.append('no aaa authorization map fallback server-err') + + +def main(): + """ main entry point for module execution + """ + OnyxAAAModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_bfd.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_bfd.py new file mode 100644 index 00000000..2d5e56a4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_bfd.py @@ -0,0 +1,241 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_bfd +version_added: '0.2.0' +author: "Sara Touqan (@sarato)" +short_description: Configures BFD parameters +description: + - This module provides declarative management of BFD protocol params + on Mellanox ONYX network devices. +options: + shutdown: + description: + - Administratively shut down BFD protection. + type: bool + vrf: + description: + - Specifys the vrf name. + type: str + interval_min_rx: + description: + - Minimum desired receive rate, should be between 50 and 6000. + type: int + interval_multiplier: + description: + - Desired detection multiplier, should be between 3 and 50. + type: int + interval_transmit_rate: + description: + - Minimum desired transmit rate, should be between 50 and 60000. + type: int + iproute_network_prefix: + description: + - Configures the ip route network prefix, e.g 1.1.1.1. + type: str + iproute_mask_length: + description: + - Configures the mask length of the ip route network prefix, e.g 24. + type: int + iproute_next_hop: + description: + - Configures the ip route next hop, e.g 2.2.2.2. + type: str +''' + +EXAMPLES = """ +- name: Configures bfd + onyx_bfd: + shutdown: yes + vrf: 5 + interval_min_rx: 55 + interval_multiplier: 8 + interval_transmit_rate: 88 + iproute_network_prefix: 1.1.1.0 + iproute_mask_length: 24 + iproute_next_hop: 3.2.2.2 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - ip bfd shutdown + - no ip bfd shutdown + - ip bfd shutdown vrf <vrf_name> + - no ip bfd shutdown vrf <vrf_name> + - ip bfd vrf <vrf_name> interval min-rx <min_rx> multiplier <multiplier> transmit-rate <transmit_rate> force + - ip bfd interval min-rx <min_rx> multiplier <multiplier> transmit-rate <transmit_rate> force + - ip route vrf <vrf_name> <network_prefix>/<mask_length> <next_hop> bfd + - ip route <network_prefix>/<mask_length> <next_hop> bfd +""" + +import re + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxBFDModule(BaseOnyxModule): + + def init_module(self): + """ initialize module + """ + element_spec = dict( + shutdown=dict(type='bool'), + vrf=dict(type='str'), + interval_min_rx=dict(type='int'), + interval_multiplier=dict(type='int'), + interval_transmit_rate=dict(type='int'), + iproute_network_prefix=dict(type='str'), + iproute_mask_length=dict(type='int'), + iproute_next_hop=dict(type='str'), + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[ + ['interval_min_rx', 'interval_multiplier', 'interval_transmit_rate'], + ['iproute_network_prefix', 'iproute_mask_length', 'iproute_next_hop']]) + + def validate_bfd_interval_values(self): + interval_min_rx = self._required_config.get('interval_min_rx') + if interval_min_rx: + if ((interval_min_rx < 50) or (interval_min_rx > 6000)): + self._module.fail_json(msg='Receive interval should be between 50 and 6000.') + interval_multiplier = self._required_config.get('interval_multiplier') + if interval_multiplier: + if ((interval_multiplier < 3) or (interval_multiplier > 50)): + self._module.fail_json(msg='Multiplier should be between 3 and 50.') + interval_transmit_rate = self._required_config.get('interval_transmit_rate') + if interval_transmit_rate: + if ((interval_transmit_rate < 50) or (interval_transmit_rate > 60000)): + self._module.fail_json(msg='Transmit interval should be between 50 and 60000.') + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + self.validate_bfd_interval_values() + + def _set_bfd_config(self, bfd_config): + curr_config_arr = [] + bfd_config = bfd_config.get('Lines') + if bfd_config is None: + return + for runn_config in bfd_config: + curr_config_arr.append(runn_config.strip()) + if 'ip bfd shutdown vrf default' in curr_config_arr: + self._current_config['bfd_shutdown'] = True + else: + self._current_config['bfd_shutdown'] = False + self._current_config['curr_config_arr'] = curr_config_arr + + def _show_bfd_config(self): + cmd = "show running-config | include bfd" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + bfd_config = self._show_bfd_config() + if bfd_config: + self._set_bfd_config(bfd_config) + + def generate_shutdown_commands(self, curr_config_arr): + shutdown_enabled = self._required_config.get('shutdown') + vrf_name = self._required_config.get('vrf') + current_shutdown = self._current_config.get("bfd_shutdown") + if shutdown_enabled is not None: + if vrf_name is not None: + if curr_config_arr is not None: + if ('ip bfd shutdown vrf {0}' .format(vrf_name)) not in curr_config_arr: + if shutdown_enabled is True: + self._commands.append('ip bfd shutdown vrf {0}' .format(vrf_name)) + else: + if shutdown_enabled is False: + self._commands.append('no ip bfd shutdown vrf {0}' .format(vrf_name)) + else: + if ((current_shutdown is not None and (current_shutdown != shutdown_enabled)) or (current_shutdown is None)): + if shutdown_enabled is True: + self._commands.append('ip bfd shutdown') + else: + self._commands.append('no ip bfd shutdown') + + def generate_interval_commands(self, curr_config_arr): + interval_min_rx = self._required_config.get('interval_min_rx') + interval_multiplier = self._required_config.get('interval_multiplier') + interval_transmit_rate = self._required_config.get('interval_transmit_rate') + vrf_name = self._required_config.get('vrf') + if ((interval_min_rx is not None) and (interval_multiplier is not None) and (interval_transmit_rate is not None)): + if vrf_name is not None: + if curr_config_arr is not None: + if ((('ip bfd vrf {0} interval transmit-rate {1} force' .format(vrf_name, interval_transmit_rate)) not in curr_config_arr) or + (('ip bfd vrf {0} interval min-rx {1} force' .format(vrf_name, interval_min_rx)) not in curr_config_arr) or + (('ip bfd vrf {0} interval multiplier {1} force' .format(vrf_name, interval_multiplier)) not in curr_config_arr)): + self._commands.append('ip bfd vrf {0} interval min-rx {1} multiplier {2} transmit-rate {3} force' + .format(vrf_name, interval_min_rx, interval_multiplier, interval_transmit_rate)) + else: + self._commands.append('ip bfd vrf {0} interval min-rx {1} multiplier {2} transmit-rate {3} force' + .format(vrf_name, interval_min_rx, interval_multiplier, interval_transmit_rate)) + else: + if curr_config_arr is not None: + if ((('ip bfd vrf default interval transmit-rate {0} force' .format(interval_transmit_rate)) not in curr_config_arr) or + (('ip bfd vrf default interval min-rx {0} force' .format(interval_min_rx)) not in curr_config_arr) or + (('ip bfd vrf default interval multiplier {0} force' .format(interval_multiplier)) not in curr_config_arr)): + self._commands.append('ip bfd interval min-rx {0} multiplier {1} transmit-rate {2} force' + .format(interval_min_rx, interval_multiplier, interval_transmit_rate)) + else: + self._commands.append('ip bfd interval min-rx {0} multiplier {1} transmit-rate {2} force' + .format(interval_min_rx, interval_multiplier, interval_transmit_rate)) + + def generate_iproute_commands(self, curr_config_arr): + iproute_network_prefix = self._required_config.get('iproute_network_prefix') + iproute_mask_length = self._required_config.get('iproute_mask_length') + iproute_next_hop = self._required_config.get('iproute_next_hop') + vrf_name = self._required_config.get('vrf') + if ((iproute_network_prefix is not None) and (iproute_mask_length is not None) and + (iproute_next_hop is not None)): + if vrf_name is not None: + if curr_config_arr is not None: + if ('ip route vrf {0} {1}/{2} {3} bfd' .format(vrf_name, iproute_network_prefix, + iproute_mask_length, iproute_next_hop)) not in curr_config_arr: + self._commands.append('ip route vrf {0} {1} /{2} {3} bfd' + .format(vrf_name, iproute_network_prefix, iproute_mask_length, iproute_next_hop)) + else: + self._commands.append('ip route vrf {0} {1} /{2} {3} bfd' .format(vrf_name, iproute_network_prefix, iproute_mask_length, iproute_next_hop)) + else: + if curr_config_arr is not None: + if ('ip route vrf default {0}/{1} {2} bfd' .format(iproute_network_prefix, + iproute_mask_length, iproute_next_hop)) not in curr_config_arr: + self._commands.append('ip route {0} /{1} {2} bfd' .format(iproute_network_prefix, iproute_mask_length, iproute_next_hop)) + else: + self._commands.append('ip route {0} /{1} {2} bfd' .format(iproute_network_prefix, iproute_mask_length, iproute_next_hop)) + + def generate_commands(self): + curr_config_arr = self._current_config.get("curr_config_arr") + self.generate_shutdown_commands(curr_config_arr) + self.generate_interval_commands(curr_config_arr) + self.generate_iproute_commands(curr_config_arr) + + +def main(): + """ main entry point for module execution + """ + OnyxBFDModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_bgp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_bgp.py new file mode 100644 index 00000000..0025ed0b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_bgp.py @@ -0,0 +1,446 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_bgp +author: "Samer Deeb (@samerd), Anas Badaha (@anasb)" +short_description: Configures BGP on Mellanox ONYX network devices +description: + - This module provides declarative management of BGP router and neighbors + on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.4000 +options: + as_number: + description: + - Local AS number. + required: true + router_id: + description: + - Router IP address. + neighbors: + description: + - List of neighbors. Required if I(state=present). + suboptions: + remote_as: + description: + - Remote AS number. + required: true + neighbor: + description: + - Neighbor IP address. + required: true + multihop: + description: + - multihop number. + networks: + description: + - List of advertised networks. + fast_external_fallover: + description: + - will configure fast_external_fallover when it is True. + type: bool + max_paths: + description: + - Maximum bgp paths. + ecmp_bestpath: + description: + - Enables ECMP across AS paths. + type: bool + evpn: + description: + - Configure evpn peer-group. + type: bool + vrf: + description: + - vrf name. + state: + description: + - BGP state. + default: present + choices: ['present', 'absent'] + purge: + description: + - will remove all neighbors when it is True. + type: bool + default: false +''' + +EXAMPLES = """ +- name: Configure bgp + onyx_bgp: + as_number: 320 + router_id: 10.3.3.3 + neighbors: + - remote_as: 321 + neighbor: 10.3.3.4 + - remote_as: 322 + neighbor: 10.3.3.5 + multihop: 250 + purge: True + state: present + networks: + - 172.16.1.0/24 + vrf: default + evpn: yes + fast_external_fallover: yes + max_paths: 32 + ecmp_bestpath: yes + +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - router bgp 320 vrf default + - exit + - router bgp 320 router-id 10.3.3.3 force + - router bgp 320 vrf default bgp fast-external-fallover + - router bgp 320 vrf default maximum-paths 32 + - router bgp 320 vrf default bestpath as-path multipath-relax force + - router bgp 320 vrf default neighbor evpn peer-group + - router bgp 320 vrf default neighbor evpn send-community extended + - router bgp 320 vrf default address-family l2vpn-evpn neighbor evpn next-hop-unchanged + - router bgp 320 vrf default address-family l2vpn-evpn neighbor evpn activate + - router bgp 320 vrf default address-family l2vpn-evpn auto-create + - router bgp 320 vrf default neighbor 10.3.3.4 remote-as 321 + - router bgp 320 vrf default neighbor 10.3.3.4 ebgp-multihop 250 + - router bgp 320 vrf default neighbor 10.3.3.5 remote-as 322 + - router bgp 320 vrf default network 172.16.1.0 /24 +""" +import re +from ansible.module_utils.six import iteritems + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import get_bgp_summary +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxBgpModule(BaseOnyxModule): + LOCAL_AS_REGEX = re.compile(r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+).*') + ROUTER_ID_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+).*router-id\s+(\S+)\s+.*') + NEIGHBOR_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+).*neighbor\s+(\S+)\s+remote\-as\s+(\d+).*') + NEIGHBOR_MULTIHOP_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+).*neighbor\s+(\S+)\s+ebgp\-multihop\s+(\d+).*') + NETWORK_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+).*network\s+(\S+)\s+(\S+).*') + FAST_EXTERNAL_FALLOVER_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+bgp fast\-external\-fallover.*') + MAX_PATHS_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+maximum\-paths\s+(\d+).*') + ECMP_BESTPATH_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+bestpath as\-path multipath\-relax.*') + NEIGHBOR_EVPN_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+neighbor\s+(\S+)\s+peer\-group evpn.*') + EVPN_PEER_GROUP_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+neighbor evpn peer\-group.*') + EVPN_SEND_COMMUNITY_EXTENDED_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+neighbor evpn send-community extended.*') + EVPN_NEXT_HOP_UNCHANGED_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+address\-family l2vpn\-evpn neighbor evpn next\-hop-unchanged.*') + EVPN_ACTIVATE_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+address-family l2vpn\-evpn neighbor evpn activate.*') + EVPN_AUTO_CREATE_REGEX = re.compile( + r'^\s.*router bgp\s+(\d+)\s+vrf\s+(\S+)\s+address-family l2vpn\-evpn auto-create.*') + + _purge = False + + EVPN_PEER_GROUP_ATTR = "evpn_peer_group" + EVPN_SEND_COMMUNITY_EXTENDED_ATTR = "evpn_send_community_extended" + EVPN_NEXT_HOP_UNCHANGED_ATTR = "evpn_next_hop_unchanged" + EVPN_ACTIVATE_ATTR = "evpn_activate" + EVPN_AUTO_CREATE_ATTR = "evpn_auto_create" + + EVPN_PEER_GROUP_CMD = "router bgp %s vrf %s neighbor evpn peer-group" + EVPN_SEND_COMMUNITY_EXTENDED_CMD = "router bgp %s vrf %s neighbor evpn send-community extended" + EVPN_NEXT_HOP_UNCHANGED_CMD = "router bgp %s vrf %s address-family l2vpn-evpn neighbor evpn next-hop-unchanged" + EVPN_ACTIVATE_CMD = "router bgp %s vrf %s address-family l2vpn-evpn neighbor evpn activate" + EVPN_AUTO_CREATE_CMD = "router bgp %s vrf %s address-family l2vpn-evpn auto-create" + + EVPN_ENABLE_ATTRS = [EVPN_PEER_GROUP_ATTR, EVPN_SEND_COMMUNITY_EXTENDED_ATTR, + EVPN_NEXT_HOP_UNCHANGED_ATTR, EVPN_ACTIVATE_ATTR, EVPN_AUTO_CREATE_ATTR] + + EVPN_DISABLE_ATTRS = [EVPN_PEER_GROUP_ATTR, EVPN_AUTO_CREATE_ATTR] + + EVPN_COMMANDS_REGEX_MAPPER = { + EVPN_PEER_GROUP_ATTR: (EVPN_PEER_GROUP_REGEX, EVPN_PEER_GROUP_CMD), + EVPN_SEND_COMMUNITY_EXTENDED_ATTR: (EVPN_SEND_COMMUNITY_EXTENDED_REGEX, + EVPN_SEND_COMMUNITY_EXTENDED_CMD), + EVPN_NEXT_HOP_UNCHANGED_ATTR: (EVPN_NEXT_HOP_UNCHANGED_REGEX, + EVPN_NEXT_HOP_UNCHANGED_CMD), + EVPN_ACTIVATE_ATTR: (EVPN_ACTIVATE_REGEX, EVPN_ACTIVATE_CMD), + EVPN_AUTO_CREATE_ATTR: (EVPN_AUTO_CREATE_REGEX, EVPN_AUTO_CREATE_CMD) + } + + def init_module(self): + """ initialize module + """ + neighbor_spec = dict( + remote_as=dict(type='int', required=True), + neighbor=dict(required=True), + multihop=dict(type='int') + ) + element_spec = dict( + as_number=dict(type='int', required=True), + router_id=dict(), + neighbors=dict(type='list', elements='dict', + options=neighbor_spec), + networks=dict(type='list', elements='str'), + state=dict(choices=['present', 'absent'], default='present'), + purge=dict(default=False, type='bool'), + vrf=dict(), + fast_external_fallover=dict(type='bool'), + max_paths=dict(type='int'), + ecmp_bestpath=dict(type='bool'), + evpn=dict(type='bool') + ) + argument_spec = dict() + + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self._purge = self._required_config.get('purge', False) + self.validate_param_values(self._required_config) + + def _set_bgp_config(self, bgp_config): + lines = bgp_config.split('\n') + self._current_config['router_id'] = None + self._current_config['as_number'] = None + self._current_config['fast_external_fallover'] = False + self._current_config['ecmp_bestpath'] = False + self._current_config[self.EVPN_PEER_GROUP_ATTR] = False + self._current_config[self.EVPN_SEND_COMMUNITY_EXTENDED_ATTR] = False + self._current_config[self.EVPN_NEXT_HOP_UNCHANGED_ATTR] = False + self._current_config[self.EVPN_AUTO_CREATE_ATTR] = False + self._current_config[self.EVPN_ACTIVATE_ATTR] = False + neighbors = self._current_config['neighbors'] = dict() + networks = self._current_config['networks'] = list() + for line in lines: + if line.startswith('#'): + continue + if not self._current_config['as_number']: + match = self.LOCAL_AS_REGEX.match(line) + if match: + self._current_config['as_number'] = int(match.group(1)) + self._current_config['vrf'] = match.group(2) + continue + if not self._current_config['router_id']: + match = self.ROUTER_ID_REGEX.match(line) + if match: + self._current_config['router_id'] = match.group(2) + continue + match = self.NEIGHBOR_REGEX.match(line) + if match: + neighbor = neighbors.setdefault(match.group(2), dict()) + neighbor['remote_as'] = int(match.group(3)) + continue + match = self.NEIGHBOR_MULTIHOP_REGEX.match(line) + if match: + neighbor = neighbors.setdefault(match.group(2), dict()) + neighbor["multihop"] = int(match.group(3)) + continue + match = self.NEIGHBOR_EVPN_REGEX.match(line) + if match: + neighbor = neighbors.setdefault(match.group(3), dict()) + neighbor["evpn"] = True + continue + match = self.NETWORK_REGEX.match(line) + if match: + network = match.group(2) + match.group(3) + networks.append(network) + continue + match = self.FAST_EXTERNAL_FALLOVER_REGEX.match(line) + if match: + self._current_config['fast_external_fallover'] = True + continue + match = self.ECMP_BESTPATH_REGEX.match(line) + if match: + self._current_config['ecmp_bestpath'] = True + continue + match = self.MAX_PATHS_REGEX.match(line) + if match: + self._current_config['max_paths'] = int(match.group(3)) + continue + for key, value in iteritems(self.EVPN_COMMANDS_REGEX_MAPPER): + match = value[0].match(line) + if match: + self._current_config[key] = True + break + + def _get_bgp_summary(self): + return get_bgp_summary(self._module) + + def load_current_config(self): + self._current_config = dict() + bgp_config = self._get_bgp_summary() + if bgp_config: + self._set_bgp_config(bgp_config) + + def generate_commands(self): + state = self._required_config['state'] + if state == 'present': + self._generate_bgp_cmds() + else: + self._generate_no_bgp_cmds() + + def _generate_bgp_cmds(self): + vrf = self._required_config.get('vrf') + if vrf is None: + vrf = "default" + + as_number = self._required_config['as_number'] + curr_as_num = self._current_config.get('as_number') + curr_vrf = self._current_config.get("vrf") + bgp_removed = False + if curr_as_num != as_number or vrf != curr_vrf: + if curr_as_num: + self._commands.append('no router bgp %d vrf %s' % (curr_as_num, curr_vrf)) + bgp_removed = True + self._commands.append('router bgp %d vrf %s' % (as_number, vrf)) + self._commands.append('exit') + + req_router_id = self._required_config.get('router_id') + if req_router_id is not None: + curr_route_id = self._current_config.get('router_id') + if bgp_removed or req_router_id != curr_route_id: + self._commands.append('router bgp %d vrf %s router-id %s force' % (as_number, vrf, req_router_id)) + + fast_external_fallover = self._required_config.get('fast_external_fallover') + if fast_external_fallover is not None: + current_fast_external_fallover = self._current_config.get('fast_external_fallover') + if fast_external_fallover and (bgp_removed or fast_external_fallover != current_fast_external_fallover): + self._commands.append('router bgp %d vrf %s bgp fast-external-fallover' % (as_number, vrf)) + elif not fast_external_fallover and (bgp_removed or fast_external_fallover != current_fast_external_fallover): + self._commands.append('router bgp %d vrf %s no bgp fast-external-fallover' % (as_number, vrf)) + + max_paths = self._required_config.get('max_paths') + if max_paths is not None: + current_max_paths = self._current_config.get('max_paths') + if bgp_removed or max_paths != current_max_paths: + self._commands.append('router bgp %d vrf %s maximum-paths %s' % (as_number, vrf, max_paths)) + + ecmp_bestpath = self._required_config.get('ecmp_bestpath') + if ecmp_bestpath is not None: + current_ecmp_bestpath = self._current_config.get('ecmp_bestpath') + if ecmp_bestpath and (bgp_removed or ecmp_bestpath != current_ecmp_bestpath): + self._commands.append('router bgp %d vrf %s bestpath as-path multipath-relax force' % (as_number, vrf)) + elif not ecmp_bestpath and (bgp_removed or ecmp_bestpath != current_ecmp_bestpath): + self._commands.append('router bgp %d vrf %s no bestpath as-path multipath-relax force' % (as_number, vrf)) + + evpn = self._required_config.get('evpn') + if evpn is not None: + self._generate_evpn_cmds(evpn, as_number, vrf) + + self._generate_neighbors_cmds(as_number, vrf, bgp_removed) + self._generate_networks_cmds(as_number, vrf, bgp_removed) + + def _generate_neighbors_cmds(self, as_number, vrf, bgp_removed): + req_neighbors = self._required_config['neighbors'] + curr_neighbors = self._current_config.get('neighbors', {}) + evpn = self._required_config.get('evpn') + if self._purge: + for neighbor in curr_neighbors: + remote_as = curr_neighbors[neighbor].get("remote_as") + self._commands.append('router bgp %s vrf %s no neighbor %s remote-as %s' % ( + as_number, vrf, neighbor, remote_as)) + + if req_neighbors is not None: + for neighbor_data in req_neighbors: + neighbor = neighbor_data.get("neighbor") + curr_neighbor = curr_neighbors.get(neighbor) + remote_as = neighbor_data.get("remote_as") + multihop = neighbor_data.get("multihop") + if bgp_removed or curr_neighbor is None: + if remote_as is not None: + self._commands.append( + 'router bgp %s vrf %s neighbor %s remote-as %s' % (as_number, vrf, neighbor, remote_as)) + if multihop is not None: + self._commands.append( + 'router bgp %s vrf %s neighbor %s ebgp-multihop %s' % (as_number, vrf, neighbor, multihop)) + if evpn: + self._commands.append( + 'router bgp %s vrf %s neighbor %s peer-group evpn' % (as_number, vrf, neighbor)) + elif curr_neighbor is not None: + curr_remote_as = curr_neighbor.get("remote_as") + curr_multihop = curr_neighbor.get("multihop") + curr_neighbor_evpn = curr_neighbor.get("evpn") + if remote_as != curr_remote_as: + self._commands.append( + 'router bgp %s vrf %s neighbor %s remote-as %s' % (as_number, vrf, neighbor, remote_as)) + if multihop is not None and multihop != curr_multihop: + self._commands.append( + 'router bgp %s vrf %s neighbor %s ebgp-multihop %s' % (as_number, vrf, neighbor, multihop)) + if evpn and curr_neighbor_evpn is not True: + self._commands.append( + 'router bgp %s vrf %s neighbor %s peer-group evpn' % (as_number, vrf, neighbor)) + + def _generate_networks_cmds(self, as_number, vrf, bgp_removed): + req_networks = self._required_config['networks'] or [] + curr_networks = self._current_config.get('networks', []) + if not bgp_removed: + for network in curr_networks: + if network not in req_networks: + net_attrs = network.split('/') + if len(net_attrs) != 2: + self._module.fail_json( + msg='Invalid network %s' % network) + + net_address, netmask = net_attrs + cmd = 'router bgp %s no network %s /%s' % ( + as_number, net_address, netmask) + self._commands.append(cmd) + + for network in req_networks: + if bgp_removed or network not in curr_networks: + net_attrs = network.split('/') + if len(net_attrs) != 2: + self._module.fail_json( + msg='Invalid network %s' % network) + net_address, netmask = net_attrs + cmd = 'router bgp %s vrf %s network %s /%s' % ( + as_number, vrf, net_address, netmask) + self._commands.append(cmd) + + def _generate_no_bgp_cmds(self): + as_number = self._required_config['as_number'] + curr_as_num = self._current_config.get('as_number') + if curr_as_num and curr_as_num == as_number: + self._commands.append('no router bgp %d' % as_number) + + def _generate_evpn_cmds(self, evpn, as_number, vrf): + if evpn: + for attr in self.EVPN_ENABLE_ATTRS: + curr_attr = self._current_config.get(attr) + if curr_attr is not True: + self._commands.append(self.EVPN_COMMANDS_REGEX_MAPPER.get(attr)[1] % (as_number, vrf)) + elif not evpn: + for attr in self.EVPN_DISABLE_ATTRS: + curr_attr = self._current_config.get(attr) + if curr_attr is not False: + self._commands.append("no " + self.EVPN_COMMANDS_REGEX_MAPPER.get(attr)[1] % (as_number, vrf)) + + +def main(): + """ main entry point for module execution + """ + OnyxBgpModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_buffer_pool.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_buffer_pool.py new file mode 100644 index 00000000..94e127e3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_buffer_pool.py @@ -0,0 +1,140 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_buffer_pool +author: "Anas Badaha (@anasb)" +short_description: Configures Buffer Pool +description: + - This module provides declarative management of Onyx Buffer Pool configuration + on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.8130 +options: + name: + description: + - pool name. + required: true + pool_type: + description: + - pool type. + choices: ['lossless', 'lossy'] + default: lossy + memory_percent: + description: + - memory percent. + switch_priority: + description: + - switch priority, range 1-7. +''' + +EXAMPLES = """ +- name: Configure buffer pool + onyx_buffer_pool: + name: roce + pool_type: lossless + memory_percent: 50.00 + switch_priority: 3 + +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - traffic pool roce type lossless + - traffic pool roce memory percent 50.00 + - traffic pool roce map switch-priority 3 +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxBufferPoolModule(BaseOnyxModule): + + def init_module(self): + """ initialize module + """ + element_spec = dict( + name=dict(type='str', required=True), + pool_type=dict(choices=['lossless', 'lossy'], default='lossy'), + memory_percent=dict(type='float'), + switch_priority=dict(type='int') + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def validate_switch_priority(self, value): + if value and not 0 <= int(value) <= 7: + self._module.fail_json(msg='switch_priority value must be between 0 and 7') + + def _set_traffic_pool_config(self, traffic_pool_config): + if traffic_pool_config is None: + return + traffic_pool_config = traffic_pool_config.get(self._required_config.get('name')) + self._current_config['pool_type'] = traffic_pool_config[0].get("Type") + self._current_config['switch_priority'] = int(traffic_pool_config[0].get("Switch Priorities")) + self._current_config['memory_percent'] = float(traffic_pool_config[0].get("Memory [%]")) + + def _show_traffic_pool(self): + cmd = "show traffic pool {0}".format(self._required_config.get("name")) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + traffic_pool_config = self._show_traffic_pool() + self._set_traffic_pool_config(traffic_pool_config) + + def generate_commands(self): + name = self._required_config.get("name") + pool_type = self._required_config.get("pool_type") + + if self._current_config is None: + self._add_add_traffic_pool_cmds(name, pool_type) + else: + current_pool_type = self._current_config.get("pool_type") + if pool_type != current_pool_type: + self._add_add_traffic_pool_cmds(name, pool_type) + + memory_percent = self._required_config.get("memory_percent") + if memory_percent is not None: + curr_memory_percent = self._current_config.get("memory_percent") + if curr_memory_percent is None or memory_percent != curr_memory_percent: + self._commands.append('traffic pool {0} memory percent {1}'.format(name, memory_percent)) + + switch_priority = self._required_config.get("switch_priority") + if switch_priority is not None: + curr_switch_priority = self._current_config.get("switch_priority") + if curr_switch_priority is None or switch_priority != curr_switch_priority: + self._commands.append('traffic pool {0} map switch-priority {1}'.format(name, switch_priority)) + + def _add_add_traffic_pool_cmds(self, name, pool_type): + self._commands.append('traffic pool {0} type {1}'.format(name, pool_type)) + + +def main(): + """ main entry point for module execution + """ + OnyxBufferPoolModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_command.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_command.py new file mode 100644 index 00000000..719e8f23 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_command.py @@ -0,0 +1,210 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_command + +author: "Samer Deeb (@samerd)" +short_description: Run commands on remote devices running Mellanox ONYX +description: + - Sends arbitrary commands to an Mellanox ONYX network device and returns + the results read from the device. This module includes an + argument that will cause the module to wait for a specific condition + before returning or timing out if the condition is not met. + - This module does not support running commands in configuration mode. + Please use M(onyx_config) to configure Mellanox ONYX devices. +notes: + - Tested on ONYX 3.6.4000 +options: + commands: + description: + - List of commands to send to the remote Mellanox ONYX network device. + The resulting output from the command + is returned. If the I(wait_for) argument is provided, the + module is not returned until the condition is satisfied or + the number of retries has expired. + required: true + wait_for: + description: + - List of conditions to evaluate against the output of the + command. The task will wait for each condition to be true + before moving forward. If the conditional is not true + within the configured number of retries, the task fails. + See examples. + match: + description: + - The I(match) argument is used in conjunction with the + I(wait_for) argument to specify the match policy. Valid + values are C(all) or C(any). If the value is set to C(all) + then all conditionals in the wait_for must be satisfied. If + the value is set to C(any) then only one of the values must be + satisfied. + default: all + choices: ['any', 'all'] + retries: + description: + - Specifies the number of retries a command should by tried + before it is considered failed. The command is run on the + target device every retry and evaluated against the + I(wait_for) conditions. + default: 10 + interval: + description: + - Configures the interval in seconds to wait between retries + of the command. If the command does not pass the specified + conditions, the interval indicates how long to wait before + trying the command again. + default: 1 +''' + +EXAMPLES = """ +tasks: + - name: Run show version on remote devices + onyx_command: + commands: show version + + - name: Run show version and check to see if output contains MLNXOS + onyx_command: + commands: show version + wait_for: result[0] contains MLNXOS + + - name: Run multiple commands on remote nodes + onyx_command: + commands: + - show version + - show interfaces + + - name: Run multiple commands and evaluate the output + onyx_command: + commands: + - show version + - show interfaces + wait_for: + - result[0] contains MLNXOS + - result[1] contains mgmt1 +""" + +RETURN = """ +stdout: + description: The set of responses from the commands + returned: always apart from low level errors (such as action plugin) + type: list + sample: ['...', '...'] +stdout_lines: + description: The value of stdout split into a list + returned: always apart from low level errors (such as action plugin) + type: list + sample: [['...', '...'], ['...'], ['...']] +failed_conditions: + description: The list of conditionals that have failed + returned: failed + type: list + sample: ['...', '...'] +""" + +import time + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import Conditional +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ComplexList +from ansible.module_utils.six import string_types + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import run_commands + + +def to_lines(stdout): + for item in stdout: + if isinstance(item, string_types): + item = str(item).split('\n') + yield item + + +def parse_commands(module, warnings): + command = ComplexList(dict( + command=dict(key=True), + prompt=dict(), + answer=dict() + ), module) + commands = command(module.params['commands']) + for item in list(commands): + if module.check_mode and not item['command'].startswith('show'): + warnings.append( + 'only show commands are supported when using check mode, not ' + 'executing `%s`' % item['command'] + ) + commands.remove(item) + elif item['command'].startswith('conf'): + module.fail_json( + msg='onyx_command does not support running config mode ' + 'commands. Please use onyx_config instead' + ) + return commands + + +def main(): + """main entry point for module execution + """ + argument_spec = dict( + commands=dict(type='list', required=True), + + wait_for=dict(type='list'), + match=dict(default='all', choices=['all', 'any']), + + retries=dict(default=10, type='int'), + interval=dict(default=1, type='int') + ) + + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True) + + result = {'changed': False} + + warnings = list() + commands = parse_commands(module, warnings) + result['warnings'] = warnings + + wait_for = module.params['wait_for'] or list() + conditionals = [Conditional(c) for c in wait_for] + + retries = module.params['retries'] + interval = module.params['interval'] + match = module.params['match'] + + while retries > 0: + responses = run_commands(module, commands) + + for item in list(conditionals): + if item(responses): + if match == 'any': + conditionals = list() + break + conditionals.remove(item) + + if not conditionals: + break + + time.sleep(interval) + retries -= 1 + + if conditionals: + failed_conditions = [item.raw for item in conditionals] + msg = 'One or more conditional statements have not been satisfied' + module.fail_json(msg=msg, failed_conditions=failed_conditions) + + result.update({ + 'changed': False, + 'stdout': responses, + 'stdout_lines': list(to_lines(responses)) + }) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_config.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_config.py new file mode 100644 index 00000000..cdd532f0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_config.py @@ -0,0 +1,248 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_config + +author: "Alex Tabachnik (@atabachnik), Samer Deeb (@samerd)" +short_description: Manage Mellanox ONYX configuration sections +description: + - Mellanox ONYX configurations uses a simple block indent file syntax + for segmenting configuration into sections. This module provides + an implementation for working with ONYX configuration sections in + a deterministic way. +options: + lines: + description: + - The ordered set of commands that should be configured in the + section. The commands must be the exact same commands as found + in the device running-config. Be sure to note the configuration + command syntax as some commands are automatically modified by the + device config parser. + aliases: ['commands'] + parents: + description: + - The ordered set of parents that uniquely identify the section + the commands should be checked against. If the parents argument + is omitted, the commands are checked against the set of top + level or global commands. + src: + description: + - Specifies the source path to the file that contains the configuration + or configuration template to load. The path to the source file can + either be the full path on the Ansible control host or a relative + path from the playbook or role root directory. This argument is mutually + exclusive with I(lines), I(parents). + before: + description: + - The ordered set of commands to push on to the command stack if + a change needs to be made. This allows the playbook designer + the opportunity to perform configuration commands prior to pushing + any changes without affecting how the set of commands are matched + against the system. + after: + description: + - The ordered set of commands to append to the end of the command + stack if a change needs to be made. Just like with I(before) this + allows the playbook designer to append a set of commands to be + executed after the command set. + match: + description: + - Instructs the module on the way to perform the matching of + the set of commands against the current device config. If + match is set to I(line), commands are matched line by line. If + match is set to I(strict), command lines are matched with respect + to position. If match is set to I(exact), command lines + must be an equal match. Finally, if match is set to I(none), the + module will not attempt to compare the source configuration with + the running configuration on the remote device. + default: line + choices: ['line', 'strict', 'exact', 'none'] + replace: + description: + - Instructs the module on the way to perform the configuration + on the device. If the replace argument is set to I(line) then + the modified lines are pushed to the device in configuration + mode. If the replace argument is set to I(block) then the entire + command block is pushed to the device in configuration mode if any + line is not correct + default: line + choices: ['line', 'block'] + backup: + description: + - This argument will cause the module to create a full backup of + the current C(running-config) from the remote device before any + changes are made. If the C(backup_options) value is not given, + the backup file is written to the C(backup) folder in the playbook + root directory. If the directory does not exist, it is created. + default: no + type: bool + config: + description: + - The C(config) argument allows the playbook designer to supply + the base configuration to be used to validate configuration + changes necessary. If this argument is provided, the module + will not download the running-config from the remote node. + save: + description: + - The C(save) argument instructs the module to save the running- + config to the startup-config at the conclusion of the module + running. If check mode is specified, this argument is ignored. + default: no + type: bool + backup_options: + description: + - This is a dict object containing configurable options related to backup file path. + The value of this option is read only when C(backup) is set to I(yes), if C(backup) is set + to I(no) this option will be silently ignored. + suboptions: + filename: + description: + - The filename to be used to store the backup configuration. If the filename + is not given it will be generated based on the hostname, current time and date + in format defined by <hostname>_config.<current-date>@<current-time> + dir_path: + description: + - This option provides the path ending with directory name in which the backup + configuration file will be stored. If the directory does not exist it will be first + created and the filename is either the value of C(filename) or default filename + as described in C(filename) options description. If the path value is not given + in that case a I(backup) directory will be created in the current working directory + and backup configuration will be copied in C(filename) within I(backup) directory. + type: path + type: dict +''' + +EXAMPLES = """ +--- +- onyx_config: + lines: + - snmp-server community + - snmp-server host 10.2.2.2 traps version 2c +""" + +RETURN = """ +updates: + description: The set of commands that will be pushed to the remote device + returned: always + type: list + sample: ['...', '...'] +backup_path: + description: The full path to the backup file + returned: when backup is yes + type: str + sample: /playbooks/ansible/backup/onyx_config.2016-07-16@22:28:34 +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import NetworkConfig, dumps + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import get_config +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import load_config +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import run_commands + + +def get_candidate(module): + candidate = NetworkConfig(indent=1) + if module.params['src']: + candidate.load(module.params['src']) + elif module.params['lines']: + parents = module.params['parents'] or list() + candidate.add(module.params['lines'], parents=parents) + return candidate + + +def run(module, result): + match = module.params['match'] + replace = module.params['replace'] + path = module.params['parents'] + + candidate = get_candidate(module) + if match != 'none': + contents = module.params['config'] + if not contents: + contents = get_config(module) + config = NetworkConfig(indent=1, contents=contents) + configobjs = candidate.difference(config, path=path, match=match, + replace=replace) + + else: + configobjs = candidate.items + + total_commands = [] + if configobjs: + commands = dumps(configobjs, 'commands').split('\n') + + if module.params['lines']: + if module.params['before']: + commands[:0] = module.params['before'] + + if module.params['after']: + commands.extend(module.params['after']) + + total_commands.extend(commands) + result['updates'] = total_commands + + if module.params['save']: + total_commands.append('configuration write') + if total_commands: + result['changed'] = True + if not module.check_mode: + load_config(module, total_commands) + + +def main(): + """ main entry point for module execution + """ + backup_spec = dict( + filename=dict(), + dir_path=dict(type='path') + ) + argument_spec = dict( + src=dict(type='path'), + + lines=dict(aliases=['commands'], type='list'), + parents=dict(type='list'), + + before=dict(type='list'), + after=dict(type='list'), + + match=dict(default='line', choices=['line', 'strict', 'exact', 'none']), + replace=dict(default='line', choices=['line', 'block']), + + config=dict(), + + backup=dict(type='bool', default=False), + backup_options=dict(type='dict', options=backup_spec), + save=dict(type='bool', default=False), + ) + + mutually_exclusive = [('lines', 'src'), + ('parents', 'src')] + + required_if = [('match', 'strict', ['lines']), + ('match', 'exact', ['lines']), + ('replace', 'block', ['lines'])] + + module = AnsibleModule(argument_spec=argument_spec, + mutually_exclusive=mutually_exclusive, + required_if=required_if, + supports_check_mode=True) + + result = {'changed': False} + if module.params['backup']: + result['__backup__'] = get_config(module) + + run(module, result) + + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_facts.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_facts.py new file mode 100644 index 00000000..997d4df1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_facts.py @@ -0,0 +1,241 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_facts +author: "Waleed Mousa (@waleedym), Samer Deeb (@samerd)" +short_description: Collect facts from Mellanox ONYX network devices +description: + - Collects a base set of device facts from a ONYX Mellanox network devices + This module prepends all of the base network fact keys with + C(ansible_net_<fact>). The facts module will always collect a base set of + facts from the device and can enable or disable collection of additional + facts. +notes: + - Tested against ONYX 3.6 +options: + gather_subset: + description: + - When supplied, this argument will restrict the facts collected + to a given subset. Possible values for this argument include + all, version, module, and interfaces. Can specify a list of + values to include a larger subset. Values can also be used + with an initial C(M(!)) to specify that a specific subset should + not be collected. + required: false + default: version +''' + +EXAMPLES = """ +--- +- name: Collect all facts from the device + onyx_facts: + gather_subset: all +- name: Collect only the interfaces facts + onyx_facts: + gather_subset: + - interfaces +- name: Do not collect version facts + onyx_facts: + gather_subset: + - "!version" +""" + +RETURN = """ +ansible_net_gather_subset: + description: The list of fact subsets collected from the device + returned: always + type: list +# version +ansible_net_version: + description: A hash of all currently running system image information + returned: when version is configured or when no gather_subset is provided + type: dict +# modules +ansible_net_modules: + description: A hash of all modules on the systeme with status + returned: when modules is configured + type: dict +# interfaces +ansible_net_interfaces: + description: A hash of all interfaces running on the system + returned: when interfaces is configured + type: dict +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxFactsModule(BaseOnyxModule): + + def get_runable_subset(self, gather_subset): + runable_subsets = set() + exclude_subsets = set() + for subset in gather_subset: + if subset == 'all': + runable_subsets.update(VALID_SUBSETS) + continue + + if subset.startswith('!'): + subset = subset[1:] + if subset == 'all': + exclude_subsets.update(VALID_SUBSETS) + continue + exclude = True + else: + exclude = False + + if subset not in VALID_SUBSETS: + self._module.fail_json(msg='Bad subset') + + if exclude: + exclude_subsets.add(subset) + else: + runable_subsets.add(subset) + + if not runable_subsets: + runable_subsets.update(VALID_SUBSETS) + + runable_subsets.difference_update(exclude_subsets) + if not runable_subsets: + runable_subsets.add('version') + return runable_subsets + + def init_module(self): + """ module initialization + """ + argument_spec = dict( + gather_subset=dict(default=['version'], type='list') + ) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def run(self): + self.init_module() + gather_subset = self._module.params['gather_subset'] + runable_subsets = self.get_runable_subset(gather_subset) + facts = dict() + facts['gather_subset'] = list(runable_subsets) + + instances = list() + for key in runable_subsets: + facter_cls = FACT_SUBSETS[key] + instances.append(facter_cls(self._module)) + + for inst in instances: + inst.populate() + facts.update(inst.facts) + + ansible_facts = dict() + for key, value in iteritems(facts): + key = 'ansible_net_%s' % key + ansible_facts[key] = value + self._module.exit_json(ansible_facts=ansible_facts) + + +class FactsBase(object): + + COMMANDS = [''] + + def __init__(self, module): + self.module = module + self.facts = dict() + self.responses = None + + def _show_cmd(self, cmd): + return show_cmd(self.module, cmd, json_fmt=True) + + def populate(self): + self.responses = [] + for cmd in self.COMMANDS: + self.responses.append(self._show_cmd(cmd)) + + +class Version(FactsBase): + + COMMANDS = ['show version'] + + def populate(self): + super(Version, self).populate() + data = self.responses[0] + if data: + self.facts['version'] = data + + +class Module(FactsBase): + + COMMANDS = ['show module'] + + def populate(self): + super(Module, self).populate() + data = self.responses[0] + if data: + self.facts['modules'] = data + + +class Interfaces(FactsBase): + + COMMANDS = ['show version', 'show interfaces ethernet'] + + def populate(self): + super(Interfaces, self).populate() + + version_data = self.responses[0] + os_version = version_data['Product release'] + data = self.responses[1] + + if data: + self.facts['interfaces'] = self.populate_interfaces(data, os_version) + + def extractIfData(self, interface_data): + return {"MAC Address": interface_data["Mac address"], + "Actual Speed": interface_data["Actual speed"], + "MTU": interface_data["MTU"], + "Admin State": interface_data["Admin state"], + "Operational State": interface_data["Operational state"]} + + def populate_interfaces(self, interfaces, os_version): + interfaces_dict = dict() + for if_data in interfaces: + if_dict = dict() + if os_version >= BaseOnyxModule.ONYX_API_VERSION: + for if_name, interface_data in iteritems(if_data): + interface_data = interface_data[0] + if_dict = self.extractIfData(interface_data) + if_name = if_dict["Interface Name"] = if_name + + else: + if_dict = self.extractIfData(if_data) + if_name = if_dict["Interface Name"] = if_data["header"] + interfaces_dict[if_name] = if_dict + return interfaces_dict + + +FACT_SUBSETS = dict( + version=Version, + modules=Module, + interfaces=Interfaces +) + +VALID_SUBSETS = frozenset(FACT_SUBSETS.keys()) + + +def main(): + """ main entry point for module execution + """ + OnyxFactsModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp.py new file mode 100644 index 00000000..77a09960 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp.py @@ -0,0 +1,220 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_igmp +author: "Samer Deeb (@samerd)" +short_description: Configures IGMP global parameters +description: + - This module provides declarative management of IGMP protocol params + on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.6107 +options: + state: + description: + - IGMP state. + required: true + choices: ['enabled', 'disabled'] + last_member_query_interval: + description: + - Configure the last member query interval, range 1-25 + mrouter_timeout: + description: + - Configure the mrouter timeout, range 60-600 + port_purge_timeout: + description: + - Configure the host port purge timeout, range 130-1225 + proxy_reporting: + description: + - Configure ip igmp snooping proxy and enable reporting mode + choices: ['enabled', 'disabled'] + report_suppression_interval: + description: + - Configure the report suppression interval, range 1-25 + unregistered_multicast: + description: + - Configure the unregistered multicast mode + Flood unregistered multicast + Forward unregistered multicast to mrouter ports + choices: ['flood', 'forward-to-mrouter-ports'] + default_version: + description: + - Configure the default operating version of the IGMP snooping + choices: ['V2','V3'] +''' + +EXAMPLES = """ +- name: Configure igmp + onyx_igmp: + state: enabled + unregistered_multicast: flood +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - ip igmp snooping + - ip igmp snooping last-member-query-interval 10 + - ip igmp snooping mrouter-timeout 150 + - ip igmp snooping port-purge-timeout 150 +""" + +import re + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxIgmpModule(BaseOnyxModule): + TIME_INTERVAL_REGEX = re.compile(r'^(\d+)\s+seconds') + + _RANGE_INTERVALS = dict( + last_member_query_interval=(1, 25, 'Last member query interval'), + mrouter_timeout=(60, 600, 'Mrouter timeout'), + port_purge_timeout=(130, 1225, 'Port purge timeout'), + report_suppression_interval=(1, 25, 'Report suppression interval'), + ) + + def init_module(self): + """ initialize module + """ + element_spec = dict( + state=dict(choices=['enabled', 'disabled'], required=True), + last_member_query_interval=dict(type='int'), + mrouter_timeout=dict(type='int'), + port_purge_timeout=dict(type='int'), + proxy_reporting=dict(choices=['enabled', 'disabled']), + report_suppression_interval=dict(type='int'), + unregistered_multicast=dict( + choices=['flood', 'forward-to-mrouter-ports']), + default_version=dict(choices=['V2', 'V3']), + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def _validate_key(self, param, key): + interval_params = self._RANGE_VALIDATORS.get(key) + if interval_params: + min_val, max_val = interval_params[0], interval_params[1] + value = param.get(key) + self._validate_range(key, min_val, max_val, value) + else: + super(OnyxIgmpModule, self)._validate_key(param, key) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def _set_igmp_config(self, igmp_config): + igmp_config = igmp_config[0] + if not igmp_config: + return + self._current_config['state'] = igmp_config.get( + 'IGMP snooping globally', 'disabled') + self._current_config['proxy_reporting'] = igmp_config.get( + 'Proxy-reporting globally', 'disabled') + self._current_config['default_version'] = igmp_config.get( + 'IGMP default version for new VLAN', 'V3') + self._current_config['unregistered_multicast'] = igmp_config.get( + 'IGMP snooping unregistered multicast', 'flood') + + for interval_name, interval_params in iteritems(self._RANGE_INTERVALS): + display_str = interval_params[2] + value = igmp_config.get(display_str, '') + match = self.TIME_INTERVAL_REGEX.match(value) + if match: + interval_value = int(match.group(1)) + else: + interval_value = None + self._current_config[interval_name] = interval_value + + def _show_igmp(self): + cmd = "show ip igmp snooping" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + igmp_config = self._show_igmp() + if igmp_config: + self._set_igmp_config(igmp_config) + + def generate_commands(self): + state = self._required_config['state'] + if state == 'enabled': + self._generate_igmp_cmds() + else: + self._generate_no_igmp_cmds() + + def _generate_igmp_cmds(self): + curr_state = self._current_config.get('state', 'disabled') + if curr_state == 'disabled': + self._commands.append('ip igmp snooping') + for interval_name in self._RANGE_INTERVALS: + req_val = self._required_config.get(interval_name) + if not req_val: + continue + curr_value = self._current_config.get(interval_name) + if curr_value == req_val: + continue + interval_cmd = interval_name.replace('_', '-') + self._commands.append( + 'ip igmp snooping %s %s' % (interval_cmd, req_val)) + + req_val = self._required_config.get('unregistered_multicast') + if req_val: + curr_value = self._current_config.get( + 'unregistered_multicast', 'flood') + if req_val != curr_value: + self._commands.append( + 'ip igmp snooping unregistered multicast %s' % req_val) + + req_val = self._required_config.get('proxy_reporting') + if req_val: + curr_value = self._current_config.get( + 'proxy_reporting', 'disabled') + if req_val != curr_value: + cmd = 'ip igmp snooping proxy reporting' + if req_val == 'disabled': + cmd = 'no %s' % cmd + self._commands.append(cmd) + + req_val = self._required_config.get('default_version') + if req_val: + curr_value = self._current_config.get( + 'default_version', 'V3') + if req_val != curr_value: + version = req_val[1] # remove the 'V' and take the number only + self._commands.append( + 'ip igmp snooping version %s' % version) + + def _generate_no_igmp_cmds(self): + curr_state = self._current_config.get('state', 'disabled') + if curr_state != 'disabled': + self._commands.append('no ip igmp snooping') + + +def main(): + """ main entry point for module execution + """ + OnyxIgmpModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp_interface.py new file mode 100644 index 00000000..28034732 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp_interface.py @@ -0,0 +1,131 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_igmp_interface +author: "Anas Badaha (@anasb)" +short_description: Configures IGMP interface parameters +description: + - This module provides declarative management of IGMP interface configuration + on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.8130 +options: + name: + description: + - interface name that we want to configure IGMP on it + required: true + state: + description: + - IGMP Interface state. + choices: ['enabled', 'disabled'] + default: enabled +''' + +EXAMPLES = """ +- name: Configure igmp interface + onyx_igmp_interface: + state: enabled + name: Eth1/1 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface ethernet 1/1 ip igmp snooping fast-leave +""" + +import re +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxIgmpInterfaceModule(BaseOnyxModule): + IF_NAME_REGEX = re.compile(r"^(Eth\d+\/\d+|Eth\d+\/\d+\d+)$") + + def init_module(self): + """ initialize module + """ + element_spec = dict( + state=dict(choices=['enabled', 'disabled'], default='enabled'), + name=dict(required=True) + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + match = self.IF_NAME_REGEX.match(self._required_config["name"]) + if not match: + raise AttributeError("Please Insert Valid Interface Name") + + self.validate_param_values(self._required_config) + + def _set_igmp_config(self, igmp_interfaces_config): + if not igmp_interfaces_config: + return + name = self._required_config.get('name') + interface_state = igmp_interfaces_config[name][0].get('leave-mode') + if interface_state == "Fast": + self._current_config['state'] = "enabled" + else: + self._current_config['state'] = "disabled" + + def _show_igmp_interfaces(self): + cmd = "show ip igmp snooping interfaces" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + igmp_interfaces_config = self._show_igmp_interfaces() + if igmp_interfaces_config: + self._set_igmp_config(igmp_interfaces_config) + + def generate_commands(self): + req_state = self._required_config['state'] + self._req_val = self._required_config.get('name').replace("Eth", "ethernet ") + + if req_state == 'enabled': + self._generate_igmp_interface_cmds() + else: + self._generate_no_igmp_cmds() + + def _generate_igmp_interface_cmds(self): + curr_state = self._current_config.get('state', 'enabled') + if curr_state == 'enabled': + pass + + elif curr_state == 'disabled': + self._commands.append('interface %s ip igmp snooping fast-leave' % self._req_val) + + def _generate_no_igmp_cmds(self): + curr_state = self._current_config.get('state', 'enabled') + if curr_state == 'enabled': + self._commands.append('interface %s no ip igmp snooping fast-leave' % self._req_val) + else: + pass + + +def main(): + """ main entry point for module execution + """ + OnyxIgmpInterfaceModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp_vlan.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp_vlan.py new file mode 100644 index 00000000..4c41b01e --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_igmp_vlan.py @@ -0,0 +1,431 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_igmp_vlan +author: Anas Badaha (@anasbadaha) +short_description: Configures IGMP Vlan parameters +description: + - This module provides declarative management of IGMP vlan configuration on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.7.0932-01 +options: + vlan_id: + description: + - VLAN ID, vlan should exist. + required: true + state: + description: + - IGMP state. + choices: ['enabled', 'disabled'] + default: enabled + mrouter: + description: + - Configure ip igmp snooping mrouter port on vlan + suboptions: + state: + description: + - Enable IGMP snooping mrouter on vlan interface. + choices: ['enabled', 'disabled'] + default: enabled + name: + description: + - Configure mrouter interface + required: true + querier: + description: + - Configure the IGMP querier parameters + suboptions: + state: + description: + - Enable IGMP snooping querier on vlan in the switch. + choices: ['enabled', 'disabled'] + default: enabled + interval: + description: + - Update time interval between querier queries, range 60-600 + address: + description: + - Update IP address for the querier + static_groups: + description: + - List of IGMP static groups. + suboptions: + multicast_ip_address: + description: + - Configure static IP multicast group, range 224.0.1.0-239.255.255.25. + required: true + name: + description: + - interface name to configure static groups on it. + sources: + description: + - List of IP sources to be configured + version: + description: + - IGMP snooping operation version on this vlan + choices: ['V2','V3'] +''' + +EXAMPLES = """ +- name: Configure igmp vlan + onyx_igmp_vlan: + state: enabled + vlan_id: 10 + version: + V2 + querier: + state: enabled + interval: 70 + address: 10.11.121.13 + mrouter: + state: disabled + name: Eth1/2 + static_groups: + - multicast_ip_address: 224.5.5.8 + name: Eth1/1 + sources: + - 1.1.1.1 + - 1.1.1.2 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - vlan 10 ip igmp snooping + - vlan 10 ip igmp snooping static-group 224.5.5.5 interface ethernet 1/1 +""" +import socket +import struct + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +def _ip_to_int(addr): + return struct.unpack("!I", socket.inet_aton(addr))[0] + + +class OnyxIgmpVlanModule(BaseOnyxModule): + MIN_MULTICAST_IP = _ip_to_int("224.0.1.0") + MAX_MULTICAST_IP = _ip_to_int("239.255.255.255") + + def init_module(self): + """ initialize module + """ + mrouter_spec = dict(name=dict(required=True), + state=dict(choices=['enabled', 'disabled'], default='enabled')) + querier_spec = dict(state=dict(choices=['enabled', 'disabled'], default='enabled'), + interval=dict(type='int'), address=dict()) + static_groups_spec = dict(multicast_ip_address=dict(required=True), + name=dict(required=True), sources=dict(type='list')) + element_spec = dict(vlan_id=dict(type='int', required=True), + state=dict(choices=['enabled', 'disabled'], default='enabled'), + querier=dict(type='dict', options=querier_spec), + static_groups=dict(type='list', elements='dict', options=static_groups_spec), + mrouter=dict(type='dict', options=mrouter_spec), + version=dict(choices=['V2', 'V3'])) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def _validate_attr_is_not_none(self, attr_name, attr_value): + if attr_name == 'vlan_id' or attr_name == 'state': + pass + elif attr_value is not None: + self._module.fail_json(msg='Can not set %s value on switch while state is disabled' % attr_name) + + def validate_param_values(self, obj, param=None): + if obj['state'] == 'disabled': + for attr_name in obj: + self._validate_attr_is_not_none(attr_name, obj[attr_name]) + super(OnyxIgmpVlanModule, self).validate_param_values(obj, param) + + def validate_querier(self, value): + interval = value.get('interval') + if interval and not 60 <= int(interval) <= 600: + self._module.fail_json(msg='query-interval value must be between 60 and 600') + + def validate_static_groups(self, value): + multicast_ip = value.get('multicast_ip_address') + multicast_ip = _ip_to_int(multicast_ip) + + if multicast_ip < self.MIN_MULTICAST_IP or multicast_ip > self.MAX_MULTICAST_IP: + self._module.fail_json(msg='multicast IP address must be in range 224.0.1.0 - 239.255.255.255') + + @staticmethod + def _get_curr_mrouter_config(mrouter_port): + if mrouter_port == "none": + return {'state': 'disabled'} + else: + return {'state': 'enabled', + 'name': mrouter_port} + + def _get_curr_querier_config(self, querier_config): + if "Non-Querier" in querier_config: + return {'state': 'disabled'} + elif "Querier" in querier_config: + igmp_querier_config = self._show_igmp_querier_config()[0] + snooping_querier_info = igmp_querier_config["Snooping querier information for VLAN %d" % ( + self._required_config['vlan_id'])] + snooping_querier_info = snooping_querier_info[1] + interval = int(snooping_querier_info["Query interval"]) + address = snooping_querier_info["Configured querier IP address"] + return {'state': 'enabled', + 'interval': interval, + 'address': address} + + @staticmethod + def _get_curr_version(version): + if "V3" in version: + return "V3" + elif "V2" in version: + return "V2" + + def _get_curr_static_group_config(self, multicast_ip_address): + sources = None + names = None + igmp_snooping_groups_config = self._show_igmp_snooping_groups_config(multicast_ip_address) + if igmp_snooping_groups_config is not None: + igmp_snooping_groups_config = igmp_snooping_groups_config[0] + snooping_group_information = igmp_snooping_groups_config.get('Snooping group ' + 'information for VLAN %d and group ' + '%s' % (self._required_config['vlan_id'], + multicast_ip_address)) + if snooping_group_information is not None: + if len(snooping_group_information) == 1: + names = snooping_group_information[0].get('V1/V2 Receiver Ports') + elif len(snooping_group_information) == 2: + sources_dict = dict() + v3_receiver_ports = snooping_group_information[1].get('V3 Receiver Ports') + ports_number = v3_receiver_ports[0].get('Port Number') + sources = v3_receiver_ports[0].get('Include sources') + if isinstance(ports_number, list): + i = 0 + for port_number in ports_number: + sources_dict[port_number] = sources[i] + i += 1 + else: + sources_dict[ports_number] = sources + names = snooping_group_information[0].get('V1/V2 Receiver Ports') + sources = sources_dict + + return {'sources': sources, + 'names': names} + else: + return None + else: + return None + + def _set_igmp_config(self, igmp_vlan_config): + igmp_vlan_config = igmp_vlan_config[0] + if not igmp_vlan_config: + return + + self._current_config['state'] = igmp_vlan_config.get('message 1') + if "enabled" in self._current_config['state']: + self._current_config['state'] = "enabled" + elif "disabled" in self._current_config['state']: + self._current_config['state'] = "disabled" + + mrouter_port = igmp_vlan_config.get('mrouter static port list') + self._current_config['mrouter'] = dict(self._get_curr_mrouter_config(mrouter_port)) + + querier_config = igmp_vlan_config.get('message 3') + self._current_config['querier'] = dict(self._get_curr_querier_config(querier_config)) + + version = igmp_vlan_config.get('message 2') + self._current_config['version'] = self._get_curr_version(version) + + req_static_groups = self._required_config.get('static_groups') + if req_static_groups is not None: + static_groups = self._current_config['static_groups'] = dict() + for static_group in req_static_groups: + static_group_config = self._get_curr_static_group_config(static_group['multicast_ip_address']) + static_groups[static_group['multicast_ip_address']] = static_group_config + + def _show_igmp_vlan(self): + cmd = ("show ip igmp snooping vlan %d" % self._required_config['vlan_id']) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def _show_igmp_querier_config(self): + cmd = ("show ip igmp snooping querier vlan %d " % self._required_config['vlan_id']) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def _show_igmp_snooping_groups_config(self, multicast_ip_address): + cmd = ("show ip igmp snooping groups vlan %d group %s" % (self._required_config['vlan_id'], + multicast_ip_address)) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + igmp_vlan_config = self._show_igmp_vlan() + if igmp_vlan_config: + self._set_igmp_config(igmp_vlan_config) + + def generate_commands(self): + req_state = self._required_config.get('state', 'enabled') + self._generate_igmp_vlan_cmds(req_state) + + _mrouter = self._required_config.get('mrouter') + if _mrouter is not None: + self._generate_igmp_mrouter_cmds(_mrouter) + + _querier = self._required_config.get('querier') + if _querier is not None: + req_querier_state = _querier.get('state', 'enabled') + self._generate_igmp_querier_cmds(req_querier_state) + + req_querier_interval = _querier.get('interval') + if req_querier_interval is not None: + self._gen_querier_attr_commands("interval", req_querier_interval, "query-interval") + + req_querier_address = _querier.get('address') + if req_querier_address is not None: + self._gen_querier_attr_commands("address", req_querier_address, "address") + + _version = self._required_config.get('version') + if _version is not None: + self._generate_igmp_version_cmds(_version) + + _static_groups = self._required_config.get('static_groups') + if _static_groups is not None: + for static_group in _static_groups: + self._generate_igmp_static_groups_cmd(static_group) + + def _add_igmp_vlan_commands(self, req_state): + if req_state == 'enabled': + igmp_vlan_cmd = 'vlan %d ip igmp snooping' % self._required_config['vlan_id'] + else: + igmp_vlan_cmd = 'vlan %d no ip igmp snooping' % self._required_config['vlan_id'] + + self._commands.append(igmp_vlan_cmd) + + def _generate_igmp_vlan_cmds(self, req_state): + curr_state = self._current_config.get('state') + if curr_state != req_state: + self._add_igmp_vlan_commands(req_state) + + def _gen_querier_attr_commands(self, attr_name, req_attr_value, attr_cmd_name): + _curr_querier = self._current_config.get('querier') + curr_querier_val = _curr_querier.get(attr_name) + if req_attr_value != curr_querier_val: + self._commands.append('vlan %d ip igmp snooping querier %s %s' % (self._required_config['vlan_id'], + attr_cmd_name, req_attr_value)) + + def _add_querier_commands(self, req_querier_state): + if req_querier_state == 'enabled': + self._commands.append('vlan %d ip igmp snooping querier' % self._required_config['vlan_id']) + elif req_querier_state == 'disabled': + self._commands.append('vlan %d no ip igmp snooping querier' % ( + self._required_config['vlan_id'])) + + def _generate_igmp_querier_cmds(self, req_querier_state): + _curr_querier = self._current_config.get('querier') + curr_querier_state = _curr_querier.get('state') + if req_querier_state != curr_querier_state: + self._add_querier_commands(req_querier_state) + + def _generate_igmp_version_cmds(self, version): + _curr_version = self._current_config.get('version') + if version != _curr_version: + self._commands.append('vlan %d ip igmp snooping version %s' % ( + self._required_config['vlan_id'], version[1])) + + def _add_mrouter_commands(self, req_mrouter, curr_mrouter): + curr_state = curr_mrouter.get('state') + curr_interface = curr_mrouter.get('name') + req_state = req_mrouter.get('state') + req_interface = req_mrouter.get('name') + mrouter_interface = req_interface.replace("Eth", "ethernet ") + if curr_state == 'enabled' and req_state == 'disabled': + self._commands.append('vlan %d no ip igmp snooping mrouter interface ' + '%s' % (self._required_config['vlan_id'], mrouter_interface)) + elif curr_state == 'disabled' and req_state == 'enabled': + self._commands.append('vlan %d ip igmp snooping mrouter interface ' + '%s' % (self._required_config['vlan_id'], mrouter_interface)) + elif req_state == 'enabled' and curr_state == 'enabled' and req_interface != curr_interface: + self._commands.append('vlan %d ip igmp snooping mrouter interface ' + '%s' % (self._required_config['vlan_id'], mrouter_interface)) + + def _generate_igmp_mrouter_cmds(self, req_mrouter): + curr_mrouter = self._current_config.get('mrouter') + if curr_mrouter != req_mrouter: + self._add_mrouter_commands(req_mrouter, curr_mrouter) + + def _add_igmp_static_groups_cmd(self, req_name, req_multicast_ip_address, curr_names): + if curr_names is None: + self._commands.append('vlan %d ip igmp snooping static-group %s interface %s' % ( + self._required_config['vlan_id'], req_multicast_ip_address, req_name.replace('Eth', 'ethernet '))) + elif req_name.replace('E', 'e') not in curr_names: + self._commands.append('vlan %d ip igmp snooping static-group %s interface %s' % ( + self._required_config['vlan_id'], req_multicast_ip_address, req_name.replace('Eth', 'ethernet '))) + + def _add_igmp_static_groups_sources_cmd(self, req_sources, req_name, req_multicast_ip_address, curr_sources): + if curr_sources is None: + for source in req_sources: + self._commands.append('vlan %d ip igmp snooping static-group %s interface %s source %s' % ( + self._required_config['vlan_id'], req_multicast_ip_address, req_name.replace('Eth', 'ethernet '), + source)) + else: + curr_sources = curr_sources.get(req_name.replace('E', 'e')) + if curr_sources is None: + curr_sources = set([]) + else: + curr_sources = set(x.strip() for x in curr_sources.split(',')) + sources_to_add = set(req_sources) - set(curr_sources) + sources_to_remove = set(curr_sources) - set(req_sources) + if len(sources_to_add) != 0: + for source in sources_to_add: + self._commands.append('vlan %d ip igmp snooping static-group %s interface %s source %s' % ( + self._required_config['vlan_id'], req_multicast_ip_address, + req_name.replace('Eth', 'ethernet '), source)) + if len(sources_to_remove) != 0: + for source in sources_to_remove: + self._commands.append('vlan %d no ip igmp snooping static-group %s interface %s source %s' % ( + self._required_config['vlan_id'], req_multicast_ip_address, + req_name.replace('Eth', 'ethernet '), + source)) + + def _generate_igmp_static_groups_cmd(self, static_group): + req_multicast_ip_address = static_group.get('multicast_ip_address') + req_name = static_group.get('name') + req_sources = static_group.get('sources') + curr_static_groups = self._current_config.get('static_groups') + curr_static_group = curr_static_groups.get(req_multicast_ip_address) + curr_names = None + curr_sources = None + if curr_static_group is not None: + curr_names = curr_static_group.get('names') + curr_sources = curr_static_group.get('sources') + + self._add_igmp_static_groups_cmd(req_name, req_multicast_ip_address, curr_names) + if req_sources is not None: + self._add_igmp_static_groups_sources_cmd(req_sources, req_name, req_multicast_ip_address, curr_sources) + + +def main(): + """ main entry point for module execution + """ + OnyxIgmpVlanModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_interface.py new file mode 100644 index 00000000..6926d24c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_interface.py @@ -0,0 +1,497 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_interface +author: "Samer Deeb (@samerd)" +short_description: Manage Interfaces on Mellanox ONYX network devices +description: + - This module provides declarative management of Interfaces + on Mellanox ONYX network devices. +notes: +options: + name: + description: + - Name of the Interface. + required: true + description: + description: + - Description of Interface. + enabled: + description: + - Interface link status. + type: bool + speed: + description: + - Interface link speed. + choices: ['1G', '10G', '25G', '40G', '50G', '56G', '100G'] + mtu: + description: + - Maximum size of transmit packet. + aggregate: + description: List of Interfaces definitions. + duplex: + description: + - Interface link status + default: auto + choices: ['full', 'half', 'auto'] + tx_rate: + description: + - Transmit rate in bits per second (bps). + - This is state check parameter only. + - Supports conditionals, see L(Conditionals in Networking Modules,../network/user_guide/network_working_with_command_output.html) + rx_rate: + description: + - Receiver rate in bits per second (bps). + - This is state check parameter only. + - Supports conditionals, see L(Conditionals in Networking Modules,../network/user_guide/network_working_with_command_output.html) + delay: + description: + - Time in seconds to wait before checking for the operational state on + remote device. This wait is applicable for operational state argument + which are I(state) with values C(up)/C(down). + default: 10 + purge: + description: + - Purge Interfaces not defined in the aggregate parameter. + This applies only for logical interface. + default: false + type: bool + state: + description: + - State of the Interface configuration, C(up) means present and + operationally up and C(down) means present and operationally C(down) + default: present + choices: ['present', 'absent', 'up', 'down'] +''' + +EXAMPLES = """ +- name: Configure interface + onyx_interface: + name: Eth1/2 + description: test-interface + speed: 100G + mtu: 512 + +- name: Make interface up + onyx_interface: + name: Eth1/2 + enabled: True + +- name: Make interface down + onyx_interface: + name: Eth1/2 + enabled: False + +- name: Check intent arguments + onyx_interface: + name: Eth1/2 + state: up + +- name: Config + intent + onyx_interface: + name: Eth1/2 + enabled: False + state: down +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface ethernet 1/2 + - description test-interface + - mtu 512 + - exit +""" + +from copy import deepcopy +import re +from time import sleep + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import conditional +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import remove_default_spec + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import get_interfaces_config + + +class OnyxInterfaceModule(BaseOnyxModule): + IF_ETH_REGEX = re.compile(r"^Eth(\d+\/\d+|\d+\/\d+\/\d+)$") + IF_VLAN_REGEX = re.compile(r"^Vlan (\d+)$") + IF_LOOPBACK_REGEX = re.compile(r"^Loopback (\d+)$") + IF_PO_REGEX = re.compile(r"^Po(\d+)$") + + IF_TYPE_ETH = "ethernet" + IF_TYPE_LOOPBACK = "loopback" + IF_TYPE_VLAN = "vlan" + IF_TYPE_PO = "port-channel" + + IF_TYPE_MAP = { + IF_TYPE_ETH: IF_ETH_REGEX, + IF_TYPE_VLAN: IF_VLAN_REGEX, + IF_TYPE_LOOPBACK: IF_LOOPBACK_REGEX, + IF_TYPE_PO: IF_PO_REGEX + } + UNSUPPORTED_ATTRS = { + IF_TYPE_ETH: (), + IF_TYPE_VLAN: ('speed', 'rx_rate', 'tx_rate'), + IF_TYPE_LOOPBACK: ('speed', 'mtu', 'rx_rate', 'tx_rate'), + IF_TYPE_PO: ('speed', 'rx_rate', 'tx_rate'), + } + UNSUPPORTED_STATES = { + IF_TYPE_ETH: ('absent',), + IF_TYPE_VLAN: (), + IF_TYPE_LOOPBACK: ('up', 'down'), + IF_TYPE_PO: ('absent'), + } + + IF_MODIFIABLE_ATTRS = ('speed', 'description', 'mtu') + _interface_type = None + + @classmethod + def _get_element_spec(cls): + return dict( + name=dict(type='str'), + description=dict(), + speed=dict(choices=['1G', '10G', '25G', '40G', '50G', '56G', '100G']), + mtu=dict(type='int'), + enabled=dict(type='bool'), + delay=dict(default=10, type='int'), + state=dict(default='present', + choices=['present', 'absent', 'up', 'down']), + tx_rate=dict(), + rx_rate=dict(), + ) + + @classmethod + def _get_aggregate_spec(cls, element_spec): + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + return aggregate_spec + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + aggregate_spec = self._get_aggregate_spec(element_spec) + argument_spec = dict( + aggregate=dict(type='list', elements='dict', + options=aggregate_spec), + purge=dict(default=False, type='bool'), + ) + argument_spec.update(element_spec) + required_one_of = [['name', 'aggregate']] + mutually_exclusive = [['name', 'aggregate']] + self._module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True) + + def validate_purge(self, value): + if value: + self._module.fail_json( + msg='Purge is not supported!') + + def validate_duplex(self, value): + if value != 'auto': + self._module.fail_json( + msg='Duplex is not supported!') + + def _get_interface_type(self, if_name): + if_type = None + if_id = None + for interface_type, interface_regex in iteritems(self.IF_TYPE_MAP): + match = interface_regex.match(if_name) + if match: + if_type = interface_type + if_id = match.group(1) + break + return if_type, if_id + + def _set_if_type(self, params): + if_name = params['name'] + if_type, if_id = self._get_interface_type(if_name) + if not if_id: + self._module.fail_json( + msg='unsupported interface: %s' % if_name) + params['if_type'] = if_type + params['if_id'] = if_id + + def _check_supported_attrs(self, if_obj): + unsupported_attrs = self.UNSUPPORTED_ATTRS[self._interface_type] + for attr in unsupported_attrs: + val = if_obj[attr] + if val is not None: + self._module.fail_json( + msg='attribute %s is not supported for %s interface' % ( + attr, self._interface_type)) + req_state = if_obj['state'] + unsupported_states = self.UNSUPPORTED_STATES[self._interface_type] + if req_state in unsupported_states: + self._module.fail_json( + msg='%s state is not supported for %s interface' % ( + req_state, self._interface_type)) + + def _validate_interface_type(self): + for if_obj in self._required_config: + if_type = if_obj['if_type'] + if not self._interface_type: + self._interface_type = if_type + elif self._interface_type != if_type: + self._module.fail_json( + msg='Cannot aggregate interfaces from different types') + self._check_supported_attrs(if_obj) + + def get_required_config(self): + self._required_config = list() + module_params = self._module.params + aggregate = module_params.get('aggregate') + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module_params[key] + + self.validate_param_values(item, item) + req_item = item.copy() + self._set_if_type(req_item) + self._required_config.append(req_item) + else: + params = { + 'name': module_params['name'], + 'description': module_params['description'], + 'speed': module_params['speed'], + 'mtu': module_params['mtu'], + 'state': module_params['state'], + 'delay': module_params['delay'], + 'enabled': module_params['enabled'], + 'tx_rate': module_params['tx_rate'], + 'rx_rate': module_params['rx_rate'], + } + + self.validate_param_values(params) + self._set_if_type(params) + self._required_config.append(params) + self._validate_interface_type() + + @classmethod + def get_if_name(cls, item): + return cls.get_config_attr(item, "header") + + @classmethod + def get_admin_state(cls, item): + admin_state = cls.get_config_attr(item, "Admin state") + return str(admin_state).lower() == "enabled" + + @classmethod + def get_oper_state(cls, item): + oper_state = cls.get_config_attr(item, "Operational state") + if not oper_state: + oper_state = cls.get_config_attr(item, "State") + return str(oper_state).lower() + + @classmethod + def get_speed(cls, item): + speed = cls.get_config_attr(item, 'Actual speed') + if not speed: + return + try: + speed = int(speed.split()[0]) + return "%dG" % speed + except ValueError: + return None + + def _create_if_data(self, name, item): + regex = self.IF_TYPE_MAP[self._interface_type] + if_id = '' + match = regex.match(name) + if match: + if_id = match.group(1) + return dict( + name=name, + description=self.get_config_attr(item, 'Description'), + speed=self.get_speed(item), + mtu=self.get_mtu(item), + enabled=self.get_admin_state(item), + state=self.get_oper_state(item), + if_id=if_id) + + def _get_interfaces_config(self): + return get_interfaces_config(self._module, self._interface_type) + + def load_current_config(self): + self._os_version = self._get_os_version() + self._current_config = dict() + config = self._get_interfaces_config() + if not config: + return + if self._os_version < self.ONYX_API_VERSION: + for if_data in config: + if_name = self.get_if_name(if_data) + self._current_config[if_name] = self._create_if_data( + if_name, if_data) + else: + if_data = dict() + for if_config in config: + for if_name, if_attr in iteritems(if_config): + for config in if_attr: + for key, value in iteritems(config): + if_data[key] = value + self._current_config[if_name] = self._create_if_data( + if_name, if_data) + + def _generate_no_if_commands(self, req_if, curr_if): + if self._interface_type == self.IF_TYPE_ETH: + name = req_if['name'] + self._module.fail_json( + msg='cannot remove ethernet interface %s' % name) + if not curr_if: + return + if_id = req_if['if_id'] + if not if_id: + return + self._commands.append( + 'no interface %s %s' % (self._interface_type, if_id)) + + def _add_commands_to_interface(self, req_if, cmd_list): + if not cmd_list: + return + if_id = req_if['if_id'] + if not if_id: + return + self._commands.append( + 'interface %s %s' % (self._interface_type, if_id)) + self._commands.extend(cmd_list) + self._commands.append('exit') + + def _generate_if_commands(self, req_if, curr_if): + enabled = req_if['enabled'] + cmd_list = [] + for attr_name in self.IF_MODIFIABLE_ATTRS: + candidate = req_if.get(attr_name) + running = curr_if.get(attr_name) + if candidate != running: + if candidate: + cmd = attr_name + ' ' + str(candidate) + if self._interface_type == self.IF_TYPE_ETH and \ + attr_name in ('mtu', 'speed'): + cmd = cmd + ' ' + 'force' + cmd_list.append(cmd) + curr_enabled = curr_if.get('enabled', False) + if enabled is not None and enabled != curr_enabled: + cmd = 'shutdown' + if enabled: + cmd = "no %s" % cmd + cmd_list.append(cmd) + if cmd_list: + self._add_commands_to_interface(req_if, cmd_list) + + def generate_commands(self): + for req_if in self._required_config: + name = req_if['name'] + curr_if = self._current_config.get(name, {}) + if not curr_if and self._interface_type == self.IF_TYPE_ETH: + self._module.fail_json( + msg='could not find ethernet interface %s' % name) + continue + req_state = req_if['state'] + if req_state == 'absent': + self._generate_no_if_commands(req_if, curr_if) + else: + self._generate_if_commands(req_if, curr_if) + + def _get_interfaces_rates(self): + return get_interfaces_config(self._module, self._interface_type, + "rates") + + def _get_interfaces_status(self): + return get_interfaces_config(self._module, self._interface_type, + "status") + + def _check_state(self, name, want_state, statuses): + curr_if = statuses.get(name, {}) + if curr_if: + curr_if = curr_if[0] + curr_state = self.get_oper_state(curr_if).strip() + if curr_state is None or not conditional(want_state, curr_state): + return 'state eq(%s)' % want_state + + def check_declarative_intent_params(self, result): + failed_conditions = [] + delay_called = False + rates = None + statuses = None + for req_if in self._required_config: + want_state = req_if.get('state') + want_tx_rate = req_if.get('tx_rate') + want_rx_rate = req_if.get('rx_rate') + name = req_if['name'] + if want_state not in ('up', 'down') and not want_tx_rate and not \ + want_rx_rate: + continue + if not delay_called and result['changed']: + delay_called = True + delay = req_if['delay'] + if delay > 0: + sleep(delay) + if want_state in ('up', 'down'): + if statuses is None: + statuses = self._get_interfaces_status() or {} + cond = self._check_state(name, want_state, statuses) + if cond: + failed_conditions.append(cond) + if_rates = None + if want_tx_rate or want_rx_rate: + if not rates: + rates = self._get_interfaces_rates() + if_rates = rates.get(name) + if if_rates: + if_rates = if_rates[0] + if want_tx_rate: + have_tx_rate = None + if if_rates: + have_tx_rate = if_rates.get('egress rate') + if have_tx_rate: + have_tx_rate = have_tx_rate.split()[0] + if have_tx_rate is None or not \ + conditional(want_tx_rate, have_tx_rate.strip(), + cast=int): + failed_conditions.append('tx_rate ' + want_tx_rate) + + if want_rx_rate: + have_rx_rate = None + if if_rates: + have_rx_rate = if_rates.get('ingress rate') + if have_rx_rate: + have_rx_rate = have_rx_rate.split()[0] + if have_rx_rate is None or not \ + conditional(want_rx_rate, have_rx_rate.strip(), + cast=int): + failed_conditions.append('rx_rate ' + want_rx_rate) + + return failed_conditions + + +def main(): + """ main entry point for module execution + """ + OnyxInterfaceModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_l2_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_l2_interface.py new file mode 100644 index 00000000..8dc43ef5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_l2_interface.py @@ -0,0 +1,294 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_l2_interface +author: "Samer Deeb (@samerd)" +short_description: Manage Layer-2 interface on Mellanox ONYX network devices +description: + - This module provides declarative management of Layer-2 interface + on Mellanox ONYX network devices. +options: + name: + description: + - Name of the interface. + aggregate: + description: + - List of Layer-2 interface definitions. + mode: + description: + - Mode in which interface needs to be configured. + default: access + choices: ['access', 'trunk', 'hybrid'] + access_vlan: + description: + - Configure given VLAN in access port. + trunk_allowed_vlans: + description: + - List of allowed VLANs in a given trunk port. + state: + description: + - State of the Layer-2 Interface configuration. + default: present + choices: ['present', 'absent'] +''' + +EXAMPLES = """ +- name: Configure Layer-2 interface + onyx_l2_interface: + name: Eth1/1 + mode: access + access_vlan: 30 +- name: Remove Layer-2 interface configuration + onyx_l2_interface: + name: Eth1/1 + state: absent +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - interface ethernet 1/1 + - switchport mode access + - switchport access vlan 30 +""" +from copy import deepcopy +import re + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import remove_default_spec + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import get_interfaces_config + + +class OnyxL2InterfaceModule(BaseOnyxModule): + IFNAME_REGEX = re.compile(r"^.*(Eth\d+\/\d+|Mpo\d+|Po\d+)") + + @classmethod + def _get_element_spec(cls): + return dict( + name=dict(), + access_vlan=dict(type='int'), + trunk_allowed_vlans=dict(type='list', elements='int'), + state=dict(default='present', + choices=['present', 'absent']), + mode=dict(default='access', + choices=['access', 'hybrid', 'trunk']), + ) + + @classmethod + def _get_aggregate_spec(cls, element_spec): + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + return aggregate_spec + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + aggregate_spec = self._get_aggregate_spec(element_spec) + argument_spec = dict( + aggregate=dict(type='list', elements='dict', + options=aggregate_spec), + ) + argument_spec.update(element_spec) + required_one_of = [['name', 'aggregate']] + mutually_exclusive = [['name', 'aggregate']] + self._module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True) + + def get_required_config(self): + self._required_config = list() + module_params = self._module.params + aggregate = module_params.get('aggregate') + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module_params[key] + self.validate_param_values(item, item) + req_item = item.copy() + self._required_config.append(req_item) + else: + params = { + 'name': module_params['name'], + 'access_vlan': module_params['access_vlan'], + 'trunk_allowed_vlans': module_params['trunk_allowed_vlans'], + 'mode': module_params['mode'], + 'state': module_params['state'], + } + self.validate_param_values(params) + self._required_config.append(params) + + def validate_access_vlan(self, value): + if value and not 1 <= int(value) <= 4094: + self._module.fail_json(msg='vlan id must be between 1 and 4094') + + @classmethod + def get_allowed_vlans(cls, if_data): + allowed_vlans = cls.get_config_attr(if_data, 'Allowed vlans') + interface_allwoed_vlans = [] + if allowed_vlans: + vlans = [x.strip() for x in allowed_vlans.split(',')] + for vlan in vlans: + if '-' not in vlan: + interface_allwoed_vlans.append(int(vlan)) + else: + vlan_range = vlan.split("-") + min_number = int(vlan_range[0].strip()) + max_number = int(vlan_range[1].strip()) + vlan_list = range(min_number, max_number + 1) + interface_allwoed_vlans.extend(vlan_list) + return interface_allwoed_vlans + + @classmethod + def get_access_vlan(cls, if_data): + access_vlan = cls.get_config_attr(if_data, 'Access vlan') + if access_vlan: + try: + return int(access_vlan) + except ValueError: + return None + + def _create_switchport_data(self, if_name, if_data): + if self._os_version >= self.ONYX_API_VERSION: + if_data = if_data[0] + + return { + 'name': if_name, + 'mode': self.get_config_attr(if_data, 'Mode'), + 'access_vlan': self.get_access_vlan(if_data), + 'trunk_allowed_vlans': self.get_allowed_vlans(if_data) + } + + def _get_switchport_config(self): + return get_interfaces_config(self._module, 'switchport') + + def load_current_config(self): + # called in base class in run function + self._os_version = self._get_os_version() + self._current_config = dict() + switchports_config = self._get_switchport_config() + if not switchports_config: + return + for if_name, if_data in iteritems(switchports_config): + self._current_config[if_name] = \ + self._create_switchport_data(if_name, if_data) + + def _get_switchport_command_name(self, if_name): + if if_name.startswith('Eth'): + return if_name.replace("Eth", "ethernet ") + if if_name.startswith('Po'): + return if_name.replace("Po", "port-channel ") + if if_name.startswith('Mpo'): + return if_name.replace("Mpo", "mlag-port-channel ") + self._module.fail_json( + msg='invalid interface name: %s' % if_name) + + def _add_interface_commands(self, if_name, commands): + if_cmd_name = self._get_switchport_command_name(if_name) + self._commands.append("interface %s" % if_cmd_name) + self._commands.extend(commands) + self._commands.append('exit') + + def _generate_no_switchport_commands(self, if_name): + commands = ['no switchport force'] + self._add_interface_commands(if_name, commands) + + def _generate_switchport_commands(self, if_name, req_conf): + commands = [] + curr_conf = self._current_config.get(if_name, {}) + curr_mode = curr_conf.get('mode') + req_mode = req_conf.get('mode') + if req_mode != curr_mode: + commands.append('switchport mode %s' % req_mode) + curr_access_vlan = curr_conf.get('access_vlan') + req_access_vlan = req_conf.get('access_vlan') + if curr_access_vlan != req_access_vlan and req_access_vlan: + commands.append('switchport access vlan %s' % req_access_vlan) + curr_trunk_vlans = curr_conf.get('trunk_allowed_vlans') or set() + if curr_trunk_vlans: + curr_trunk_vlans = set(curr_trunk_vlans) + req_trunk_vlans = req_conf.get('trunk_allowed_vlans') or set() + if req_trunk_vlans: + req_trunk_vlans = set(req_trunk_vlans) + if req_mode != 'access' and curr_trunk_vlans != req_trunk_vlans: + added_vlans = req_trunk_vlans - curr_trunk_vlans + for vlan_id in added_vlans: + commands.append('switchport %s allowed-vlan add %s' % + (req_mode, vlan_id)) + removed_vlans = curr_trunk_vlans - req_trunk_vlans + for vlan_id in removed_vlans: + commands.append('switchport %s allowed-vlan remove %s' % + (req_mode, vlan_id)) + + if commands: + self._add_interface_commands(if_name, commands) + + def generate_commands(self): + for req_conf in self._required_config: + state = req_conf['state'] + if_name = req_conf['name'] + if state == 'absent': + if if_name in self._current_config: + self._generate_no_switchport_commands(if_name) + else: + self._generate_switchport_commands(if_name, req_conf) + + def _generate_vlan_commands(self, vlan_id, req_conf): + curr_vlan = self._current_config.get(vlan_id, {}) + if not curr_vlan: + cmd = "vlan " + vlan_id + self._commands.append("vlan %s" % vlan_id) + self._commands.append("exit") + vlan_name = req_conf['vlan_name'] + if vlan_name: + if vlan_name != curr_vlan.get('vlan_name'): + self._commands.append("vlan %s name %s" % (vlan_id, vlan_name)) + curr_members = set(curr_vlan.get('interfaces', [])) + req_members = req_conf['interfaces'] + mode = req_conf['mode'] + for member in req_members: + if member in curr_members: + continue + if_name = self.get_switchport_command_name(member) + cmd = "interface %s switchport mode %s" % (if_name, mode) + self._commands.append(cmd) + cmd = "interface %s switchport %s allowed-vlan add %s" % ( + if_name, mode, vlan_id) + self._commands.append(cmd) + req_members = set(req_members) + for member in curr_members: + if member in req_members: + continue + if_name = self.get_switchport_command_name(member) + cmd = "interface %s switchport %s allowed-vlan remove %s" % ( + if_name, mode, vlan_id) + self._commands.append(cmd) + + +def main(): + """ main entry point for module execution + """ + OnyxL2InterfaceModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_l3_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_l3_interface.py new file mode 100644 index 00000000..c28c84fc --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_l3_interface.py @@ -0,0 +1,297 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_l3_interface +author: "Samer Deeb (@samerd)" +short_description: Manage L3 interfaces on Mellanox ONYX network devices +description: + - This module provides declarative management of L3 interfaces + on Mellanox ONYX network devices. +options: + name: + description: + - Name of the L3 interface. + ipv4: + description: + - IPv4 of the L3 interface. + ipv6: + description: + - IPv6 of the L3 interface (not supported for now). + aggregate: + description: List of L3 interfaces definitions + purge: + description: + - Purge L3 interfaces not defined in the I(aggregate) parameter. + default: false + type: bool + state: + description: + - State of the L3 interface configuration. + default: present + choices: ['present', 'absent'] +''' + +EXAMPLES = """ +- name: Set Eth1/1 IPv4 address + onyx_l3_interface: + name: Eth1/1 + ipv4: 192.168.0.1/24 + +- name: Remove Eth1/1 IPv4 address + onyx_l3_interface: + name: Eth1/1 + state: absent + +- name: Set IP addresses on aggregate + onyx_l3_interface: + aggregate: + - { name: Eth1/1, ipv4: 192.168.2.10/24 } + - { name: Eth1/2, ipv4: 192.168.3.10/24 } + +- name: Remove IP addresses on aggregate + onyx_l3_interface: + aggregate: + - { name: Eth1/1, ipv4: 192.168.2.10/24 } + - { name: Eth1/2, ipv4: 192.168.3.10/24 } + state: absent +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - interfaces ethernet 1/1 ip address 192.168.0.1 /24 +""" +import re +from copy import deepcopy + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import remove_default_spec + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import get_interfaces_config + + +class OnyxL3InterfaceModule(BaseOnyxModule): + IF_ETH_REGEX = re.compile(r"^Eth(\d+\/\d+|Eth\d+\/\d+\d+)$") + IF_VLAN_REGEX = re.compile(r"^Vlan (\d+)$") + IF_LOOPBACK_REGEX = re.compile(r"^Loopback (\d+)$") + + IF_TYPE_ETH = "ethernet" + IF_TYPE_LOOPBACK = "loopback" + IF_TYPE_VLAN = "vlan" + + IF_TYPE_MAP = { + IF_TYPE_ETH: IF_ETH_REGEX, + IF_TYPE_VLAN: IF_VLAN_REGEX, + IF_TYPE_LOOPBACK: IF_LOOPBACK_REGEX, + } + + IP_ADDR_ATTR_MAP = { + IF_TYPE_ETH: 'IP Address', + IF_TYPE_VLAN: 'Internet Address', + IF_TYPE_LOOPBACK: 'Internet Address', + } + + _purge = False + + @classmethod + def _get_element_spec(cls): + return dict( + name=dict(type='str'), + ipv4=dict(type='str'), + ipv6=dict(type='str'), + state=dict(default='present', + choices=['present', 'absent', 'enabled', 'disabled']), + ) + + @classmethod + def _get_aggregate_spec(cls, element_spec): + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + return aggregate_spec + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + aggregate_spec = self._get_aggregate_spec(element_spec) + argument_spec = dict( + aggregate=dict(type='list', elements='dict', + options=aggregate_spec), + purge=dict(default=False, type='bool'), + ) + argument_spec.update(element_spec) + required_one_of = [['name', 'aggregate']] + mutually_exclusive = [['name', 'aggregate']] + self._module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True) + + def _get_interface_type(self, if_name): + if_type = None + if_id = None + for interface_type, interface_regex in iteritems(self.IF_TYPE_MAP): + match = interface_regex.match(if_name) + if match: + if_type = interface_type + if_id = match.group(1) + break + return if_type, if_id + + def _set_if_type(self, params): + if_name = params['name'] + if_type, if_id = self._get_interface_type(if_name) + if not if_id: + self._module.fail_json( + msg='unsupported interface: %s' % if_name) + params['if_type'] = if_type + params['if_id'] = if_id + + def get_required_config(self): + self._required_config = list() + module_params = self._module.params + aggregate = module_params.get('aggregate') + self._purge = module_params.get('purge', False) + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module_params[key] + self.validate_param_values(item, item) + req_item = item.copy() + self._set_if_type(req_item) + self._required_config.append(req_item) + else: + params = { + 'name': module_params['name'], + 'ipv4': module_params['ipv4'], + 'ipv6': module_params['ipv6'], + 'state': module_params['state'], + } + self.validate_param_values(params) + self._set_if_type(params) + self._required_config.append(params) + + def _get_interfaces_config(self, interface_type): + return get_interfaces_config(self._module, interface_type) + + def _parse_interfaces_config(self, if_type, if_config): + if self._os_version < self.ONYX_API_VERSION: + for if_data in if_config: + if_name = self.get_config_attr(if_data, 'header') + self._get_if_attributes(if_type, if_name, if_data) + else: + for if_config_item in if_config: + for if_name, if_data in iteritems(if_config_item): + if_data = if_data[0] + self._get_if_attributes(if_type, if_name, if_data) + + def _get_if_attributes(self, if_type, if_name, if_data): + ipaddr_attr = self.IP_ADDR_ATTR_MAP[if_type] + regex = self.IF_TYPE_MAP[if_type] + match = regex.match(if_name) + if not match: + return + ipv4 = self.get_config_attr(if_data, ipaddr_attr) + if ipv4: + ipv4 = ipv4.replace(' ', '') + ipv6 = self.get_config_attr(if_data, 'IPv6 address(es)') + if ipv6: + ipv6 = ipv6.replace('[primary]', '') + ipv6 = ipv6.strip() + if_id = match.group(1) + switchport = self.get_config_attr(if_data, 'Switchport mode') + if_obj = { + 'name': if_name, + 'if_id': if_id, + 'if_type': if_type, + 'ipv4': ipv4, + 'ipv6': ipv6, + 'switchport': switchport, + } + self._current_config[if_name] = if_obj + + def load_current_config(self): + # called in base class in run function + self._os_version = self._get_os_version() + self._current_config = dict() + if_types = set([if_obj['if_type'] for if_obj in self._required_config]) + for if_type in if_types: + if_config = self._get_interfaces_config(if_type) + if not if_config: + continue + self._parse_interfaces_config(if_type, if_config) + + def _generate_no_ip_commands(self, req_conf, curr_conf): + curr_ip = curr_conf.get('ipv4') + if_type = req_conf['if_type'] + if_id = req_conf['if_id'] + if curr_ip: + cmd = "interface %s %s no ip address" % (if_type, if_id) + self._commands.append(cmd) + curr_ipv6 = curr_conf.get('ipv6') + if curr_ipv6: + cmd = "interface %s %s no ipv6 address %s" % ( + if_type, if_id, curr_ipv6) + self._commands.append(cmd) + + def _generate_ip_commands(self, req_conf, curr_conf): + curr_ipv4 = curr_conf.get('ipv4') + req_ipv4 = req_conf.get('ipv4') + curr_ipv6 = curr_conf.get('ipv6') + req_ipv6 = req_conf.get('ipv6') + if_type = req_conf['if_type'] + if_id = req_conf['if_id'] + switchport = curr_conf.get('switchport') + if switchport: + cmd = "interface %s %s no switchport force" % (if_type, if_id) + self._commands.append(cmd) + if curr_ipv4 != req_ipv4: + cmd = "interface %s %s ip address %s" % (if_type, if_id, req_ipv4) + self._commands.append(cmd) + if curr_ipv6 != req_ipv6: + cmd = "interface %s %s ipv6 address %s" % ( + if_type, if_id, req_ipv6) + self._commands.append(cmd) + + def generate_commands(self): + req_interfaces = set() + for req_conf in self._required_config: + state = req_conf['state'] + if_name = req_conf['name'] + curr_conf = self._current_config.get(if_name, {}) + if state == 'absent': + self._generate_no_ip_commands(req_conf, curr_conf) + else: + req_interfaces.add(if_name) + self._generate_ip_commands(req_conf, curr_conf) + if self._purge: + for if_name, curr_conf in iteritems(self._current_config): + if if_name not in req_interfaces: + self._generate_no_ip_commands(req_conf, curr_conf) + + +def main(): + """ main entry point for module execution + """ + OnyxL3InterfaceModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_linkagg.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_linkagg.py new file mode 100644 index 00000000..7ed02a7e --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_linkagg.py @@ -0,0 +1,349 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_linkagg +author: "Samer Deeb (@samerd)" +short_description: Manage link aggregation groups on Mellanox ONYX network devices +description: + - This module provides declarative management of link aggregation groups + on Mellanox ONYX network devices. +options: + name: + description: + - Name of the link aggregation group. + required: true + mode: + description: + - Mode of the link aggregation group. A value of C(on) will enable LACP. + C(active) configures the link to actively information about the state of the link, + or it can be configured in C(passive) mode ie. send link state information only when + received them from another link. + default: on + choices: ['on', 'active', 'passive'] + members: + description: + - List of members interfaces of the link aggregation group. The value can be + single interface or list of interfaces. + required: true + aggregate: + description: List of link aggregation definitions. + purge: + description: + - Purge link aggregation groups not defined in the I(aggregate) parameter. + default: false + type: bool + state: + description: + - State of the link aggregation group. + default: present + choices: ['present', 'absent', 'up', 'down'] +''' + +EXAMPLES = """ +- name: Configure link aggregation group + onyx_linkagg: + name: Po1 + members: + - Eth1/1 + - Eth1/2 + +- name: Remove configuration + onyx_linkagg: + name: Po1 + state: absent + +- name: Create aggregate of linkagg definitions + onyx_linkagg: + aggregate: + - { name: Po1, members: [Eth1/1] } + - { name: Po2, members: [Eth1/2] } + +- name: Remove aggregate of linkagg definitions + onyx_linkagg: + aggregate: + - name: Po1 + - name: Po2 + state: absent +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - interface port-channel 1 + - exit + - interface ethernet 1/1 channel-group 1 mode on + - interface ethernet 1/2 channel-group 1 mode on +""" + +import re +from copy import deepcopy + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import remove_default_spec +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import get_interfaces_config + + +class OnyxLinkAggModule(BaseOnyxModule): + LAG_ID_REGEX = re.compile(r"^\d+ (Po\d+|Mpo\d+)\(([A-Z])\)$") + LAG_NAME_REGEX = re.compile(r"^(Po|Mpo)(\d+)$") + IF_NAME_REGEX = re.compile(r"^(Eth\d+\/\d+|Eth\d+\/\d+\/\d+)(.*)$") + PORT_CHANNEL = 'port-channel' + CHANNEL_GROUP = 'channel-group' + MLAG_PORT_CHANNEL = 'mlag-port-channel' + MLAG_CHANNEL_GROUP = 'mlag-channel-group' + MLAG_SUMMARY = 'MLAG Port-Channel Summary' + + LAG_TYPE = 'lag' + MLAG_TYPE = 'mlag' + + IF_TYPE_MAP = dict( + lag=PORT_CHANNEL, + mlag=MLAG_PORT_CHANNEL + ) + + _purge = False + + @classmethod + def _get_element_spec(cls): + return dict( + name=dict(type='str'), + members=dict(type='list'), + mode=dict(default='on', choices=['active', 'on', 'passive']), + state=dict(default='present', choices=['present', 'absent']), + ) + + @classmethod + def _get_aggregate_spec(cls, element_spec): + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + return aggregate_spec + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + aggregate_spec = self._get_aggregate_spec(element_spec) + argument_spec = dict( + aggregate=dict(type='list', elements='dict', + options=aggregate_spec), + purge=dict(default=False, type='bool'), + ) + argument_spec.update(element_spec) + required_one_of = [['name', 'aggregate']] + mutually_exclusive = [['name', 'aggregate']] + self._module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True) + + def _get_lag_type(self, lag_name): + match = self.LAG_NAME_REGEX.match(lag_name) + if match: + prefix = match.group(1) + if prefix == "Po": + return self.LAG_TYPE + return self.MLAG_TYPE + self._module.fail_json( + msg='invalid lag name: %s, lag name should start with Po or ' + 'Mpo' % lag_name) + + def get_required_config(self): + self._required_config = list() + module_params = self._module.params + aggregate = module_params.get('aggregate') + self._purge = module_params.get('purge', False) + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module_params[key] + self.validate_param_values(item, item) + req_item = item.copy() + req_item['type'] = self._get_lag_type(req_item['name']) + self._required_config.append(req_item) + else: + params = { + 'name': module_params['name'], + 'state': module_params['state'], + 'members': module_params['members'], + 'mode': module_params['mode'], + 'type': self._get_lag_type(module_params['name']), + } + self.validate_param_values(params) + self._required_config.append(params) + + @classmethod + def _extract_lag_name(cls, header): + match = cls.LAG_ID_REGEX.match(header) + state = None + lag_name = None + if match: + state = 'up' if match.group(2) == 'U' else 'down' + lag_name = match.group(1) + return lag_name, state + + @classmethod + def _extract_if_name(cls, member): + match = cls.IF_NAME_REGEX.match(member) + if match: + return match.group(1) + + @classmethod + def _extract_lag_members(cls, lag_type, lag_item): + members = "" + if lag_type == cls.LAG_TYPE: + members = cls.get_config_attr(lag_item, "Member Ports") + else: + for attr_name, attr_val in iteritems(lag_item): + if attr_name.startswith('Local Ports'): + members = attr_val + return [cls._extract_if_name(member) for member in members.split()] + + def _get_port_channels(self, if_type): + return get_interfaces_config(self._module, if_type, flags="summary") + + def _parse_port_channels_summary(self, lag_type, lag_summary): + if lag_type == self.MLAG_TYPE: + if self._os_version >= self.ONYX_API_VERSION: + found_summary = False + for summary_item in lag_summary: + if self.MLAG_SUMMARY in summary_item: + lag_summary = summary_item[self.MLAG_SUMMARY] + if lag_summary: + lag_summary = lag_summary[0] + else: + lag_summary = dict() + found_summary = True + break + if not found_summary: + lag_summary = dict() + else: + lag_summary = lag_summary.get(self.MLAG_SUMMARY, dict()) + for lag_key, lag_data in iteritems(lag_summary): + lag_name, state = self._extract_lag_name(lag_key) + if not lag_name: + continue + lag_members = self._extract_lag_members(lag_type, lag_data[0]) + lag_obj = dict( + name=lag_name, + state=state, + members=lag_members + ) + self._current_config[lag_name] = lag_obj + + def load_current_config(self): + self._current_config = dict() + self._os_version = self._get_os_version() + lag_types = set([lag_obj['type'] for lag_obj in self._required_config]) + for lag_type in lag_types: + if_type = self.IF_TYPE_MAP[lag_type] + lag_summary = self._get_port_channels(if_type) + if lag_summary: + self._parse_port_channels_summary(lag_type, lag_summary) + + def _get_interface_command_suffix(self, if_name): + if if_name.startswith('Eth'): + return if_name.replace("Eth", "ethernet ") + if if_name.startswith('Po'): + return if_name.replace("Po", "port-channel ") + if if_name.startswith('Mpo'): + return if_name.replace("Mpo", "mlag-port-channel ") + self._module.fail_json( + msg='invalid interface name: %s' % if_name) + + def _get_channel_group(self, if_name): + if if_name.startswith('Po'): + return if_name.replace("Po", "channel-group ") + if if_name.startswith('Mpo'): + return if_name.replace("Mpo", "mlag-channel-group ") + self._module.fail_json( + msg='invalid interface name: %s' % if_name) + + def _generate_no_linkagg_commands(self, lag_name): + suffix = self._get_interface_command_suffix(lag_name) + command = 'no interface %s' % suffix + self._commands.append(command) + + def _generate_linkagg_commands(self, lag_name, req_lag): + curr_lag = self._current_config.get(lag_name, {}) + if not curr_lag: + suffix = self._get_interface_command_suffix(lag_name) + self._commands.append("interface %s" % suffix) + self._commands.append("exit") + curr_members = set(curr_lag.get('members', [])) + req_members = set(req_lag.get('members') or []) + + lag_mode = req_lag['mode'] + if req_members != curr_members: + channel_group = self._get_channel_group(lag_name) + channel_group_type = channel_group.split()[0] + for member in req_members: + if member in curr_members: + continue + suffix = self._get_interface_command_suffix(member) + self._commands.append( + "interface %s %s mode %s" % + (suffix, channel_group, lag_mode)) + for member in curr_members: + if member in req_members: + continue + suffix = self._get_interface_command_suffix(member) + self._commands.append( + "interface %s no %s" % (suffix, channel_group_type)) + req_state = req_lag.get('state') + if req_state in ('up', 'down'): + curr_state = curr_lag.get('state') + if curr_state != req_state: + suffix = self._get_interface_command_suffix(lag_name) + cmd = "interface %s " % suffix + if req_state == 'up': + cmd += 'no shutdown' + else: + cmd += 'shutdown' + self._commands.append(cmd) + + def generate_commands(self): + req_lags = set() + for req_conf in self._required_config: + state = req_conf['state'] + lag_name = req_conf['name'] + if state == 'absent': + if lag_name in self._current_config: + self._generate_no_linkagg_commands(lag_name) + else: + req_lags.add(lag_name) + self._generate_linkagg_commands(lag_name, req_conf) + if self._purge: + for lag_name in self._current_config: + if lag_name not in req_lags: + self._generate_no_linkagg_commands(lag_name) + + def check_declarative_intent_params(self, result): + pass + + +def main(): + """ main entry point for module execution + """ + OnyxLinkAggModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_lldp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_lldp.py new file mode 100644 index 00000000..c7f6fe88 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_lldp.py @@ -0,0 +1,112 @@ +#!/usr/bin/python + +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_lldp +author: "Samer Deeb (@samerd)" +short_description: Manage LLDP configuration on Mellanox ONYX network devices +description: + - This module provides declarative management of LLDP service configuration + on Mellanox ONYX network devices. +options: + state: + description: + - State of the LLDP protocol configuration. + default: present + choices: ['present', 'absent'] +''' + +EXAMPLES = """ +- name: Enable LLDP protocol + onyx_lldp: + state: present + +- name: Disable LLDP protocol + onyx_lldp: + state: lldp +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - lldp +""" + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxLldpModule(BaseOnyxModule): + LLDP_ENTRY = 'LLDP' + SHOW_LLDP_CMD = 'show lldp local' + + @classmethod + def _get_element_spec(cls): + return dict( + state=dict(default='present', choices=['present', 'absent']), + ) + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + self._required_config = dict() + module_params = self._module.params + params = { + 'state': module_params['state'], + } + + self.validate_param_values(params) + self._required_config.update(params) + + def _get_lldp_config(self): + return show_cmd(self._module, self.SHOW_LLDP_CMD) + + def load_current_config(self): + self._current_config = dict() + state = 'absent' + config = self._get_lldp_config() or dict() + for item in config: + lldp_state = item.get(self.LLDP_ENTRY) + if lldp_state is not None: + if lldp_state == 'enabled': + state = 'present' + break + self._current_config['state'] = state + + def generate_commands(self): + req_state = self._required_config['state'] + curr_state = self._current_config['state'] + if curr_state != req_state: + cmd = 'lldp' + if req_state == 'absent': + cmd = 'no %s' % cmd + self._commands.append(cmd) + + +def main(): + """ main entry point for module execution + """ + OnyxLldpModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_lldp_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_lldp_interface.py new file mode 100644 index 00000000..795a5286 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_lldp_interface.py @@ -0,0 +1,224 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_lldp_interface +author: "Samer Deeb (@samerd)" +short_description: Manage LLDP interfaces configuration on Mellanox ONYX network devices +description: + - This module provides declarative management of LLDP interfaces + configuration on Mellanox ONYX network devices. +options: + name: + description: + - Name of the interface LLDP should be configured on. + aggregate: + description: List of interfaces LLDP should be configured on. + purge: + description: + - Purge interfaces not defined in the aggregate parameter. + type: bool + default: false + state: + description: + - State of the LLDP configuration. + default: present + choices: ['present', 'absent', 'enabled', 'disabled'] +''' + +EXAMPLES = """ +- name: Configure LLDP on specific interfaces + onyx_lldp_interface: + name: Eth1/1 + state: present + +- name: Disable LLDP on specific interfaces + onyx_lldp_interface: + name: Eth1/1 + state: disabled + +- name: Enable LLDP on specific interfaces + onyx_lldp_interface: + name: Eth1/1 + state: enabled + +- name: Delete LLDP on specific interfaces + onyx_lldp_interface: + name: Eth1/1 + state: absent + +- name: Create aggregate of LLDP interface configurations + onyx_lldp_interface: + aggregate: + - { name: Eth1/1 } + - { name: Eth1/2 } + state: present + +- name: Delete aggregate of LLDP interface configurations + onyx_lldp_interface: + aggregate: + - { name: Eth1/1 } + - { name: Eth1/2 } + state: absent +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - interface ethernet 1/1 lldp transmit + - interface ethernet 1/1 lldp receive +""" +import re +from copy import deepcopy + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import remove_default_spec + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxLldpInterfaceModule(BaseOnyxModule): + IF_NAME_REGEX = re.compile(r"^(Eth\d+\/\d+|Eth\d+\/\d+\d+)$") + _purge = False + + @classmethod + def _get_element_spec(cls): + return dict( + name=dict(type='str'), + state=dict(default='present', + choices=['present', 'absent', 'enabled', 'disabled']), + ) + + @classmethod + def _get_aggregate_spec(cls, element_spec): + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + return aggregate_spec + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + aggregate_spec = self._get_aggregate_spec(element_spec) + argument_spec = dict( + aggregate=dict(type='list', elements='dict', + options=aggregate_spec), + purge=dict(default=False, type='bool'), + ) + argument_spec.update(element_spec) + required_one_of = [['name', 'aggregate']] + mutually_exclusive = [['name', 'aggregate']] + self._module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True) + + def get_required_config(self): + self._required_config = list() + module_params = self._module.params + aggregate = module_params.get('aggregate') + self._purge = module_params.get('purge', False) + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module_params[key] + self.validate_param_values(item, item) + req_item = item.copy() + self._required_config.append(req_item) + else: + params = { + 'name': module_params['name'], + 'state': module_params['state'], + } + self.validate_param_values(params) + self._required_config.append(params) + + def _create_if_lldp_data(self, if_name, if_lldp_data): + return { + 'name': if_name, + 'receive': self.get_config_attr(if_lldp_data, 'Receive'), + 'transmit': self.get_config_attr(if_lldp_data, 'Transmit'), + } + + def _get_lldp_config(self): + return show_cmd(self._module, "show lldp interfaces") + + def load_current_config(self): + # called in base class in run function + self._current_config = dict() + lldp_config = self._get_lldp_config() + if not lldp_config: + return + for if_name, if_lldp_data in iteritems(lldp_config): + match = self.IF_NAME_REGEX.match(if_name) + if not match: + continue + if if_lldp_data: + if_lldp_data = if_lldp_data[0] + self._current_config[if_name] = \ + self._create_if_lldp_data(if_name, if_lldp_data) + + def _get_interface_cmd_name(self, if_name): + return if_name.replace("Eth", "ethernet ") + + def _add_if_lldp_commands(self, if_name, flag, enable): + cmd_prefix = "interface %s " % self._get_interface_cmd_name(if_name) + lldp_cmd = "lldp %s" % flag + if not enable: + lldp_cmd = 'no %s' % lldp_cmd + self._commands.append(cmd_prefix + lldp_cmd) + + def _gen_lldp_commands(self, if_name, req_state, curr_conf): + curr_receive = curr_conf.get('receive') + curr_transmit = curr_conf.get('transmit') + enable = (req_state == 'Enabled') + if curr_receive != req_state: + flag = 'receive' + self._add_if_lldp_commands(if_name, flag, enable) + if curr_transmit != req_state: + flag = 'transmit' + self._add_if_lldp_commands(if_name, flag, enable) + + def generate_commands(self): + req_interfaces = set() + for req_conf in self._required_config: + state = req_conf['state'] + if_name = req_conf['name'] + if state in ('absent', 'disabled'): + req_state = 'Disabled' + else: + req_interfaces.add(if_name) + req_state = 'Enabled' + curr_conf = self._current_config.get(if_name, {}) + self._gen_lldp_commands(if_name, req_state, curr_conf) + if self._purge: + for if_name, curr_conf in iteritems(self._current_config): + if if_name not in req_interfaces: + req_state = 'Disabled' + self._gen_lldp_commands(if_name, req_state, curr_conf) + + +def main(): + """ main entry point for module execution + """ + OnyxLldpInterfaceModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_magp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_magp.py new file mode 100644 index 00000000..94189cd3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_magp.py @@ -0,0 +1,231 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_magp +author: "Samer Deeb (@samerd)" +short_description: Manage MAGP protocol on Mellanox ONYX network devices +description: + - This module provides declarative management of MAGP protocol on vlan + interface of Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.4000 +options: + magp_id: + description: + - "MAGP instance number 1-255" + required: true + interface: + description: + - VLAN Interface name. + required: true + state: + description: + - MAGP state. + default: present + choices: ['present', 'absent', 'enabled', 'disabled'] + router_ip: + description: + - MAGP router IP address. + router_mac: + description: + - MAGP router MAC address. +''' + +EXAMPLES = """ +- name: Run add vlan interface with magp + onyx_magp: + magp_id: 103 + router_ip: 192.168.8.2 + router_mac: AA:1B:2C:3D:4E:5F + interface: Vlan 1002 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface vlan 234 magp 103 + - exit + - interface vlan 234 magp 103 ip virtual-router address 1.2.3.4 +""" +import re + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxMagpModule(BaseOnyxModule): + IF_VLAN_REGEX = re.compile(r"^Vlan (\d+)$") + + @classmethod + def _get_element_spec(cls): + return dict( + magp_id=dict(type='int', required=True), + state=dict(default='present', + choices=['present', 'absent', 'enabled', 'disabled']), + interface=dict(required=True), + router_ip=dict(), + router_mac=dict(), + ) + + def init_module(self): + """ Ansible module initialization + """ + element_spec = self._get_element_spec() + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def validate_magp_id(self, value): + if value and not 1 <= int(value) <= 255: + self._module.fail_json(msg='magp id must be between 1 and 255') + + def get_required_config(self): + module_params = self._module.params + interface = module_params['interface'] + match = self.IF_VLAN_REGEX.match(interface) + vlan_id = 0 + if match: + vlan_id = int(match.group(1)) + else: + self._module.fail_json( + msg='Invalid interface name: should be "Vlan <vlan_id>"') + + self._required_config = dict( + magp_id=module_params['magp_id'], + state=module_params['state'], + vlan_id=vlan_id, + router_ip=module_params['router_ip'], + router_mac=module_params['router_mac']) + self.validate_param_values(self._required_config) + + @classmethod + def get_magp_id(cls, item): + header = cls.get_config_attr(item, "header") + return int(header.split()[1]) + + def _create_magp_instance_data(self, magp_id, item): + vlan_id = int(self.get_config_attr(item, "Interface vlan")) + state = self.get_config_attr(item, "Admin state").lower() + return dict( + magp_id=magp_id, + state=state, + vlan_id=vlan_id, + router_ip=self.get_config_attr(item, "Virtual IP"), + router_mac=self.get_config_attr(item, "Virtual MAC")) + + def _update_magp_data(self, magp_data): + if self._os_version >= self.ONYX_API_VERSION: + for magp_config in magp_data: + for magp_name, data in iteritems(magp_config): + magp_id = int(magp_name.replace('MAGP ', '')) + self._current_config[magp_id] = \ + self._create_magp_instance_data(magp_id, data[0]) + else: + for magp_item in magp_data: + magp_id = self.get_magp_id(magp_item) + inst_data = self._create_magp_instance_data(magp_id, magp_item) + self._current_config[magp_id] = inst_data + + def _get_magp_config(self): + cmd = "show magp" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + # called in base class in run function + self._os_version = self._get_os_version() + self._current_config = dict() + magp_data = self._get_magp_config() + if magp_data: + self._update_magp_data(magp_data) + + def _generate_no_magp_commands(self): + req_vlan_id = self._required_config['vlan_id'] + req_magp_id = self._required_config['magp_id'] + curr_magp_data = self._current_config.get(req_magp_id) + if not curr_magp_data: + return + curr_vlan_id = curr_magp_data.get(req_vlan_id) + if curr_vlan_id == req_vlan_id: + cmd = 'interface vlan %s no magp %s' % (req_vlan_id, req_magp_id) + self._commands.append(cmd) + + def _generate_magp_commands(self, req_state): + req_vlan_id = self._required_config['vlan_id'] + req_magp_id = self._required_config['magp_id'] + curr_magp_data = self._current_config.get(req_magp_id, dict()) + curr_vlan_id = curr_magp_data.get('vlan_id') + magp_prefix = 'interface vlan %s magp %s' % (req_vlan_id, req_magp_id) + create_new_magp = False + if curr_vlan_id != req_vlan_id: + if curr_vlan_id: + cmd = 'interface vlan %s no magp %s' % ( + curr_vlan_id, req_magp_id) + self._commands.append(cmd) + create_new_magp = True + self._commands.append(magp_prefix) + self._commands.append('exit') + req_router_ip = self._required_config['router_ip'] + curr_router_ip = curr_magp_data.get('router_ip') + if req_router_ip: + if curr_router_ip != req_router_ip or create_new_magp: + cmd = '%s ip virtual-router address %s' % ( + magp_prefix, req_router_ip) + self._commands.append(cmd) + else: + if curr_router_ip and curr_router_ip != '0.0.0.0': + cmd = '%s no ip virtual-router address' % magp_prefix + self._commands.append(cmd) + req_router_mac = self._required_config['router_mac'] + curr_router_mac = curr_magp_data.get('router_mac') + if curr_router_mac: + curr_router_mac = curr_router_mac.lower() + if req_router_mac: + req_router_mac = req_router_mac.lower() + if curr_router_mac != req_router_mac or create_new_magp: + cmd = '%s ip virtual-router mac-address %s' % ( + magp_prefix, req_router_mac) + self._commands.append(cmd) + else: + if curr_router_mac and curr_router_mac != '00:00:00:00:00:00': + cmd = '%s no ip virtual-router mac-address' % magp_prefix + self._commands.append(cmd) + if req_state in ('enabled', 'disabled'): + curr_state = curr_magp_data.get('state', 'enabled') + if curr_state != req_state: + if req_state == 'enabled': + suffix = 'no shutdown' + else: + suffix = 'shutdown' + cmd = '%s %s' % (magp_prefix, suffix) + self._commands.append(cmd) + + def generate_commands(self): + req_state = self._required_config['state'] + if req_state == 'absent': + return self._generate_no_magp_commands() + return self._generate_magp_commands(req_state) + + +def main(): + """ main entry point for module execution + """ + OnyxMagpModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_mlag_ipl.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_mlag_ipl.py new file mode 100644 index 00000000..6257a5c8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_mlag_ipl.py @@ -0,0 +1,205 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_mlag_ipl +author: "Samer Deeb (@samerd)" +short_description: Manage IPL (inter-peer link) on Mellanox ONYX network devices +description: + - This module provides declarative management of IPL (inter-peer link) + management on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.4000 +options: + name: + description: + - Name of the interface (port-channel) IPL should be configured on. + required: true + vlan_interface: + description: + - Name of the IPL vlan interface. + state: + description: + - IPL state. + default: present + choices: ['present', 'absent'] + peer_address: + description: + - IPL peer IP address. +''' + +EXAMPLES = """ +- name: Run configure ipl + onyx_mlag_ipl: + name: Po1 + vlan_interface: Vlan 322 + state: present + peer_address: 192.168.7.1 + +- name: Run remove ipl + onyx_mlag_ipl: + name: Po1 + state: absent +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface port-channel 1 ipl 1 + - interface vlan 1024 ipl 1 peer-address 10.10.10.10 +""" +import re + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxMlagIplModule(BaseOnyxModule): + VLAN_IF_REGEX = re.compile(r'^Vlan \d+') + + @classmethod + def _get_element_spec(cls): + return dict( + name=dict(required=True), + state=dict(default='present', + choices=['present', 'absent']), + peer_address=dict(), + vlan_interface=dict(), + ) + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict( + name=module_params['name'], + state=module_params['state'], + peer_address=module_params['peer_address'], + vlan_interface=module_params['vlan_interface']) + self.validate_param_values(self._required_config) + + def _update_mlag_data(self, mlag_data): + if not mlag_data: + return + mlag_summary = mlag_data.get("MLAG IPLs Summary", {}) + ipl_id = "1" + ipl_list = mlag_summary.get(ipl_id) + if ipl_list: + ipl_data = ipl_list[0] + vlan_id = ipl_data.get("Vlan Interface") + vlan_interface = "" + if vlan_id != "N/A": + vlan_interface = "Vlan %s" % vlan_id + peer_address = ipl_data.get("Peer IP address") + name = ipl_data.get("Group Port-Channel") + self._current_config = dict( + name=name, + peer_address=peer_address, + vlan_interface=vlan_interface) + + def _show_mlag_data(self): + cmd = "show mlag" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + # called in base class in run function + self._current_config = dict() + mlag_data = self._show_mlag_data() + self._update_mlag_data(mlag_data) + + def _get_interface_cmd_name(self, if_name): + if if_name.startswith('Po'): + return if_name.replace("Po", "port-channel ") + self._module.fail_json( + msg='invalid interface name: %s' % if_name) + + def _generate_port_channel_command(self, if_name, enable): + if_cmd_name = self._get_interface_cmd_name(if_name) + if enable: + ipl_cmd = 'ipl 1' + else: + ipl_cmd = "no ipl 1" + cmd = "interface %s %s" % (if_cmd_name, ipl_cmd) + return cmd + + def _generate_vlan_if_command(self, if_name, enable, peer_address): + if_cmd_name = if_name.lower() + if enable: + ipl_cmd = 'ipl 1 peer-address %s' % peer_address + else: + ipl_cmd = "no ipl 1" + cmd = "interface %s %s" % (if_cmd_name, ipl_cmd) + return cmd + + def _generate_no_ipl_commands(self): + curr_interface = self._current_config.get('name') + req_interface = self._required_config.get('name') + if curr_interface == req_interface: + cmd = self._generate_port_channel_command( + req_interface, enable=False) + self._commands.append(cmd) + + def _generate_ipl_commands(self): + curr_interface = self._current_config.get('name') + req_interface = self._required_config.get('name') + if curr_interface != req_interface: + if curr_interface and curr_interface != 'N/A': + cmd = self._generate_port_channel_command( + curr_interface, enable=False) + self._commands.append(cmd) + cmd = self._generate_port_channel_command( + req_interface, enable=True) + self._commands.append(cmd) + curr_vlan = self._current_config.get('vlan_interface') + req_vlan = self._required_config.get('vlan_interface') + add_peer = False + if curr_vlan != req_vlan: + add_peer = True + if curr_vlan: + cmd = self._generate_vlan_if_command(curr_vlan, enable=False, + peer_address=None) + self._commands.append(cmd) + curr_peer = self._current_config.get('peer_address') + req_peer = self._required_config.get('peer_address') + if req_peer != curr_peer: + add_peer = True + if add_peer and req_peer: + cmd = self._generate_vlan_if_command(req_vlan, enable=True, + peer_address=req_peer) + self._commands.append(cmd) + + def generate_commands(self): + state = self._required_config['state'] + if state == 'absent': + self._generate_no_ipl_commands() + else: + self._generate_ipl_commands() + + +def main(): + """ main entry point for module execution + """ + OnyxMlagIplModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_mlag_vip.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_mlag_vip.py new file mode 100644 index 00000000..b7df229e --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_mlag_vip.py @@ -0,0 +1,180 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_mlag_vip +author: "Samer Deeb (@samerd)" +short_description: Configures MLAG VIP on Mellanox ONYX network devices +description: + - This module provides declarative management of MLAG virtual IPs + on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.4000 +options: + ipaddress: + description: + - Virtual IP address of the MLAG. Required if I(state=present). + group_name: + description: + - MLAG group name. Required if I(state=present). + mac_address: + description: + - MLAG system MAC address. Required if I(state=present). + state: + description: + - MLAG VIP state. + choices: ['present', 'absent'] + delay: + description: + - Delay interval, in seconds, waiting for the changes on mlag VIP to take + effect. + default: 12 +''' + +EXAMPLES = """ +- name: Configure mlag-vip + onyx_mlag_vip: + ipaddress: 50.3.3.1/24 + group_name: ansible-test-group + mac_address: 00:11:12:23:34:45 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - mlag-vip ansible_test_group ip 50.3.3.1 /24 force + - no mlag shutdown +""" + +import time + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxMLagVipModule(BaseOnyxModule): + + def init_module(self): + """ initialize module + """ + element_spec = dict( + ipaddress=dict(), + group_name=dict(), + mac_address=dict(), + delay=dict(type='int', default=12), + state=dict(choices=['present', 'absent'], default='present'), + ) + argument_spec = dict() + + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + lag_params = { + 'ipaddress': module_params['ipaddress'], + 'group_name': module_params['group_name'], + 'mac_address': module_params['mac_address'], + 'delay': module_params['delay'], + 'state': module_params['state'], + } + + self.validate_param_values(lag_params) + self._required_config = lag_params + + def _show_mlag_cmd(self, cmd): + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def _show_mlag(self): + cmd = "show mlag" + return self._show_mlag_cmd(cmd) + + def _show_mlag_vip(self): + cmd = "show mlag-vip" + return self._show_mlag_cmd(cmd) + + def load_current_config(self): + self._current_config = dict() + mlag_config = self._show_mlag() + mlag_vip_config = self._show_mlag_vip() + if mlag_vip_config: + mlag_vip = mlag_vip_config.get("MLAG-VIP", {}) + self._current_config['group_name'] = \ + mlag_vip.get("MLAG group name") + self._current_config['ipaddress'] = \ + mlag_vip.get("MLAG VIP address") + if mlag_config: + self._current_config['mac_address'] = \ + mlag_config.get("System-mac") + + def generate_commands(self): + state = self._required_config['state'] + if state == 'present': + self._generate_mlag_vip_cmds() + else: + self._generate_no_mlag_vip_cmds() + + def _generate_mlag_vip_cmds(self): + current_group = self._current_config.get('group_name') + current_ip = self._current_config.get('ipaddress') + current_mac = self._current_config.get('mac_address') + if current_mac: + current_mac = current_mac.lower() + + req_group = self._required_config.get('group_name') + req_ip = self._required_config.get('ipaddress') + req_mac = self._required_config.get('mac_address') + if req_mac: + req_mac = req_mac.lower() + + if req_ip is not None: + if req_group is None: + self._module.fail_json(msg='In order to configure Mlag-Vip you must send ' + 'group name param beside IPaddress') + ipaddr, mask = req_ip.split('/') + if req_group != current_group or req_ip != current_ip: + self._commands.append('mlag-vip %s ip %s /%s force' % (req_group, ipaddr, mask)) + elif req_group and req_group != current_group: + self._commands.append('mlag-vip %s' % req_group) + + if req_mac and req_mac != current_mac: + self._commands.append( + 'mlag system-mac %s' % (req_mac)) + if self._commands: + self._commands.append('no mlag shutdown') + + def _generate_no_mlag_vip_cmds(self): + if self._current_config.get('group_name'): + self._commands.append('no mlag-vip') + + def check_declarative_intent_params(self, result): + if not result['changed']: + return + delay_interval = self._required_config.get('delay') + if delay_interval > 0: + time.sleep(delay_interval) + for cmd in ("show mlag-vip", ""): + show_cmd(self._module, cmd, json_fmt=False, fail_on_error=False) + + +def main(): + """ main entry point for module execution + """ + OnyxMLagVipModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ntp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ntp.py new file mode 100644 index 00000000..0f17263c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ntp.py @@ -0,0 +1,239 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_ntp +version_added: '0.2.0' +author: "Sara-Touqan (@sarato)" +short_description: Manage NTP general configurations and ntp keys configurations on Mellanox ONYX network devices +description: + - This module provides declarative management of NTP & NTP Keys + on Mellanox ONYX network devices. +options: + state: + description: + - State of the NTP configuration. + choices: ['enabled', 'disabled'] + type: str + authenticate_state: + description: + - State of the NTP authentication configuration. + choices: ['enabled', 'disabled'] + type: str + ntp_authentication_keys: + type: list + description: + - List of ntp authentication keys + suboptions: + auth_key_id: + description: + - Configures ntp key-id, range 1-65534 + required: true + type: int + auth_key_encrypt_type: + description: + - encryption type used to configure ntp authentication key. + required: true + choices: ['md5', 'sha1'] + type: str + auth_key_password: + description: + - password used for ntp authentication key. + required: true + type: str + auth_key_state: + description: + - Used to decide if you want to delete given ntp key or not + choices: ['present', 'absent'] + type: str + trusted_keys: + type: list + description: + - List of ntp trusted keys +''' + +EXAMPLES = """ +- name: Configure NTP + onyx_ntp: + state: enabled + authenticate_state: enabled + ntp_authentication_keys: + - auth_key_id: 1 + auth_key_encrypt_type: md5 + auth_key_password: 12345 + auth_key_state: absent + trusted_keys: 1,2,3 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - ntp enable + - ntp disable + - ntp authenticate + - no ntp authenticate + - ntp authentication-key 1 md5 12345 + - no ntp authentication-key 1 + - ntp trusted-key 1,2,3 +""" + + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxNTPModule(BaseOnyxModule): + + def init_module(self): + """ module initialization + """ + ntp_authentication_key_spec = dict(auth_key_id=dict(type='int', required=True), + auth_key_encrypt_type=dict(required=True, choices=['md5', 'sha1']), + auth_key_password=dict(required=True), + auth_key_state=dict(choices=['present', 'absent'])) + element_spec = dict( + state=dict(choices=['enabled', 'disabled']), + authenticate_state=dict(choices=['enabled', 'disabled']), + ntp_authentication_keys=dict(type='list', elements='dict', options=ntp_authentication_key_spec), + trusted_keys=dict(type='list', elements='int') + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def _validate_key_id(self): + keys_id_list = self._required_config.get("ntp_authentication_keys") + if keys_id_list: + for key_item in keys_id_list: + key_id = key_item.get("auth_key_id") + if (key_id < 1) or (key_id > 65534): + self._module.fail_json( + msg='Invalid Key value, value should be in the range 1-65534') + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + self._validate_key_id() + + def _show_ntp_config(self): + show_cmds = [] + cmd = "show ntp" + show_cmds.append(show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False)) + cmd = "show ntp keys" + show_cmds.append(show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False)) + return show_cmds + + def _set_ntp_keys_config(self, ntp_config): + if not ntp_config: + return + for req_ntp_auth_key in ntp_config: + ecryption_type = req_ntp_auth_key.get("Encryption Type") + self._current_config[req_ntp_auth_key.get("header")] = ecryption_type + + def _set_ntp_config(self, ntp_config): + ntp_config = ntp_config[0] + if not ntp_config: + return + self._current_config['state'] = ntp_config.get("NTP is administratively") + self._current_config['authenticate_state'] = ntp_config.get("NTP Authentication administratively") + + def load_current_config(self): + self._current_config = dict() + ntp_config = self._show_ntp_config() + if ntp_config: + if ntp_config[0]: + self._set_ntp_config(ntp_config[0]) + if ntp_config[1]: + self._set_ntp_keys_config(ntp_config[1]) + + def generate_commands(self): + current_state = self._current_config.get("state") + state = self._required_config.get("state") + if state is None: + state = current_state + if state is not None: + if current_state != state: + if state == 'enabled': + self._commands.append('ntp enable') + else: + self._commands.append('no ntp enable') + authenticate_state = self._required_config.get("authenticate_state") + if authenticate_state: + current_authenticate_state = self._current_config.get("authenticate_state") + if authenticate_state is not None: + if current_authenticate_state != authenticate_state: + if authenticate_state == 'enabled': + self._commands.append('ntp authenticate') + else: + self._commands.append('no ntp authenticate') + req_ntp_auth_keys = self._required_config.get('ntp_authentication_keys') + if req_ntp_auth_keys: + if req_ntp_auth_keys is not None: + for req_ntp_auth_key in req_ntp_auth_keys: + req_key_id = req_ntp_auth_key.get('auth_key_id') + req_key = 'NTP Key ' + str(req_key_id) + current_req_key = self._current_config.get(req_key) + auth_key_state = req_ntp_auth_key.get('auth_key_state') + req_encrypt_type = req_ntp_auth_key.get('auth_key_encrypt_type') + req_password = req_ntp_auth_key.get('auth_key_password') + if current_req_key: + if req_encrypt_type == current_req_key: + if auth_key_state: + if auth_key_state == 'absent': + self._commands.append('no ntp authentication-key {0}' .format(req_key_id)) + else: + continue + else: + if auth_key_state: + if auth_key_state == 'present': + self._commands.append('ntp authentication-key {0} {1} {2}' + .format(req_key_id, + req_encrypt_type, + req_password)) + else: + self._commands.append('ntp authentication-key {0} {1} {2}' + .format(req_key_id, + req_encrypt_type, + req_password)) + + else: + if auth_key_state: + if auth_key_state == 'present': + self._commands.append('ntp authentication-key {0} {1} {2}' + .format(req_key_id, + req_encrypt_type, + req_password)) + else: + self._commands.append('ntp authentication-key {0} {1} {2}' + .format(req_key_id, + req_encrypt_type, + req_password)) + + req_trusted_keys = self._required_config.get('trusted_keys') + if req_trusted_keys: + for key in req_trusted_keys: + self._commands.append('ntp trusted-key {0}' .format(key)) + + +def main(): + """ main entry point for module execution + """ + OnyxNTPModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ntp_servers_peers.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ntp_servers_peers.py new file mode 100644 index 00000000..f49daa24 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ntp_servers_peers.py @@ -0,0 +1,282 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_ntp_servers_peers +version_added: '0.2.0' +author: "Sara-Touqan (@sarato)" +short_description: Configures NTP peers and servers parameters +description: + - This module provides declarative management of NTP peers and servers configuration on Mellanox ONYX network devices. +options: + peer: + type: list + description: + - List of ntp peers. + suboptions: + ip_or_name: + description: + - Configures ntp peer name or ip. + required: true + type: str + enabled: + description: + - Disables/Enables ntp peer state + type: bool + version: + description: + - version number for the ntp peer + choices: [3, 4] + type: int + key_id: + description: + - Used to configure the key-id for the ntp peer + type: int + state: + description: + - Indicates if the ntp peer exists or should be deleted + choices: ['present', 'absent'] + type: str + server: + type: list + description: + - List of ntp servers. + suboptions: + ip_or_name: + description: + - Configures ntp server name or ip. + required: true + type: str + enabled: + description: + - Disables/Enables ntp server + type: bool + trusted_enable: + description: + - Disables/Enables the trusted state for the ntp server. + type: bool + version: + description: + - version number for the ntp server + choices: [3, 4] + type: int + key_id: + description: + - Used to configure the key-id for the ntp server + type: int + state: + description: + - Indicates if the ntp peer exists or should be deleted. + choices: ['present', 'absent'] + type: str + ntpdate: + description: + - Sets system clock once from a remote server using NTP. + type: str +''' + +EXAMPLES = """ +- name: Configure NTP peers and servers + onyx_ntp_peers_servers: + peer: + - ip_or_name: 1.1.1.1 + enabled: yes + version: 4 + key_id: 6 + state: present + server: + - ip_or_name: 2.2.2.2 + enabled: true + version: 3 + key_id: 8 + trusted_enable: no + state: present + ntpdate: 192.168.10.10 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - ntp peer 1.1.1.1 disable + no ntp peer 1.1.1.1 disable + ntp peer 1.1.1.1 keyId 6 + ntp peer 1.1.1.1 version 4 + no ntp peer 1.1.1.1 + ntp server 2.2.2.2 disable + no ntp server 2.2.2.2 disable + ntp server 2.2.2.2 keyID 8 + ntp server 2.2.2.2 version 3 + ntp server 2.2.2.2 trusted-enable + no ntp server 2.2.2.2 + ntp server 192.168.10.10 + ntpdate 192.168.10.10 +""" + +from copy import deepcopy +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import remove_default_spec + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxNTPServersPeersModule(BaseOnyxModule): + + def init_module(self): + """ module initialization + """ + peer_spec = dict(ip_or_name=dict(required=True), + enabled=dict(type='bool'), + version=dict(type='int', choices=[3, 4]), + key_id=dict(type='int'), + state=dict(choices=['present', 'absent'])) + server_spec = dict(ip_or_name=dict(required=True), + enabled=dict(type='bool'), + version=dict(type='int', choices=[3, 4]), + trusted_enable=dict(type='bool'), + key_id=dict(type='int'), + state=dict(choices=['present', 'absent'])) + element_spec = dict(peer=dict(type='list', elements='dict', options=peer_spec), + server=dict(type='list', elements='dict', options=server_spec), + ntpdate=dict()) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def _show_peers_servers_config(self): + cmd = "show ntp configured" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def _set_servers_config(self, peers_servers_config): + servers = dict() + peers = dict() + if not peers_servers_config: + return + index = 0 + for peer_server in peers_servers_config: + if (index == 0): + index += 1 + continue + else: + header_list = peer_server.get("header").split(" ") + header_type = header_list[1] + if peer_server.get("Enabled") == "yes": + enabled_state = True + else: + enabled_state = False + if (header_type == 'server'): + trusted_state = peer_server.get("Trusted") + if trusted_state == 'yes': + trusted_state = True + else: + trusted_state = False + server_entry = {"version": peer_server.get("NTP version"), + "enabled": enabled_state, + "trusted_enable": trusted_state, + "key_id": peer_server.get("Key ID")} + servers[header_list[2]] = server_entry + else: + peer_entry = {"version": peer_server.get("NTP version"), + "enabled": enabled_state, + "key_id": peer_server.get("Key ID")} + peers[header_list[2]] = peer_entry + index += 1 + self._current_config = dict(server=servers, + peer=peers) + + def load_current_config(self): + servers = dict() + peers = dict() + self._current_config = dict(server=servers, + peer=peers) + peers_servers_config = self._show_peers_servers_config() + if peers_servers_config: + self._set_servers_config(peers_servers_config) + + def generate_commands(self): + for option in self._current_config: + req_ntp = self._required_config.get(option) + if req_ntp is not None: + for ntp_peer in req_ntp: + peer_name = ntp_peer.get('ip_or_name') + peer_key = ntp_peer.get('key_id') + peer_state = ntp_peer.get("state") + peer_enabled = ntp_peer.get("enabled") + peer_version = ntp_peer.get("version") + peer_key = ntp_peer.get("key_id") + curr_name = self._current_config.get(option).get(peer_name) + peer_version = ntp_peer.get('version') + if self._current_config.get(option) and curr_name: + if peer_state: + if(peer_state == "absent"): + self._commands.append('no ntp {0} {1}' .format(option, peer_name)) + continue + if peer_enabled is not None: + if curr_name.get("enabled") != peer_enabled: + if(peer_enabled is True): + self._commands.append('no ntp {0} {1} disable' .format(option, peer_name)) + else: + self._commands.append('ntp {0} {1} disable' .format(option, peer_name)) + if peer_version: + if (int(curr_name.get("version")) != peer_version): + self._commands.append('ntp {0} {1} version {2}' .format(option, peer_name, peer_version)) + if peer_key: + if curr_name.get("key_id") != "none": + if (int(curr_name.get("key_id")) != peer_key): + self._commands.append('ntp {0} {1} keyID {2}' .format(option, peer_name, peer_key)) + else: + self._commands.append('ntp {0} {1} keyID {2}' .format(option, peer_name, peer_key)) + if option == "server": + server_trusted = ntp_peer.get("trusted_enable") + if server_trusted is not None: + if (curr_name.get("trusted_enable") != server_trusted): + if server_trusted is True: + self._commands.append('ntp {0} {1} trusted-enable' .format(option, peer_name)) + else: + self._commands.append('no ntp {0} {1} trusted-enable' .format(option, peer_name)) + else: + if peer_state: + if(peer_state == "absent"): + continue + if peer_enabled is not None: + if(peer_enabled is True): + self._commands.append('no ntp {0} {1} disable' .format(option, peer_name)) + else: + self._commands.append('ntp {0} {1} disable' .format(option, peer_name)) + else: + self._commands.append('ntp {0} {1} disable' .format(option, peer_name)) + if peer_version: + self._commands.append('ntp {0} {1} version {2}' .format(option, peer_name, peer_version)) + if peer_key: + self._commands.append('ntp {0} {1} keyID {2}' .format(option, peer_name, peer_key)) + + ntpdate = self._required_config.get("ntpdate") + if ntpdate is not None: + self._commands.append('ntpdate {0}' .format(ntpdate)) + + +def main(): + """ main entry point for module execution + """ + OnyxNTPServersPeersModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ospf.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ospf.py new file mode 100644 index 00000000..1de0e413 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ospf.py @@ -0,0 +1,233 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_ospf +author: "Samer Deeb (@samerd)" +short_description: Manage OSPF protocol on Mellanox ONYX network devices +description: + - This module provides declarative management and configuration of OSPF + protocol on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.4000 +options: + ospf: + description: + - "OSPF instance number 1-65535" + required: true + router_id: + description: + - OSPF router ID. Required if I(state=present). + interfaces: + description: + - List of interfaces and areas. Required if I(state=present). + suboptions: + name: + description: + - Interface name. + required: true + area: + description: + - OSPF area. + required: true + state: + description: + - OSPF state. + default: present + choices: ['present', 'absent'] +''' + +EXAMPLES = """ +- name: Add ospf router to interface + onyx_ospf: + ospf: 2 + router_id: 192.168.8.2 + interfaces: + - name: Eth1/1 + - area: 0.0.0.0 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - router ospf 2 + - router-id 192.168.8.2 + - exit + - interface ethernet 1/1 ip ospf area 0.0.0.0 +""" +import re + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxOspfModule(BaseOnyxModule): + OSPF_IF_REGEX = re.compile( + r'^(Loopback\d+|Eth\d+\/\d+|Vlan\d+|Po\d+)\s+(\S+).*') + OSPF_ROUTER_REGEX = re.compile(r'^Routing Process (\d+).*ID\s+(\S+).*') + + @classmethod + def _get_element_spec(cls): + interface_spec = dict( + name=dict(required=True), + area=dict(required=True), + ) + element_spec = dict( + ospf=dict(type='int', required=True), + router_id=dict(), + interfaces=dict(type='list', elements='dict', + options=interface_spec), + state=dict(choices=['present', 'absent'], default='present'), + ) + return element_spec + + def init_module(self): + """ Ansible module initialization + """ + element_spec = self._get_element_spec() + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def validate_ospf(self, value): + if value and not 1 <= int(value) <= 65535: + self._module.fail_json(msg='ospf id must be between 1 and 65535') + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict( + ospf=module_params['ospf'], + router_id=module_params['router_id'], + state=module_params['state'], + ) + interfaces = module_params['interfaces'] or list() + req_interfaces = self._required_config['interfaces'] = dict() + for interface_data in interfaces: + req_interfaces[interface_data['name']] = interface_data['area'] + self.validate_param_values(self._required_config) + + def _update_ospf_data(self, ospf_data): + match = self.OSPF_ROUTER_REGEX.match(ospf_data) + if match: + ospf_id = int(match.group(1)) + router_id = match.group(2) + self._current_config['ospf'] = ospf_id + self._current_config['router_id'] = router_id + + def _update_ospf_interfaces(self, ospf_interfaces): + interfaces = self._current_config['interfaces'] = dict() + lines = ospf_interfaces.split('\n') + for line in lines: + line = line.strip() + match = self.OSPF_IF_REGEX.match(line) + if match: + name = match.group(1) + area = match.group(2) + for prefix in ("Vlan", "Loopback"): + if name.startswith(prefix): + name = name.replace(prefix, prefix + ' ') + interfaces[name] = area + + def _get_ospf_config(self, ospf_id): + cmd = 'show ip ospf %s | include Process' % ospf_id + return show_cmd(self._module, cmd, json_fmt=False, fail_on_error=False) + + def _get_ospf_interfaces_config(self, ospf_id): + cmd = 'show ip ospf interface %s brief' % ospf_id + return show_cmd(self._module, cmd, json_fmt=False, fail_on_error=False) + + def load_current_config(self): + # called in base class in run function + ospf_id = self._required_config['ospf'] + self._current_config = dict() + ospf_data = self._get_ospf_config(ospf_id) + if ospf_data: + self._update_ospf_data(ospf_data) + ospf_interfaces = self._get_ospf_interfaces_config(ospf_id) + if ospf_interfaces: + self._update_ospf_interfaces(ospf_interfaces) + + def _generate_no_ospf_commands(self): + req_ospf_id = self._required_config['ospf'] + curr_ospf_id = self._current_config.get('ospf') + if curr_ospf_id == req_ospf_id: + cmd = 'no router ospf %s' % req_ospf_id + self._commands.append(cmd) + + def _get_interface_command_name(self, if_name): + if if_name.startswith('Eth'): + return if_name.replace("Eth", "ethernet ") + if if_name.startswith('Po'): + return if_name.replace("Po", "port-channel ") + if if_name.startswith('Vlan'): + return if_name.replace("Vlan", "vlan") + if if_name.startswith('Loopback'): + return if_name.replace("Loopback", "loopback") + self._module.fail_json( + msg='invalid interface name: %s' % if_name) + + def _get_interface_area_cmd(self, if_name, area): + interface_prefix = self._get_interface_command_name(if_name) + if area: + area_cmd = 'ip ospf area %s' % area + else: + area_cmd = 'no ip ospf area' + cmd = 'interface %s %s' % (interface_prefix, area_cmd) + return cmd + + def _generate_ospf_commands(self): + req_router_id = self._required_config['router_id'] + req_ospf_id = self._required_config['ospf'] + curr_router_id = self._current_config.get('router_id') + curr_ospf_id = self._current_config.get('ospf') + if curr_ospf_id != req_ospf_id or req_router_id != curr_router_id: + cmd = 'router ospf %s' % req_ospf_id + self._commands.append(cmd) + if req_router_id != curr_router_id: + if req_router_id: + cmd = 'router-id %s' % req_router_id + else: + cmd = 'no router-id' + self._commands.append(cmd) + self._commands.append('exit') + req_interfaces = self._required_config['interfaces'] + curr_interfaces = self._current_config.get('interfaces', dict()) + for if_name, area in iteritems(req_interfaces): + curr_area = curr_interfaces.get(if_name) + if curr_area != area: + cmd = self._get_interface_area_cmd(if_name, area) + self._commands.append(cmd) + for if_name in curr_interfaces: + if if_name not in req_interfaces: + cmd = self._get_interface_area_cmd(if_name, None) + self._commands.append(cmd) + + def generate_commands(self): + req_state = self._required_config['state'] + if req_state == 'absent': + return self._generate_no_ospf_commands() + return self._generate_ospf_commands() + + +def main(): + """ main entry point for module execution + """ + OnyxOspfModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_pfc_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_pfc_interface.py new file mode 100644 index 00000000..21ab4fbb --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_pfc_interface.py @@ -0,0 +1,208 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_pfc_interface +author: "Samer Deeb (@samerd)" +short_description: Manage priority flow control on ONYX network devices +description: + - This module provides declarative management of priority flow control (PFC) + on interfaces of Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.4000 +options: + name: + description: + - Name of the interface PFC should be configured on. + aggregate: + description: List of interfaces PFC should be configured on. + purge: + description: + - Purge interfaces not defined in the aggregate parameter. + type: bool + default: false + state: + description: + - State of the PFC configuration. + default: enabled + choices: ['enabled', 'disabled'] +''' + +EXAMPLES = """ +- name: Configure PFC + onyx_pfc_interface: + name: Eth1/1 + state: enabled +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface ethernet 1/17 dcb priority-flow-control mode on +""" +from copy import deepcopy +import re + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import remove_default_spec +from ansible.module_utils.six import iteritems + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxPfcInterfaceModule(BaseOnyxModule): + PFC_IF_REGEX = re.compile( + r"^(Eth\d+\/\d+)|(Eth\d+\/\d+\/\d+)|(Po\d+)|(Mpo\d+)$") + + _purge = False + + @classmethod + def _get_element_spec(cls): + return dict( + name=dict(type='str'), + state=dict(default='enabled', + choices=['enabled', 'disabled']), + ) + + @classmethod + def _get_aggregate_spec(cls, element_spec): + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + return aggregate_spec + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + aggregate_spec = self._get_aggregate_spec(element_spec) + argument_spec = dict( + aggregate=dict(type='list', elements='dict', + options=aggregate_spec), + purge=dict(default=False, type='bool'), + ) + argument_spec.update(element_spec) + required_one_of = [['name', 'aggregate']] + mutually_exclusive = [['name', 'aggregate']] + self._module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True) + + def get_required_config(self): + self._required_config = list() + module_params = self._module.params + aggregate = module_params.get('aggregate') + self._purge = module_params.get('purge', False) + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module_params[key] + self.validate_param_values(item, item) + req_item = item.copy() + self._required_config.append(req_item) + else: + params = { + 'name': module_params['name'], + 'state': module_params['state'], + } + self.validate_param_values(params) + self._required_config.append(params) + + def _create_if_pfc_data(self, if_name, if_pfc_data): + state = self.get_config_attr(if_pfc_data, "PFC oper") + state = state.lower() + return dict( + name=if_name, + state=state) + + def _get_pfc_config(self): + return show_cmd(self._module, "show dcb priority-flow-control") + + def load_current_config(self): + # called in base class in run function + self._os_version = self._get_os_version() + self._current_config = dict() + pfc_config = self._get_pfc_config() + if not pfc_config: + return + if self._os_version >= self.ONYX_API_VERSION: + if len(pfc_config) >= 3: + pfc_config = pfc_config[2] + else: + pfc_config = dict() + else: + if 'Table 2' in pfc_config: + pfc_config = pfc_config['Table 2'] + + for if_name, if_pfc_data in iteritems(pfc_config): + match = self.PFC_IF_REGEX.match(if_name) + if not match: + continue + if if_pfc_data: + if_pfc_data = if_pfc_data[0] + self._current_config[if_name] = \ + self._create_if_pfc_data(if_name, if_pfc_data) + + def _get_interface_cmd_name(self, if_name): + if if_name.startswith('Eth'): + return if_name.replace("Eth", "ethernet ") + if if_name.startswith('Po'): + return if_name.replace("Po", "port-channel ") + if if_name.startswith('Mpo'): + return if_name.replace("Mpo", "mlag-port-channel ") + self._module.fail_json( + msg='invalid interface name: %s' % if_name) + + def _add_if_pfc_commands(self, if_name, req_state): + cmd_prefix = "interface %s " % self._get_interface_cmd_name(if_name) + + if req_state == 'disabled': + pfc_cmd = 'no dcb priority-flow-control mode force' + else: + pfc_cmd = 'dcb priority-flow-control mode on force' + self._commands.append(cmd_prefix + pfc_cmd) + + def _gen_pfc_commands(self, if_name, curr_conf, req_state): + curr_state = curr_conf.get('state', 'disabled') + if curr_state != req_state: + self._add_if_pfc_commands(if_name, req_state) + + def generate_commands(self): + req_interfaces = set() + for req_conf in self._required_config: + req_state = req_conf['state'] + if_name = req_conf['name'] + if req_state == 'enabled': + req_interfaces.add(if_name) + curr_conf = self._current_config.get(if_name, {}) + self._gen_pfc_commands(if_name, curr_conf, req_state) + if self._purge: + for if_name, curr_conf in iteritems(self._current_config): + if if_name not in req_interfaces: + req_state = 'disabled' + self._gen_pfc_commands(if_name, curr_conf, req_state) + + +def main(): + """ main entry point for module execution + """ + OnyxPfcInterfaceModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_protocol.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_protocol.py new file mode 100644 index 00000000..133ccbca --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_protocol.py @@ -0,0 +1,191 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_protocol +author: "Samer Deeb (@samerd)" +short_description: Enables/Disables protocols on Mellanox ONYX network devices +description: + - This module provides a mechanism for enabling and disabling protocols + Mellanox on ONYX network devices. +notes: + - Tested on ONYX 3.6.4000 +options: + mlag: + description: MLAG protocol + choices: ['enabled', 'disabled'] + magp: + description: MAGP protocol + choices: ['enabled', 'disabled'] + spanning_tree: + description: Spanning Tree support + choices: ['enabled', 'disabled'] + dcb_pfc: + description: DCB priority flow control + choices: ['enabled', 'disabled'] + igmp_snooping: + description: IP IGMP snooping + choices: ['enabled', 'disabled'] + lacp: + description: LACP protocol + choices: ['enabled', 'disabled'] + ip_l3: + description: IP L3 support + choices: ['enabled', 'disabled'] + ip_routing: + description: IP routing support + choices: ['enabled', 'disabled'] + lldp: + description: LLDP protocol + choices: ['enabled', 'disabled'] + bgp: + description: BGP protocol + choices: ['enabled', 'disabled'] + ospf: + description: OSPF protocol + choices: ['enabled', 'disabled'] + nve: + description: nve protocol + choices: ['enabled', 'disabled'] + bfd: + description: bfd protocol + choices: ['enabled', 'disabled'] + version_added: '0.2.0' +''' + +EXAMPLES = """ +- name: Enable protocols for MLAG + onyx_protocol: + lacp: enabled + spanning_tree: disabled + ip_routing: enabled + mlag: enabled + dcb_pfc: enabled +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - no spanning-tree + - protocol mlag +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxProtocolModule(BaseOnyxModule): + + PROTOCOL_MAPPING = dict( + mlag=dict(name="mlag", enable="protocol mlag", + disable="no protocol mlag"), + magp=dict(name="magp", enable="protocol magp", + disable="no protocol magp"), + spanning_tree=dict(name="spanning-tree", enable="spanning-tree", + disable="no spanning-tree"), + dcb_pfc=dict(name="priority-flow-control", + enable="dcb priority-flow-control enable force", + disable="no dcb priority-flow-control enable force"), + igmp_snooping=dict(name="igmp-snooping", enable="ip igmp snooping", + disable="no ip igmp snooping"), + lacp=dict(name="lacp", enable="lacp", disable="no lacp"), + ip_l3=dict(name="IP L3", enable="ip l3", + disable="no ip l3"), + ip_routing=dict(name="IP routing", enable="ip routing", + disable="no ip routing"), + lldp=dict(name="lldp", enable="lldp", disable="no lldp"), + bgp=dict(name="bgp", enable="protocol bgp", disable="no protocol bgp"), + ospf=dict(name="ospf", enable="protocol ospf", + disable="no protocol ospf"), + nve=dict(name="nve", enable="protocol nve", + disable="no protocol nve"), + bfd=dict(name="bfd", enable="protocol bfd", + disable="no protocol bfd"), + ) + + @classmethod + def _get_element_spec(cls): + element_spec = dict() + for protocol in cls.PROTOCOL_MAPPING: + element_spec[protocol] = dict(choices=['enabled', 'disabled']) + return element_spec + + def init_module(self): + """ Ansible module initialization + """ + element_spec = self._get_element_spec() + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True + ) + + def get_required_config(self): + self._required_config = dict() + module_params = self._module.params + for key, val in iteritems(module_params): + if key in self.PROTOCOL_MAPPING and val is not None: + self._required_config[key] = val + + def _get_protocols(self): + return show_cmd(self._module, "show protocols") + + def _get_ip_routing(self): + return show_cmd(self._module, 'show ip routing | include "IP routing"', + json_fmt=False) + + def load_current_config(self): + self._current_config = dict() + protocols_config = self._get_protocols() + if not protocols_config: + protocols_config = dict() + ip_config = self._get_ip_routing() + if ip_config: + lines = ip_config.split('\n') + for line in lines: + line = line.strip() + line_attr = line.split(':') + if len(line_attr) == 2: + attr = line_attr[0].strip() + val = line_attr[1].strip() + protocols_config[attr] = val + for protocol, protocol_metadata in iteritems(self.PROTOCOL_MAPPING): + protocol_json_attr = protocol_metadata['name'] + val = protocols_config.get(protocol_json_attr, 'disabled') + if val not in ('enabled', 'disabled'): + val = 'enabled' + self._current_config[protocol] = val + + def generate_commands(self): + for protocol, req_val in iteritems(self._required_config): + protocol_metadata = self.PROTOCOL_MAPPING[protocol] + curr_val = self._current_config.get(protocol, 'disabled') + if curr_val != req_val: + if req_val == 'disabled': + command = protocol_metadata['disable'] + else: + command = protocol_metadata['enable'] + self._commands.append(command) + + +def main(): + """ main entry point for module execution + """ + OnyxProtocolModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ptp_global.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ptp_global.py new file mode 100644 index 00000000..1a7314e2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ptp_global.py @@ -0,0 +1,202 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_ptp_global +author: "Anas Badaha (@anasb)" +short_description: Configures PTP Global parameters +description: + - This module provides declarative management of PTP Global configuration + on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.8130 + ptp and ntp protocols cannot be enabled at the same time +options: + ptp_state: + description: + - PTP state. + choices: ['enabled', 'disabled'] + default: enabled + ntp_state: + description: + - NTP state. + choices: ['enabled', 'disabled'] + domain: + description: + - "set PTP domain number Range 0-127" + primary_priority: + description: + - "set PTP primary priority Range 0-225" + secondary_priority: + description: + - "set PTP secondary priority Range 0-225" +''' + +EXAMPLES = """ +- name: Configure PTP + onyx_ptp_global: + ntp_state: enabled + ptp_state: disabled + domain: 127 + primary_priority: 128 + secondary_priority: 128 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - no ntp enable + - protocol ptp + - ptp domain 127 +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxPtpGlobalModule(BaseOnyxModule): + + def init_module(self): + """ initialize module + """ + element_spec = dict( + ntp_state=dict(choices=['enabled', 'disabled']), + ptp_state=dict(choices=['enabled', 'disabled'], default='enabled'), + domain=dict(type=int), + primary_priority=dict(type=int), + secondary_priority=dict(type=int) + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self._validate_param_values(self._required_config) + + def _validate_param_values(self, obj, param=None): + super(OnyxPtpGlobalModule, self).validate_param_values(obj, param) + if obj['ntp_state'] == 'enabled' and obj['ptp_state'] == 'enabled': + self._module.fail_json(msg='PTP State and NTP State Can not be enabled at the same time') + + def validate_domain(self, value): + if value and not 0 <= int(value) <= 127: + self._module.fail_json(msg='domain must be between 0 and 127') + + def validate_primary_priority(self, value): + if value and not 0 <= int(value) <= 255: + self._module.fail_json(msg='Primary Priority must be between 0 and 255') + + def validate_secondary_priority(self, value): + if value and not 0 <= int(value) <= 255: + self._module.fail_json(msg='Secondary Priority must be between 0 and 255') + + def _set_ntp_config(self, ntp_config): + ntp_config = ntp_config[0] + if not ntp_config: + return + ntp_state = ntp_config.get('NTP enabled') + if ntp_state == "yes": + self._current_config['ntp_state'] = "enabled" + else: + self._current_config['ntp_state'] = "disabled" + + def _set_ptp_config(self, ptp_config): + if ptp_config is None: + self._current_config['ptp_state'] = 'disabled' + else: + self._current_config['ptp_state'] = 'enabled' + self._current_config['domain'] = int(ptp_config['Domain']) + self._current_config['primary_priority'] = int(ptp_config['Priority1']) + self._current_config['secondary_priority'] = int(ptp_config['Priority2']) + + def _show_ntp_config(self): + cmd = "show ntp configured" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def _show_ptp_config(self): + cmd = "show ptp clock" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + + ntp_config = self._show_ntp_config() + self._set_ntp_config(ntp_config) + + ptp_config = self._show_ptp_config() + self._set_ptp_config(ptp_config) + + def generate_commands(self): + ntp_state = self._required_config.get("ntp_state") + if ntp_state == "enabled": + self._enable_ntp() + elif ntp_state == "disabled": + self._disable_ntp() + + ptp_state = self._required_config.get("ptp_state", "enabled") + if ptp_state == "enabled": + self._enable_ptp() + else: + self._disable_ptp() + + domain = self._required_config.get("domain") + if domain is not None: + curr_domain = self._current_config.get("domain") + if domain != curr_domain: + self._commands.append('ptp domain %d' % domain) + + primary_priority = self._required_config.get("primary_priority") + if primary_priority is not None: + curr_primary_priority = self._current_config.get("primary_priority") + if primary_priority != curr_primary_priority: + self._commands.append('ptp priority1 %d' % primary_priority) + + secondary_priority = self._required_config.get("secondary_priority") + if secondary_priority is not None: + curr_secondary_priority = self._current_config.get("secondary_priority") + if secondary_priority != curr_secondary_priority: + self._commands.append('ptp priority2 %d' % secondary_priority) + + def _enable_ptp(self): + curr_ptp_state = self._current_config['ptp_state'] + if curr_ptp_state == 'disabled': + self._commands.append('protocol ptp') + + def _disable_ptp(self): + curr_ptp_state = self._current_config['ptp_state'] + if curr_ptp_state == 'enabled': + self._commands.append('no protocol ptp') + + def _enable_ntp(self): + curr_ntp_state = self._current_config.get('ntp_state') + if curr_ntp_state == 'disabled': + self._commands.append('ntp enable') + + def _disable_ntp(self): + curr_ntp_state = self._current_config['ntp_state'] + if curr_ntp_state == 'enabled': + self._commands.append('no ntp enable') + + +def main(): + """ main entry point for module execution + """ + OnyxPtpGlobalModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ptp_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ptp_interface.py new file mode 100644 index 00000000..f3eb1f11 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_ptp_interface.py @@ -0,0 +1,224 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_ptp_interface +author: 'Anas Badaha (@anasb)' +short_description: 'Configures PTP on interface' +description: + - "This module provides declarative management of PTP interfaces configuration +on Mellanox ONYX network devices." +notes: + - 'Tested on ONYX 3.6.8130' + - 'PTP Protocol must be enabled on switch.' + - 'Interface must not be a switch port interface.' +options: + name: + description: + - 'ethernet or vlan interface name that we want to configure PTP on it' + required: true + state: + description: + - 'Enable/Disable PTP on Interface' + default: enabled + choices: + - enabled + - disabled + delay_request: + description: + - 'configure PTP delay request interval, Range 0-5' + announce_interval: + description: + - 'configure PTP announce setting for interval, Range -3-1' + announce_timeout: + description: + - 'configure PTP announce setting for timeout, Range 2-10' + sync_interval: + description: + - 'configure PTP sync interval, Range -7--1' +''' + +EXAMPLES = """ +- name: Configure PTP interface + onyx_ptp_interface: + state: enabled + name: Eth1/1 + delay_request: 0 + announce_interval: -2 + announce_timeout: 3 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface ethernet 1/16 ptp enable + - interface ethernet 1/16 ptp delay-req interval 0 + - interface ethernet 1/16 ptp announce interval -1 +""" + +import re + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxPtpInterfaceModule(BaseOnyxModule): + IF_ETH_REGEX = re.compile(r"^Eth(\d+\/\d+|Eth\d+\/\d+\d+)$") + IF_VLAN_REGEX = re.compile(r"^Vlan (\d+)$") + + IF_TYPE_ETH = "ethernet" + IF_TYPE_VLAN = "vlan" + + IF_TYPE_MAP = { + IF_TYPE_ETH: IF_ETH_REGEX, + IF_TYPE_VLAN: IF_VLAN_REGEX + } + + RANGE_ATTR = { + "delay_request": (0, 5), + "announce_interval": (-3, -1), + "announce_timeout": (2, 10), + "sync_interval": (-7, -1) + } + + _interface_type = None + _interface_id = None + + def init_module(self): + """ initialize module + """ + element_spec = dict( + name=dict(required=True), + state=dict(choices=['enabled', 'disabled'], default='enabled'), + delay_request=dict(type=int), + announce_interval=dict(type=int), + announce_timeout=dict(type=int), + sync_interval=dict(type=int) + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + @classmethod + def _get_interface_type(cls, if_name): + if_type = None + if_id = None + for interface_type, interface_regex in iteritems(cls.IF_TYPE_MAP): + match = interface_regex.match(if_name) + if match: + if_type = interface_type + if_id = match.group(1) + break + return if_type, if_id + + def _set_if_type(self, module_params): + if_name = module_params['name'] + self._interface_type, self._interface_id = self._get_interface_type(if_name) + if not self._interface_id: + self._module.fail_json( + msg='unsupported interface name/type: %s' % if_name) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self._set_if_type(self._required_config) + self.validate_param_values(self._required_config) + + def _validate_attr_is_not_none(self, attr_name, attr_value): + if attr_value is not None: + self._module.fail_json(msg='Can not set %s value on switch while state is disabled' % attr_name) + + def validate_param_values(self, obj, param=None): + if obj['state'] == 'disabled': + for attr_name in self.RANGE_ATTR: + self._validate_attr_is_not_none(attr_name, obj[attr_name]) + super(OnyxPtpInterfaceModule, self).validate_param_values(obj, param) + + def _validate_range(self, value, attr_name): + min_value, max_value = self.RANGE_ATTR[attr_name] + if value and not min_value <= int(value) <= max_value: + self._module.fail_json(msg='%s value must be between %d and %d' % (attr_name, min_value, max_value)) + + def validate_delay_request(self, value): + self._validate_range(value, "delay_request") + + def validate_announce_interval(self, value): + self._validate_range(value, "announce_interval") + + def validate_announce_timeout(self, value): + self._validate_range(value, "announce_timeout") + + def validate_sync_interval(self, value): + self._validate_range(value, "sync_interval") + + def _set_ptp_interface_config(self, ptp_interface_config): + if ptp_interface_config is None: + self._current_config['state'] = 'disabled' + return + ptp_interface_config = ptp_interface_config[0] + self._current_config['state'] = 'enabled' + self._current_config['delay_request'] = int(ptp_interface_config['Delay request interval(log mean)']) + self._current_config['announce_interval'] = int(ptp_interface_config['Announce interval(log mean)']) + self._current_config['announce_timeout'] = int(ptp_interface_config['Announce receipt time out']) + self._current_config['sync_interval'] = int(ptp_interface_config['Sync interval(log mean)']) + + def _show_ptp_interface_config(self): + cmd = "show ptp interface %s %s" % (self._interface_type, self._interface_id) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + ptp_interface_config = self._show_ptp_interface_config() + self._set_ptp_interface_config(ptp_interface_config) + + def _generate_attr_command(self, attr_name, attr_cmd_name): + attr_val = self._required_config.get(attr_name) + if attr_val is not None: + curr_val = self._current_config.get(attr_name) + if attr_val != curr_val: + self._commands.append( + 'interface %s %s ptp %s %d' % (self._interface_type, self._interface_id, attr_cmd_name, attr_val)) + + def generate_commands(self): + state = self._required_config.get("state", "enabled") + self._gen_ptp_commands(state) + + self._generate_attr_command("delay_request", "delay-req interval") + self._generate_attr_command("announce_interval", "announce interval") + self._generate_attr_command("announce_timeout", "announce timeout") + self._generate_attr_command("sync_interval", "sync interval") + + def _add_if_ptp_cmd(self, req_state): + if req_state == 'enabled': + if_ptp_cmd = 'interface %s %s ptp enable' % (self._interface_type, self._interface_id) + else: + if_ptp_cmd = 'no interface %s %s ptp enable' % (self._interface_type, self._interface_id) + self._commands.append(if_ptp_cmd) + + def _gen_ptp_commands(self, req_state): + curr_state = self._current_config.get('state') + if curr_state != req_state: + self._add_if_ptp_cmd(req_state) + + +def main(): + """ main entry point for module execution + """ + OnyxPtpInterfaceModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_qos.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_qos.py new file mode 100644 index 00000000..79074e66 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_qos.py @@ -0,0 +1,231 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_qos +author: "Anas Badaha (@anasb)" +short_description: Configures QoS +description: + - This module provides declarative management of Onyx QoS configuration + on Mellanox ONYX network devices. +notes: + - Tested on ONYX 3.6.8130 +options: + interfaces: + description: + - list of interfaces name. + required: true + trust: + description: + - trust type. + choices: ['L2', 'L3', 'both'] + default: L2 + rewrite_pcp: + description: + - rewrite with type pcp. + choices: ['enabled', 'disabled'] + default: disabled + rewrite_dscp: + description: + - rewrite with type dscp. + choices: ['enabled', 'disabled'] + default: disabled +''' + +EXAMPLES = """ +- name: Configure QoS + onyx_QoS: + interfaces: + - Mpo7 + - Mpo7 + trust: L3 + rewrite_pcp: disabled + rewrite_dscp: enabled + +- name: Configure QoS + onyx_QoS: + interfaces: + - Eth1/1 + - Eth1/2 + trust: both + rewrite_pcp: disabled + rewrite_dscp: enabled +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface ethernet 1/16 qos trust L3 + - interface mlag-port-channel 7 qos trust L3 + - interface port-channel 1 qos trust L3 + - interface mlag-port-channel 7 qos trust L2 + - interface mlag-port-channel 7 qos rewrite dscp + - interface ethernet 1/16 qos rewrite pcp + - interface ethernet 1/1 no qos rewrite pcp +""" + +import re +from ansible.module_utils.six import iteritems +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxQosModule(BaseOnyxModule): + TRUST_CMD = "interface {0} {1} qos trust {2}" + NO_REWRITE_PCP_CMD = "interface {0} {1} no qos rewrite pcp" + NO_REWRITE_DSCP_CMD = "interface {0} {1} no qos rewrite dscp" + REWRITE_PCP_CMD = "interface {0} {1} qos rewrite pcp" + REWRITE_DSCP_CMD = "interface {0} {1} qos rewrite dscp" + + REWRITE_PCP = "pcp" + REWRITE_DSCP = "dscp" + + IF_ETH_REGEX = re.compile(r"^Eth(\d+\/\d+|Eth\d+\/\d+\d+)$") + IF_PO_REGEX = re.compile(r"^Po(\d+)$") + MLAG_NAME_REGEX = re.compile(r"^Mpo(\d+)$") + + IF_TYPE_ETH = "ethernet" + PORT_CHANNEL = "port-channel" + MLAG_PORT_CHANNEL = "mlag-port-channel" + + IF_TYPE_MAP = { + IF_TYPE_ETH: IF_ETH_REGEX, + PORT_CHANNEL: IF_PO_REGEX, + MLAG_PORT_CHANNEL: MLAG_NAME_REGEX + } + + def init_module(self): + """ initialize module + """ + element_spec = dict( + interfaces=dict(type='list', required=True), + trust=dict(choices=['L2', 'L3', 'both'], default='L2'), + rewrite_pcp=dict(choices=['enabled', 'disabled'], default='disabled'), + rewrite_dscp=dict(choices=['enabled', 'disabled'], default='disabled') + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def _get_interface_type(self, if_name): + if_type = None + if_id = None + for interface_type, interface_regex in iteritems(self.IF_TYPE_MAP): + match = interface_regex.match(if_name) + if match: + if_type = interface_type + if_id = match.group(1) + break + return if_type, if_id + + def _set_interface_qos_config(self, interface_qos_config, interface, if_type, if_id): + interface_qos_config = interface_qos_config[0].get(interface) + trust = interface_qos_config[0].get("Trust mode") + rewrite_dscp = interface_qos_config[0].get("DSCP rewrite") + rewrite_pcp = interface_qos_config[0].get("PCP,DEI rewrite") + + self._current_config[interface] = dict(trust=trust, rewrite_dscp=rewrite_dscp, + rewrite_pcp=rewrite_pcp, if_type=if_type, if_id=if_id) + + def _show_interface_qos(self, if_type, interface): + cmd = "show qos interface {0} {1}".format(if_type, interface) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + for interface in self._required_config.get("interfaces"): + if_type, if_id = self._get_interface_type(interface) + if not if_id: + self._module.fail_json( + msg='unsupported interface: {0}'.format(interface)) + interface_qos_config = self._show_interface_qos(if_type, if_id) + if interface_qos_config is not None: + self._set_interface_qos_config(interface_qos_config, interface, if_type, if_id) + else: + self._module.fail_json( + msg='Interface {0} does not exist on switch'.format(interface)) + + def generate_commands(self): + trust = self._required_config.get("trust") + rewrite_pcp = self._required_config.get("rewrite_pcp") + rewrite_dscp = self._required_config.get("rewrite_dscp") + for interface in self._required_config.get("interfaces"): + ignored1, ignored2, current_trust, if_type, if_id = self._get_current_rewrite_config(interface) + self._add_interface_trust_cmds(if_type, if_id, interface, trust, current_trust) + self._add_interface_rewrite_cmds(if_type, if_id, interface, + rewrite_pcp, rewrite_dscp) + + def _get_current_rewrite_config(self, interface): + current_interface_qos_config = self._current_config.get(interface) + current_rewrite_pcp = current_interface_qos_config.get('rewrite_pcp') + current_rewrite_dscp = current_interface_qos_config.get('rewrite_dscp') + if_type = current_interface_qos_config.get("if_type") + if_id = current_interface_qos_config.get("if_id") + current_trust = current_interface_qos_config.get('trust') + + return current_rewrite_pcp, current_rewrite_dscp, current_trust, if_type, if_id + + def _add_interface_trust_cmds(self, if_type, if_id, interface, trust, current_trust): + + current_rewrite_pcp, current_rewrite_dscp, ignored1, ignored2, ignored3 = self._get_current_rewrite_config( + interface) + + if trust == "L3" and trust != current_trust: + self._add_no_rewrite_cmd(if_type, if_id, interface, self.REWRITE_DSCP, current_rewrite_dscp) + self._commands.append(self.TRUST_CMD.format(if_type, if_id, trust)) + elif trust == "L2" and trust != current_trust: + self._add_no_rewrite_cmd(if_type, if_id, interface, self.REWRITE_PCP, current_rewrite_pcp) + self._commands.append(self.TRUST_CMD.format(if_type, if_id, trust)) + elif trust == "both" and trust != current_trust: + self._add_no_rewrite_cmd(if_type, if_id, interface, self.REWRITE_DSCP, current_rewrite_dscp) + self._add_no_rewrite_cmd(if_type, if_id, interface, self.REWRITE_PCP, current_rewrite_pcp) + self._commands.append(self.TRUST_CMD.format(if_type, if_id, trust)) + + def _add_interface_rewrite_cmds(self, if_type, if_id, interface, rewrite_pcp, rewrite_dscp): + current_rewrite_pcp, current_rewrite_dscp, ignored1, ignored2, ignored3 = self._get_current_rewrite_config( + interface) + + if rewrite_pcp == "enabled" and rewrite_pcp != current_rewrite_pcp: + self._commands.append(self.REWRITE_PCP_CMD.format(if_type, if_id)) + elif rewrite_pcp == "disabled" and rewrite_pcp != current_rewrite_pcp: + self._commands.append(self.NO_REWRITE_PCP_CMD.format(if_type, if_id)) + + if rewrite_dscp == "enabled" and rewrite_dscp != current_rewrite_dscp: + self._commands.append(self.REWRITE_DSCP_CMD.format(if_type, if_id)) + elif rewrite_dscp == "disabled" and rewrite_dscp != current_rewrite_dscp: + self._commands.append(self.NO_REWRITE_DSCP_CMD.format(if_type, if_id)) + + def _add_no_rewrite_cmd(self, if_type, if_id, interface, rewrite_type, current_rewrite): + if rewrite_type == self.REWRITE_PCP and current_rewrite == "enabled": + self._commands.append(self.NO_REWRITE_PCP_CMD.format(if_type, if_id)) + self._current_config[interface]["rewrite_pcp"] = "disabled" + elif rewrite_type == self.REWRITE_DSCP and current_rewrite == "enabled": + self._commands.append(self.NO_REWRITE_DSCP_CMD.format(if_type, if_id)) + self._current_config[interface]["rewrite_dscp"] = "disabled" + + +def main(): + """ main entry point for module execution + """ + OnyxQosModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp.py new file mode 100644 index 00000000..895d003a --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp.py @@ -0,0 +1,423 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_snmp +version_added: '0.2.0' +author: "Sara-Touqan (@sarato)" +short_description: Manages SNMP general configurations on Mellanox ONYX network devices +description: + - This module provides declarative management of SNMP + on Mellanox ONYX network devices. +options: + state_enabled: + description: + - Enables/Disables the state of the SNMP configuration. + type: bool + contact_name: + description: + - Sets the SNMP contact name. + type: str + location: + description: + - Sets the SNMP location. + type: str + communities_enabled: + description: + - Enables/Disables community-based authentication on the system. + type: bool + multi_communities_enabled: + description: + - Enables/Disables multiple communities to be configured. + type: bool + snmp_communities: + type: list + description: + - List of snmp communities + suboptions: + community_name: + description: + - Configures snmp community name. + required: true + type: str + community_type: + description: + - Add this community as either a read-only or read-write community. + choices: ['read-only', 'read-write'] + type: str + state: + description: + - Used to decide if you want to delete the given snmp community or not + choices: ['present', 'absent'] + type: str + notify_enabled: + description: + - Enables/Disables sending of SNMP notifications (traps and informs) from thee system. + type: bool + notify_port: + description: + - Sets the default port to which notifications are sent. + type: str + notify_community: + description: + - Sets the default community for SNMP v1 and v2c notifications sent to hosts which do not have a community override set. + type: str + notify_send_test: + description: + - Sends a test notification. + type: str + choices: ['yes','no'] + notify_event: + description: + - Specifys which events will be sent as SNMP notifications. + type: str + choices: ['asic-chip-down', 'dcbx-pfc-port-oper-state-trap', 'insufficient-power', 'mstp-new-bridge-root', + 'ospf-lsdb-approaching-overflow', 'sm-stop', 'user-logout', 'cli-line-executed', 'dcbx-pfc-port-peer-state-trap', + 'interface-down', 'mstp-new-root-port', 'ospf-lsdb-overflow', 'snmp-authtrap', 'xstp-new-root-bridge', + 'cpu-util-high', 'disk-io-high', 'interface-up', 'mstp-topology-change', 'ospf-nbr-state-change', + 'temperature-too-high', 'xstp-root-port-change', 'dcbx-ets-module-state-change', 'disk-space-low', + 'internal-bus-error', 'netusage-high', 'paging-high', 'topology_change', 'xstp-topology-change', + 'dcbx-ets-port-admin-state-trap', 'entity-state-change', 'internal-link-speed-mismatch', 'new_root', + 'power-redundancy-mismatch', 'unexpected-cluster-join', 'dcbx-ets-port-oper-state-trap', 'expected-shutdown', + 'liveness-failure', 'ospf-auth-fail', 'process-crash', 'unexpected-cluster-leave', 'dcbx-ets-port-peer-state-trap', + 'health-module-status', 'low-power', 'ospf-config-error', 'process-exit', 'unexpected-cluster-size', + 'dcbx-pfc-module-state-change', 'insufficient-fans', 'low-power-recover', 'ospf-if-rx-bad-packet', + 'sm-restart', 'unexpected-shutdown', 'dcbx-pfc-port-admin-state-trap', 'insufficient-fans-recover', 'memusage-high', + 'ospf-if-state-change', 'sm-start', 'user-login'] + engine_id_reset: + description: + - Sets SNMPv3 engineID to node unique value. + type: bool + snmp_permissions: + type: list + description: + - Allow SNMPSET requests for items in a MIB. + suboptions: + state_enabled: + description: + - Enables/Disables the request. + required: true + type: bool + permission_type: + description: + - Configures the request type. + choices: ['MELLANOX-CONFIG-DB-MIB', 'MELLANOX-EFM-MIB','MELLANOX-POWER-CYCLE','MELLANOX-SW-UPDATE','RFC1213-MIB'] + type: str +''' + +EXAMPLES = """ +- name: Configure SNMP + onyx_snmp: + state_enabled: yes + contact_name: sara + location: Nablus + communities_enabled: no + multi_communities_enabled: no + notify_enabled: yes + notify_port: 1 + notify_community: community_1 + notify_send_test: yes + notify_event: temperature-too-high + snmp_communities: + - community_name: public + community_type: read-only + state: absent + snmp_permissions: + - state_enabled: yes + permission_type: MELLANOX-CONFIG-DB-MIB +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - snmp-server enable + - no snmp-server enable + - snmp-server location <location_name> + - snmp-server contact <contact_name> + - snmp-server enable communities + - no snmp-server enable communities + - snmp-server enable mult-communities + - no snmp-server enable mult-communities + - snmp-server enable notify + - snmp-server notify port <port_number> + - snmp-server notify community <community_name> + - snmp-server notify send-test + - snmp-server notify event <event_name> + - snmp-server enable set-permission <permission_type> + - no snmp-server enable set-permission <permission_type> + - snmp-server community <community_name> <community_type> + - no snmp-server community <community_name>. + - snmp-server engineID reset. +""" + + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxSNMPModule(BaseOnyxModule): + + def init_module(self): + """ module initialization + """ + + community_spec = dict(community_name=dict(required=True), + community_type=dict(choices=['read-only', 'read-write']), + state=dict(choices=['present', 'absent'])) + + snmp_permission_spec = dict(state_enabled=dict(type='bool', required=True), + permission_type=dict(choices=['MELLANOX-CONFIG-DB-MIB', 'MELLANOX-EFM-MIB', 'MELLANOX-POWER-CYCLE', + 'MELLANOX-SW-UPDATE', 'RFC1213-MIB'])) + + event_choices = ['asic-chip-down', 'dcbx-pfc-port-oper-state-trap', 'insufficient-power', 'mstp-new-bridge-root', + 'ospf-lsdb-approaching-overflow', 'sm-stop', 'user-logout', 'cli-line-executed', 'dcbx-pfc-port-peer-state-trap', + 'interface-down', 'mstp-new-root-port', 'ospf-lsdb-overflow', 'snmp-authtrap', 'xstp-new-root-bridge', + 'cpu-util-high', 'disk-io-high', 'interface-up', 'mstp-topology-change', 'ospf-nbr-state-change', + 'temperature-too-high', 'xstp-root-port-change', 'dcbx-ets-module-state-change', 'disk-space-low', + 'internal-bus-error', 'netusage-high', 'paging-high', 'topology_change', 'xstp-topology-change', + 'dcbx-ets-port-admin-state-trap', 'entity-state-change', 'internal-link-speed-mismatch', 'new_root', + 'power-redundancy-mismatch', 'unexpected-cluster-join', 'dcbx-ets-port-oper-state-trap', 'expected-shutdown', + 'liveness-failure', 'ospf-auth-fail', 'process-crash', 'unexpected-cluster-leave', 'dcbx-ets-port-peer-state-trap', + 'health-module-status', 'low-power', 'ospf-config-error', 'process-exit', 'unexpected-cluster-size', + 'dcbx-pfc-module-state-change', 'insufficient-fans', 'low-power-recover', 'ospf-if-rx-bad-packet', + 'sm-restart', 'unexpected-shutdown', 'dcbx-pfc-port-admin-state-trap', 'insufficient-fans-recover', 'memusage-high', + 'ospf-if-state-change', 'sm-start', 'user-login'] + element_spec = dict( + state_enabled=dict(type='bool'), + contact_name=dict(type='str'), + location=dict(type='str'), + communities_enabled=dict(type='bool'), + multi_communities_enabled=dict(type='bool'), + snmp_communities=dict(type='list', elements='dict', options=community_spec), + notify_enabled=dict(type='bool'), + notify_port=dict(type='str'), + notify_community=dict(type='str'), + notify_send_test=dict(type='str', choices=['yes', 'no']), + notify_event=dict(type='str', choices=event_choices), + engine_id_reset=dict(type='bool'), + snmp_permissions=dict(type='list', elements='dict', options=snmp_permission_spec) + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def _show_snmp_config(self): + show_cmds = [] + cmd = "show snmp" + show_cmds.append(show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False)) + cmd = "show running-config | include snmp" + show_cmds.append(show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False)) + return show_cmds + + def _set_snmp_config(self, all_snmp_config): + ro_communities_list = [] + rw_communities_list = [] + snmp_config = all_snmp_config[0] + if not snmp_config: + return + if snmp_config.get("SNMP enabled") == 'yes': + self._current_config['state_enabled'] = True + else: + self._current_config['state_enabled'] = False + self._current_config['contact_name'] = snmp_config.get("System contact") + self._current_config['location'] = snmp_config.get("System location") + curr_ro_comm = snmp_config.get("Read-only community") + if curr_ro_comm: + ro_arr = curr_ro_comm.split(' ') + rw_arr = snmp_config.get("Read-write community").split(' ') + ro_communities_list = ro_arr[0] + rw_communities_list = rw_arr[0] + if (len(ro_arr) == 2): + self._current_config['communities_enabled'] = False + else: + self._current_config['communities_enabled'] = True + else: + read_only_communities = all_snmp_config[1] + read_write_communities = all_snmp_config[2] + if not read_only_communities: + return + read_only_comm = read_only_communities.get("Read-only communities") + if read_only_comm: + self._current_config['communities_enabled'] = True + ro_communities_list = read_only_comm[0].get("Lines") + else: + self._current_config['communities_enabled'] = False + ro_comm_disabled = read_only_communities.get("Read-only communities (DISABLED)") + if ro_comm_disabled: + ro_communities_list = ro_comm_disabled[0].get("Lines") + if not read_write_communities: + return + read_write_comm = read_write_communities.get("Read-write communities") + if read_write_comm: + self._current_config['communities_enabled'] = True + rw_communities_list = read_write_comm[0].get("Lines") + else: + self._current_config['communities_enabled'] = False + rw_comm_disabled = read_write_communities.get("Read-write communities (DISABLED)") + if rw_comm_disabled: + rw_communities_list = rw_comm_disabled[0].get("Lines") + self._current_config['ro_communities_list'] = ro_communities_list + self._current_config['rw_communities_list'] = rw_communities_list + + def _set_snmp_running_config(self, snmp_running_config): + self._current_config['multi_comm_enabled'] = True + self._current_config['notify_enabled'] = True + curr_config_arr = [] + snmp_lines = snmp_running_config.get('Lines') + for runn_config in snmp_lines: + curr_config_arr.append(runn_config.strip()) + if 'no snmp-server enable mult-communities' in snmp_lines: + self._current_config['multi_comm_enabled'] = False + if 'no snmp-server enable notify' in snmp_lines: + self._current_config['notify_enabled'] = False + self._current_config['snmp_running_config'] = curr_config_arr + + def load_current_config(self): + self._current_config = dict() + snmp_config = self._show_snmp_config() + if snmp_config[0]: + self._set_snmp_config(snmp_config[0]) + if snmp_config[1]: + self._set_snmp_running_config(snmp_config[1]) + + def generate_commands(self): + current_state = self._current_config.get("state_enabled") + state = current_state + req_state = self._required_config.get("state_enabled") + if req_state is not None: + state = req_state + if state is not None: + if current_state != state: + if state is True: + self._commands.append('snmp-server enable') + else: + self._commands.append('no snmp-server enable') + + contact_name = self._required_config.get("contact_name") + if contact_name: + current_contact_name = self._current_config.get("contact_name") + if contact_name is not None: + if current_contact_name != contact_name: + self._commands.append('snmp-server contact {0}' .format(contact_name)) + + location = self._required_config.get("location") + if location: + current_location = self._current_config.get("location") + if location is not None: + if current_location != location: + self._commands.append('snmp-server location {0}' .format(location)) + + communities_enabled = self._required_config.get("communities_enabled") + if communities_enabled is not None: + current_communities_enabled = self._current_config.get("communities_enabled") + if communities_enabled is not None: + if current_communities_enabled != communities_enabled: + if communities_enabled is True: + self._commands.append('snmp-server enable communities') + else: + self._commands.append('no snmp-server enable communities') + + ro_communities = self._current_config.get("ro_communities_list") + rw_communities = self._current_config.get("rw_communities_list") + snmp_communities = self._required_config.get("snmp_communities") + if snmp_communities: + if snmp_communities is not None: + for community in snmp_communities: + community_name = community.get("community_name") + state = community.get("state") + if state: + if state == 'absent': + self._commands.append('no snmp-server community {0}' .format(community_name)) + continue + community_type = community.get("community_type") + if community_type: + if community_type == 'read-only': + if community_name not in ro_communities: + self._commands.append('snmp-server community {0} ro' .format(community_name)) + else: + if community_name not in rw_communities: + self._commands.append('snmp-server community {0} rw' .format(community_name)) + else: + if community_name not in ro_communities: + self._commands.append('snmp-server community {0}' .format(community_name)) + + engine_id_reset = self._required_config.get("engine_id_reset") + if engine_id_reset is not None: + if engine_id_reset: + self._commands.append('snmp-server engineID reset') + + current_multi_comm_state = self._current_config.get("multi_comm_enabled") + multi_communities_enabled = self._required_config.get("multi_communities_enabled") + if multi_communities_enabled is not None: + if current_multi_comm_state != multi_communities_enabled: + if multi_communities_enabled is True: + self._commands.append('snmp-server enable mult-communities') + else: + self._commands.append('no snmp-server enable mult-communities') + + notify_enabled = self._required_config.get("notify_enabled") + if notify_enabled is not None: + current_notify_state = self._current_config.get("notify_enabled") + if current_notify_state != notify_enabled: + if notify_enabled is True: + self._commands.append('snmp-server enable notify') + else: + self._commands.append('no snmp-server enable notify') + + snmp_permissions = self._required_config.get("snmp_permissions") + if snmp_permissions is not None: + for permission in snmp_permissions: + permission_type = permission.get('permission_type') + if permission.get('state_enabled') is True: + self._commands.append('snmp-server enable set-permission {0}' .format(permission_type)) + else: + self._commands.append('no snmp-server enable set-permission {0}' .format(permission_type)) + + snmp_running_config = self._current_config.get("snmp_running_config") + notify_port = self._required_config.get("notify_port") + if notify_port is not None: + notified_cmd = 'snmp-server notify port {0}' .format(notify_port) + if notified_cmd not in snmp_running_config: + self._commands.append('snmp-server notify port {0}' .format(notify_port)) + + notify_community = self._required_config.get("notify_community") + if notify_community is not None: + notified_cmd = 'snmp-server notify community {0}' .format(notify_community) + if notified_cmd not in snmp_running_config: + self._commands.append('snmp-server notify community {0}' .format(notify_community)) + + notify_send_test = self._required_config.get("notify_send_test") + if notify_send_test is not None: + if notify_send_test == 'yes': + self._commands.append('snmp-server notify send-test') + + notify_event = self._required_config.get("notify_event") + if notify_event is not None: + self._commands.append('snmp-server notify event {0}' .format(notify_event)) + + +def main(): + """ main entry point for module execution + """ + OnyxSNMPModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp_hosts.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp_hosts.py new file mode 100644 index 00000000..93facf7d --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp_hosts.py @@ -0,0 +1,421 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_snmp_hosts +version_added: '0.2.0' +author: "Sara Touqan (@sarato)" +short_description: Configures SNMP host parameters +description: + - This module provides declarative management of SNMP hosts protocol params + on Mellanox ONYX network devices. +options: + hosts: + type: list + description: + - List of snmp hosts + suboptions: + name: + description: + - Specifies the name of the host. + required: true + type: str + enabled: + description: + - Temporarily Enables/Disables sending of all notifications to this host. + type: bool + notification_type: + description: + - Configures the type of sending notification to the specified host. + choices: ['trap', 'inform'] + type: str + port: + description: + - Overrides default target port for this host. + type: str + version: + description: + - Specifys SNMP version of informs to send. + choices: ['1', '2c', '3'] + type: str + user_name: + description: + - Specifys username for this inform sink. + type: str + auth_type: + description: + - Configures SNMP v3 security parameters, specifying passwords in a nother parameter (auth_password) (passwords are always stored encrypted). + choices: ['md5', 'sha', 'sha224', 'sha256', 'sha384', 'sha512'] + type: str + auth_password: + description: + - The password needed to configure the auth type. + type: str + privacy_type: + description: + - Specifys SNMP v3 privacy settings for this user. + choices: ['3des', 'aes-128', 'aes-192', 'aes-192-cfb', 'aes-256', 'aes-256-cfb', 'des'] + type: str + privacy_password: + description: + - The password needed to configure the privacy type. + type: str + state: + description: + - Used to decide if you want to delete the specified host or not. + choices: ['present' , 'absent'] + type: str +''' + +EXAMPLES = """ +- name: Enables snmp host + onyx_snmp_hosts: + hosts: + - name: 1.1.1.1 + enabled: true + +- name: Configures snmp host with version 2c + onyx_snmp_hosts: + hosts: + - name: 2.3.2.4 + enabled: true + notification_type: trap + port: 66 + version: 2c + +- name: Configures snmp host with version 3 and configures it with user as sara + onyx_snmp_hosts: + hosts: + - name: 2.3.2.4 + enabled: true + notification_type: trap + port: 66 + version: 3 + user_name: sara + auth_type: sha + auth_password: jnbdfijbdsf + privacy_type: 3des + privacy_password: nojfd8uherwiugfh + +- name: Deletes the snmp host + onyx_snmp_hosts: + hosts: + - name: 2.3.2.4 + state: absent +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - snmp-server host <host_name> disable + - no snmp-server host <host_name> disable + - snmp-server host <host_name> informs port <port_number> version <version_number> + - snmp-server host <host_name> traps port <port_number> version <version_number> + - snmp-server host <host_name> informs port <port_number> version <version_number> user <user_name> auth <auth_type> + <auth_password> priv <privacy_type> <privacy_password> + - snmp-server host <host_name> traps port <port_number> version <version_number> user <user_name> auth <auth_type> + <auth_password> priv <privacy_type> <privacy_password> + - no snmp-server host <host_name>. +""" + +import re + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxSNMPHostsModule(BaseOnyxModule): + + def init_module(self): + """ initialize module + """ + host_spec = dict(name=dict(required=True), + enabled=dict(type='bool'), + notification_type=dict(type='str', choices=['trap', 'inform']), + port=dict(type='str'), + version=dict(type='str', choices=['1', '2c', '3']), + user_name=dict(type='str'), + auth_type=dict(type='str', choices=['md5', 'sha', 'sha224', 'sha256', 'sha384', 'sha512']), + privacy_type=dict(type='str', choices=['3des', 'aes-128', 'aes-192', 'aes-192-cfb', 'aes-256', 'aes-256-cfb', 'des']), + privacy_password=dict(type='str', no_log=True), + auth_password=dict(type='str', no_log=True), + state=dict(type='str', choices=['present', 'absent']) + ) + element_spec = dict( + hosts=dict(type='list', elements='dict', options=host_spec), + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def validate_snmp_required_params(self): + req_hosts = self._required_config.get("hosts") + if req_hosts: + for host in req_hosts: + version = host.get('version') + if version: + if version == '3': + if host.get('user_name') is None or host.get('auth_type') is None or host.get('auth_password') is None: + self._module.fail_json(msg='user_name, auth_type and auth_password are required when version number is 3.') + + if host.get('notification_type') is not None: + if host.get('version') is None or host.get('port') is None: + self._module.fail_json(msg='port and version are required when notification_type is provided.') + + if host.get('auth_type') is not None: + if host.get('auth_password') is None: + self._module.fail_json(msg='auth_password is required when auth_type is provided.') + + if host.get('privacy_type') is not None: + if host.get('privacy_password') is None: + self._module.fail_json(msg='privacy_password is required when privacy_type is provided.') + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + self.validate_snmp_required_params() + + def _set_host_config(self, hosts_config): + hosts = hosts_config.get('Notification sinks') + if hosts[0].get('Lines'): + self._current_config['current_hosts'] = dict() + self._current_config['host_names'] = [] + return + + current_hosts = dict() + host_names = [] + for host in hosts: + host_info = dict() + for host_name in host: + host_names.append(host_name) + enabled = True + first_entry = host.get(host_name)[0] + if first_entry: + if first_entry.get('Enabled') == 'no': + enabled = False + notification_type = first_entry.get('Notification type') + notification_type = notification_type.split() + host_info['notification_type'] = notification_type[2] + version = notification_type[1][1:] + host_info['port'] = first_entry.get('Port') + host_info['name'] = host_name + host_info['enabled'] = enabled + host_info['version'] = version + if first_entry.get('Community') is None: + if len(first_entry) == 8: + host_info['user_name'] = first_entry.get('Username') + host_info['auth_type'] = first_entry.get('Authentication type') + host_info['privacy_type'] = first_entry.get('Privacy type') + elif len(host.get(host_name)) == 2: + second_entry = host.get(host_name)[1] + host_info['user_name'] = second_entry.get('Username') + host_info['auth_type'] = second_entry.get('Authentication type') + host_info['privacy_type'] = second_entry.get('Privacy type') + else: + host_info['user_name'] = '' + host_info['auth_type'] = '' + host_info['privacy_type'] = '' + else: + host_info['user_name'] = '' + host_info['auth_type'] = '' + host_info['privacy_type'] = '' + current_hosts[host_name] = host_info + self._current_config['current_hosts'] = current_hosts + self._current_config['host_names'] = host_names + + def _show_hosts_config(self): + cmd = "show snmp host" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + hosts_config = self._show_hosts_config() + if hosts_config[1]: + self._set_host_config(hosts_config[1]) + + def generate_snmp_commands_with_current_config(self, host): + host_id = host.get('name') + host_notification_type = host.get('notification_type') + host_enabled = host.get("enabled") + host_port = host.get('port') + host_version = host.get('version') + host_username = host.get('user_name') + host_auth_type = host.get('auth_type') + host_auth_pass = host.get('auth_password') + host_priv_type = host.get('privacy_type') + host_priv_pass = host.get('privacy_password') + present_state = host.get('state') + current_hosts = self._current_config.get("current_hosts") + current_entry = current_hosts.get(host_id) + if present_state is not None: + if present_state == 'absent': + self._commands.append('no snmp-server host {0}' .format(host_id)) + return + if host_enabled is not None: + if current_entry.get('enabled') != host_enabled: + if host_enabled is True: + self._commands.append('no snmp-server host {0} disable' .format(host_id)) + else: + self._commands.append('snmp-server host {0} disable' .format(host_id)) + if host_notification_type is not None: + current_port = current_entry.get('port') + current_version = current_entry.get('version') + current_priv_type = current_entry.get('privacy_type') + current_username = current_entry.get('user_name') + current_auth_type = current_entry.get('auth_type') + current_noti_type = current_entry.get('notification_type') + if host_port is not None: + if host_version is not None: + if host_version == '3': + if (host_priv_type is not None and host_priv_pass is not None): + if((current_noti_type != host_notification_type) or + ((current_port != host_port)) or + (current_version != host_version) or + (current_priv_type != host_priv_type) or + (current_username != host_username) or + (current_auth_type != host_auth_type)): + self._commands.append('snmp-server host {0} {1}s port {2} version {3} user {4} auth {5} {6} priv {7} {8}' + .format(host_id, host_notification_type, host_port, + host_version, host_username, host_auth_type, host_auth_pass, + host_priv_type, host_priv_pass)) + else: + if((current_noti_type != host_notification_type) or + ((current_port != host_port)) or + (current_version != host_version) or + (current_username != host_username) or + (current_auth_type != host_auth_type)): + self._commands.append('snmp-server host {0} {1}s port {2} version {3} user {4} auth {5} {6}' + .format(host_id, host_notification_type, + host_port, host_version, host_username, + host_auth_type, host_auth_pass)) + else: + if((current_noti_type != host_notification_type) or + ((current_port != host_port)) or + (current_version != host_version)): + self._commands.append('snmp-server host {0} {1}s port {2} version {3}' + .format(host_id, host_notification_type, + host_port, host_version)) + else: + if ((current_noti_type != host_notification_type) or + ((current_port != host_port))): + self._commands.append('snmp-server host {0} {1}s port {2}' + .format(host_id, host_notification_type, host_port)) + else: + if host_version is not None: + if host_version == '3': + if (host_priv_type is not None and host_priv_pass is not None): + if ((current_noti_type != host_notification_type) or + ((current_version != host_version)) or + (current_username != host_username) or + ((current_auth_type != host_auth_type)) or + (current_priv_type != host_priv_type)): + self._commands.append('snmp-server host {0} {1}s version {2} user {3} auth {4} {5} priv {6} {7}' + .format(host_id, host_notification_type, host_version, host_username, + host_auth_type, host_auth_pass, host_priv_type, host_priv_pass)) + + else: + if ((current_noti_type != host_notification_type) or + ((current_version != host_version)) or + (current_username != host_username) or + ((current_auth_type != host_auth_type))): + self._commands.append('snmp-server host {0} {1}s version {2} user {3} auth {4} {5}' + .format(host_id, host_notification_type, + host_version, host_username, host_auth_type, host_auth_pass)) + + else: + if ((current_noti_type != host_notification_type) or + ((current_version != host_version))): + self._commands.append('snmp-server host {0} {1}s version {2}' .format(host_id, + host_notification_type, host_version)) + + def generate_snmp_commands_without_current_config(self, host): + host_id = host.get('name') + host_notification_type = host.get('notification_type') + host_enabled = host.get("enabled") + host_port = host.get('port') + host_version = host.get('version') + host_username = host.get('user_name') + host_auth_type = host.get('auth_type') + host_auth_pass = host.get('auth_password') + host_priv_type = host.get('privacy_type') + host_priv_pass = host.get('privacy_password') + present_state = host.get('state') + present_state = host.get('state') + if present_state is not None: + if present_state == 'absent': + return + if host_enabled is not None: + if host_enabled is True: + self._commands.append('no snmp-server host {0} disable' .format(host_id)) + else: + self._commands.append('snmp-server host {0} disable' .format(host_id)) + + if host_notification_type is not None: + if host_port is not None: + if host_version is not None: + if host_version == '3': + if (host_priv_type is not None and host_priv_pass is not None): + self._commands.append('snmp-server host {0} {1}s port {2} version {3} user {4} auth {5} {6} priv {7} {8}' + .format(host_id, host_notification_type, host_port, host_version, host_username, + host_auth_type, host_auth_pass, host_priv_type, host_priv_pass)) + else: + self._commands.append('snmp-server host {0} {1}s port {2} version {3} user {4} auth {5} {6}' + .format(host_id, host_notification_type, host_port, host_version, host_username, + host_auth_type, host_auth_pass)) + else: + self._commands.append('snmp-server host {0} {1}s port {2} version {3}' .format(host_id, + host_notification_type, host_port, host_version)) + else: + self._commands.append('snmp-server host {0} {1}s port {2}' .format(host_id, + host_notification_type, host_port)) + else: + if host_version is not None: + if host_version == '3': + if (host_priv_type is not None and host_priv_pass is not None): + self._commands.append('snmp-server host {0} {1}s version {2} user {3} auth {4} {5} priv {6} {7}' + .format(host_id, host_notification_type, host_version, host_username, + host_auth_type, host_auth_pass, host_priv_type, host_priv_pass)) + else: + self._commands.append('snmp-server host {0} {1}s version {2} user {3} auth {4} {5}' .format(host_id, + host_notification_type, host_version, host_username, + host_auth_type, host_auth_pass)) + else: + self._commands.append('snmp-server host {0} {1}s version {2}' .format(host_id, + host_notification_type, host_version)) + + def generate_commands(self): + req_hosts = self._required_config.get("hosts") + host_names = self._current_config.get("host_names") + + if req_hosts: + for host in req_hosts: + host_id = host.get('name') + if host_id: + if host_names and (host_id in host_names): + self.generate_snmp_commands_with_current_config(host) + else: + self.generate_snmp_commands_without_current_config(host) + + +def main(): + """ main entry point for module execution + """ + OnyxSNMPHostsModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp_users.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp_users.py new file mode 100644 index 00000000..94744229 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_snmp_users.py @@ -0,0 +1,274 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_snmp_users +version_added: '0.2.0' +author: "Sara Touqan (@sarato)" +short_description: Configures SNMP User parameters +description: + - This module provides declarative management of SNMP Users protocol params + on Mellanox ONYX network devices. +options: + users: + type: list + description: + - List of snmp users + suboptions: + name: + description: + - Specifies the name of the user. + required: true + type: str + enabled: + description: + - Enables/Disables SNMP v3 access for the user. + type: bool + set_access_enabled: + description: + - Enables/Disables SNMP SET requests for the user. + type: bool + require_privacy: + description: + - Enables/Disables the Require privacy (encryption) for requests from this user + type: bool + auth_type: + description: + - Configures the hash type used to configure SNMP v3 security parameters. + choices: ['md5', 'sha', 'sha224', 'sha256', 'sha384', 'sha512'] + type: str + auth_password: + description: + - The password needed to configure the hash type. + type: str + capability_level: + description: + - Sets capability level for SET requests. + choices: ['admin','monitor','unpriv','v_admin'] + type: str +''' + +EXAMPLES = """ +- name: Enables snmp user + onyx_snmp_users: + users: + - name: sara + enabled: true + +- name: Enables snmp set requests + onyx_snmp_users: + users: + - name: sara + set_access_enabled: yes + +- name: Enables user require privacy + onyx_snmp_users: + users: + - name: sara + require_privacy: true + +- name: Configures user hash type + onyx_snmp_users: + users: + - auth_type: md5 + auth_password: 1297sara1234sara + +- name: Configures user capability_level + onyx_snmp_users: + users: + - name: sara + capability_level: admin +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - snmp-server user <user_name> v3 enable + - no snmp-server user <user_name> v3 enable + - snmp-server user <user_name> v3 enable sets + - no snmp-server user <user_name> v3 enable sets + - snmp-server user <user_name> v3 require-privacy + - no snmp-server user <user_name> v3 require-privacy + - snmp-server user <user_name> v3 capability <capability_level> + - snmp-server user <user_name> v3 auth <hash_type> <password> +""" + +import re + +from ansible.module_utils.basic import AnsibleModule + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxSNMPUsersModule(BaseOnyxModule): + + def init_module(self): + """ initialize module + """ + user_spec = dict(name=dict(required=True), + enabled=dict(type='bool'), + set_access_enabled=dict(type='bool'), + require_privacy=dict(type='bool'), + auth_type=dict(type='str', choices=['md5', 'sha', 'sha224', 'sha256', 'sha384', 'sha512']), + auth_password=dict(type='str'), + capability_level=dict(type='str', choices=['admin', 'monitor', 'unpriv', 'v_admin']), + ) + element_spec = dict( + users=dict(type='list', elements='dict', options=user_spec), + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def _set_snmp_config(self, users_config): + if users_config[0]: + if users_config[0].get('Lines'): + return + current_users = [] + count = 0 + enabled = True + set_access_enabled = True + require_privacy = True + auth_type = '' + capability_level = '' + name = '' + all_users_names = [] + for user in users_config: + user_dict = {} + entry_dict = {} + for entry in user: + name = entry.split()[2] + if user.get(entry): + if user.get(entry)[0]: + enabled = user.get(entry)[0].get('Enabled overall') + if enabled == 'no': + enabled = False + else: + enabled = True + set_access_enabled = user.get(entry)[1].get('SET access')[0].get('Enabled') + if set_access_enabled == 'no': + set_access_enabled = False + else: + set_access_enabled = True + require_privacy = user.get(entry)[0].get('Require privacy') + if require_privacy == 'yes': + require_privacy = True + else: + require_privacy = False + capability_level = user.get(entry)[1].get('SET access')[0].get('Capability level') + auth_type = user.get(entry)[0].get('Authentication type') + user_dict['enabled'] = enabled + user_dict['set_access_enabled'] = set_access_enabled + user_dict['auth_type'] = auth_type + user_dict['capability_level'] = capability_level + user_dict['require_privacy'] = require_privacy + entry_dict[name] = user_dict + all_users_names.append(name) + current_users.append(entry_dict) + self._current_config['users'] = current_users + self._current_config['current_names'] = all_users_names + + def _show_users(self): + cmd = "show snmp user" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + users_config = self._show_users() + if users_config: + self._set_snmp_config(users_config) + + def generate_commands(self): + req_uers = self._required_config.get("users") + current_users = self._current_config.get("users") + current_names = self._current_config.get("current_names") + if req_uers: + for user in req_uers: + user_id = user.get('name') + if user_id: + if current_names and (user_id in current_names): + for user_entry in current_users: + for user_name in user_entry: + if user_name == user_id: + user_state = user.get("enabled") + user_entry_name = user_entry.get(user_name) + if user_state is not None: + if user_state != user_entry_name.get("enabled"): + if user_state is True: + self._commands.append('snmp-server user {0} v3 enable' .format(user_id)) + else: + self._commands.append('no snmp-server user {0} v3 enable' .format(user_id)) + set_state = user.get("set_access_enabled") + if set_state is not None: + if set_state != user_entry_name.get("set_access_enabled"): + if set_state is True: + self._commands.append('snmp-server user {0} v3 enable sets' .format(user_id)) + else: + self._commands.append('no snmp-server user {0} v3 enable sets' .format(user_id)) + auth_type = user.get("auth_type") + if auth_type is not None: + if user.get("auth_password") is not None: + if auth_type != user_entry_name.get("auth_type"): + self._commands.append('snmp-server user {0} v3 auth {1} {2}' + .format(user_id, user.get('auth_type'), user.get('auth_password'))) + cap_level = user.get("capability_level") + if cap_level is not None: + if cap_level != user_entry_name.get("capability_level"): + self._commands.append('snmp-server user {0} v3 capability {1}' + .format(user_id, user.get('capability_level'))) + req_priv = user.get("require_privacy") + if req_priv is not None: + if req_priv != user_entry_name.get("require_privacy"): + if req_priv is True: + self._commands.append('snmp-server user {0} v3 require-privacy' .format(user_id)) + else: + self._commands.append('no snmp-server user {0} v3 require-privacy' .format(user_id)) + + else: + user_state = user.get("enabled") + if user_state is not None: + if user_state is True: + self._commands.append('snmp-server user {0} v3 enable' .format(user_id)) + else: + self._commands.append('no snmp-server user {0} v3 enable' .format(user_id)) + set_state = user.get("set_access_enabled") + if set_state is not None: + if set_state is True: + self._commands.append('snmp-server user {0} v3 enable sets' .format(user_id)) + else: + self._commands.append('no snmp-server user {0} v3 enable sets' .format(user_id)) + if user.get("capability_level") is not None: + self._commands.append('snmp-server user {0} v3 capability {1}' .format(user_id, user.get('capability_level'))) + req_priv = user.get("require_privacy") + if req_priv is not None: + if req_priv is True: + self._commands.append('snmp-server user {0} v3 require-privacy' .format(user_id)) + else: + self._commands.append('no snmp-server user {0} v3 require-privacy' .format(user_id)) + + +def main(): + """ main entry point for module execution + """ + OnyxSNMPUsersModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_syslog_files.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_syslog_files.py new file mode 100644 index 00000000..43410b18 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_syslog_files.py @@ -0,0 +1,248 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +module: onyx_syslog_files +version_added: '0.2.0' +author: "Anas Shami (@anass)" +short_description: Configure file management syslog module +description: + - This module provides declarative management of syslog + on Mellanox ONYX network devices. +notes: +options: + debug: + description: + - Configure settings for debug log files + type: bool + default: False + delete_group: + description: + - Delete certain log files + choices: ['current', 'oldest'] + type: str + rotation: + description: + - rotation related attributes + type: dict + suboptions: + frequency: + description: + - Rotate log files on a fixed time-based schedule + choices: ['daily', 'weekly', 'monthly'] + type: str + force: + description: + - force an immediate rotation of log files + type: bool + max_num: + description: + - Sepcify max_num of old log files to keep + type: int + size: + description: + - Rotate files when they pass max size + type: float + size_pct: + description: + - Rotatoe files when they pass percent of HD + type: float + upload_url: + description: + - upload local log files to remote host (ftp, scp, sftp, tftp) with format protocol://username[:password]@server/path + type: str + upload_file: + description: + - Upload compressed log file (current or filename) + type: str +''' + +EXAMPLES = """ +- name: Syslog delete old files +- onyx_syslog_files: + delete_group: oldest +- name: Syslog upload file +- onyx_syslog_files: + upload_url: scp://username:password@hostnamepath/filename + upload_file: current +- name: Syslog rotation force, frequency and max number +- onyx_syslog_files: + rotation: + force: true + max_num: 30 + frequency: daily + size: 128 +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - logging files delete current + - logging files rotate criteria + - logging files upload current url +""" +import re +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxSyslogFilesModule(BaseOnyxModule): + MAX_FILES = 999999 + URL_REGEX = re.compile( + r'^(ftp|scp|ftps):\/\/[a-z0-9\.]*:(.*)@(.*):([a-zA-Z\/\/])*$') + FREQUANCIES = ['daily', 'weekly', 'monthly'] + ROTATION_KEYS = ['frequency', 'max_num', 'size', 'size_pct', 'force'] + ROTATION_CMDS = {'size': 'logging {0} rotation criteria size {1}', + 'frequency': 'logging {0} rotation criteria frequency {1}', + 'max_num': 'logging {0} rotation max-num {1}', + 'size_pct': 'logging {0} rotation criteria size-pct {1}', + 'force': 'logging {0} rotation force'} + + def init_module(self): + """" Ansible module initialization + """ + rotation_spec = dict(frequency=dict(choices=self.FREQUANCIES), + max_num=dict(type="int"), + force=dict(type="bool"), + size=dict(type="float"), + size_pct=dict(type="float")) + + element_spec = dict(delete_group=dict(choices=['oldest', 'current']), + rotation=dict(type="dict", options=rotation_spec), + upload_file=dict(type="str"), + upload_url=dict(type="str"), + debug=dict(type="bool", default=False)) + + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[['upload_file', 'upload_url']]) + + def validate_rotation(self, rotation): + size_pct = rotation.get('size_pct', None) + max_num = rotation.get('max_num', None) + if size_pct is not None and (float(size_pct) < 0 or float(size_pct) > 100): + self._module.fail_json( + msg='logging size_pct must be in range 0-100') + elif max_num is not None and (int(max_num) < 0 or int(max_num) > self.MAX_FILES): + self._module.fail_json( + msg='logging max_num must be positive number less than {0}'.format(self.MAX_FILES)) + + def validate_upload_url(self, upload_url): + check = self.URL_REGEX.match(upload_url) + if upload_url and not check: + self._module.fail_json( + msg='Invalid url, make sure that you use "[ftp, scp, tftp, sftp]://username:password@hostname:/location" format') + + def show_logging(self): + show_logging = show_cmd(self._module, "show logging", json_fmt=True, fail_on_error=False) + running_config = show_cmd(self._module, "show running-config | include .*logging.*debug-files.*", json_fmt=True, fail_on_error=False) + + if len(show_logging) > 0: + show_logging[0]['debug'] = running_config['Lines'] if 'Lines' in running_config else [] + else: + show_logging = [{ + 'debug': running_config['Lines'] if 'Lines' in running_config else [] + }] + return show_logging + + def load_current_config(self): + self._current_config = dict() + current_config = self.show_logging()[0] + freq = current_config.get('Log rotation frequency') # daily (Once per day at midnight) + size = current_config.get('Log rotation size threshold') # 19.07 megabytes or 10.000% of partition (987.84 megabytes) + max_num = current_config.get('Number of archived log files to keep') + if freq is not None: + freq_str = freq.split()[0] + self._current_config['frequency'] = freq_str + + if size is not None: + size_arr = size.split(' ') + if '%' in size: + size_pct_value = size_arr[0].replace('%', '') + self._current_config['size_pct'] = float(size_pct_value) + size_value = re.sub(r'(\(|\)|megabytes)', '', size_arr[-2]).strip() + self._current_config['size'] = float(size_value) + else: + size_value = size_arr[0] + self._current_config['size'] = float(size_value) + + if max_num is not None: + self._current_config['max_num'] = int(max_num) + + '''debug params''' + for line in current_config['debug']: + if 'size' in line: + self._current_config['debug_size'] = float(line.split(' ')[-1]) + elif 'frequency' in line: + self._current_config['debug_frequency'] = line.split(' ')[-1] + elif 'size-pct' in line: + self._current_config['debug_size_pct'] = float(line.split(' ')[-1]) + elif 'max-num' in line: + self._current_config['debug_max_num'] = int(line.split(' ')[-1]) + + def get_required_config(self): + self._required_config = dict() + required_config = dict() + module_params = self._module.params + + delete_group = module_params.get('delete_group') + upload_file = module_params.get('upload_file') + rotation = module_params.get('rotation') + if delete_group: + required_config['delete_group'] = delete_group + if upload_file: + required_config.update({'upload_file': upload_file, + 'upload_url': module_params.get('upload_url')}) + if rotation: + required_config['rotation'] = rotation + required_config['debug'] = module_params['debug'] + + self.validate_param_values(required_config) + self._required_config = required_config + + def generate_commands(self): + required_config = self._required_config + current_config = self._current_config + + logging_files_type = 'debug-files' if required_config['debug'] else 'files' + debug_prefix = 'debug_' if required_config['debug'] else '' + + rotation = required_config.get('rotation') + if rotation: + for key in rotation: + if rotation.get(key) and current_config.get(debug_prefix + key) != rotation.get(key): + cmd = self.ROTATION_CMDS[key].format(logging_files_type, rotation[key]) if key != 'force' else\ + self.ROTATION_CMDS[key].format(logging_files_type) + self._commands.append(cmd) + + delete_group = required_config.get('delete_group') + if delete_group: + self._commands.append('logging {0} delete {1}'.format(logging_files_type, + delete_group)) + + upload_file = required_config.get('upload_file') + if upload_file: + self._commands.append('logging {0} upload {1} {2}'.format(logging_files_type, + upload_file, required_config.get('upload_url'))) + + +def main(): + """ main entry point for module execution + """ + OnyxSyslogFilesModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_syslog_remote.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_syslog_remote.py new file mode 100644 index 00000000..ca3e45f2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_syslog_remote.py @@ -0,0 +1,346 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +module: onyx_syslog_remote +version_added: '0.2.0' +author: "Anas Shami (@anass)" +short_description: Configure remote syslog module +description: + - This module provides declarative management of syslog + on Mellanox ONYX network devices. +notes: +options: + enabled: + description: + - Disable/Enable logging to given remote host + default: true + type: bool + host: + description: + - <IP4/IP6 Hostname> Send event logs to this server using the syslog protocol + required: true + type: str + port: + description: + - Set remote server destination port for log messages + type: int + trap: + description: + - Minimum severity level for messages to this syslog server + choices: ['none', 'debug', 'info', 'notice', 'alert', 'warning', 'err', 'emerg', 'crit'] + type: str + trap_override: + description: + - Override log levels for this sink on a per-class basis + type: list + suboptions: + override_class: + description: + - Specify a class whose log level to override + choices: ['mgmt-front', 'mgmt-back', 'mgmt-core', 'events', 'debug-module', 'sx-sdk', 'mlx-daemons', 'protocol-stack'] + required: True + type: str + override_priority: + description: + -Specify a priority whose log level to override + choices: ['none', 'debug', 'info', 'notice', 'alert', 'warning', 'err', 'emerg', 'crit'] + type: str + override_enabled: + description: + - disable override priorities for specific class. + default: True + type: bool + + filter: + description: + - Specify a filter type + choices: ['include', 'exclude'] + type: str + filter_str: + description: + - Specify a regex filter string + type: str +''' + +EXAMPLES = """ +- name: Remote logging port 8080 +- onyx_syslog_remote: + host: 10.10.10.10 + port: 8080 + +- name: Remote logging trap override +- onyx_syslog_remote: + host: 10.10.10.10 + trap_override: + - override_class: events + override_priority: emerg + +- name: Remote logging trap emerg +- onyx_syslog_remote: + host: 10.10.10.10 + trap: emerg + +- name: Remote logging filter include 'ERR' +- onyx_syslog_remote: + host: 10.10.10.10 + filter: include + filter_str: /ERR/ + +- name: Disable remote logging with class events +- onyx_syslog_remote: + enabled: False + host: 10.10.10.10 + class: events +- name : disable remote logging +- onyx_syslog_remote: + enabled: False + host: 10.10.10.10 + +- name : enable/disable override class +- onyx_syslog_remote: + host: 10.7.144.71 + trap_override: + - override_class: events + override_priority: emerg + override_enabled: False + - override_class: mgmt-front + override_priority: alert +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - logging x port 8080 + - logging 10.10.10.10 trap override class events priority emerg + - no logging 10.10.10.10 trap override class events + - logging 10.10.10.10 trap emerg + - logging 10.10.10.10 filter [include | exclude] ERR +""" + +import re +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxSyslogRemoteModule(BaseOnyxModule): + MAX_PORT = 65535 + LEVELS = ['none', 'debug', 'info', 'notice', 'alert', 'warning', 'err', 'emerg', 'crit'] + CLASSES = ['mgmt-front', 'mgmt-back', 'mgmt-core', 'events', 'debug-module', 'sx-sdk', 'mlx-daemons', 'protocol-stack'] + FILTER = ['include', 'exclude'] + + LOGGING_HOST = re.compile(r'^logging ([a-z0-9\.]+)$') + LOGGING_PORT = re.compile(r'^logging ([a-z0-9\.]+) port ([0-9]+)$') + LOGGING_TRAP = re.compile(r'^logging ([a-z0-9\.]+) trap ([a-z]+)$') + LOGGING_TRAP_OVERRIDE = re.compile(r'^logging ([a-z0-9\.]+) trap override class ([a-z\-]+) priority ([a-z]+)$') + LOGGING_FILTER = re.compile(r'^logging ([a-z0-9\.]+) filter (include|exclude) "([\D\d]+)"$') + + def init_module(self): + """" Ansible module initialization + """ + override_spec = dict(override_priority=dict(choices=self.LEVELS), + override_class=dict(choices=self.CLASSES, required=True), + override_enabled=dict(default=True, type="bool")) + + element_spec = dict(enabled=dict(type="bool", default=True), + host=dict(type="str", required=True), + port=dict(type="int"), + trap=dict(choices=self.LEVELS), + trap_override=dict(type="list", elements='dict', options=override_spec), + filter=dict(choices=self.FILTER), + filter_str=dict(type="str")) + + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[ + ['filter', 'filter_str'] + ]) + + def validate_port(self, port): + if port and (port < 1 or port > self.MAX_PORT): + self._module.fail_json(msg='logging port must be between 1 and {0}'.format(self.MAX_PORT)) + + def show_logging(self): + # we can't use show logging it has lack of information + return show_cmd(self._module, "show running-config | include .*logging.*", json_fmt=False, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + current_config = self.show_logging().split('\n') + for line in current_config: + line = line.strip() + match = self.LOGGING_HOST.match(line) + if match: + host = match.group(1) + self._current_config[host] = dict() + continue + + match = self.LOGGING_PORT.match(line) + if match: + host = match.group(1) + port = int(match.group(2)) + if host in self._current_config: + self._current_config[host]['port'] = port + else: + self._current_config[host] = dict(port=port) + continue + + match = self.LOGGING_TRAP.match(line) + if match: + host = match.group(1) + trap = match.group(2) + host_config = self._current_config.get(host) + if host_config: + self._current_config[host]['trap'] = trap + else: + self._current_config[host] = dict(trap=trap) + continue + + match = self.LOGGING_TRAP_OVERRIDE.match(line) + if match: + host = match.group(1) + override_class = match.group(2) + override_priority = match.group(3) + host_config = self._current_config.get(host) + + if host_config: + if 'trap_override' in host_config: + self._current_config[host]['trap_override'].append(dict(override_class=override_class, override_priority=override_priority)) + else: + self._current_config[host]['trap_override'] = [dict(override_class=override_class, override_priority=override_priority)] + else: + self._current_config[host] = {'trap_override': [dict(override_class=override_class, override_priority=override_priority)]} + continue + + match = self.LOGGING_FILTER.match(line) + if match: + host = match.group(1) + filter_type = match.group(2) + filter_str = match.group(3) + if host in self._current_config: + self._current_config[host].update({'filter': filter_type, 'filter_str': filter_str}) + else: + self._current_config[host] = dict(filter=filter_type, filter_str=filter_str) + + def get_required_config(self): + self._required_config = dict() + required_config = dict() + module_params = self._module.params + port = module_params.get('port') + trap = module_params.get('trap') + trap_override = module_params.get('trap_override') + filtered = module_params.get('filter') + + required_config['host'] = module_params.get('host') + required_config['enabled'] = module_params.get('enabled') + + if port: + required_config['port'] = port + if trap: + required_config['trap'] = trap + if trap_override: + required_config['trap_override'] = trap_override + if filtered: + required_config['filter'] = filtered + required_config['filter_str'] = module_params.get('filter_str', '') + + self.validate_param_values(required_config) + self._required_config = required_config + + def generate_commands(self): + required_config = self._required_config + current_config = self._current_config + host = required_config.get('host') + enabled = required_config['enabled'] + ''' + cases: + if host in current config and current config != required config and its enable + if host in current config and its disable + if host in current and it has override_class with disable flag + ''' + host_config = current_config.get(host, dict()) + + if host in current_config and not enabled: + self._commands.append('no logging {0}'.format(host)) + else: + if host not in current_config: + self._commands.append('logging {0}'.format(host)) + if 'port' in required_config: + if required_config['port'] != host_config.get('port', None) or not host_config: + '''Edit/Create new one''' + self._commands.append('logging {0} port {1}'.format(host, required_config['port'])) + + if 'trap' in required_config or 'trap_override' in required_config: + trap_commands = self._get_trap_commands(host) + self._commands += trap_commands + + if 'filter' in required_config: + is_change = host_config.get('filter', None) != required_config['filter'] or \ + host_config.get('filter_str', None) != required_config['filter_str'] + if is_change or not host_config: + self._commands.append('logging {0} filter {1} {2}'.format(host, required_config['filter'], required_config['filter_str'])) + + ''' ********** private methods ********** ''' + def _get_trap_commands(self, host): + current_config = self._current_config + required_config = self._required_config + trap_commands = [] + host_config = current_config.get(host, dict()) + + override_list = required_config.get('trap_override') + if override_list: + current_override_list = host_config.get('trap_override', []) + + for override_trap in override_list: + override_class = override_trap.get('override_class') + override_priority = override_trap.get('override_priority') + override_enabled = override_trap.get('override_enabled') + found, found_class = False, False + for current_override in current_override_list: + if current_override.get('override_class') == override_class: + found_class = True + if not override_enabled: + break + if override_priority and current_override.get('override_priority') == override_priority: + found = True + break + + if override_enabled: + if not found and override_priority: + trap_commands.append('logging {0} trap override class {1} priority {2}'.format( + host, override_class, override_priority)) + elif found_class: # disabled option will use only class + trap_commands.append('no logging {0} trap override class {1}'.format( + host, override_class)) + + else: + if required_config['enabled']: # no disabled option for this, just override trap level can be disabled + trap = required_config.get('trap') + if trap and (trap != host_config.get('trap', None) or not host_config): + trap_commands.append('logging {0} trap {1}'.format( + host, trap)) + '''no disable for trap''' + + return trap_commands + + +def main(): + """ main entry point for module execution + """ + OnyxSyslogRemoteModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_traffic_class.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_traffic_class.py new file mode 100644 index 00000000..5b388c5f --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_traffic_class.py @@ -0,0 +1,321 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_traffic_class +author: "Anas Badaha (@anasb)" +short_description: Configures Traffic Class +description: + - This module provides declarative management of Traffic Class configuration + on Mellanox ONYX network devices. +options: + state: + description: + - enable congestion control on interface. + choices: ['enabled', 'disabled'] + default: enabled + interfaces: + description: + - list of interfaces name. + required: true + tc: + description: + - traffic class, range 0-7. + required: true + congestion_control: + description: + - configure congestion control on interface. + suboptions: + control: + description: + - congestion control type. + choices: ['red', 'ecn', 'both'] + required: true + threshold_mode: + description: + - congestion control threshold mode. + choices: ['absolute', 'relative'] + required: true + min_threshold: + description: + - Set minimum-threshold value (in KBs) for marking traffic-class queue. + required: true + max_threshold: + description: + - Set maximum-threshold value (in KBs) for marking traffic-class queue. + required: true + dcb: + description: + - configure dcb control on interface. + suboptions: + mode: + description: + - dcb control mode. + choices: ['strict', 'wrr'] + required: true + weight: + description: + - Relevant only for wrr mode. +''' + +EXAMPLES = """ +- name: Configure traffic class + onyx_traffic_class: + interfaces: + - Eth1/1 + - Eth1/2 + tc: 3 + congestion_control: + control: ecn + threshold_mode: absolute + min_threshold: 500 + max_threshold: 1500 + dcb: + mode: strict +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface ethernet 1/15 traffic-class 3 congestion-control ecn minimum-absolute 150 maximum-absolute 1500 + - interface ethernet 1/16 traffic-class 3 congestion-control ecn minimum-absolute 150 maximum-absolute 1500 + - interface mlag-port-channel 7 traffic-class 3 congestion-control ecn minimum-absolute 150 maximum-absolute 1500 + - interface port-channel 1 traffic-class 3 congestion-control ecn minimum-absolute 150 maximum-absolute 1500 + - interface ethernet 1/15 traffic-class 3 dcb ets strict + - interface ethernet 1/16 traffic-class 3 dcb ets strict + - interface mlag-port-channel 7 traffic-class 3 dcb ets strict + - interface port-channel 1 traffic-class 3 dcb ets strict +""" + +import re +from ansible.module_utils.six import iteritems +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxTrafficClassModule(BaseOnyxModule): + + IF_ETH_REGEX = re.compile(r"^Eth(\d+\/\d+|Eth\d+\/\d+\d+)$") + IF_PO_REGEX = re.compile(r"^Po(\d+)$") + MLAG_NAME_REGEX = re.compile(r"^Mpo(\d+)$") + + IF_TYPE_ETH = "ethernet" + PORT_CHANNEL = "port-channel" + MLAG_PORT_CHANNEL = "mlag-port-channel" + + IF_TYPE_MAP = { + IF_TYPE_ETH: IF_ETH_REGEX, + PORT_CHANNEL: IF_PO_REGEX, + MLAG_PORT_CHANNEL: MLAG_NAME_REGEX + } + + def init_module(self): + """ initialize module + """ + congestion_control_spec = dict(control=dict(choices=['red', 'ecn', 'both'], required=True), + threshold_mode=dict(choices=['absolute', 'relative'], required=True), + min_threshold=dict(type=int, required=True), + max_threshold=dict(type=int, required=True)) + + dcb_spec = dict(mode=dict(choices=['strict', 'wrr'], required=True), + weight=dict(type=int)) + + element_spec = dict( + interfaces=dict(type='list', required=True), + tc=dict(type=int, required=True), + congestion_control=dict(type='dict', options=congestion_control_spec), + dcb=dict(type='dict', options=dcb_spec), + state=dict(choices=['enabled', 'disabled'], default='enabled')) + + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def validate_tc(self, value): + if value and not 0 <= int(value) <= 7: + self._module.fail_json(msg='tc value must be between 0 and 7') + + def validate_param_values(self, obj, param=None): + dcb = obj.get("dcb") + if dcb is not None: + dcb_mode = dcb.get("mode") + weight = dcb.get("weight") + if dcb_mode == "wrr" and weight is None: + self._module.fail_json(msg='User should send weight attribute when dcb mode is wrr') + super(OnyxTrafficClassModule, self).validate_param_values(obj, param) + + def _get_interface_type(self, if_name): + if_type = None + if_id = None + for interface_type, interface_regex in iteritems(self.IF_TYPE_MAP): + match = interface_regex.match(if_name) + if match: + if_type = interface_type + if_id = match.group(1) + break + return if_type, if_id + + def _set_interface_congestion_control_config(self, interface_congestion_control_config, + interface, if_type, if_id): + tc = self._required_config.get("tc") + interface_dcb_ets = self._show_interface_dcb_ets(if_type, if_id)[0].get(interface) + if interface_dcb_ets is None: + dcb = dict() + else: + ets_per_tc = interface_dcb_ets[2].get("ETS per TC") + tc_config = ets_per_tc[0].get(str(tc)) + dcb_mode = tc_config[0].get("S.Mode") + dcb_weight = int(tc_config[0].get("W")) + dcb = dict(mode=dcb_mode.lower(), weight=dcb_weight) + + interface_congestion_control_config = interface_congestion_control_config[tc + 1] + mode = interface_congestion_control_config.get("Mode") + if mode == "none": + self._current_config[interface] = dict(state="disabled", dcb=dcb, if_type=if_type, if_id=if_id) + return + + threshold_mode = interface_congestion_control_config.get("Threshold mode") + max_threshold = interface_congestion_control_config.get("Maximum threshold") + min_threshold = interface_congestion_control_config.get("Minimum threshold") + + if threshold_mode == "absolute": + delimiter = ' ' + else: + delimiter = '%' + min_value = int(min_threshold.split(delimiter)[0]) + max_malue = int(max_threshold.split(delimiter)[0]) + congestion_control = dict(control=mode.lower(), threshold_mode=threshold_mode, + min_threshold=min_value, max_threshold=max_malue) + + self._current_config[interface] = dict(state="enabled", congestion_control=congestion_control, + dcb=dcb, if_type=if_type, if_id=if_id) + + def _show_interface_congestion_control(self, if_type, interface): + cmd = "show interfaces {0} {1} congestion-control".format(if_type, interface) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def _show_interface_dcb_ets(self, if_type, interface): + cmd = "show dcb ets interface {0} {1}".format(if_type, interface) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + for interface in self._required_config.get("interfaces"): + if_type, if_id = self._get_interface_type(interface) + if not if_id: + self._module.fail_json( + msg='unsupported interface: {0}'.format(interface)) + interface_congestion_control_config = self._show_interface_congestion_control(if_type, if_id) + if interface_congestion_control_config is not None: + self._set_interface_congestion_control_config(interface_congestion_control_config, + interface, if_type, if_id) + else: + self._module.fail_json( + msg='Interface {0} does not exist on switch'.format(interface)) + + def generate_commands(self): + state = self._required_config.get("state") + tc = self._required_config.get("tc") + interfaces = self._required_config.get("interfaces") + for interface in interfaces: + current_interface = self._current_config.get(interface) + current_state = current_interface.get("state") + if_type = current_interface.get("if_type") + if_id = current_interface.get("if_id") + if state == "disabled": + if current_state == "enabled": + self._commands.append('interface {0} {1} no traffic-class {2} congestion-control'.format(if_type, if_id, tc)) + continue + + congestion_control = self._required_config.get("congestion_control") + + if congestion_control is not None: + control = congestion_control.get("control") + current_congestion_control = current_interface.get("congestion_control") + threshold_mode = congestion_control.get("threshold_mode") + min_threshold = congestion_control.get("min_threshold") + max_threshold = congestion_control.get("max_threshold") + if current_congestion_control is None: + self._threshold_mode_generate_cmds_mappers(threshold_mode, if_type, if_id, tc, + control, min_threshold, max_threshold) + else: + current_control = current_congestion_control.get("control") + curr_threshold_mode = current_congestion_control.get("threshold_mode") + curr_min_threshold = current_congestion_control.get("min_threshold") + curr_max_threshold = current_congestion_control.get("max_threshold") + + if control != current_control: + self._threshold_mode_generate_cmds_mappers(threshold_mode, if_type, if_id, tc, + control, min_threshold, max_threshold) + else: + if threshold_mode != curr_threshold_mode: + self._threshold_mode_generate_cmds_mappers(threshold_mode, if_type, if_id, tc, + control, min_threshold, max_threshold) + elif min_threshold != curr_min_threshold or max_threshold != curr_max_threshold: + self._threshold_mode_generate_cmds_mappers(threshold_mode, if_type, if_id, tc, + control, min_threshold, max_threshold) + + dcb = self._required_config.get("dcb") + if dcb is not None: + dcb_mode = dcb.get("mode") + current_dcb = current_interface.get("dcb") + current_dcb_mode = current_dcb.get("mode") + if dcb_mode == "strict" and dcb_mode != current_dcb_mode: + self._commands.append('interface {0} {1} traffic-class {2} ' + 'dcb ets {3}'.format(if_type, if_id, tc, dcb_mode)) + elif dcb_mode == "wrr": + weight = dcb.get("weight") + current_weight = current_dcb.get("weight") + if dcb_mode != current_dcb_mode or weight != current_weight: + self._commands.append('interface {0} {1} traffic-class {2} ' + 'dcb ets {3} {4}'.format(if_type, if_id, tc, dcb_mode, weight)) + + def _threshold_mode_generate_cmds_mappers(self, threshold_mode, if_type, if_id, tc, + control, min_threshold, max_threshold): + if threshold_mode == 'absolute': + self._generate_congestion_control_absolute_cmds(if_type, if_id, tc, control, + min_threshold, max_threshold) + else: + self._generate_congestion_control_relative_cmds(if_type, if_id, tc, control, + min_threshold, max_threshold) + + def _generate_congestion_control_absolute_cmds(self, if_type, if_id, tc, control, + min_absolute, max_absolute): + self._commands.append('interface {0} {1} traffic-class {2} ' + 'congestion-control {3} minimum-absolute {4} ' + 'maximum-absolute {5}'.format(if_type, if_id, tc, control, + min_absolute, max_absolute)) + + def _generate_congestion_control_relative_cmds(self, if_type, if_id, tc, control, + min_relative, max_relative): + self._commands.append('interface {0} {1} traffic-class {2} ' + 'congestion-control {3} minimum-relative {4} ' + 'maximum-relative {5}'.format(if_type, if_id, tc, control, + min_relative, max_relative)) + + +def main(): + """ main entry point for module execution + """ + OnyxTrafficClassModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_username.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_username.py new file mode 100644 index 00000000..f6f6f318 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_username.py @@ -0,0 +1,286 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_username +version_added: '0.2.0' +author: "Anas Shami (@anass)" +short_description: Configure username module +description: + - This module provides declarative management of users/roles + on Mellanox ONYX network devices. +notes: +options: + username: + description: + - Create/Edit user using username + type: str + required: True + full_name: + description: + - Set the full name of this user + type: str + nopassword: + description: + - Clear password for such user + type: bool + default: False + password: + description: + - Set password fot such user + type: str + encrypted_password: + description: + - Decide the type of setted password (plain text or encrypted) + type: bool + default: False + capability: + description: + - Grant capability to this user account + type: str + choices: ['monitor', 'unpriv', 'v_admin', 'admin'] + reset_capability: + description: + - Reset capability to this user account + type: bool + default: False + disconnected: + description: + - Disconnect all sessions of this user + type: bool + default: False + disabled: + description: + - Disable means of logging into this account + type: str + choices: ['none', 'login', 'password', 'all'] + state: + description: + - Set state of the given account + default: present + type: str + choices: ['present', 'absent'] +''' + +EXAMPLES = """ +- name: Create new user + onyx_username: + username: anass + +- name: Set the user full-name + onyx_username: + username: anass + full_name: anasshami + +- name: Set the user encrypted password + onyx_username: + username: anass + password: 12345 + encrypted_password: True + +- name: Set the user capability + onyx_username: + username: anass + capability: monitor + +- name: Reset the user capability + onyx_username: + username: anass + reset_capability: True + +- name: Remove the user configuration + onyx_username: + username: anass + state: absent +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - username * + - username * password * + - username * nopassword + - username * disable login + - username * capability admin + - no username * + - no username * disable + +""" +import re + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule, show_cmd + + +class OnyxUsernameModule(BaseOnyxModule): + ACCOUNT_STATE = { + 'Account locked out': dict(disabled='all'), + 'No password required for login': dict(nopassword=True), + 'Local password login disabled': dict(disabled='password'), + 'Account disabled': dict(disabled='all') + } + ENCRYPTED_ID = 7 + + def init_module(self): + """ + module initialization + """ + element_spec = dict() + + argument_spec = dict(state=dict(choices=['absent', 'present'], default='present'), + username=dict(type='str', required=True), + disabled=dict(choices=['none', 'login', 'password', 'all']), + capability=dict(choices=['monitor', 'unpriv', 'v_admin', 'admin']), + nopassword=dict(type='bool', default=False), + password=dict(type='str', no_log=True), + encrypted_password=dict(type='bool', default=False), + reset_capability=dict(type="bool", default=False), + disconnected=dict(type='bool', default=False), + full_name=dict(type='str')) + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + mutually_exclusive=[['password', 'nopassword']]) + + def get_required_config(self): + self._required_config = dict() + module_params = self._module.params + params = {} + ''' Requred/Default fields ''' + params['username'] = module_params.get('username') + params['state'] = module_params.get('state') + params['encrypted_password'] = module_params.get('encrypted_password') + params['reset_capability'] = module_params.get('reset_capability') + ''' Other fields ''' + for key, value in module_params.items(): + if value is not None: + params[key] = value + self.validate_param_values(params) + self._required_config = params + + def _get_username_config(self): + return show_cmd(self._module, "show usernames", json_fmt=True, fail_on_error=False) + + def _set_current_config(self, users_config): + ''' + users_config ex: + { + admin": [ + { + "CAPABILITY": "admin", + "ACCOUNT STATUS": "No password required for login", + "FULL NAME": "System Administrator" + } + ], + } + ''' + if not users_config: + return + current_config = self._current_config + for username, config in users_config.items(): + config_json = config[0] + current_config[username] = current_config.get(username, {}) + account_status = config_json.get('ACCOUNT STATUS') + status_value = self.ACCOUNT_STATE.get(account_status) + + if status_value is not None: + # None for enabled account with password account "Password set (SHA512 | MD5)" so we won't change any attribute here. + current_config[username].update(status_value) + current_config[username].update({ + 'capability': config_json.get('CAPABILITY'), + 'full_name': config_json.get('FULL NAME') + }) + + def load_current_config(self): + self._current_config = dict() + users_config = self._get_username_config() + self._set_current_config(users_config) + + def generate_commands(self): + current_config, required_config = self._current_config, self._required_config + username = required_config.get('username') + current_user = current_config.get(username) + if current_user is not None: + '''created account we just need to edit his attributes''' + full_name = required_config.get('full_name') + if full_name is not None and current_user.get('full_name') != full_name: + self._commands.append("username {0} full-name {1}".format(username, full_name)) + + disabled = required_config.get('disabled') + if disabled is not None and current_user.get('disabled') != disabled: + if disabled == 'none': + self._commands.append("no username {0} disable".format(username)) + elif disabled == 'all': + self._commands.append("username {0} disable".format(username)) + else: + self._commands.append("username {0} disable {1}".format(username, disabled)) + + state = required_config.get('state') + if state == 'absent': # this will remove the user + self._commands.append("no username {0}".format(username)) + + capability = required_config.get('capability') + if capability is not None and current_user.get('capability') != capability: + self._commands.append("username {0} capability {1}".format(username, capability)) + + reset_capability = required_config.get('reset_capability') + if reset_capability: + self._commands.append("no username {0} capability".format(username)) + + password = required_config.get('password') + if password is not None: + encrypted = required_config.get('encrypted_password') + if encrypted: + self._commands.append("username {0} password {1} {2}".format(username, self.ENCRYPTED_ID, password)) + else: + self._commands.append("username {0} password {1}".format(username, password)) + + nopassword = required_config.get('nopassword') + if nopassword and nopassword != current_user.get('nopassword', False): + self._commands.append("username {0} nopassword".format(username)) + + disconnected = required_config.get('disconnected') + if disconnected: + self._commands.append("username {0} disconnect".format(username)) + else: + '''create new account if we have valid inforamtion, just check for username, capability, full_name, password''' + + capability = required_config.get('capability') + password = required_config.get('password') + full_name = required_config.get('full_name') + if capability is not None or password is not None or full_name is not None: + if capability is not None: + self._commands.append("username {0} capability {1}".format(username, capability)) + + if password is not None: + encrypted = required_config.get('encrypted_password') + if encrypted: + self._commands.append("username {0} password {1} {2} ".format(username, self.ENCRYPTED_ID, password)) + else: + self._commands.append("username {0} password {1}".format(username, password)) + + if full_name is not None: + self._commands.append("username {0} full-name {1}".format(username, full_name)) + + else: + self._commands.append("username {0}".format(username)) + + +def main(): + """ main entry point for module execution + """ + OnyxUsernameModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_vlan.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_vlan.py new file mode 100644 index 00000000..d4e10cca --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_vlan.py @@ -0,0 +1,200 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_vlan +author: "Samer Deeb (@samerd) Alex Tabachnik (@atabachnik)" +short_description: Manage VLANs on Mellanox ONYX network devices +description: + - This module provides declarative management of VLANs + on Mellanox ONYX network devices. +options: + name: + description: + - Name of the VLAN. + vlan_id: + description: + - ID of the VLAN. + aggregate: + description: List of VLANs definitions. + purge: + description: + - Purge VLANs not defined in the I(aggregate) parameter. + default: no + type: bool + state: + description: + - State of the VLAN configuration. + default: present + choices: ['present', 'absent'] +''' + +EXAMPLES = """ +- name: Configure VLAN ID and name + onyx_vlan: + vlan_id: 20 + name: test-vlan + +- name: Remove configuration + onyx_vlan: + state: absent +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device + returned: always. + type: list + sample: + - vlan 20 + - name test-vlan + - exit +""" + +from copy import deepcopy + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import remove_default_spec + +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd + + +class OnyxVlanModule(BaseOnyxModule): + _purge = False + + @classmethod + def _get_element_spec(cls): + return dict( + vlan_id=dict(type='int'), + name=dict(type='str'), + state=dict(default='present', choices=['present', 'absent']), + ) + + @classmethod + def _get_aggregate_spec(cls, element_spec): + aggregate_spec = deepcopy(element_spec) + aggregate_spec['vlan_id'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + return aggregate_spec + + def init_module(self): + """ module initialization + """ + element_spec = self._get_element_spec() + aggregate_spec = self._get_aggregate_spec(element_spec) + argument_spec = dict( + aggregate=dict(type='list', elements='dict', + options=aggregate_spec), + purge=dict(default=False, type='bool'), + ) + argument_spec.update(element_spec) + required_one_of = [['vlan_id', 'aggregate']] + mutually_exclusive = [['vlan_id', 'aggregate']] + self._module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + supports_check_mode=True) + + def validate_vlan_id(self, value): + if value and not 1 <= int(value) <= 4094: + self._module.fail_json(msg='vlan id must be between 1 and 4094') + + def get_required_config(self): + self._required_config = list() + module_params = self._module.params + aggregate = module_params.get('aggregate') + self._purge = module_params.get('purge', False) + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module_params[key] + self.validate_param_values(item, item) + req_item = item.copy() + req_item['vlan_id'] = int(req_item['vlan_id']) + self._required_config.append(req_item) + else: + params = { + 'vlan_id': module_params['vlan_id'], + 'name': module_params['name'], + 'state': module_params['state'], + } + self.validate_param_values(params) + self._required_config.append(params) + + def _create_vlan_data(self, vlan_id, vlan_data): + if self._os_version >= self.ONYX_API_VERSION: + vlan_data = vlan_data[0] + return { + 'vlan_id': vlan_id, + 'name': self.get_config_attr(vlan_data, 'Name') + } + + def _get_vlan_config(self): + return show_cmd(self._module, "show vlan") + + def load_current_config(self): + # called in base class in run function + self._os_version = self._get_os_version() + self._current_config = dict() + vlan_config = self._get_vlan_config() + if not vlan_config: + return + for vlan_id, vlan_data in iteritems(vlan_config): + try: + vlan_id = int(vlan_id) + except ValueError: + continue + self._current_config[vlan_id] = \ + self._create_vlan_data(vlan_id, vlan_data) + + def generate_commands(self): + req_vlans = set() + for req_conf in self._required_config: + state = req_conf['state'] + vlan_id = req_conf['vlan_id'] + if state == 'absent': + if vlan_id in self._current_config: + self._commands.append('no vlan %s' % vlan_id) + else: + req_vlans.add(vlan_id) + self._generate_vlan_commands(vlan_id, req_conf) + if self._purge: + for vlan_id in self._current_config: + if vlan_id not in req_vlans: + self._commands.append('no vlan %s' % vlan_id) + + def _generate_vlan_commands(self, vlan_id, req_conf): + curr_vlan = self._current_config.get(vlan_id, {}) + if not curr_vlan: + self._commands.append("vlan %s" % vlan_id) + self._commands.append("exit") + req_name = req_conf['name'] + curr_name = curr_vlan.get('name') + if req_name: + if req_name != curr_name: + self._commands.append("vlan %s name %s" % (vlan_id, req_name)) + elif req_name is not None: + if curr_name: + self._commands.append("vlan %s no name" % vlan_id) + + +def main(): + """ main entry point for module execution + """ + OnyxVlanModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_vxlan.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_vxlan.py new file mode 100644 index 00000000..747e62ee --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_vxlan.py @@ -0,0 +1,260 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_vxlan +author: "Anas Badaha (@anasb)" +short_description: Configures Vxlan +description: + - This module provides declarative management of Vxlan configuration + on Mellanox ONYX network devices. +notes: + - Tested on ONYX evpn_dev.031. + - nve protocol must be enabled. +options: + nve_id: + description: + - nve interface ID. + required: true + loopback_id: + description: + - loopback interface ID. + bgp: + description: + - configure bgp on nve interface. + type: bool + default: true + mlag_tunnel_ip: + description: + - vxlan Mlag tunnel IP + vni_vlan_list: + description: + - Each item in the list has two attributes vlan_id, vni_id. + arp_suppression: + description: + - A flag telling if to configure arp suppression. + type: bool + default: false +''' + +EXAMPLES = """ +- name: Configure Vxlan + onyx_vxlan: + nve_id: 1 + loopback_id: 1 + bgp: yes + mlag-tunnel-ip: 100.0.0.1 + vni_vlan_list: + - vlan_id: 10 + vni_id: 10010 + - vlan_id: 6 + vni_id: 10060 + arp_suppression: yes +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - interface nve 1 + - interface nve 1 vxlan source interface loopback 1 + - interface nve 1 nve controller bgp + - interface nve 1 vxlan mlag-tunnel-ip 100.0.0.1 + - interface nve 1 nve vni 10010 vlan 10 + - interface nve 1 nve vni 10060 vlan 6 + - interface nve 1 nve neigh-suppression + - interface vlan 6 + - interface vlan 10 +""" + +import re +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import show_cmd +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule + + +class OnyxVxlanModule(BaseOnyxModule): + + LOOPBACK_REGEX = re.compile(r'^loopback (\d+).*') + NVE_ID_REGEX = re.compile(r'^Interface NVE (\d+).*') + + def init_module(self): + """ initialize module + """ + vni_vlan_spec = dict(vlan_id=dict(type=int), + vni_id=dict(type=int)) + element_spec = dict( + nve_id=dict(type=int), + loopback_id=dict(type=int), + bgp=dict(default=True, type='bool'), + mlag_tunnel_ip=dict(type='str'), + vni_vlan_list=dict(type='list', + elements='dict', + options=vni_vlan_spec), + arp_suppression=dict(default=False, type='bool') + ) + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True) + + def get_required_config(self): + module_params = self._module.params + self._required_config = dict(module_params) + self.validate_param_values(self._required_config) + + def _set_vxlan_config(self, vxlan_config): + vxlan_config = vxlan_config[0] + if not vxlan_config: + return + nve_header = vxlan_config.get("header") + match = self.NVE_ID_REGEX.match(nve_header) + if match: + current_nve_id = int(match.group(1)) + self._current_config['nve_id'] = current_nve_id + if int(current_nve_id) != self._required_config.get("nve_id"): + return + + self._current_config['mlag_tunnel_ip'] = vxlan_config.get("Mlag tunnel IP") + controller_mode = vxlan_config.get("Controller mode") + if controller_mode == "BGP": + self._current_config['bgp'] = True + else: + self._current_config['bgp'] = False + + loopback_str = vxlan_config.get("Source interface") + match = self.LOOPBACK_REGEX.match(loopback_str) + if match: + loopback_id = match.group(1) + self._current_config['loopback_id'] = int(loopback_id) + + self._current_config['global_neigh_suppression'] = vxlan_config.get("Global Neigh-Suppression") + + vni_vlan_mapping = self._current_config['vni_vlan_mapping'] = dict() + nve_detail = self._show_nve_detail() + + if nve_detail is not None: + nve_detail = nve_detail[0] + + if nve_detail: + for vlan_id in nve_detail: + vni_vlan_mapping[int(vlan_id)] = dict( + vni_id=int(nve_detail[vlan_id][0].get("VNI")), + arp_suppression=nve_detail[vlan_id][0].get("Neigh Suppression")) + + def _show_vxlan_config(self): + cmd = "show interfaces nve" + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def _show_nve_detail(self): + cmd = "show interface nve {0} detail".format(self._required_config.get("nve_id")) + return show_cmd(self._module, cmd, json_fmt=True, fail_on_error=False) + + def load_current_config(self): + self._current_config = dict() + vxlan_config = self._show_vxlan_config() + if vxlan_config: + self._set_vxlan_config(vxlan_config) + + def generate_commands(self): + nve_id = self._required_config.get("nve_id") + current_nve_id = self._current_config.get("nve_id") + + if current_nve_id is None: + self._add_nve_commands(nve_id) + elif current_nve_id != nve_id: + self._add_no_nve_commands(current_nve_id) + self._add_nve_commands(nve_id) + + bgp = self._required_config.get("bgp") + if bgp is not None: + curr_bgp = self._current_config.get("bgp") + if bgp and bgp != curr_bgp: + self._commands.append('interface nve {0} nve controller bgp'.format(nve_id)) + + loopback_id = self._required_config.get("loopback_id") + if loopback_id is not None: + curr_loopback_id = self._current_config.get("loopback_id") + if loopback_id != curr_loopback_id: + self._commands.append('interface nve {0} vxlan source interface ' + 'loopback {1} '.format(nve_id, loopback_id)) + + mlag_tunnel_ip = self._required_config.get("mlag_tunnel_ip") + if mlag_tunnel_ip is not None: + curr_mlag_tunnel_ip = self._current_config.get("mlag_tunnel_ip") + if mlag_tunnel_ip != curr_mlag_tunnel_ip: + self._commands.append('interface nve {0} vxlan ' + 'mlag-tunnel-ip {1}'.format(nve_id, mlag_tunnel_ip)) + + vni_vlan_list = self._required_config.get("vni_vlan_list") + arp_suppression = self._required_config.get("arp_suppression") + if vni_vlan_list is not None: + self._generate_vni_vlan_cmds(vni_vlan_list, nve_id, arp_suppression) + + def _generate_vni_vlan_cmds(self, vni_vlan_list, nve_id, arp_suppression): + + current_global_arp_suppression = self._current_config.get('global_neigh_suppression') + if arp_suppression is True and current_global_arp_suppression != "Enable": + self._commands.append('interface nve {0} nve neigh-suppression'.format(nve_id)) + + current_vni_vlan_mapping = self._current_config.get('vni_vlan_mapping') + if current_vni_vlan_mapping is None: + for vni_vlan in vni_vlan_list: + vlan_id = vni_vlan.get("vlan_id") + vni_id = vni_vlan.get("vni_id") + self._add_vni_vlan_cmds(nve_id, vni_id, vlan_id) + self._add_arp_suppression_cmds(arp_suppression, vlan_id) + else: + for vni_vlan in vni_vlan_list: + vlan_id = vni_vlan.get("vlan_id") + vni_id = vni_vlan.get("vni_id") + + currt_vlan_id = current_vni_vlan_mapping.get(vlan_id) + + if currt_vlan_id is None: + self._add_vni_vlan_cmds(nve_id, vni_id, vlan_id) + self._add_arp_suppression_cmds(arp_suppression, vlan_id) + else: + current_vni_id = currt_vlan_id.get("vni_id") + current_arp_suppression = currt_vlan_id.get("arp_suppression") + + if int(current_vni_id) != vni_id: + self._add_vni_vlan_cmds(nve_id, vni_id, vlan_id) + + if current_arp_suppression == "Disable": + self._add_arp_suppression_cmds(arp_suppression, vlan_id) + + def _add_no_nve_commands(self, current_nve_id): + self._commands.append('no interface nve {0}'.format(current_nve_id)) + + def _add_nve_commands(self, nve_id): + self._commands.append('interface nve {0}'.format(nve_id)) + self._commands.append('exit') + + def _add_vni_vlan_cmds(self, nve_id, vni_id, vlan_id): + self._commands.append('interface nve {0} nve vni {1} ' + 'vlan {2}'.format(nve_id, vni_id, vlan_id)) + + def _add_arp_suppression_cmds(self, arp_suppression, vlan_id): + if arp_suppression is True: + self._commands.append('interface vlan {0}'.format(vlan_id)) + self._commands.append('exit') + + +def main(): + """ main entry point for module execution + """ + OnyxVxlanModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_wjh.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_wjh.py new file mode 100644 index 00000000..bf97884c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/modules/onyx_wjh.py @@ -0,0 +1,219 @@ +#!/usr/bin/python +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: onyx_wjh +author: "Anas Shami (@anass)" +short_description: Configure what-just-happend module +description: + - This module provides declarative management of wjh + on Mellanox ONYX network devices. +notes: +options: + group: + description: + - Name of wjh group. + choices: ['all', 'forwarding', 'acl'] + type: str + enabled: + description: + - wjh group status + type: bool + auto_export: + description: + - wjh group auto export pcap file status + type: bool + export_group: + description: + - wjh group auto export group + choices: ['all', 'forwarding', 'acl'] + type: str + clear_group: + description: + - clear pcap file by group + choices: ['all', 'user', 'auto-export'] + type: str +''' + +EXAMPLES = """ +- name: Enable wjh + onyx_wjh: + group: forwarding + enabled: True + +- name: Disable wjh + onyx_wjh: + group: forwarding + enabled: False + +- name: Enable auto-export + onyx_wjh: + auto_export: True + export_group: forwarding +- name: Disable auto-export + onyx_wjh: + auto_export: False + export_group: forwarding +- name: Clear pcap file + onyx_wjh: + clear_group: auto-export +""" + +RETURN = """ +commands: + description: The list of configuration mode commands to send to the device. + returned: always + type: list + sample: + - what-just-happend forwarding enable + - what-just-happend auto-export forwarding enable + - clear what-just-happend pcap-file user +""" +import re + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx import BaseOnyxModule, show_cmd + + +class OnyxWJHModule(BaseOnyxModule): + WJH_DISABLED_REGX = re.compile(r'^no what-just-happened ([a-z]+) enable.*') + WJH_DISABLED_AUTO_EXPORT_REGX = re.compile(r'^no what-just-happened auto-export ([a-z]+) enable.*') + + WJH_CMD_FMT = '{0}what-just-happened {1} enable' + WJH_EXPORT_CMD_FMT = '{0}what-just-happened auto-export {1} enable' + WJH_CLEAR_CMD_FMT = 'clear what-just-happened pcap-files {0}' + + WJH_GROUPS = ['all', 'forwarding', 'acl'] + CLEAR_GROUPS = ['all', 'user', 'auto-export'] + + def init_module(self): + """ + module initialization + """ + element_spec = dict(group=dict(choices=self.WJH_GROUPS), + enabled=dict(type='bool'), + auto_export=dict(type='bool'), + export_group=dict(choices=self.WJH_GROUPS), + clear_group=dict(choices=self.CLEAR_GROUPS)) + + argument_spec = dict() + argument_spec.update(element_spec) + self._module = AnsibleModule( + argument_spec=argument_spec, + supports_check_mode=True, + required_together=[ + ['group', 'enabled'], + ['auto_export', 'export_group'] + ]) + + def get_required_config(self): + self._required_config = dict() + module_params = self._module.params + group = module_params.get('group') + export_group = module_params.get('export_group') + clear_group = module_params.get('clear_group') + + params = dict() + if group: + enabled = module_params.get('enabled') + params.update({ + 'group': group, + 'enabled': enabled + }) + + if export_group: + auto_export = module_params.get('auto_export') + params.update({ + 'export_group': export_group, + 'auto_export': auto_export + }) + + if clear_group: + params.update({ + 'clear_group': clear_group + }) + + self.validate_param_values(params) + self._required_config = params + + def _get_wjh_config(self): + return show_cmd(self._module, "show running-config | include .*what-just-happened.*", json_fmt=False, fail_on_error=False) + + def _set_current_config(self, config): + if not config: + return + current_config = self._current_config + lines = config.split('\n') + for line in lines: + if line.startswith('#'): + continue + match = self.WJH_DISABLED_REGX.match(line) + if match: + # wjh is disabled + group = match.group(1) + current_config[group] = False + + match = self.WJH_DISABLED_AUTO_EXPORT_REGX.match(line) + if match: + # wjh auto export is disabled + export_group = match.group(1) + '_export' + current_config[export_group] = False + + ''' + show running config will contains [no wjh * group enable] if disabled - default config is enabled + ''' + def load_current_config(self): + self._current_config = dict() + config_lines = self._get_wjh_config() + if config_lines: + self._set_current_config(config_lines) + + def wjh_group_status(self, current_config, group_value, suffix=''): + current_enabled = False + if group_value == 'all': + # no disabled group so all would be false + current_enabled = not all([ + (group + suffix) in current_config for group in self.WJH_GROUPS]) + else: + # if no current-value its enabled + current_enabled = current_config[group_value + suffix] if((group_value + suffix) in current_config) else True + return current_enabled + + ''' + wjh is enabled "by default" + when wjh disable we will find no wjh commands in running config + ''' + def generate_commands(self): + current_config, required_config = self._current_config, self._required_config + group = required_config.get('group') + export_group = required_config.get('export_group') + clear_group = required_config.get('clear_group') + if group: + current_enabled = self.wjh_group_status(current_config, group) + if(required_config['enabled'] != current_enabled): + self._commands.append(self.WJH_CMD_FMT + .format(('' if required_config['enabled'] else 'no '), group)) + if export_group: + current_enabled = self.wjh_group_status(current_config, required_config['export_group'], '_export') + if(required_config['auto_export'] != current_enabled): + self._commands.append(self.WJH_EXPORT_CMD_FMT + .format(('' if required_config['auto_export'] else 'no '), export_group)) + if clear_group: + # clear pcap files + self._commands.append(self.WJH_CLEAR_CMD_FMT.format(clear_group)) + + +def main(): + """ main entry point for module execution + """ + OnyxWJHModule.main() + + +if __name__ == '__main__': + main() diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/terminal/__init__.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/terminal/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/terminal/__init__.py diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/terminal/onyx.py b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/terminal/onyx.py new file mode 100644 index 00000000..52d630b9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/plugins/terminal/onyx.py @@ -0,0 +1,80 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. +# +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json +import re + +from ansible.errors import AnsibleConnectionFailure +from ansible.module_utils._text import to_text, to_bytes +from ansible.plugins.terminal import TerminalBase + + +class TerminalModule(TerminalBase): + + terminal_stdout_re = [ + re.compile(br"(?P<prompt>(.*)( > | # )\Z)"), + ] + + terminal_stderr_re = [ + re.compile(br"\A%|\r\n%|\n%"), + ] + + init_commands = [b'no cli session paging enable', ] + + def on_open_shell(self): + try: + for cmd in self.init_commands: + self._exec_cli_command(cmd) + except AnsibleConnectionFailure: + raise AnsibleConnectionFailure('unable to set terminal parameters') + + def on_become(self, passwd=None): + if self._get_prompt().endswith(b'#'): + return + + cmd = {u'command': u'enable'} + if passwd: + # Note: python-3.5 cannot combine u"" and r"" together. Thus make + # an r string and use to_text to ensure it's text on both py2 and + # py3. + cmd[u'prompt'] = to_text(r"[\r\n]?password: $", + errors='surrogate_or_strict') + cmd[u'answer'] = passwd + + try: + self._exec_cli_command(to_bytes(json.dumps(cmd), + errors='surrogate_or_strict')) + except AnsibleConnectionFailure: + raise AnsibleConnectionFailure( + 'unable to elevate privilege to enable mode') + + def on_unbecome(self): + prompt = self._get_prompt() + if prompt is None: + # if prompt is None most likely the terminal is hung up at a prompt + return + + if b'(config' in prompt: + self._exec_cli_command(b'exit') + self._exec_cli_command(b'disable') + + elif prompt.endswith(b'#'): + self._exec_cli_command(b'disable') diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.10.txt b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.10.txt new file mode 100644 index 00000000..cd173497 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.10.txt @@ -0,0 +1,105 @@ +plugins/modules/onyx_bgp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_bgp.py validate-modules:doc-missing-type +plugins/modules/onyx_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_buffer_pool.py validate-modules:doc-missing-type +plugins/modules/onyx_buffer_pool.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_command.py validate-modules:doc-missing-type +plugins/modules/onyx_command.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_config.py validate-modules:doc-missing-type +plugins/modules/onyx_config.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_facts.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_igmp.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_igmp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_igmp_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_igmp_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_interface.py validate-modules:nonexistent-parameter-documented +plugins/modules/onyx_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_l2_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_l3_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_linkagg.py validate-modules:doc-default-does-not-match-spec +plugins/modules/onyx_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_linkagg.py validate-modules:doc-missing-type +plugins/modules/onyx_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/onyx_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/onyx_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_linkagg.py validate-modules:undocumented-parameter +plugins/modules/onyx_lldp.py validate-modules:doc-missing-type +plugins/modules/onyx_lldp_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_lldp_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_lldp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_lldp_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_lldp_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_lldp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_lldp_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_magp.py validate-modules:doc-missing-type +plugins/modules/onyx_magp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_mlag_ipl.py validate-modules:doc-missing-type +plugins/modules/onyx_mlag_vip.py validate-modules:doc-default-does-not-match-spec +plugins/modules/onyx_mlag_vip.py validate-modules:doc-missing-type +plugins/modules/onyx_mlag_vip.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_ntp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ntp_servers_peers.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ospf.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ospf.py validate-modules:doc-missing-type +plugins/modules/onyx_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_pfc_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_pfc_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_pfc_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_pfc_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_pfc_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_pfc_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_pfc_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_protocol.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_global.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_ptp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_qos.py validate-modules:doc-missing-type +plugins/modules/onyx_qos.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_qos.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_snmp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_snmp_hosts.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_snmp_users.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_syslog_remote.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_traffic_class.py validate-modules:doc-missing-type +plugins/modules/onyx_traffic_class.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_traffic_class.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_vlan.py validate-modules:doc-missing-type +plugins/modules/onyx_vlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_vlan.py validate-modules:missing-suboption-docs +plugins/modules/onyx_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vlan.py validate-modules:undocumented-parameter +plugins/modules/onyx_vxlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_vxlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_vxlan.py validate-modules:missing-suboption-docs +plugins/modules/onyx_vxlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vxlan.py validate-modules:undocumented-parameter diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.10.txt.orig b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.10.txt.orig new file mode 100644 index 00000000..36d5809c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.10.txt.orig @@ -0,0 +1,1719 @@ +plugins/action/aireos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/aruba.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/ce.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/ce_template.py action-plugin-docs # undocumented action plugin to fix, existed before sanity test was added +plugins/action/cnos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/edgeos_config.py action-plugin-docs # undocumented action plugin to fix +plugins/action/enos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/exos.py action-plugin-docs # undocumented action plugin to fix +plugins/action/ironware.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/nos_config.py action-plugin-docs # undocumented action plugin to fix +plugins/action/onyx_config.py action-plugin-docs # undocumented action plugin to fix +plugins/action/slxos.py action-plugin-docs # undocumented action plugin to fix +plugins/action/sros.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/voss.py action-plugin-docs # undocumented action plugin to fix +plugins/doc_fragments/a10.py future-import-boilerplate +plugins/doc_fragments/a10.py metaclass-boilerplate +plugins/doc_fragments/aireos.py future-import-boilerplate +plugins/doc_fragments/aireos.py metaclass-boilerplate +plugins/doc_fragments/aruba.py future-import-boilerplate +plugins/doc_fragments/aruba.py metaclass-boilerplate +plugins/doc_fragments/avi.py future-import-boilerplate +plugins/doc_fragments/avi.py metaclass-boilerplate +plugins/doc_fragments/ce.py future-import-boilerplate +plugins/doc_fragments/ce.py metaclass-boilerplate +plugins/doc_fragments/cnos.py future-import-boilerplate +plugins/doc_fragments/cnos.py metaclass-boilerplate +plugins/doc_fragments/enos.py future-import-boilerplate +plugins/doc_fragments/enos.py metaclass-boilerplate +plugins/doc_fragments/ingate.py future-import-boilerplate +plugins/doc_fragments/ingate.py metaclass-boilerplate +plugins/doc_fragments/ironware.py future-import-boilerplate +plugins/doc_fragments/ironware.py metaclass-boilerplate +plugins/doc_fragments/netscaler.py future-import-boilerplate +plugins/doc_fragments/netscaler.py metaclass-boilerplate +plugins/doc_fragments/nso.py future-import-boilerplate +plugins/doc_fragments/nso.py metaclass-boilerplate +plugins/doc_fragments/onyx.py future-import-boilerplate +plugins/doc_fragments/onyx.py metaclass-boilerplate +plugins/doc_fragments/panos.py future-import-boilerplate +plugins/doc_fragments/panos.py metaclass-boilerplate +plugins/doc_fragments/sros.py future-import-boilerplate +plugins/doc_fragments/sros.py metaclass-boilerplate +plugins/module_utils/network/a10/a10.py future-import-boilerplate +plugins/module_utils/network/a10/a10.py metaclass-boilerplate +plugins/module_utils/network/aireos/aireos.py future-import-boilerplate +plugins/module_utils/network/aireos/aireos.py metaclass-boilerplate +plugins/module_utils/network/aos/aos.py future-import-boilerplate +plugins/module_utils/network/aos/aos.py metaclass-boilerplate +plugins/module_utils/network/aruba/aruba.py future-import-boilerplate +plugins/module_utils/network/aruba/aruba.py metaclass-boilerplate +plugins/module_utils/network/avi/ansible_utils.py future-import-boilerplate +plugins/module_utils/network/avi/ansible_utils.py metaclass-boilerplate +plugins/module_utils/network/avi/avi.py future-import-boilerplate +plugins/module_utils/network/avi/avi.py metaclass-boilerplate +plugins/module_utils/network/avi/avi_api.py future-import-boilerplate +plugins/module_utils/network/avi/avi_api.py metaclass-boilerplate +plugins/module_utils/network/bigswitch/bigswitch.py future-import-boilerplate +plugins/module_utils/network/bigswitch/bigswitch.py metaclass-boilerplate +plugins/module_utils/network/cloudengine/ce.py future-import-boilerplate +plugins/module_utils/network/cloudengine/ce.py metaclass-boilerplate +plugins/module_utils/network/cnos/cnos.py future-import-boilerplate +plugins/module_utils/network/cnos/cnos.py metaclass-boilerplate +plugins/module_utils/network/cnos/cnos_devicerules.py future-import-boilerplate +plugins/module_utils/network/cnos/cnos_devicerules.py metaclass-boilerplate +plugins/module_utils/network/cnos/cnos_errorcodes.py future-import-boilerplate +plugins/module_utils/network/cnos/cnos_errorcodes.py metaclass-boilerplate +plugins/module_utils/network/edgeos/edgeos.py future-import-boilerplate +plugins/module_utils/network/edgeos/edgeos.py metaclass-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch.py future-import-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch.py metaclass-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch_interface.py future-import-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch_interface.py metaclass-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch_interface.py pylint:duplicate-string-formatting-argument +plugins/module_utils/network/enos/enos.py future-import-boilerplate +plugins/module_utils/network/enos/enos.py metaclass-boilerplate +plugins/module_utils/network/exos/exos.py future-import-boilerplate +plugins/module_utils/network/exos/exos.py metaclass-boilerplate +plugins/module_utils/network/ftd/common.py future-import-boilerplate +plugins/module_utils/network/ftd/common.py metaclass-boilerplate +plugins/module_utils/network/ftd/configuration.py future-import-boilerplate +plugins/module_utils/network/ftd/configuration.py metaclass-boilerplate +plugins/module_utils/network/ftd/device.py future-import-boilerplate +plugins/module_utils/network/ftd/device.py metaclass-boilerplate +plugins/module_utils/network/ftd/fdm_swagger_client.py future-import-boilerplate +plugins/module_utils/network/ftd/fdm_swagger_client.py metaclass-boilerplate +plugins/module_utils/network/ftd/operation.py future-import-boilerplate +plugins/module_utils/network/ftd/operation.py metaclass-boilerplate +plugins/module_utils/network/netscaler/netscaler.py future-import-boilerplate +plugins/module_utils/network/netscaler/netscaler.py metaclass-boilerplate +plugins/module_utils/network/nos/nos.py future-import-boilerplate +plugins/module_utils/network/nos/nos.py metaclass-boilerplate +plugins/module_utils/network/nso/nso.py future-import-boilerplate +plugins/module_utils/network/nso/nso.py metaclass-boilerplate +plugins/module_utils/network/onyx/onyx.py future-import-boilerplate +plugins/module_utils/network/onyx/onyx.py metaclass-boilerplate +plugins/module_utils/network/ordnance/ordnance.py future-import-boilerplate +plugins/module_utils/network/ordnance/ordnance.py metaclass-boilerplate +plugins/module_utils/network/routeros/routeros.py future-import-boilerplate +plugins/module_utils/network/routeros/routeros.py metaclass-boilerplate +plugins/module_utils/network/slxos/slxos.py future-import-boilerplate +plugins/module_utils/network/slxos/slxos.py metaclass-boilerplate +plugins/module_utils/network/sros/sros.py future-import-boilerplate +plugins/module_utils/network/sros/sros.py metaclass-boilerplate +plugins/module_utils/network/voss/voss.py future-import-boilerplate +plugins/module_utils/network/voss/voss.py metaclass-boilerplate +plugins/modules/network/a10/a10_server.py validate-modules:parameter-list-no-elements +plugins/modules/network/a10/a10_server.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/a10/a10_server_axapi3.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/a10/a10_server_axapi3.py validate-modules:parameter-list-no-elements +plugins/modules/network/a10/a10_server_axapi3.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/a10/a10_service_group.py validate-modules:parameter-list-no-elements +plugins/modules/network/a10/a10_service_group.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/a10/a10_virtual_server.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/a10/a10_virtual_server.py validate-modules:doc-required-mismatch +plugins/modules/network/a10/a10_virtual_server.py validate-modules:parameter-list-no-elements +plugins/modules/network/a10/a10_virtual_server.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/aireos/aireos_command.py validate-modules:collection-deprecated-version +plugins/modules/network/aireos/aireos_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/aireos/aireos_command.py validate-modules:doc-missing-type +plugins/modules/network/aireos/aireos_command.py validate-modules:doc-required-mismatch +plugins/modules/network/aireos/aireos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/aireos/aireos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/aireos/aireos_config.py validate-modules:collection-deprecated-version +plugins/modules/network/aireos/aireos_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/aireos/aireos_config.py validate-modules:doc-missing-type +plugins/modules/network/aireos/aireos_config.py validate-modules:doc-required-mismatch +plugins/modules/network/aireos/aireos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/aireos/aireos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/apconos/apconos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/aruba/aruba_command.py validate-modules:collection-deprecated-version +plugins/modules/network/aruba/aruba_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/aruba/aruba_command.py validate-modules:doc-missing-type +plugins/modules/network/aruba/aruba_command.py validate-modules:doc-required-mismatch +plugins/modules/network/aruba/aruba_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/aruba/aruba_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/aruba/aruba_config.py validate-modules:collection-deprecated-version +plugins/modules/network/aruba/aruba_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/aruba/aruba_config.py validate-modules:doc-missing-type +plugins/modules/network/aruba/aruba_config.py validate-modules:doc-required-mismatch +plugins/modules/network/aruba/aruba_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/aruba/aruba_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_actiongroupconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_actiongroupconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_actiongroupconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_actiongroupconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_alertconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_alertconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_alertconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_alertconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_alertemailconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_alertemailconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_alertemailconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_alertemailconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_alertscriptconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_alertscriptconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_alertscriptconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_alertscriptconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_alertsyslogconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_alertsyslogconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_alertsyslogconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_alertsyslogconfig.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_alertsyslogconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_analyticsprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_analyticsprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_analyticsprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_analyticsprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_analyticsprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_api_session.py future-import-boilerplate +plugins/modules/network/avi/avi_api_session.py metaclass-boilerplate +plugins/modules/network/avi/avi_api_session.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_api_session.py validate-modules:doc-required-mismatch +plugins/modules/network/avi/avi_api_session.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_api_version.py future-import-boilerplate +plugins/modules/network/avi/avi_api_version.py metaclass-boilerplate +plugins/modules/network/avi/avi_api_version.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_api_version.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_applicationpersistenceprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_applicationpersistenceprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_applicationpersistenceprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_applicationpersistenceprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_applicationprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_applicationprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_applicationprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_applicationprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_authprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_authprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_authprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_authprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_autoscalelaunchconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_autoscalelaunchconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_autoscalelaunchconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_autoscalelaunchconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_backup.py future-import-boilerplate +plugins/modules/network/avi/avi_backup.py metaclass-boilerplate +plugins/modules/network/avi/avi_backup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_backup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_backupconfiguration.py future-import-boilerplate +plugins/modules/network/avi/avi_backupconfiguration.py metaclass-boilerplate +plugins/modules/network/avi/avi_backupconfiguration.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_backupconfiguration.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_certificatemanagementprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_certificatemanagementprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_certificatemanagementprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_certificatemanagementprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_certificatemanagementprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_cloud.py future-import-boilerplate +plugins/modules/network/avi/avi_cloud.py metaclass-boilerplate +plugins/modules/network/avi/avi_cloud.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_cloud.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_cloud.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_cloudconnectoruser.py future-import-boilerplate +plugins/modules/network/avi/avi_cloudconnectoruser.py metaclass-boilerplate +plugins/modules/network/avi/avi_cloudconnectoruser.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_cloudconnectoruser.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_cloudproperties.py future-import-boilerplate +plugins/modules/network/avi/avi_cloudproperties.py metaclass-boilerplate +plugins/modules/network/avi/avi_cloudproperties.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_cloudproperties.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_cloudproperties.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_cluster.py future-import-boilerplate +plugins/modules/network/avi/avi_cluster.py metaclass-boilerplate +plugins/modules/network/avi/avi_cluster.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_cluster.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_cluster.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_clusterclouddetails.py future-import-boilerplate +plugins/modules/network/avi/avi_clusterclouddetails.py metaclass-boilerplate +plugins/modules/network/avi/avi_clusterclouddetails.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_clusterclouddetails.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_controllerproperties.py future-import-boilerplate +plugins/modules/network/avi/avi_controllerproperties.py metaclass-boilerplate +plugins/modules/network/avi/avi_controllerproperties.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_controllerproperties.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_controllerproperties.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_customipamdnsprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_customipamdnsprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_customipamdnsprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_customipamdnsprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_customipamdnsprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_dnspolicy.py future-import-boilerplate +plugins/modules/network/avi/avi_dnspolicy.py metaclass-boilerplate +plugins/modules/network/avi/avi_dnspolicy.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_dnspolicy.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_dnspolicy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_errorpagebody.py future-import-boilerplate +plugins/modules/network/avi/avi_errorpagebody.py metaclass-boilerplate +plugins/modules/network/avi/avi_errorpagebody.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_errorpagebody.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_errorpageprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_errorpageprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_errorpageprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_errorpageprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_errorpageprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_gslb.py future-import-boilerplate +plugins/modules/network/avi/avi_gslb.py metaclass-boilerplate +plugins/modules/network/avi/avi_gslb.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_gslb.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_gslb.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_gslbgeodbprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_gslbgeodbprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_gslbgeodbprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_gslbgeodbprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_gslbgeodbprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_gslbservice.py future-import-boilerplate +plugins/modules/network/avi/avi_gslbservice.py metaclass-boilerplate +plugins/modules/network/avi/avi_gslbservice.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_gslbservice.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_gslbservice.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_gslbservice_patch_member.py future-import-boilerplate +plugins/modules/network/avi/avi_gslbservice_patch_member.py metaclass-boilerplate +plugins/modules/network/avi/avi_gslbservice_patch_member.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_gslbservice_patch_member.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_hardwaresecuritymodulegroup.py future-import-boilerplate +plugins/modules/network/avi/avi_hardwaresecuritymodulegroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_hardwaresecuritymodulegroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_hardwaresecuritymodulegroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_healthmonitor.py future-import-boilerplate +plugins/modules/network/avi/avi_healthmonitor.py metaclass-boilerplate +plugins/modules/network/avi/avi_healthmonitor.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_healthmonitor.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_httppolicyset.py future-import-boilerplate +plugins/modules/network/avi/avi_httppolicyset.py metaclass-boilerplate +plugins/modules/network/avi/avi_httppolicyset.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_httppolicyset.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_ipaddrgroup.py future-import-boilerplate +plugins/modules/network/avi/avi_ipaddrgroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_ipaddrgroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_ipaddrgroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_ipaddrgroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_ipamdnsproviderprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_ipamdnsproviderprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_ipamdnsproviderprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_ipamdnsproviderprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_l4policyset.py future-import-boilerplate +plugins/modules/network/avi/avi_l4policyset.py metaclass-boilerplate +plugins/modules/network/avi/avi_l4policyset.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_l4policyset.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_microservicegroup.py future-import-boilerplate +plugins/modules/network/avi/avi_microservicegroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_microservicegroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_microservicegroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_microservicegroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_network.py future-import-boilerplate +plugins/modules/network/avi/avi_network.py metaclass-boilerplate +plugins/modules/network/avi/avi_network.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_network.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_network.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_networkprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_networkprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_networkprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_networkprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_networksecuritypolicy.py future-import-boilerplate +plugins/modules/network/avi/avi_networksecuritypolicy.py metaclass-boilerplate +plugins/modules/network/avi/avi_networksecuritypolicy.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_networksecuritypolicy.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_networksecuritypolicy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_pkiprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_pkiprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_pkiprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_pkiprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_pkiprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_pool.py future-import-boilerplate +plugins/modules/network/avi/avi_pool.py metaclass-boilerplate +plugins/modules/network/avi/avi_pool.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_pool.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_pool.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_poolgroup.py future-import-boilerplate +plugins/modules/network/avi/avi_poolgroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_poolgroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_poolgroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_poolgroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py future-import-boilerplate +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py metaclass-boilerplate +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_prioritylabels.py future-import-boilerplate +plugins/modules/network/avi/avi_prioritylabels.py metaclass-boilerplate +plugins/modules/network/avi/avi_prioritylabels.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_prioritylabels.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_prioritylabels.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_role.py future-import-boilerplate +plugins/modules/network/avi/avi_role.py metaclass-boilerplate +plugins/modules/network/avi/avi_role.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_role.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_role.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_scheduler.py future-import-boilerplate +plugins/modules/network/avi/avi_scheduler.py metaclass-boilerplate +plugins/modules/network/avi/avi_scheduler.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_scheduler.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_seproperties.py future-import-boilerplate +plugins/modules/network/avi/avi_seproperties.py metaclass-boilerplate +plugins/modules/network/avi/avi_seproperties.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_seproperties.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_serverautoscalepolicy.py future-import-boilerplate +plugins/modules/network/avi/avi_serverautoscalepolicy.py metaclass-boilerplate +plugins/modules/network/avi/avi_serverautoscalepolicy.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_serverautoscalepolicy.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_serverautoscalepolicy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_serviceengine.py future-import-boilerplate +plugins/modules/network/avi/avi_serviceengine.py metaclass-boilerplate +plugins/modules/network/avi/avi_serviceengine.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_serviceengine.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_serviceengine.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_serviceenginegroup.py future-import-boilerplate +plugins/modules/network/avi/avi_serviceenginegroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_serviceenginegroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_serviceenginegroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_serviceenginegroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_snmptrapprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_snmptrapprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_snmptrapprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_snmptrapprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_snmptrapprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_sslkeyandcertificate.py future-import-boilerplate +plugins/modules/network/avi/avi_sslkeyandcertificate.py metaclass-boilerplate +plugins/modules/network/avi/avi_sslkeyandcertificate.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_sslkeyandcertificate.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_sslkeyandcertificate.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_sslprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_sslprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_sslprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_sslprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_sslprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_stringgroup.py future-import-boilerplate +plugins/modules/network/avi/avi_stringgroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_stringgroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_stringgroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_stringgroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_systemconfiguration.py future-import-boilerplate +plugins/modules/network/avi/avi_systemconfiguration.py metaclass-boilerplate +plugins/modules/network/avi/avi_systemconfiguration.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_systemconfiguration.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_systemconfiguration.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_tenant.py future-import-boilerplate +plugins/modules/network/avi/avi_tenant.py metaclass-boilerplate +plugins/modules/network/avi/avi_tenant.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_tenant.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_trafficcloneprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_trafficcloneprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_trafficcloneprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_trafficcloneprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_trafficcloneprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_user.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_user.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_user.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_useraccount.py future-import-boilerplate +plugins/modules/network/avi/avi_useraccount.py metaclass-boilerplate +plugins/modules/network/avi/avi_useraccount.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_useraccount.py validate-modules:doc-required-mismatch +plugins/modules/network/avi/avi_useraccount.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_useraccountprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_useraccountprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_useraccountprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_useraccountprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_virtualservice.py future-import-boilerplate +plugins/modules/network/avi/avi_virtualservice.py metaclass-boilerplate +plugins/modules/network/avi/avi_virtualservice.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_virtualservice.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_virtualservice.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_vrfcontext.py future-import-boilerplate +plugins/modules/network/avi/avi_vrfcontext.py metaclass-boilerplate +plugins/modules/network/avi/avi_vrfcontext.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_vrfcontext.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_vrfcontext.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_vsdatascriptset.py future-import-boilerplate +plugins/modules/network/avi/avi_vsdatascriptset.py metaclass-boilerplate +plugins/modules/network/avi/avi_vsdatascriptset.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_vsdatascriptset.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_vsdatascriptset.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_vsvip.py future-import-boilerplate +plugins/modules/network/avi/avi_vsvip.py metaclass-boilerplate +plugins/modules/network/avi/avi_vsvip.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_vsvip.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_vsvip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_webhook.py future-import-boilerplate +plugins/modules/network/avi/avi_webhook.py metaclass-boilerplate +plugins/modules/network/avi/avi_webhook.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_webhook.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/bigswitch/bcf_switch.py validate-modules:doc-missing-type +plugins/modules/network/bigswitch/bcf_switch.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/bigswitch/bigmon_chain.py validate-modules:doc-missing-type +plugins/modules/network/bigswitch/bigmon_chain.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/bigswitch/bigmon_policy.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/bigswitch/bigmon_policy.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/bigswitch/bigmon_policy.py validate-modules:doc-missing-type +plugins/modules/network/bigswitch/bigmon_policy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_acl.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_acl.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_acl.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_acl.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_acl.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_acl.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:doc-default-incompatible-type +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_command.py pylint:blacklisted-name +plugins/modules/network/cloudengine/ce_command.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_command.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_command.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_command.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_config.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_config.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_config.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_config.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_dldp_interface.py pylint:blacklisted-name +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_facts.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_facts.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_facts.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_facts.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_is_is_view.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_mlag_interface.py pylint:blacklisted-name +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:mutually_exclusive-unknown +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_startup.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_startup.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_startup.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_startup.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_startup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_startup.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_static_route_bfd.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_static_route_bfd.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_stp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_stp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_stp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_stp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_stp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_stp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:undocumented-parameter +plugins/modules/network/cloudvision/cv_server_provision.py pylint:blacklisted-name +plugins/modules/network/cloudvision/cv_server_provision.py validate-modules:doc-missing-type +plugins/modules/network/cloudvision/cv_server_provision.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudvision/cv_server_provision.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/cnos/cnos_backup.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_backup.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_backup.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_backup.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cnos/cnos_backup.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_backup.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_banner.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_banner.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_banner.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_banner.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_banner.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_bgp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_bgp.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_bgp.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_bgp.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_command.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_conditional_command.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_conditional_command.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_conditional_command.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_conditional_command.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_conditional_template.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_conditional_template.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_conditional_template.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_conditional_template.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_config.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_config.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_factory.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_factory.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_factory.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_facts.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cnos/cnos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_facts.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_image.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_image.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_image.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_image.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_lldp.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_logging.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_logging.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_logging.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_logging.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_logging.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_logging.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_reload.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_reload.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_reload.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_rollback.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_rollback.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_rollback.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_rollback.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cnos/cnos_rollback.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_rollback.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_save.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_save.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_save.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_showrun.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_showrun.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cnos/cnos_showrun.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_static_route.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_static_route.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_static_route.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_static_route.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_static_route.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_static_route.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_static_route.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_system.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_system.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_system.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_template.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_template.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_template.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_template.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_user.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_user.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_user.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_user.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_user.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_user.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_user.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_vlag.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_vlag.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_vlag.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_vlag.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_vrf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_vrf.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_vrf.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_vrf.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_vrf.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_vrf.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_vrf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_vrf.py validate-modules:undocumented-parameter +plugins/modules/network/cumulus/nclu.py validate-modules:parameter-list-no-elements +plugins/modules/network/cumulus/nclu.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeos/edgeos_command.py validate-modules:doc-missing-type +plugins/modules/network/edgeos/edgeos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeos/edgeos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeos/edgeos_config.py validate-modules:doc-missing-type +plugins/modules/network/edgeos/edgeos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeos/edgeos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeos/edgeos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeos/edgeos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeswitch/edgeswitch_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeswitch/edgeswitch_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:doc-missing-type +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/enos/enos_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/enos/enos_command.py validate-modules:doc-missing-type +plugins/modules/network/enos/enos_command.py validate-modules:doc-required-mismatch +plugins/modules/network/enos/enos_command.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/enos/enos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/enos/enos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/enos/enos_command.py validate-modules:undocumented-parameter +plugins/modules/network/enos/enos_command.py yamllint:unparsable-with-libyaml +plugins/modules/network/enos/enos_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/enos/enos_config.py validate-modules:doc-missing-type +plugins/modules/network/enos/enos_config.py validate-modules:doc-required-mismatch +plugins/modules/network/enos/enos_config.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/enos/enos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/enos/enos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/enos/enos_config.py validate-modules:undocumented-parameter +plugins/modules/network/enos/enos_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/enos/enos_facts.py validate-modules:doc-missing-type +plugins/modules/network/enos/enos_facts.py validate-modules:doc-required-mismatch +plugins/modules/network/enos/enos_facts.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/enos/enos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/enos/enos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/enos/enos_facts.py validate-modules:undocumented-parameter +plugins/modules/network/enos/enos_facts.py yamllint:unparsable-with-libyaml +plugins/modules/network/eric_eccli/eric_eccli_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/exos/exos_command.py validate-modules:doc-missing-type +plugins/modules/network/exos/exos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/exos/exos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/exos/exos_config.py validate-modules:doc-missing-type +plugins/modules/network/exos/exos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/exos/exos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/exos/exos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/exos/exos_l2_interfaces.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortianalyzer/faz_device.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_device.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_device.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_device_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_device_group.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_device_group.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_device_provision_template.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_device_provision_template.py validate-modules:invalid-argument-name +plugins/modules/network/fortimanager/fmgr_device_provision_template.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/fortimanager/fmgr_device_provision_template.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_address.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_ippool.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_fwobj_ippool.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_ippool6.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_fwobj_ippool6.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_service.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_vip.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_fwobj_vip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwpol_ipv4.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_fwpol_ipv4.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwpol_package.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_fwpol_package.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_ha.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_provisioning.py validate-modules:doc-missing-type +plugins/modules/network/fortimanager/fmgr_provisioning.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_provisioning.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_query.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_query.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_script.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/fortimanager/fmgr_script.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_script.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_appctrl.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_appctrl.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_av.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_av.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_dns.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_ips.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_ips.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_profile_group.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_proxy.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_proxy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_spam.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_spam.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_ssl_ssh.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_ssl_ssh.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_voip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_waf.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_waf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_wanopt.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_web.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_web.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/icx/icx_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_lldp.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_lldp.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_logging.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_logging.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_static_route.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_static_route.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_system.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_system.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_user.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_user.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/illumos/dladm_etherstub.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_etherstub.py validate-modules:doc-missing-type +plugins/modules/network/illumos/dladm_iptun.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_iptun.py validate-modules:doc-missing-type +plugins/modules/network/illumos/dladm_iptun.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/illumos/dladm_linkprop.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_linkprop.py validate-modules:doc-missing-type +plugins/modules/network/illumos/dladm_linkprop.py validate-modules:no-default-for-required-parameter +plugins/modules/network/illumos/dladm_linkprop.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/illumos/dladm_vlan.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_vlan.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/illumos/dladm_vlan.py validate-modules:doc-missing-type +plugins/modules/network/illumos/dladm_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/illumos/dladm_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/illumos/dladm_vnic.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_vnic.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/illumos/dladm_vnic.py validate-modules:doc-missing-type +plugins/modules/network/illumos/flowadm.py pylint:blacklisted-name +plugins/modules/network/illumos/flowadm.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/illumos/flowadm.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_addr.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_addr.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_addr.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/illumos/ipadm_addrprop.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_addrprop.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_addrprop.py validate-modules:no-default-for-required-parameter +plugins/modules/network/illumos/ipadm_if.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_if.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_ifprop.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_ifprop.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/illumos/ipadm_ifprop.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_ifprop.py validate-modules:no-default-for-required-parameter +plugins/modules/network/illumos/ipadm_prop.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_prop.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/illumos/ipadm_prop.py validate-modules:doc-missing-type +plugins/modules/network/ingate/ig_config.py validate-modules:doc-missing-type +plugins/modules/network/ingate/ig_config.py validate-modules:doc-required-mismatch +plugins/modules/network/ingate/ig_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ingate/ig_config.py validate-modules:return-syntax-error +plugins/modules/network/ingate/ig_unit_information.py validate-modules:doc-required-mismatch +plugins/modules/network/ingate/ig_unit_information.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ironware/ironware_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ironware/ironware_command.py validate-modules:doc-missing-type +plugins/modules/network/ironware/ironware_command.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/ironware/ironware_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/ironware/ironware_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ironware/ironware_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ironware/ironware_config.py validate-modules:doc-missing-type +plugins/modules/network/ironware/ironware_config.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/ironware/ironware_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/ironware/ironware_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ironware/ironware_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ironware/ironware_facts.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/ironware/ironware_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/ironware/ironware_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/itential/iap_start_workflow.py validate-modules:doc-required-mismatch +plugins/modules/network/itential/iap_token.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netact/netact_cm_command.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/netact/netact_cm_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_cs_action.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_cs_action.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_cs_policy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:undocumented-parameter +plugins/modules/network/netscaler/netscaler_gslb_service.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_gslb_service.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_gslb_site.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_gslb_vserver.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_gslb_vserver.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_gslb_vserver.py validate-modules:undocumented-parameter +plugins/modules/network/netscaler/netscaler_lb_monitor.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/netscaler/netscaler_lb_monitor.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_lb_monitor.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_lb_monitor.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_lb_vserver.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_lb_vserver.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_lb_vserver.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_nitro_request.py pylint:ansible-bad-function +plugins/modules/network/netscaler/netscaler_nitro_request.py validate-modules:doc-missing-type +plugins/modules/network/netscaler/netscaler_nitro_request.py validate-modules:doc-required-mismatch +plugins/modules/network/netscaler/netscaler_nitro_request.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_nitro_request.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_save_config.py validate-modules:doc-missing-type +plugins/modules/network/netscaler/netscaler_save_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_server.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/netscaler/netscaler_server.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_service.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_service.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_service.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_servicegroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_servicegroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_ssl_certkey.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_access_list.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_access_list.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_access_list_ip.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_access_list_ip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_admin_service.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_admin_session_timeout.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_admin_syslog.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_cluster.py future-import-boilerplate +plugins/modules/network/netvisor/pn_cluster.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_cluster.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_connection_stats_settings.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_cpu_class.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_cpu_class.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_cpu_mgmt_class.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_dhcp_filter.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_dscp_map.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_dscp_map.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_dscp_map_pri_map.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_fabric_local.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_fabric_local.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_igmp_snooping.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_igmp_snooping.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_ipv6security_raguard.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_ipv6security_raguard_port.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_ipv6security_raguard_vlan.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_log_audit_exception.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_log_audit_exception.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_ospf.py future-import-boilerplate +plugins/modules/network/netvisor/pn_ospf.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_ospf.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_ospfarea.py future-import-boilerplate +plugins/modules/network/netvisor/pn_ospfarea.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_ospfarea.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_port_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_port_config.py validate-modules:required_one_of-unknown +plugins/modules/network/netvisor/pn_port_cos_bw.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_port_cos_rate_setting.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_prefix_list.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_prefix_list_network.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_role.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_role.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_show.py future-import-boilerplate +plugins/modules/network/netvisor/pn_show.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_show.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_show.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_snmp_community.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_snmp_community.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_snmp_trap_sink.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_snmp_vacm.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_stp.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_stp_port.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_switch_setup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_trunk.py future-import-boilerplate +plugins/modules/network/netvisor/pn_trunk.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_trunk.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_user.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vflow_table_profile.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vlag.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vlag.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vlag.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vlan.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vlan.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouter.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vrouter.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vrouter.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouter_bgp.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouter_bgp_network.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_interface_ip.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_loopback_interface.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_ospf.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_ospf6.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_packet_relay.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_pim_config.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_vrouter_pim_config.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouterbgp.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vrouterbgp.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vrouterbgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouterif.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vrouterif.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vrouterif.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_vrouterif.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouterlbif.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vrouterlbif.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vrouterlbif.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_vrouterlbif.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vtep.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/nos/nos_command.py validate-modules:doc-missing-type +plugins/modules/network/nos/nos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/nos/nos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nos/nos_config.py validate-modules:doc-missing-type +plugins/modules/network/nos/nos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/nos/nos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nos/nos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/nos/nos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_action.py validate-modules:doc-missing-type +plugins/modules/network/nso/nso_action.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_config.py validate-modules:return-syntax-error +plugins/modules/network/nso/nso_query.py validate-modules:parameter-list-no-elements +plugins/modules/network/nso/nso_query.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_show.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_verify.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nuage/nuage_vspk.py validate-modules:doc-required-mismatch +plugins/modules/network/nuage/nuage_vspk.py validate-modules:missing-suboption-docs +plugins/modules/network/nuage/nuage_vspk.py validate-modules:parameter-list-no-elements +plugins/modules/network/nuage/nuage_vspk.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nuage/nuage_vspk.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_bgp.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_bgp.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_buffer_pool.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_buffer_pool.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_command.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_command.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/onyx/onyx_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_config.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_config.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/onyx/onyx_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_igmp.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_igmp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_igmp_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_interface.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/onyx/onyx_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_lldp.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_magp.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_magp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_mlag_ipl.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_mlag_vip.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/onyx/onyx_mlag_vip.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_mlag_vip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_ntp.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_ntp_servers_peers.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_ospf.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_ospf.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_protocol.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_ptp_global.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_ptp_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_ptp_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_ptp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_qos.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_qos.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_qos.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_snmp.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_snmp_hosts.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_snmp_users.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_syslog_remote.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_traffic_class.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_traffic_class.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_traffic_class.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_vlan.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:undocumented-parameter +plugins/modules/network/opx/opx_cps.py validate-modules:doc-required-mismatch +plugins/modules/network/opx/opx_cps.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ordnance/ordnance_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ordnance/ordnance_config.py validate-modules:doc-missing-type +plugins/modules/network/ordnance/ordnance_config.py validate-modules:doc-required-mismatch +plugins/modules/network/ordnance/ordnance_config.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/ordnance/ordnance_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/ordnance/ordnance_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ordnance/ordnance_config.py validate-modules:undocumented-parameter +plugins/modules/network/ordnance/ordnance_config.py yamllint:unparsable-with-libyaml +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:doc-missing-type +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:doc-required-mismatch +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:undocumented-parameter +plugins/modules/network/ordnance/ordnance_facts.py yamllint:unparsable-with-libyaml +plugins/modules/network/panos/panos_admin.py future-import-boilerplate +plugins/modules/network/panos/panos_admin.py metaclass-boilerplate +plugins/modules/network/panos/panos_admin.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_admin.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_admpwd.py future-import-boilerplate +plugins/modules/network/panos/panos_admpwd.py metaclass-boilerplate +plugins/modules/network/panos/panos_admpwd.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_cert_gen_ssh.py future-import-boilerplate +plugins/modules/network/panos/panos_cert_gen_ssh.py metaclass-boilerplate +plugins/modules/network/panos/panos_cert_gen_ssh.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_cert_gen_ssh.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_check.py future-import-boilerplate +plugins/modules/network/panos/panos_check.py metaclass-boilerplate +plugins/modules/network/panos/panos_check.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_commit.py future-import-boilerplate +plugins/modules/network/panos/panos_commit.py metaclass-boilerplate +plugins/modules/network/panos/panos_commit.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_commit.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_commit.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_commit.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_dag.py future-import-boilerplate +plugins/modules/network/panos/panos_dag.py metaclass-boilerplate +plugins/modules/network/panos/panos_dag.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_dag_tags.py future-import-boilerplate +plugins/modules/network/panos/panos_dag_tags.py metaclass-boilerplate +plugins/modules/network/panos/panos_dag_tags.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_dag_tags.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_dag_tags.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_dag_tags.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_import.py future-import-boilerplate +plugins/modules/network/panos/panos_import.py metaclass-boilerplate +plugins/modules/network/panos/panos_import.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_interface.py future-import-boilerplate +plugins/modules/network/panos/panos_interface.py metaclass-boilerplate +plugins/modules/network/panos/panos_interface.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_lic.py future-import-boilerplate +plugins/modules/network/panos/panos_lic.py metaclass-boilerplate +plugins/modules/network/panos/panos_lic.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_lic.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_loadcfg.py future-import-boilerplate +plugins/modules/network/panos/panos_loadcfg.py metaclass-boilerplate +plugins/modules/network/panos/panos_loadcfg.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_match_rule.py future-import-boilerplate +plugins/modules/network/panos/panos_match_rule.py metaclass-boilerplate +plugins/modules/network/panos/panos_match_rule.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_match_rule.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_match_rule.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_mgtconfig.py future-import-boilerplate +plugins/modules/network/panos/panos_mgtconfig.py metaclass-boilerplate +plugins/modules/network/panos/panos_mgtconfig.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_nat_rule.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_nat_rule.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_nat_rule.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_nat_rule.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_object.py future-import-boilerplate +plugins/modules/network/panos/panos_object.py metaclass-boilerplate +plugins/modules/network/panos/panos_object.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_object.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_object.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_object.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_op.py future-import-boilerplate +plugins/modules/network/panos/panos_op.py metaclass-boilerplate +plugins/modules/network/panos/panos_op.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_op.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_pg.py future-import-boilerplate +plugins/modules/network/panos/panos_pg.py metaclass-boilerplate +plugins/modules/network/panos/panos_pg.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_query_rules.py future-import-boilerplate +plugins/modules/network/panos/panos_query_rules.py metaclass-boilerplate +plugins/modules/network/panos/panos_query_rules.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_query_rules.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_restart.py future-import-boilerplate +plugins/modules/network/panos/panos_restart.py metaclass-boilerplate +plugins/modules/network/panos/panos_restart.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_sag.py future-import-boilerplate +plugins/modules/network/panos/panos_sag.py metaclass-boilerplate +plugins/modules/network/panos/panos_sag.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_sag.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_sag.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_security_rule.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_security_rule.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_security_rule.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_security_rule.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_set.py future-import-boilerplate +plugins/modules/network/panos/panos_set.py metaclass-boilerplate +plugins/modules/network/panos/panos_set.py validate-modules:doc-missing-type +plugins/modules/network/radware/vdirect_commit.py validate-modules:doc-missing-type +plugins/modules/network/radware/vdirect_commit.py validate-modules:parameter-list-no-elements +plugins/modules/network/radware/vdirect_commit.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/radware/vdirect_file.py validate-modules:doc-missing-type +plugins/modules/network/radware/vdirect_file.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/radware/vdirect_runnable.py validate-modules:doc-missing-type +plugins/modules/network/radware/vdirect_runnable.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/routeros/routeros_command.py validate-modules:doc-missing-type +plugins/modules/network/routeros/routeros_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/routeros/routeros_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/routeros/routeros_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/routeros/routeros_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_command.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_config.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_interface.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_interface.py validate-modules:undocumented-parameter +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:undocumented-parameter +plugins/modules/network/slxos/slxos_lldp.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_vlan.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/sros/sros_command.py validate-modules:collection-deprecated-version +plugins/modules/network/sros/sros_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/sros/sros_command.py validate-modules:doc-missing-type +plugins/modules/network/sros/sros_command.py validate-modules:doc-required-mismatch +plugins/modules/network/sros/sros_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/sros/sros_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/sros/sros_command.py yamllint:unparsable-with-libyaml +plugins/modules/network/sros/sros_config.py validate-modules:collection-deprecated-version +plugins/modules/network/sros/sros_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/sros/sros_config.py validate-modules:doc-missing-type +plugins/modules/network/sros/sros_config.py validate-modules:doc-required-mismatch +plugins/modules/network/sros/sros_config.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/sros/sros_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/sros/sros_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/sros/sros_config.py yamllint:unparsable-with-libyaml +plugins/modules/network/sros/sros_rollback.py validate-modules:collection-deprecated-version +plugins/modules/network/sros/sros_rollback.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/sros/sros_rollback.py validate-modules:doc-missing-type +plugins/modules/network/sros/sros_rollback.py validate-modules:doc-required-mismatch +plugins/modules/network/sros/sros_rollback.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/sros/sros_rollback.py yamllint:unparsable-with-libyaml +plugins/modules/network/voss/voss_command.py validate-modules:doc-missing-type +plugins/modules/network/voss/voss_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/voss/voss_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/voss/voss_config.py validate-modules:doc-missing-type +plugins/modules/network/voss/voss_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/voss/voss_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/voss/voss_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/voss/voss_facts.py validate-modules:parameter-type-not-in-doc +tests/unit/mock/path.py future-import-boilerplate +tests/unit/mock/path.py metaclass-boilerplate +tests/unit/mock/yaml_helper.py future-import-boilerplate +tests/unit/mock/yaml_helper.py metaclass-boilerplate +tests/unit/plugins/httpapi/test_ftd.py future-import-boilerplate +tests/unit/plugins/httpapi/test_ftd.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/avi/test_avi_api_utils.py future-import-boilerplate +tests/unit/plugins/module_utils/network/avi/test_avi_api_utils.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_common.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_common.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_configuration.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_configuration.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_device.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_device.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_parser.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_parser.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_validator.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_validator.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_with_real_data.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_with_real_data.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_upsert_functionality.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_upsert_functionality.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/netscaler/test_netscaler.py future-import-boilerplate +tests/unit/plugins/module_utils/network/netscaler/test_netscaler.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/nso/test_nso.py metaclass-boilerplate +tests/unit/plugins/modules/network/avi/test_avi_user.py future-import-boilerplate +tests/unit/plugins/modules/network/avi/test_avi_user.py metaclass-boilerplate +tests/unit/plugins/modules/network/cloudvision/test_cv_server_provision.py future-import-boilerplate +tests/unit/plugins/modules/network/cloudvision/test_cv_server_provision.py metaclass-boilerplate +tests/unit/plugins/modules/network/cumulus/test_nclu.py future-import-boilerplate +tests/unit/plugins/modules/network/cumulus/test_nclu.py metaclass-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_configuration.py future-import-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_configuration.py metaclass-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_file_download.py future-import-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_file_download.py metaclass-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_file_upload.py future-import-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_file_upload.py metaclass-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_install.py future-import-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_install.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/netscaler_module.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/netscaler_module.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_action.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_action.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_policy.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_policy.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_vserver.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_vserver.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_service.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_service.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_site.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_site.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_vserver.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_vserver.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_lb_monitor.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_lb_monitor.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_lb_vserver.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_lb_vserver.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_nitro_request.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_nitro_request.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_save_config.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_save_config.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_server.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_server.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_service.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_service.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_servicegroup.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_servicegroup.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_ssl_certkey.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_ssl_certkey.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/nso_module.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_action.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_config.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_query.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_show.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_verify.py metaclass-boilerplate +tests/unit/plugins/modules/network/nuage/nuage_module.py future-import-boilerplate +tests/unit/plugins/modules/network/nuage/nuage_module.py metaclass-boilerplate +tests/unit/plugins/modules/network/nuage/test_nuage_vspk.py future-import-boilerplate +tests/unit/plugins/modules/network/nuage/test_nuage_vspk.py metaclass-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_commit.py future-import-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_commit.py metaclass-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_file.py future-import-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_file.py metaclass-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_runnable.py future-import-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_runnable.py metaclass-boilerplate +tests/unit/plugins/modules/utils.py future-import-boilerplate +tests/unit/plugins/modules/utils.py metaclass-boilerplate +tests/utils/shippable/check_matrix.py replace-urlopen +tests/utils/shippable/timing.py shebang diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.11.txt b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.11.txt new file mode 100644 index 00000000..cd173497 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.11.txt @@ -0,0 +1,105 @@ +plugins/modules/onyx_bgp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_bgp.py validate-modules:doc-missing-type +plugins/modules/onyx_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_buffer_pool.py validate-modules:doc-missing-type +plugins/modules/onyx_buffer_pool.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_command.py validate-modules:doc-missing-type +plugins/modules/onyx_command.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_config.py validate-modules:doc-missing-type +plugins/modules/onyx_config.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_facts.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_igmp.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_igmp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_igmp_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_igmp_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_interface.py validate-modules:nonexistent-parameter-documented +plugins/modules/onyx_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_l2_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_l3_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_linkagg.py validate-modules:doc-default-does-not-match-spec +plugins/modules/onyx_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_linkagg.py validate-modules:doc-missing-type +plugins/modules/onyx_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/onyx_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/onyx_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_linkagg.py validate-modules:undocumented-parameter +plugins/modules/onyx_lldp.py validate-modules:doc-missing-type +plugins/modules/onyx_lldp_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_lldp_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_lldp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_lldp_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_lldp_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_lldp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_lldp_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_magp.py validate-modules:doc-missing-type +plugins/modules/onyx_magp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_mlag_ipl.py validate-modules:doc-missing-type +plugins/modules/onyx_mlag_vip.py validate-modules:doc-default-does-not-match-spec +plugins/modules/onyx_mlag_vip.py validate-modules:doc-missing-type +plugins/modules/onyx_mlag_vip.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_ntp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ntp_servers_peers.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ospf.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ospf.py validate-modules:doc-missing-type +plugins/modules/onyx_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_pfc_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_pfc_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_pfc_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_pfc_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_pfc_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_pfc_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_pfc_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_protocol.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_global.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_ptp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_qos.py validate-modules:doc-missing-type +plugins/modules/onyx_qos.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_qos.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_snmp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_snmp_hosts.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_snmp_users.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_syslog_remote.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_traffic_class.py validate-modules:doc-missing-type +plugins/modules/onyx_traffic_class.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_traffic_class.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_vlan.py validate-modules:doc-missing-type +plugins/modules/onyx_vlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_vlan.py validate-modules:missing-suboption-docs +plugins/modules/onyx_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vlan.py validate-modules:undocumented-parameter +plugins/modules/onyx_vxlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_vxlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_vxlan.py validate-modules:missing-suboption-docs +plugins/modules/onyx_vxlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vxlan.py validate-modules:undocumented-parameter diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.11.txt.orig b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.11.txt.orig new file mode 100644 index 00000000..36d5809c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.11.txt.orig @@ -0,0 +1,1719 @@ +plugins/action/aireos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/aruba.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/ce.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/ce_template.py action-plugin-docs # undocumented action plugin to fix, existed before sanity test was added +plugins/action/cnos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/edgeos_config.py action-plugin-docs # undocumented action plugin to fix +plugins/action/enos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/exos.py action-plugin-docs # undocumented action plugin to fix +plugins/action/ironware.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/nos_config.py action-plugin-docs # undocumented action plugin to fix +plugins/action/onyx_config.py action-plugin-docs # undocumented action plugin to fix +plugins/action/slxos.py action-plugin-docs # undocumented action plugin to fix +plugins/action/sros.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/action/voss.py action-plugin-docs # undocumented action plugin to fix +plugins/doc_fragments/a10.py future-import-boilerplate +plugins/doc_fragments/a10.py metaclass-boilerplate +plugins/doc_fragments/aireos.py future-import-boilerplate +plugins/doc_fragments/aireos.py metaclass-boilerplate +plugins/doc_fragments/aruba.py future-import-boilerplate +plugins/doc_fragments/aruba.py metaclass-boilerplate +plugins/doc_fragments/avi.py future-import-boilerplate +plugins/doc_fragments/avi.py metaclass-boilerplate +plugins/doc_fragments/ce.py future-import-boilerplate +plugins/doc_fragments/ce.py metaclass-boilerplate +plugins/doc_fragments/cnos.py future-import-boilerplate +plugins/doc_fragments/cnos.py metaclass-boilerplate +plugins/doc_fragments/enos.py future-import-boilerplate +plugins/doc_fragments/enos.py metaclass-boilerplate +plugins/doc_fragments/ingate.py future-import-boilerplate +plugins/doc_fragments/ingate.py metaclass-boilerplate +plugins/doc_fragments/ironware.py future-import-boilerplate +plugins/doc_fragments/ironware.py metaclass-boilerplate +plugins/doc_fragments/netscaler.py future-import-boilerplate +plugins/doc_fragments/netscaler.py metaclass-boilerplate +plugins/doc_fragments/nso.py future-import-boilerplate +plugins/doc_fragments/nso.py metaclass-boilerplate +plugins/doc_fragments/onyx.py future-import-boilerplate +plugins/doc_fragments/onyx.py metaclass-boilerplate +plugins/doc_fragments/panos.py future-import-boilerplate +plugins/doc_fragments/panos.py metaclass-boilerplate +plugins/doc_fragments/sros.py future-import-boilerplate +plugins/doc_fragments/sros.py metaclass-boilerplate +plugins/module_utils/network/a10/a10.py future-import-boilerplate +plugins/module_utils/network/a10/a10.py metaclass-boilerplate +plugins/module_utils/network/aireos/aireos.py future-import-boilerplate +plugins/module_utils/network/aireos/aireos.py metaclass-boilerplate +plugins/module_utils/network/aos/aos.py future-import-boilerplate +plugins/module_utils/network/aos/aos.py metaclass-boilerplate +plugins/module_utils/network/aruba/aruba.py future-import-boilerplate +plugins/module_utils/network/aruba/aruba.py metaclass-boilerplate +plugins/module_utils/network/avi/ansible_utils.py future-import-boilerplate +plugins/module_utils/network/avi/ansible_utils.py metaclass-boilerplate +plugins/module_utils/network/avi/avi.py future-import-boilerplate +plugins/module_utils/network/avi/avi.py metaclass-boilerplate +plugins/module_utils/network/avi/avi_api.py future-import-boilerplate +plugins/module_utils/network/avi/avi_api.py metaclass-boilerplate +plugins/module_utils/network/bigswitch/bigswitch.py future-import-boilerplate +plugins/module_utils/network/bigswitch/bigswitch.py metaclass-boilerplate +plugins/module_utils/network/cloudengine/ce.py future-import-boilerplate +plugins/module_utils/network/cloudengine/ce.py metaclass-boilerplate +plugins/module_utils/network/cnos/cnos.py future-import-boilerplate +plugins/module_utils/network/cnos/cnos.py metaclass-boilerplate +plugins/module_utils/network/cnos/cnos_devicerules.py future-import-boilerplate +plugins/module_utils/network/cnos/cnos_devicerules.py metaclass-boilerplate +plugins/module_utils/network/cnos/cnos_errorcodes.py future-import-boilerplate +plugins/module_utils/network/cnos/cnos_errorcodes.py metaclass-boilerplate +plugins/module_utils/network/edgeos/edgeos.py future-import-boilerplate +plugins/module_utils/network/edgeos/edgeos.py metaclass-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch.py future-import-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch.py metaclass-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch_interface.py future-import-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch_interface.py metaclass-boilerplate +plugins/module_utils/network/edgeswitch/edgeswitch_interface.py pylint:duplicate-string-formatting-argument +plugins/module_utils/network/enos/enos.py future-import-boilerplate +plugins/module_utils/network/enos/enos.py metaclass-boilerplate +plugins/module_utils/network/exos/exos.py future-import-boilerplate +plugins/module_utils/network/exos/exos.py metaclass-boilerplate +plugins/module_utils/network/ftd/common.py future-import-boilerplate +plugins/module_utils/network/ftd/common.py metaclass-boilerplate +plugins/module_utils/network/ftd/configuration.py future-import-boilerplate +plugins/module_utils/network/ftd/configuration.py metaclass-boilerplate +plugins/module_utils/network/ftd/device.py future-import-boilerplate +plugins/module_utils/network/ftd/device.py metaclass-boilerplate +plugins/module_utils/network/ftd/fdm_swagger_client.py future-import-boilerplate +plugins/module_utils/network/ftd/fdm_swagger_client.py metaclass-boilerplate +plugins/module_utils/network/ftd/operation.py future-import-boilerplate +plugins/module_utils/network/ftd/operation.py metaclass-boilerplate +plugins/module_utils/network/netscaler/netscaler.py future-import-boilerplate +plugins/module_utils/network/netscaler/netscaler.py metaclass-boilerplate +plugins/module_utils/network/nos/nos.py future-import-boilerplate +plugins/module_utils/network/nos/nos.py metaclass-boilerplate +plugins/module_utils/network/nso/nso.py future-import-boilerplate +plugins/module_utils/network/nso/nso.py metaclass-boilerplate +plugins/module_utils/network/onyx/onyx.py future-import-boilerplate +plugins/module_utils/network/onyx/onyx.py metaclass-boilerplate +plugins/module_utils/network/ordnance/ordnance.py future-import-boilerplate +plugins/module_utils/network/ordnance/ordnance.py metaclass-boilerplate +plugins/module_utils/network/routeros/routeros.py future-import-boilerplate +plugins/module_utils/network/routeros/routeros.py metaclass-boilerplate +plugins/module_utils/network/slxos/slxos.py future-import-boilerplate +plugins/module_utils/network/slxos/slxos.py metaclass-boilerplate +plugins/module_utils/network/sros/sros.py future-import-boilerplate +plugins/module_utils/network/sros/sros.py metaclass-boilerplate +plugins/module_utils/network/voss/voss.py future-import-boilerplate +plugins/module_utils/network/voss/voss.py metaclass-boilerplate +plugins/modules/network/a10/a10_server.py validate-modules:parameter-list-no-elements +plugins/modules/network/a10/a10_server.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/a10/a10_server_axapi3.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/a10/a10_server_axapi3.py validate-modules:parameter-list-no-elements +plugins/modules/network/a10/a10_server_axapi3.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/a10/a10_service_group.py validate-modules:parameter-list-no-elements +plugins/modules/network/a10/a10_service_group.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/a10/a10_virtual_server.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/a10/a10_virtual_server.py validate-modules:doc-required-mismatch +plugins/modules/network/a10/a10_virtual_server.py validate-modules:parameter-list-no-elements +plugins/modules/network/a10/a10_virtual_server.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/aireos/aireos_command.py validate-modules:collection-deprecated-version +plugins/modules/network/aireos/aireos_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/aireos/aireos_command.py validate-modules:doc-missing-type +plugins/modules/network/aireos/aireos_command.py validate-modules:doc-required-mismatch +plugins/modules/network/aireos/aireos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/aireos/aireos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/aireos/aireos_config.py validate-modules:collection-deprecated-version +plugins/modules/network/aireos/aireos_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/aireos/aireos_config.py validate-modules:doc-missing-type +plugins/modules/network/aireos/aireos_config.py validate-modules:doc-required-mismatch +plugins/modules/network/aireos/aireos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/aireos/aireos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/apconos/apconos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/aruba/aruba_command.py validate-modules:collection-deprecated-version +plugins/modules/network/aruba/aruba_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/aruba/aruba_command.py validate-modules:doc-missing-type +plugins/modules/network/aruba/aruba_command.py validate-modules:doc-required-mismatch +plugins/modules/network/aruba/aruba_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/aruba/aruba_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/aruba/aruba_config.py validate-modules:collection-deprecated-version +plugins/modules/network/aruba/aruba_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/aruba/aruba_config.py validate-modules:doc-missing-type +plugins/modules/network/aruba/aruba_config.py validate-modules:doc-required-mismatch +plugins/modules/network/aruba/aruba_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/aruba/aruba_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_actiongroupconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_actiongroupconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_actiongroupconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_actiongroupconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_alertconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_alertconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_alertconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_alertconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_alertemailconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_alertemailconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_alertemailconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_alertemailconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_alertscriptconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_alertscriptconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_alertscriptconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_alertscriptconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_alertsyslogconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_alertsyslogconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_alertsyslogconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_alertsyslogconfig.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_alertsyslogconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_analyticsprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_analyticsprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_analyticsprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_analyticsprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_analyticsprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_api_session.py future-import-boilerplate +plugins/modules/network/avi/avi_api_session.py metaclass-boilerplate +plugins/modules/network/avi/avi_api_session.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_api_session.py validate-modules:doc-required-mismatch +plugins/modules/network/avi/avi_api_session.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_api_version.py future-import-boilerplate +plugins/modules/network/avi/avi_api_version.py metaclass-boilerplate +plugins/modules/network/avi/avi_api_version.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_api_version.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_applicationpersistenceprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_applicationpersistenceprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_applicationpersistenceprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_applicationpersistenceprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_applicationprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_applicationprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_applicationprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_applicationprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_authprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_authprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_authprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_authprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_autoscalelaunchconfig.py future-import-boilerplate +plugins/modules/network/avi/avi_autoscalelaunchconfig.py metaclass-boilerplate +plugins/modules/network/avi/avi_autoscalelaunchconfig.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_autoscalelaunchconfig.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_backup.py future-import-boilerplate +plugins/modules/network/avi/avi_backup.py metaclass-boilerplate +plugins/modules/network/avi/avi_backup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_backup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_backupconfiguration.py future-import-boilerplate +plugins/modules/network/avi/avi_backupconfiguration.py metaclass-boilerplate +plugins/modules/network/avi/avi_backupconfiguration.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_backupconfiguration.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_certificatemanagementprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_certificatemanagementprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_certificatemanagementprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_certificatemanagementprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_certificatemanagementprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_cloud.py future-import-boilerplate +plugins/modules/network/avi/avi_cloud.py metaclass-boilerplate +plugins/modules/network/avi/avi_cloud.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_cloud.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_cloud.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_cloudconnectoruser.py future-import-boilerplate +plugins/modules/network/avi/avi_cloudconnectoruser.py metaclass-boilerplate +plugins/modules/network/avi/avi_cloudconnectoruser.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_cloudconnectoruser.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_cloudproperties.py future-import-boilerplate +plugins/modules/network/avi/avi_cloudproperties.py metaclass-boilerplate +plugins/modules/network/avi/avi_cloudproperties.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_cloudproperties.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_cloudproperties.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_cluster.py future-import-boilerplate +plugins/modules/network/avi/avi_cluster.py metaclass-boilerplate +plugins/modules/network/avi/avi_cluster.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_cluster.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_cluster.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_clusterclouddetails.py future-import-boilerplate +plugins/modules/network/avi/avi_clusterclouddetails.py metaclass-boilerplate +plugins/modules/network/avi/avi_clusterclouddetails.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_clusterclouddetails.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_controllerproperties.py future-import-boilerplate +plugins/modules/network/avi/avi_controllerproperties.py metaclass-boilerplate +plugins/modules/network/avi/avi_controllerproperties.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_controllerproperties.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_controllerproperties.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_customipamdnsprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_customipamdnsprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_customipamdnsprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_customipamdnsprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_customipamdnsprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_dnspolicy.py future-import-boilerplate +plugins/modules/network/avi/avi_dnspolicy.py metaclass-boilerplate +plugins/modules/network/avi/avi_dnspolicy.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_dnspolicy.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_dnspolicy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_errorpagebody.py future-import-boilerplate +plugins/modules/network/avi/avi_errorpagebody.py metaclass-boilerplate +plugins/modules/network/avi/avi_errorpagebody.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_errorpagebody.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_errorpageprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_errorpageprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_errorpageprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_errorpageprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_errorpageprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_gslb.py future-import-boilerplate +plugins/modules/network/avi/avi_gslb.py metaclass-boilerplate +plugins/modules/network/avi/avi_gslb.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_gslb.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_gslb.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_gslbgeodbprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_gslbgeodbprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_gslbgeodbprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_gslbgeodbprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_gslbgeodbprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_gslbservice.py future-import-boilerplate +plugins/modules/network/avi/avi_gslbservice.py metaclass-boilerplate +plugins/modules/network/avi/avi_gslbservice.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_gslbservice.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_gslbservice.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_gslbservice_patch_member.py future-import-boilerplate +plugins/modules/network/avi/avi_gslbservice_patch_member.py metaclass-boilerplate +plugins/modules/network/avi/avi_gslbservice_patch_member.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_gslbservice_patch_member.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_hardwaresecuritymodulegroup.py future-import-boilerplate +plugins/modules/network/avi/avi_hardwaresecuritymodulegroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_hardwaresecuritymodulegroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_hardwaresecuritymodulegroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_healthmonitor.py future-import-boilerplate +plugins/modules/network/avi/avi_healthmonitor.py metaclass-boilerplate +plugins/modules/network/avi/avi_healthmonitor.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_healthmonitor.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_httppolicyset.py future-import-boilerplate +plugins/modules/network/avi/avi_httppolicyset.py metaclass-boilerplate +plugins/modules/network/avi/avi_httppolicyset.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_httppolicyset.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_ipaddrgroup.py future-import-boilerplate +plugins/modules/network/avi/avi_ipaddrgroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_ipaddrgroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_ipaddrgroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_ipaddrgroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_ipamdnsproviderprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_ipamdnsproviderprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_ipamdnsproviderprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_ipamdnsproviderprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_l4policyset.py future-import-boilerplate +plugins/modules/network/avi/avi_l4policyset.py metaclass-boilerplate +plugins/modules/network/avi/avi_l4policyset.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_l4policyset.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_microservicegroup.py future-import-boilerplate +plugins/modules/network/avi/avi_microservicegroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_microservicegroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_microservicegroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_microservicegroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_network.py future-import-boilerplate +plugins/modules/network/avi/avi_network.py metaclass-boilerplate +plugins/modules/network/avi/avi_network.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_network.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_network.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_networkprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_networkprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_networkprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_networkprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_networksecuritypolicy.py future-import-boilerplate +plugins/modules/network/avi/avi_networksecuritypolicy.py metaclass-boilerplate +plugins/modules/network/avi/avi_networksecuritypolicy.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_networksecuritypolicy.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_networksecuritypolicy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_pkiprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_pkiprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_pkiprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_pkiprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_pkiprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_pool.py future-import-boilerplate +plugins/modules/network/avi/avi_pool.py metaclass-boilerplate +plugins/modules/network/avi/avi_pool.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_pool.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_pool.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_poolgroup.py future-import-boilerplate +plugins/modules/network/avi/avi_poolgroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_poolgroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_poolgroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_poolgroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py future-import-boilerplate +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py metaclass-boilerplate +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_poolgroupdeploymentpolicy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_prioritylabels.py future-import-boilerplate +plugins/modules/network/avi/avi_prioritylabels.py metaclass-boilerplate +plugins/modules/network/avi/avi_prioritylabels.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_prioritylabels.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_prioritylabels.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_role.py future-import-boilerplate +plugins/modules/network/avi/avi_role.py metaclass-boilerplate +plugins/modules/network/avi/avi_role.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_role.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_role.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_scheduler.py future-import-boilerplate +plugins/modules/network/avi/avi_scheduler.py metaclass-boilerplate +plugins/modules/network/avi/avi_scheduler.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_scheduler.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_seproperties.py future-import-boilerplate +plugins/modules/network/avi/avi_seproperties.py metaclass-boilerplate +plugins/modules/network/avi/avi_seproperties.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_seproperties.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_serverautoscalepolicy.py future-import-boilerplate +plugins/modules/network/avi/avi_serverautoscalepolicy.py metaclass-boilerplate +plugins/modules/network/avi/avi_serverautoscalepolicy.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_serverautoscalepolicy.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_serverautoscalepolicy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_serviceengine.py future-import-boilerplate +plugins/modules/network/avi/avi_serviceengine.py metaclass-boilerplate +plugins/modules/network/avi/avi_serviceengine.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_serviceengine.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_serviceengine.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_serviceenginegroup.py future-import-boilerplate +plugins/modules/network/avi/avi_serviceenginegroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_serviceenginegroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_serviceenginegroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_serviceenginegroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_snmptrapprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_snmptrapprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_snmptrapprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_snmptrapprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_snmptrapprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_sslkeyandcertificate.py future-import-boilerplate +plugins/modules/network/avi/avi_sslkeyandcertificate.py metaclass-boilerplate +plugins/modules/network/avi/avi_sslkeyandcertificate.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_sslkeyandcertificate.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_sslkeyandcertificate.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_sslprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_sslprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_sslprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_sslprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_sslprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_stringgroup.py future-import-boilerplate +plugins/modules/network/avi/avi_stringgroup.py metaclass-boilerplate +plugins/modules/network/avi/avi_stringgroup.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_stringgroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_stringgroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_systemconfiguration.py future-import-boilerplate +plugins/modules/network/avi/avi_systemconfiguration.py metaclass-boilerplate +plugins/modules/network/avi/avi_systemconfiguration.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_systemconfiguration.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_systemconfiguration.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_tenant.py future-import-boilerplate +plugins/modules/network/avi/avi_tenant.py metaclass-boilerplate +plugins/modules/network/avi/avi_tenant.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_tenant.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_trafficcloneprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_trafficcloneprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_trafficcloneprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_trafficcloneprofile.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_trafficcloneprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_user.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_user.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_user.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_useraccount.py future-import-boilerplate +plugins/modules/network/avi/avi_useraccount.py metaclass-boilerplate +plugins/modules/network/avi/avi_useraccount.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_useraccount.py validate-modules:doc-required-mismatch +plugins/modules/network/avi/avi_useraccount.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_useraccountprofile.py future-import-boilerplate +plugins/modules/network/avi/avi_useraccountprofile.py metaclass-boilerplate +plugins/modules/network/avi/avi_useraccountprofile.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_useraccountprofile.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_virtualservice.py future-import-boilerplate +plugins/modules/network/avi/avi_virtualservice.py metaclass-boilerplate +plugins/modules/network/avi/avi_virtualservice.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_virtualservice.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_virtualservice.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_vrfcontext.py future-import-boilerplate +plugins/modules/network/avi/avi_vrfcontext.py metaclass-boilerplate +plugins/modules/network/avi/avi_vrfcontext.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_vrfcontext.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_vrfcontext.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_vsdatascriptset.py future-import-boilerplate +plugins/modules/network/avi/avi_vsdatascriptset.py metaclass-boilerplate +plugins/modules/network/avi/avi_vsdatascriptset.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_vsdatascriptset.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_vsdatascriptset.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_vsvip.py future-import-boilerplate +plugins/modules/network/avi/avi_vsvip.py metaclass-boilerplate +plugins/modules/network/avi/avi_vsvip.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_vsvip.py validate-modules:parameter-list-no-elements +plugins/modules/network/avi/avi_vsvip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/avi/avi_webhook.py future-import-boilerplate +plugins/modules/network/avi/avi_webhook.py metaclass-boilerplate +plugins/modules/network/avi/avi_webhook.py validate-modules:doc-missing-type +plugins/modules/network/avi/avi_webhook.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/bigswitch/bcf_switch.py validate-modules:doc-missing-type +plugins/modules/network/bigswitch/bcf_switch.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/bigswitch/bigmon_chain.py validate-modules:doc-missing-type +plugins/modules/network/bigswitch/bigmon_chain.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/bigswitch/bigmon_policy.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/bigswitch/bigmon_policy.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/bigswitch/bigmon_policy.py validate-modules:doc-missing-type +plugins/modules/network/bigswitch/bigmon_policy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_aaa_server.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_aaa_server_host.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_acl.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_acl.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_acl.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_acl.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_acl.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_acl.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_acl_advance.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_acl_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bfd_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bfd_session.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:doc-default-incompatible-type +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bfd_view.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bgp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bgp_af.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bgp_neighbor.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_bgp_neighbor_af.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_command.py pylint:blacklisted-name +plugins/modules/network/cloudengine/ce_command.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_command.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_command.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_command.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_config.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_config.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_config.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_config.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_dldp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_dldp_interface.py pylint:blacklisted-name +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_dldp_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_eth_trunk.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_evpn_bd_vni.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_evpn_bgp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_evpn_bgp_rr.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_evpn_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_facts.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_facts.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_facts.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_facts.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_file_copy.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_info_center_debug.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_info_center_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_info_center_log.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_info_center_trap.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_interface_ospf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ip_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_is_is_view.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_link_status.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_mlag_config.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_mlag_interface.py pylint:blacklisted-name +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_mlag_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_mtu.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netconf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netstream_aging.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netstream_export.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netstream_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_netstream_template.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ntp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ntp_auth.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ospf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_ospf_vrf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_reboot.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_rollback.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_sflow.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_community.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_contact.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_location.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_target_host.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_traps.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:mutually_exclusive-unknown +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_snmp_user.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_startup.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_startup.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_startup.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_startup.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_startup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_startup.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_static_route.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_static_route_bfd.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudengine/ce_static_route_bfd.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_stp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_stp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_stp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_stp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_stp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_stp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_switchport.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vrf.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vrf_af.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vrf_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vrrp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_arp.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_gateway.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_global.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:parameter-list-no-elements +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_tunnel.py validate-modules:undocumented-parameter +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:doc-missing-type +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:missing-suboption-docs +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cloudengine/ce_vxlan_vap.py validate-modules:undocumented-parameter +plugins/modules/network/cloudvision/cv_server_provision.py pylint:blacklisted-name +plugins/modules/network/cloudvision/cv_server_provision.py validate-modules:doc-missing-type +plugins/modules/network/cloudvision/cv_server_provision.py validate-modules:doc-required-mismatch +plugins/modules/network/cloudvision/cv_server_provision.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/cnos/cnos_backup.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_backup.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_backup.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_backup.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cnos/cnos_backup.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_backup.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_banner.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_banner.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_banner.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_banner.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_banner.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_bgp.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_bgp.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_bgp.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_bgp.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_command.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_conditional_command.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_conditional_command.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_conditional_command.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_conditional_command.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_conditional_template.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_conditional_template.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_conditional_template.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_conditional_template.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_config.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_config.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_factory.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_factory.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_factory.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_facts.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cnos/cnos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_facts.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_image.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_image.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_image.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_image.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_linkagg.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_lldp.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_logging.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_logging.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_logging.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_logging.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_logging.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_logging.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_reload.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_reload.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_reload.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_rollback.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_rollback.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_rollback.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_rollback.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cnos/cnos_rollback.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_rollback.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_save.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_save.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_save.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_showrun.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_showrun.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/cnos/cnos_showrun.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_static_route.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_static_route.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_static_route.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_static_route.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_static_route.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_static_route.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_static_route.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_system.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_system.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_system.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_template.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_template.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_template.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_template.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_user.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_user.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_user.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_user.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_user.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_user.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_user.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_vlag.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_vlag.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_vlag.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_vlag.py yamllint:unparsable-with-libyaml +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/cnos/cnos_vrf.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/cnos/cnos_vrf.py validate-modules:doc-elements-mismatch +plugins/modules/network/cnos/cnos_vrf.py validate-modules:doc-missing-type +plugins/modules/network/cnos/cnos_vrf.py validate-modules:doc-required-mismatch +plugins/modules/network/cnos/cnos_vrf.py validate-modules:missing-suboption-docs +plugins/modules/network/cnos/cnos_vrf.py validate-modules:parameter-list-no-elements +plugins/modules/network/cnos/cnos_vrf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/cnos/cnos_vrf.py validate-modules:undocumented-parameter +plugins/modules/network/cumulus/nclu.py validate-modules:parameter-list-no-elements +plugins/modules/network/cumulus/nclu.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeos/edgeos_command.py validate-modules:doc-missing-type +plugins/modules/network/edgeos/edgeos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeos/edgeos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeos/edgeos_config.py validate-modules:doc-missing-type +plugins/modules/network/edgeos/edgeos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeos/edgeos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeos/edgeos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeos/edgeos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeswitch/edgeswitch_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeswitch/edgeswitch_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:doc-missing-type +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/edgeswitch/edgeswitch_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/enos/enos_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/enos/enos_command.py validate-modules:doc-missing-type +plugins/modules/network/enos/enos_command.py validate-modules:doc-required-mismatch +plugins/modules/network/enos/enos_command.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/enos/enos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/enos/enos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/enos/enos_command.py validate-modules:undocumented-parameter +plugins/modules/network/enos/enos_command.py yamllint:unparsable-with-libyaml +plugins/modules/network/enos/enos_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/enos/enos_config.py validate-modules:doc-missing-type +plugins/modules/network/enos/enos_config.py validate-modules:doc-required-mismatch +plugins/modules/network/enos/enos_config.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/enos/enos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/enos/enos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/enos/enos_config.py validate-modules:undocumented-parameter +plugins/modules/network/enos/enos_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/enos/enos_facts.py validate-modules:doc-missing-type +plugins/modules/network/enos/enos_facts.py validate-modules:doc-required-mismatch +plugins/modules/network/enos/enos_facts.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/enos/enos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/enos/enos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/enos/enos_facts.py validate-modules:undocumented-parameter +plugins/modules/network/enos/enos_facts.py yamllint:unparsable-with-libyaml +plugins/modules/network/eric_eccli/eric_eccli_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/exos/exos_command.py validate-modules:doc-missing-type +plugins/modules/network/exos/exos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/exos/exos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/exos/exos_config.py validate-modules:doc-missing-type +plugins/modules/network/exos/exos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/exos/exos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/exos/exos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/exos/exos_l2_interfaces.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortianalyzer/faz_device.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_device.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_device.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_device_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_device_group.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_device_group.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_device_provision_template.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_device_provision_template.py validate-modules:invalid-argument-name +plugins/modules/network/fortimanager/fmgr_device_provision_template.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/fortimanager/fmgr_device_provision_template.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_address.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_ippool.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_fwobj_ippool.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_ippool6.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_fwobj_ippool6.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_service.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwobj_vip.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_fwobj_vip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwpol_ipv4.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_fwpol_ipv4.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_fwpol_package.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_fwpol_package.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_ha.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_provisioning.py validate-modules:doc-missing-type +plugins/modules/network/fortimanager/fmgr_provisioning.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_provisioning.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_query.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_query.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_script.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/fortimanager/fmgr_script.py validate-modules:doc-required-mismatch +plugins/modules/network/fortimanager/fmgr_script.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_appctrl.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_appctrl.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_av.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_av.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_dns.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_ips.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_ips.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_profile_group.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_proxy.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_proxy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_spam.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_spam.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_ssl_ssh.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_ssl_ssh.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_voip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_waf.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_waf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_wanopt.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/fortimanager/fmgr_secprof_web.py validate-modules:parameter-list-no-elements +plugins/modules/network/fortimanager/fmgr_secprof_web.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/icx/icx_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_lldp.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_lldp.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_logging.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_logging.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_static_route.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_static_route.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_system.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_system.py validate-modules:parameter-list-no-elements +plugins/modules/network/icx/icx_user.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_user.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/icx/icx_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/icx/icx_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/illumos/dladm_etherstub.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_etherstub.py validate-modules:doc-missing-type +plugins/modules/network/illumos/dladm_iptun.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_iptun.py validate-modules:doc-missing-type +plugins/modules/network/illumos/dladm_iptun.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/illumos/dladm_linkprop.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_linkprop.py validate-modules:doc-missing-type +plugins/modules/network/illumos/dladm_linkprop.py validate-modules:no-default-for-required-parameter +plugins/modules/network/illumos/dladm_linkprop.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/illumos/dladm_vlan.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_vlan.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/illumos/dladm_vlan.py validate-modules:doc-missing-type +plugins/modules/network/illumos/dladm_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/illumos/dladm_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/illumos/dladm_vnic.py pylint:blacklisted-name +plugins/modules/network/illumos/dladm_vnic.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/illumos/dladm_vnic.py validate-modules:doc-missing-type +plugins/modules/network/illumos/flowadm.py pylint:blacklisted-name +plugins/modules/network/illumos/flowadm.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/illumos/flowadm.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_addr.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_addr.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_addr.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/illumos/ipadm_addrprop.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_addrprop.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_addrprop.py validate-modules:no-default-for-required-parameter +plugins/modules/network/illumos/ipadm_if.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_if.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_ifprop.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_ifprop.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/illumos/ipadm_ifprop.py validate-modules:doc-missing-type +plugins/modules/network/illumos/ipadm_ifprop.py validate-modules:no-default-for-required-parameter +plugins/modules/network/illumos/ipadm_prop.py pylint:blacklisted-name +plugins/modules/network/illumos/ipadm_prop.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/illumos/ipadm_prop.py validate-modules:doc-missing-type +plugins/modules/network/ingate/ig_config.py validate-modules:doc-missing-type +plugins/modules/network/ingate/ig_config.py validate-modules:doc-required-mismatch +plugins/modules/network/ingate/ig_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ingate/ig_config.py validate-modules:return-syntax-error +plugins/modules/network/ingate/ig_unit_information.py validate-modules:doc-required-mismatch +plugins/modules/network/ingate/ig_unit_information.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ironware/ironware_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ironware/ironware_command.py validate-modules:doc-missing-type +plugins/modules/network/ironware/ironware_command.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/ironware/ironware_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/ironware/ironware_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ironware/ironware_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ironware/ironware_config.py validate-modules:doc-missing-type +plugins/modules/network/ironware/ironware_config.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/ironware/ironware_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/ironware/ironware_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ironware/ironware_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ironware/ironware_facts.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/ironware/ironware_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/ironware/ironware_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/itential/iap_start_workflow.py validate-modules:doc-required-mismatch +plugins/modules/network/itential/iap_token.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netact/netact_cm_command.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/netact/netact_cm_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_cs_action.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_cs_action.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_cs_policy.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_cs_vserver.py validate-modules:undocumented-parameter +plugins/modules/network/netscaler/netscaler_gslb_service.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_gslb_service.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_gslb_site.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_gslb_vserver.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_gslb_vserver.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_gslb_vserver.py validate-modules:undocumented-parameter +plugins/modules/network/netscaler/netscaler_lb_monitor.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/netscaler/netscaler_lb_monitor.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_lb_monitor.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_lb_monitor.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_lb_vserver.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_lb_vserver.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_lb_vserver.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_nitro_request.py pylint:ansible-bad-function +plugins/modules/network/netscaler/netscaler_nitro_request.py validate-modules:doc-missing-type +plugins/modules/network/netscaler/netscaler_nitro_request.py validate-modules:doc-required-mismatch +plugins/modules/network/netscaler/netscaler_nitro_request.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_nitro_request.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_save_config.py validate-modules:doc-missing-type +plugins/modules/network/netscaler/netscaler_save_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_server.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/netscaler/netscaler_server.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_service.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/netscaler/netscaler_service.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_service.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_servicegroup.py validate-modules:parameter-list-no-elements +plugins/modules/network/netscaler/netscaler_servicegroup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netscaler/netscaler_ssl_certkey.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_access_list.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_access_list.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_access_list_ip.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_access_list_ip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_admin_service.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_admin_session_timeout.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_admin_syslog.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_cluster.py future-import-boilerplate +plugins/modules/network/netvisor/pn_cluster.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_cluster.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_connection_stats_settings.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_cpu_class.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_cpu_class.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_cpu_mgmt_class.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_dhcp_filter.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_dscp_map.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_dscp_map.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_dscp_map_pri_map.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_fabric_local.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_fabric_local.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_igmp_snooping.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_igmp_snooping.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_ipv6security_raguard.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_ipv6security_raguard_port.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_ipv6security_raguard_vlan.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_log_audit_exception.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_log_audit_exception.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_ospf.py future-import-boilerplate +plugins/modules/network/netvisor/pn_ospf.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_ospf.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_ospfarea.py future-import-boilerplate +plugins/modules/network/netvisor/pn_ospfarea.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_ospfarea.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_port_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_port_config.py validate-modules:required_one_of-unknown +plugins/modules/network/netvisor/pn_port_cos_bw.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_port_cos_rate_setting.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_prefix_list.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_prefix_list_network.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_role.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_role.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_show.py future-import-boilerplate +plugins/modules/network/netvisor/pn_show.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_show.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_show.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_snmp_community.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_snmp_community.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_snmp_trap_sink.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_snmp_vacm.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_stp.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_stp_port.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_switch_setup.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_trunk.py future-import-boilerplate +plugins/modules/network/netvisor/pn_trunk.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_trunk.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_user.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vflow_table_profile.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vlag.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vlag.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vlag.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vlan.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vlan.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouter.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vrouter.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vrouter.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouter_bgp.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouter_bgp_network.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_interface_ip.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_loopback_interface.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_ospf.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_ospf6.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_packet_relay.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouter_pim_config.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_vrouter_pim_config.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/netvisor/pn_vrouterbgp.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vrouterbgp.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vrouterbgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouterif.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vrouterif.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vrouterif.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_vrouterif.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vrouterlbif.py future-import-boilerplate +plugins/modules/network/netvisor/pn_vrouterlbif.py metaclass-boilerplate +plugins/modules/network/netvisor/pn_vrouterlbif.py validate-modules:doc-required-mismatch +plugins/modules/network/netvisor/pn_vrouterlbif.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/netvisor/pn_vtep.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/nos/nos_command.py validate-modules:doc-missing-type +plugins/modules/network/nos/nos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/nos/nos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nos/nos_config.py validate-modules:doc-missing-type +plugins/modules/network/nos/nos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/nos/nos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nos/nos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/nos/nos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_action.py validate-modules:doc-missing-type +plugins/modules/network/nso/nso_action.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_config.py validate-modules:return-syntax-error +plugins/modules/network/nso/nso_query.py validate-modules:parameter-list-no-elements +plugins/modules/network/nso/nso_query.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_show.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nso/nso_verify.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nuage/nuage_vspk.py validate-modules:doc-required-mismatch +plugins/modules/network/nuage/nuage_vspk.py validate-modules:missing-suboption-docs +plugins/modules/network/nuage/nuage_vspk.py validate-modules:parameter-list-no-elements +plugins/modules/network/nuage/nuage_vspk.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/nuage/nuage_vspk.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_bgp.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_bgp.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_buffer_pool.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_buffer_pool.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_command.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_command.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/onyx/onyx_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_config.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_config.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/onyx/onyx_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_igmp.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_igmp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_igmp_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_igmp_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_interface.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/onyx/onyx_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_linkagg.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_lldp.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_lldp_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_magp.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_magp.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_mlag_ipl.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_mlag_vip.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/onyx/onyx_mlag_vip.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_mlag_vip.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_ntp.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_ntp_servers_peers.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_ospf.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_ospf.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_pfc_interface.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_protocol.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_ptp_global.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_ptp_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_ptp_interface.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_ptp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_qos.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_qos.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_qos.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_snmp.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_snmp_hosts.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_snmp_users.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_syslog_remote.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_traffic_class.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_traffic_class.py validate-modules:parameter-list-no-elements +plugins/modules/network/onyx/onyx_traffic_class.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/onyx/onyx_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_vlan.py validate-modules:doc-missing-type +plugins/modules/network/onyx/onyx_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:doc-required-mismatch +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:missing-suboption-docs +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/onyx/onyx_vxlan.py validate-modules:undocumented-parameter +plugins/modules/network/opx/opx_cps.py validate-modules:doc-required-mismatch +plugins/modules/network/opx/opx_cps.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ordnance/ordnance_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ordnance/ordnance_config.py validate-modules:doc-missing-type +plugins/modules/network/ordnance/ordnance_config.py validate-modules:doc-required-mismatch +plugins/modules/network/ordnance/ordnance_config.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/ordnance/ordnance_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/ordnance/ordnance_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ordnance/ordnance_config.py validate-modules:undocumented-parameter +plugins/modules/network/ordnance/ordnance_config.py yamllint:unparsable-with-libyaml +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:doc-missing-type +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:doc-required-mismatch +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:invalid-ansiblemodule-schema +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/ordnance/ordnance_facts.py validate-modules:undocumented-parameter +plugins/modules/network/ordnance/ordnance_facts.py yamllint:unparsable-with-libyaml +plugins/modules/network/panos/panos_admin.py future-import-boilerplate +plugins/modules/network/panos/panos_admin.py metaclass-boilerplate +plugins/modules/network/panos/panos_admin.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_admin.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_admpwd.py future-import-boilerplate +plugins/modules/network/panos/panos_admpwd.py metaclass-boilerplate +plugins/modules/network/panos/panos_admpwd.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_cert_gen_ssh.py future-import-boilerplate +plugins/modules/network/panos/panos_cert_gen_ssh.py metaclass-boilerplate +plugins/modules/network/panos/panos_cert_gen_ssh.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_cert_gen_ssh.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_check.py future-import-boilerplate +plugins/modules/network/panos/panos_check.py metaclass-boilerplate +plugins/modules/network/panos/panos_check.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_commit.py future-import-boilerplate +plugins/modules/network/panos/panos_commit.py metaclass-boilerplate +plugins/modules/network/panos/panos_commit.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_commit.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_commit.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_commit.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_dag.py future-import-boilerplate +plugins/modules/network/panos/panos_dag.py metaclass-boilerplate +plugins/modules/network/panos/panos_dag.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_dag_tags.py future-import-boilerplate +plugins/modules/network/panos/panos_dag_tags.py metaclass-boilerplate +plugins/modules/network/panos/panos_dag_tags.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_dag_tags.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_dag_tags.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_dag_tags.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_import.py future-import-boilerplate +plugins/modules/network/panos/panos_import.py metaclass-boilerplate +plugins/modules/network/panos/panos_import.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_interface.py future-import-boilerplate +plugins/modules/network/panos/panos_interface.py metaclass-boilerplate +plugins/modules/network/panos/panos_interface.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_lic.py future-import-boilerplate +plugins/modules/network/panos/panos_lic.py metaclass-boilerplate +plugins/modules/network/panos/panos_lic.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_lic.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_loadcfg.py future-import-boilerplate +plugins/modules/network/panos/panos_loadcfg.py metaclass-boilerplate +plugins/modules/network/panos/panos_loadcfg.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_match_rule.py future-import-boilerplate +plugins/modules/network/panos/panos_match_rule.py metaclass-boilerplate +plugins/modules/network/panos/panos_match_rule.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_match_rule.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_match_rule.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_mgtconfig.py future-import-boilerplate +plugins/modules/network/panos/panos_mgtconfig.py metaclass-boilerplate +plugins/modules/network/panos/panos_mgtconfig.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_nat_rule.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_nat_rule.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_nat_rule.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_nat_rule.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_object.py future-import-boilerplate +plugins/modules/network/panos/panos_object.py metaclass-boilerplate +plugins/modules/network/panos/panos_object.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_object.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_object.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_object.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_op.py future-import-boilerplate +plugins/modules/network/panos/panos_op.py metaclass-boilerplate +plugins/modules/network/panos/panos_op.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_op.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_pg.py future-import-boilerplate +plugins/modules/network/panos/panos_pg.py metaclass-boilerplate +plugins/modules/network/panos/panos_pg.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_query_rules.py future-import-boilerplate +plugins/modules/network/panos/panos_query_rules.py metaclass-boilerplate +plugins/modules/network/panos/panos_query_rules.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_query_rules.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_restart.py future-import-boilerplate +plugins/modules/network/panos/panos_restart.py metaclass-boilerplate +plugins/modules/network/panos/panos_restart.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_sag.py future-import-boilerplate +plugins/modules/network/panos/panos_sag.py metaclass-boilerplate +plugins/modules/network/panos/panos_sag.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_sag.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_sag.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_security_rule.py validate-modules:doc-missing-type +plugins/modules/network/panos/panos_security_rule.py validate-modules:doc-required-mismatch +plugins/modules/network/panos/panos_security_rule.py validate-modules:parameter-list-no-elements +plugins/modules/network/panos/panos_security_rule.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/panos/panos_set.py future-import-boilerplate +plugins/modules/network/panos/panos_set.py metaclass-boilerplate +plugins/modules/network/panos/panos_set.py validate-modules:doc-missing-type +plugins/modules/network/radware/vdirect_commit.py validate-modules:doc-missing-type +plugins/modules/network/radware/vdirect_commit.py validate-modules:parameter-list-no-elements +plugins/modules/network/radware/vdirect_commit.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/radware/vdirect_file.py validate-modules:doc-missing-type +plugins/modules/network/radware/vdirect_file.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/radware/vdirect_runnable.py validate-modules:doc-missing-type +plugins/modules/network/radware/vdirect_runnable.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/routeros/routeros_command.py validate-modules:doc-missing-type +plugins/modules/network/routeros/routeros_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/routeros/routeros_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/routeros/routeros_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/routeros/routeros_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_command.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_config.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_interface.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_interface.py validate-modules:undocumented-parameter +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_linkagg.py validate-modules:undocumented-parameter +plugins/modules/network/slxos/slxos_lldp.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/network/slxos/slxos_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/network/slxos/slxos_vlan.py validate-modules:doc-missing-type +plugins/modules/network/slxos/slxos_vlan.py validate-modules:doc-required-mismatch +plugins/modules/network/slxos/slxos_vlan.py validate-modules:missing-suboption-docs +plugins/modules/network/slxos/slxos_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/network/slxos/slxos_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/slxos/slxos_vlan.py validate-modules:undocumented-parameter +plugins/modules/network/sros/sros_command.py validate-modules:collection-deprecated-version +plugins/modules/network/sros/sros_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/sros/sros_command.py validate-modules:doc-missing-type +plugins/modules/network/sros/sros_command.py validate-modules:doc-required-mismatch +plugins/modules/network/sros/sros_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/sros/sros_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/sros/sros_command.py yamllint:unparsable-with-libyaml +plugins/modules/network/sros/sros_config.py validate-modules:collection-deprecated-version +plugins/modules/network/sros/sros_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/sros/sros_config.py validate-modules:doc-missing-type +plugins/modules/network/sros/sros_config.py validate-modules:doc-required-mismatch +plugins/modules/network/sros/sros_config.py validate-modules:nonexistent-parameter-documented +plugins/modules/network/sros/sros_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/sros/sros_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/sros/sros_config.py yamllint:unparsable-with-libyaml +plugins/modules/network/sros/sros_rollback.py validate-modules:collection-deprecated-version +plugins/modules/network/sros/sros_rollback.py validate-modules:doc-default-does-not-match-spec +plugins/modules/network/sros/sros_rollback.py validate-modules:doc-missing-type +plugins/modules/network/sros/sros_rollback.py validate-modules:doc-required-mismatch +plugins/modules/network/sros/sros_rollback.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/sros/sros_rollback.py yamllint:unparsable-with-libyaml +plugins/modules/network/voss/voss_command.py validate-modules:doc-missing-type +plugins/modules/network/voss/voss_command.py validate-modules:parameter-list-no-elements +plugins/modules/network/voss/voss_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/voss/voss_config.py validate-modules:doc-missing-type +plugins/modules/network/voss/voss_config.py validate-modules:parameter-list-no-elements +plugins/modules/network/voss/voss_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/network/voss/voss_facts.py validate-modules:parameter-list-no-elements +plugins/modules/network/voss/voss_facts.py validate-modules:parameter-type-not-in-doc +tests/unit/mock/path.py future-import-boilerplate +tests/unit/mock/path.py metaclass-boilerplate +tests/unit/mock/yaml_helper.py future-import-boilerplate +tests/unit/mock/yaml_helper.py metaclass-boilerplate +tests/unit/plugins/httpapi/test_ftd.py future-import-boilerplate +tests/unit/plugins/httpapi/test_ftd.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/avi/test_avi_api_utils.py future-import-boilerplate +tests/unit/plugins/module_utils/network/avi/test_avi_api_utils.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_common.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_common.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_configuration.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_configuration.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_device.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_device.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_parser.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_parser.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_validator.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_validator.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_with_real_data.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_fdm_swagger_with_real_data.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_upsert_functionality.py future-import-boilerplate +tests/unit/plugins/module_utils/network/ftd/test_upsert_functionality.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/netscaler/test_netscaler.py future-import-boilerplate +tests/unit/plugins/module_utils/network/netscaler/test_netscaler.py metaclass-boilerplate +tests/unit/plugins/module_utils/network/nso/test_nso.py metaclass-boilerplate +tests/unit/plugins/modules/network/avi/test_avi_user.py future-import-boilerplate +tests/unit/plugins/modules/network/avi/test_avi_user.py metaclass-boilerplate +tests/unit/plugins/modules/network/cloudvision/test_cv_server_provision.py future-import-boilerplate +tests/unit/plugins/modules/network/cloudvision/test_cv_server_provision.py metaclass-boilerplate +tests/unit/plugins/modules/network/cumulus/test_nclu.py future-import-boilerplate +tests/unit/plugins/modules/network/cumulus/test_nclu.py metaclass-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_configuration.py future-import-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_configuration.py metaclass-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_file_download.py future-import-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_file_download.py metaclass-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_file_upload.py future-import-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_file_upload.py metaclass-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_install.py future-import-boilerplate +tests/unit/plugins/modules/network/ftd/test_ftd_install.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/netscaler_module.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/netscaler_module.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_action.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_action.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_policy.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_policy.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_vserver.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_cs_vserver.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_service.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_service.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_site.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_site.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_vserver.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_gslb_vserver.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_lb_monitor.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_lb_monitor.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_lb_vserver.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_lb_vserver.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_nitro_request.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_nitro_request.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_save_config.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_save_config.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_server.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_server.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_service.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_service.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_servicegroup.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_servicegroup.py metaclass-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_ssl_certkey.py future-import-boilerplate +tests/unit/plugins/modules/network/netscaler/test_netscaler_ssl_certkey.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/nso_module.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_action.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_config.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_query.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_show.py metaclass-boilerplate +tests/unit/plugins/modules/network/nso/test_nso_verify.py metaclass-boilerplate +tests/unit/plugins/modules/network/nuage/nuage_module.py future-import-boilerplate +tests/unit/plugins/modules/network/nuage/nuage_module.py metaclass-boilerplate +tests/unit/plugins/modules/network/nuage/test_nuage_vspk.py future-import-boilerplate +tests/unit/plugins/modules/network/nuage/test_nuage_vspk.py metaclass-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_commit.py future-import-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_commit.py metaclass-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_file.py future-import-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_file.py metaclass-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_runnable.py future-import-boilerplate +tests/unit/plugins/modules/network/radware/test_vdirect_runnable.py metaclass-boilerplate +tests/unit/plugins/modules/utils.py future-import-boilerplate +tests/unit/plugins/modules/utils.py metaclass-boilerplate +tests/utils/shippable/check_matrix.py replace-urlopen +tests/utils/shippable/timing.py shebang diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.9.txt b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.9.txt new file mode 100644 index 00000000..cdde7596 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/sanity/ignore-2.9.txt @@ -0,0 +1,106 @@ +#plugins/action/onyx_config.py action-plugin-docs # undocumented action plugin to fix +plugins/modules/onyx_bgp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_bgp.py validate-modules:doc-missing-type +plugins/modules/onyx_bgp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_buffer_pool.py validate-modules:doc-missing-type +plugins/modules/onyx_buffer_pool.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_command.py validate-modules:doc-missing-type +plugins/modules/onyx_command.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_config.py validate-modules:doc-missing-type +plugins/modules/onyx_config.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_facts.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_igmp.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_igmp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-missing-type +plugins/modules/onyx_igmp_vlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_igmp_vlan.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_igmp_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_interface.py validate-modules:nonexistent-parameter-documented +plugins/modules/onyx_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_l2_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_l2_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_l2_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_l2_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_l2_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_l2_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_l2_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_l3_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_l3_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_l3_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_l3_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_l3_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_l3_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_l3_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_linkagg.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_linkagg.py validate-modules:doc-default-does-not-match-spec +plugins/modules/onyx_linkagg.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_linkagg.py validate-modules:doc-missing-type +plugins/modules/onyx_linkagg.py validate-modules:doc-required-mismatch +plugins/modules/onyx_linkagg.py validate-modules:missing-suboption-docs +plugins/modules/onyx_linkagg.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_linkagg.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_linkagg.py validate-modules:undocumented-parameter +plugins/modules/onyx_lldp.py validate-modules:doc-missing-type +plugins/modules/onyx_lldp_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_lldp_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_lldp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_lldp_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_lldp_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_lldp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_lldp_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_magp.py validate-modules:doc-missing-type +plugins/modules/onyx_magp.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_mlag_ipl.py validate-modules:doc-missing-type +plugins/modules/onyx_mlag_vip.py validate-modules:doc-default-does-not-match-spec +plugins/modules/onyx_mlag_vip.py validate-modules:doc-missing-type +plugins/modules/onyx_mlag_vip.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_ntp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ntp_servers_peers.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ospf.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_ospf.py validate-modules:doc-missing-type +plugins/modules/onyx_ospf.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_pfc_interface.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_pfc_interface.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_pfc_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_pfc_interface.py validate-modules:doc-required-mismatch +plugins/modules/onyx_pfc_interface.py validate-modules:missing-suboption-docs +plugins/modules/onyx_pfc_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_pfc_interface.py validate-modules:undocumented-parameter +plugins/modules/onyx_protocol.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_global.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_global.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_ptp_interface.py validate-modules:doc-missing-type +plugins/modules/onyx_ptp_interface.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_qos.py validate-modules:doc-missing-type +plugins/modules/onyx_qos.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_qos.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_snmp.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_snmp_hosts.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_snmp_users.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_syslog_remote.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_traffic_class.py validate-modules:doc-missing-type +plugins/modules/onyx_traffic_class.py validate-modules:parameter-list-no-elements +plugins/modules/onyx_traffic_class.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/onyx_vlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_vlan.py validate-modules:doc-missing-type +plugins/modules/onyx_vlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_vlan.py validate-modules:missing-suboption-docs +plugins/modules/onyx_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vlan.py validate-modules:undocumented-parameter +plugins/modules/onyx_vxlan.py validate-modules:doc-elements-mismatch +plugins/modules/onyx_vxlan.py validate-modules:doc-required-mismatch +plugins/modules/onyx_vxlan.py validate-modules:missing-suboption-docs +plugins/modules/onyx_vxlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/onyx_vxlan.py validate-modules:undocumented-parameter diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/__init__.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/__init__.py diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_bgp_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_bgp_show.cfg new file mode 100644 index 00000000..b9c5c952 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_bgp_show.cfg @@ -0,0 +1,34 @@ +## +## Running database "initial" +## Generated at 2009/01/14 12:53:06 +0000 +## Hostname: r-ufm-sw102 +## + +## +## Running-config temporary prefix mode setting +## +no cli default prefix-modes enable + +## +## BGP configuration +## + protocol bgp + router bgp 172 vrf default + router bgp 172 vrf default router-id 1.2.3.4 force + router bgp 172 vrf default bgp fast-external-fallover + router bgp 172 vrf default maximum-paths 31 + router bgp 172 vrf default bestpath as-path multipath-relax force + router bgp 172 vrf default neighbor evpn peer-group + router bgp 172 vrf default neighbor evpn send-community extended + router bgp 172 vrf default neighbor 10.2.3.4 remote-as 173 + router bgp 172 vrf default neighbor 10.2.3.5 remote-as 322 + router bgp 172 vrf default neighbor 10.2.3.5 peer-group evpn + router bgp 172 vrf default neighbor 10.2.3.5 ebgp-multihop 255 + router bgp 172 vrf default address-family l2vpn-evpn neighbor evpn next-hop-unchanged + router bgp 172 vrf default address-family l2vpn-evpn neighbor evpn activate + router bgp 172 vrf default network 172.16.1.0 /24 + router bgp 172 vrf default address-family l2vpn-evpn auto-create +## +## Persistent prefix mode setting +## +cli default prefix-modes enable diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_buffer_pool.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_buffer_pool.cfg new file mode 100644 index 00000000..7172e8dc --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_buffer_pool.cfg @@ -0,0 +1,15 @@ +{ + "roce": [ + { + "Type": "lossless", + "Switch Priorities": "3", + "Max Usage": "0", + "Usage": "0", + "Memory actual": "5.9M", + "Memory [%]": "50.00" + } + ], + "Exception list": { + "message": "N/A" + } +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_command_show_version.txt b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_command_show_version.txt new file mode 100644 index 00000000..cca075b6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_command_show_version.txt @@ -0,0 +1,19 @@ +Product name: MLNX-OS +Product release: 3.6.5000 +Build ID: #1-dev +Build date: 2017-11-10 18:14:32 +Target arch: x86_64 +Target hw: x86_64 +Built by: jenkins@cc45f26cd083 +Version summary: X86_64 3.6.5000 2017-11-10 18:14:32 x86_64 + +Product model: x86onie +Host ID: 248A073D505C +System serial num: \"MT1632X00205\" +System UUID: 0b19d6d0-5eca-11e6-8000-7cfe90fadc40 + +Uptime: 1d 16h 31m 43.856s +CPU load averages: 0.06 / 0.12 / 0.13 +Number of CPUs: 4 +System memory: 2597 MB used / 5213 MB free / 7810 MB total +Swap: 0 MB used / 0 MB free / 0 MB total diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_config_config.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_config_config.cfg new file mode 100644 index 00000000..38062a8c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_config_config.cfg @@ -0,0 +1,115 @@ +## +## Running database "initial" +## Generated at 2017/11/28 17:52:08 +0000 +## Hostname: ufm-switch16 +## + +## +## Running-config temporary prefix mode setting +## +no cli default prefix-modes enable + +## +## License keys +## + license install 11223344 + +## +## MLAG protocol +## + protocol mlag + +## +## Interface Ethernet configuration +## + interface mlag-port-channel 2 + interface port-channel 1 + interface ethernet 1/7-1/8 channel-group 1 mode active + interface ethernet 1/32 mlag-channel-group 2 mode on + interface mlag-port-channel 2 switchport mode hybrid + interface mlag-port-channel 2 no shutdown + +## +## LAG configuration +## + lacp + +## +## VLAN configuration +## + vlan 101 + vlan 4094 + interface mlag-port-channel 2 switchport access vlan 101 + +## +## STP configuration +## +no spanning-tree + +## +## L3 configuration +## + ip routing vrf default + interface vlan 101 + interface vlan 4094 + interface vlan 101 ip address 10.0.0.254 255.255.255.0 + interface vlan 4094 ip address 10.10.10.1 255.255.255.0 + +## +## Other IP configuration +## +hostname ufm-switch16 + +## +## DCBX PFC configuration +## + dcb priority-flow-control enable force + interface ethernet 1/7-1/8 dcb priority-flow-control mode on force + interface port-channel 1 dcb priority-flow-control mode on force + +## +## LLDP configuration +## + lldp + +## +## MAGP configuration +## + protocol magp + interface vlan 101 magp 102 + interface vlan 101 magp 102 ip virtual-router address 10.0.0.252 + interface vlan 101 magp 102 ip virtual-router mac-address 00:00:5E:00:01:01 + +## +## MLAG configurations +## + mlag-vip neo-mlag-vip-4094 ip 192.168.1.1 /24 force +no mlag shutdown + mlag system-mac 00:00:5E:00:01:00 + interface port-channel 1 ipl 1 + interface vlan 4094 ipl 1 peer-address 10.10.10.2 + +## +## AAA remote server configuration +## +# ldap bind-password ******** +# radius-server key ******** +# tacacs-server key ******** + +## +## Network management configuration +## +# web proxy auth basic password ******** + telnet-server enable + +## +## X.509 certificates configuration +## +# +# Certificate name system-self-signed, ID 51f545df9722387056f674401f510ff56077800b +# (public-cert config omitted since private-key config is hidden) + +## +## Persistent prefix mode setting +## +cli default prefix-modes enable
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_config_src.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_config_src.cfg new file mode 100644 index 00000000..2fc2ada1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_config_src.cfg @@ -0,0 +1,3 @@ +no cli default prefix-modes enable +interface mlag-port-channel 2 + diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_interfaces_ethernet.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_interfaces_ethernet.cfg new file mode 100644 index 00000000..03128f1e --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_interfaces_ethernet.cfg @@ -0,0 +1,20 @@ +[ + { + "Fec": "auto", + "Mac address": "7c:fe:90:e5:ca:3c", + "Actual speed": "100 Gbps", + "MTU": "1500 bytes(Maximum packet size 1522 bytes)", + "header": "Eth1/1", + "Admin state": "Enabled", + "Operational state": "Down" + }, + { + "Fec": "auto", + "Mac address": "7c:fe:90:e5:ca:3e", + "Actual speed": "100 Gbps", + "MTU": "1500 bytes(Maximum packet size 1522 bytes)", + "header": "Eth1/2", + "Admin state": "Enabled", + "Operational state": "Down" + } +]
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_module.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_module.cfg new file mode 100644 index 00000000..a82fcf75 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_module.cfg @@ -0,0 +1,7 @@ +{ + "MGMT": [ + { + "Status": "ready" + } + ] +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_version.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_version.cfg new file mode 100644 index 00000000..9a486e8c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_facts_show_version.cfg @@ -0,0 +1,19 @@ +{ + "Uptime": "2d 13h 40m 34.992s", + "Product model": "x86onie", + "Build date": "2017-11-10 18:14:32", + "Target arch": "x86_64", + "Target hw": "x86_64", + "Number of CPUs": "4", + "Build ID": "#1-dev", + "CPU load averages": "0.21 / 0.07 / 0.06", + "Host ID": "248A07B0141C", + "System serial num": "MT1708X07233", + "System UUID": "03d242b6-1a24-11e7-8000-248a07f55400", + "Swap": "0 MB used / 0 MB free / 0 MB total", + "Product name": "MLNX-OS", + "Built by": "jenkins@cc45f26cd083", + "System memory": "2597 MB used / 5213 MB free / 7810 MB total", + "Version summary": "X86_64 3.6.5000 2017-11-10 18:14:32 x86_64", + "Product release": "3.6.5000" +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_igmp_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_igmp_show.cfg new file mode 100644 index 00000000..13b19d94 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_igmp_show.cfg @@ -0,0 +1,14 @@ +[ + { + "Report suppression interval": "5 seconds", + "IGMP snooping unregistered multicast": "flood", + "IGMP snooping operationally": "disabled", + "Mrouter timeout": "125 seconds", + "IGMP default version for new VLAN": "V3", + "header": "IGMP snooping global configuration", + "Last member query interval": "1 seconds", + "IGMP snooping globally": "disabled", + "Proxy-reporting globally": "disabled", + "Port purge timeout": "260 seconds" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_rates.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_rates.cfg new file mode 100644 index 00000000..11131cc5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_rates.cfg @@ -0,0 +1,10 @@ +{ + "Eth1/1": [ + { + "ingress rate": "9000 b/s", + "egress pkts/sec": "10", + "egress rate": "10000 b/s", + "ingress pkts/sec": "10" + } + ] +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_show.cfg new file mode 100644 index 00000000..982e58fd --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_show.cfg @@ -0,0 +1,74 @@ +[ + { + "Fec": "auto", + "Mac address": "7c:fe:90:f0:54:fc", + "60 seconds ingress rate": "0 bits/sec, 0 bytes/sec, 0 packets/sec", + "Last clearing of \"show interface\" counters": "Never", + "Actual speed": "40 Gbps", + "MTU": "1500 bytes(Maximum packet size 1522 bytes)", + "header": "Eth1/1", + "Telemetry threshold": "Disabled\t TCs: N\\A", + "Telemetry threshold level": "N\\A", + "Flow-control": "receive off send off", + "Forwarding mode": "inherited cut-through", + "60 seconds egress rate": "0 bits/sec, 0 bytes/sec, 0 packets/sec", + "Last change in operational status": "Never", + "Boot delay time": "0 sec", + "Description": "N\\A", + "Admin state": "Enabled", + "Telemetry sampling": "Disabled\t TCs: N\\A", + "Operational state": "Down", + "Width reduction mode": "Not supported", + "Tx": { + "error packets": "0", + "packets": "0", + "bytes": "0", + "multicast packets": "0", + "unicast packets": "0", + "discard packets": "0", + "hoq discard packets": "0", + "broadcast packets": "0" + }, + "MAC learning mode": "Enabled", + "Switchport mode": "access", + "Rx": { + "error packets": "0", + "packets": "0", + "bytes": "0", + "multicast packets": "0", + "unicast packets": "0", + "discard packets": "0", + "broadcast packets": "0" + } + }, + { + "Icmp redirect": "Enabled", + "Description": "N/A", + "Mac Address": "7C:FE:90:F0:54:C1", + "Autostate": "Enabled", + "Admin state": "Enabled", + "header": "Vlan 10", + "MTU": "1500 bytes", + "DHCP client": "Disabled", + "Operational state": "Up", + "VRF": "default", + "Arp timeout": "1500 seconds", + "Counters": "Disabled" + }, + { + "Autostate": "Enabled", + "Icmp redirect": "Enabled", + "Broadcast address": "10.2.2.255", + "Description": "N/A", + "Mac Address": "7C:FE:90:F0:54:C1", + "Internet Address": "10.2.2.3/24", + "Admin state": "Enabled", + "header": "Vlan 1002", + "MTU": "1500 bytes", + "DHCP client": "Disabled", + "Operational state": "Down", + "VRF": "default", + "Arp timeout": "1500 seconds", + "Counters": "Disabled" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_status.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_status.cfg new file mode 100644 index 00000000..7a3a974a --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_interfaces_status.cfg @@ -0,0 +1,15 @@ +{ + "Eth1/1": [ + { + "Negotiation": "No-Negotiation", + "Operational state": "Down", + "Speed": "100 Gbps" + } + ], + "Vlan 1002": [ + { + "State": "Down", + "Description": "N/A" + } + ] +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l2_interface_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l2_interface_show.cfg new file mode 100644 index 00000000..dc3704e4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l2_interface_show.cfg @@ -0,0 +1,12 @@ +{ + "Eth1/11": { + "Access vlan": "1", + "Allowed vlans": "", + "Mode": "access" + }, + "Eth1/10": { + "Access vlan": "1", + "Allowed vlans": "10", + "Mode": "hybrid" + } +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l3_interface_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l3_interface_show.cfg new file mode 100644 index 00000000..6298953b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l3_interface_show.cfg @@ -0,0 +1,89 @@ +[ + { + "Broadcast address": "172.3.1.255", + "Fec": "auto", + "Tx": { + "error packets": "0", + "packets": "0", + "bytes": "0", + "multicast packets": "0", + "unicast packets": "0", + "discard packets": "0", + "hoq discard packets": "0", + "broadcast packets": "0" + }, + "Rx": { + "error packets": "0", + "packets": "0", + "bytes": "0", + "multicast packets": "0", + "unicast packets": "0", + "discard packets": "0", + "broadcast packets": "0" + }, + "header": "Eth1/5", + "Arp timeout": "1500 seconds", + "Actual speed": "40 Gbps", + "60 seconds egress rate": "0 bits/sec, 0 bytes/sec, 0 packets/sec", + "Last change in operational status": "Never", + "Boot delay time": "0 sec", + "Description": "N\\A", + "DHCP client": "Disabled", + "VRF": "default", + "Mac address": "24:8A:07:F5:54:01", + "60 seconds ingress rate": "0 bits/sec, 0 bytes/sec, 0 packets/sec", + "Last clearing of \"show interface\" counters": "Never", + "MTU": "1500 bytes(Maximum packet size 1522 bytes)", + "Telemetry threshold": "Disabled\t TCs: N\\A", + "Telemetry threshold level": "N\\A", + "Flow-control": "receive off send off", + "Forwarding mode": "inherited cut-through", + "Admin state": "Enabled", + "Telemetry sampling": "Disabled\t TCs: N\\A", + "IP Address": "172.3.12.4 /24", + "Operational state": "Down", + "Width reduction mode": "Not supported" + }, + { + "Fec": "auto", + "Mac address": "24:8a:07:f5:54:0c", + "60 seconds ingress rate": "0 bits/sec, 0 bytes/sec, 0 packets/sec", + "Last clearing of \"show interface\" counters": "Never", + "Actual speed": "40 Gbps", + "MTU": "1500 bytes(Maximum packet size 1522 bytes)", + "header": "Eth1/6", + "Telemetry threshold": "Disabled\t TCs: N\\A", + "Telemetry threshold level": "N\\A", + "Flow-control": "receive off send off", + "Forwarding mode": "inherited cut-through", + "60 seconds egress rate": "0 bits/sec, 0 bytes/sec, 0 packets/sec", + "Last change in operational status": "Never", + "Boot delay time": "0 sec", + "Description": "N\\A", + "Admin state": "Enabled", + "Telemetry sampling": "Disabled\t TCs: N\\A", + "Operational state": "Down", + "Width reduction mode": "Not supported", + "Tx": { + "error packets": "0", + "packets": "0", + "bytes": "0", + "multicast packets": "0", + "unicast packets": "0", + "discard packets": "0", + "hoq discard packets": "0", + "broadcast packets": "0" + }, + "MAC learning mode": "Enabled", + "Switchport mode": "access", + "Rx": { + "error packets": "0", + "packets": "0", + "bytes": "0", + "multicast packets": "0", + "unicast packets": "0", + "discard packets": "0", + "broadcast packets": "0" + } + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l3_vlan_interface_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l3_vlan_interface_show.cfg new file mode 100644 index 00000000..66a5509e --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_l3_vlan_interface_show.cfg @@ -0,0 +1,18 @@ +[ + { + "Autostate": "Enabled", + "Icmp redirect": "Enabled", + "Broadcast address": "172.3.12.255", + "Description": "N/A", + "Mac Address": "7C:FE:90:E5:CA:01", + "Internet Address": "172.3.12.4/24", + "Admin state": "Enabled", + "header": "Vlan 1002", + "MTU": "1500 bytes", + "DHCP client": "Disabled", + "Operational state": "Down", + "VRF": "default", + "Arp timeout": "1500 seconds", + "Counters": "Disabled" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_lldp_interface_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_lldp_interface_show.cfg new file mode 100644 index 00000000..d3a364b9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_lldp_interface_show.cfg @@ -0,0 +1,16 @@ +{ + "Eth1/1": [ + { + "Receive": "Enabled", + "Transmit": "Enabled", + "TLVs": "PD, SN, SD, SC, MA, PFC, AP, ETS-C, ETS-R" + } + ], + "Eth1/2": [ + { + "Receive": "Disabled", + "Transmit": "Disabled", + "TLVs": "PD, SN, SD, SC, MA, PFC, AP, ETS-C, ETS-R" + } + ] +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_lldp_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_lldp_show.cfg new file mode 100644 index 00000000..7bb1cb02 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_lldp_show.cfg @@ -0,0 +1,14 @@ +[ + { + "LLDP": "enabled" + }, + { + "Supported capabilities": "B,R", + "Chassis sub type": "Mac Address", + "header": "Local global configuration", + "System Name": "ufm-switch16", + "Supported capabilities enabled": "B", + "Chassis id": "7c:fe:90:e5:ca:00", + "System Description": "Mellanox MSN2700,MLNX-OS,SWv3.6.5000-04" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_logging_config_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_logging_config_show.cfg new file mode 100644 index 00000000..235205c2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_logging_config_show.cfg @@ -0,0 +1,11 @@ + +logging trap alert +logging 10.10.10.10 +logging 10.10.10.10 filter exclude ".*ERR.*" +logging 10.10.10.10 trap info +logging 10.10.10.12 +logging 10.10.10.12 port 80 +logging 10.10.10.12 trap override class sx-sdk priority emerg +logging files rotation criteria size-pct 10.000 +logging local info +logging receive diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_logging_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_logging_show.cfg new file mode 100644 index 00000000..09e21b10 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_logging_show.cfg @@ -0,0 +1,35 @@ +[ + { + "Log format": "standard", + "Log rotation size threshold": "10.000% of partition (986.46 megabytes)", + "Allow receiving of messages from remote hosts": "yes", + "Override for class debug-module": "notice", + "Local logging level": "info", + "Number of archived log files to keep": "10", + "Default remote logging level": "alert", + "Subsecond timestamp field": "disabled", + "Log rotation frequency": "weekly", + "debug": [ + "logging debug-files rotation criteria frequency daily", + "logging debug-files rotation criteria size 20", + "logging debug-files rotation max-num 20" + ] + }, + { + "Levels at which messages are logged": [ + { + "CLI commands": "notice", + "Audit messages": "notice" + } + ] + }, + { + "Remote syslog servers": [ + { + "Lines": [ + "No remote syslog servers configured" + ] + } + ] + } +]
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_magp_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_magp_show.cfg new file mode 100644 index 00000000..7cc90b7a --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_magp_show.cfg @@ -0,0 +1,18 @@ +[ + { + "Interface vlan": "1243", + "Admin state": "Enabled", + "Virtual IP": "10.0.0.43", + "header": "MAGP 102", + "State": "Init", + "Virtual MAC": "01:02:03:04:05:06" + }, + { + "Interface vlan": "1200", + "Admin state": "Disabled", + "Virtual IP": "0.0.0.0", + "header": "MAGP 103", + "State": "Init", + "Virtual MAC": "00:00:00:00:00:00" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_ipl_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_ipl_show.cfg new file mode 100644 index 00000000..6d1f3df5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_ipl_show.cfg @@ -0,0 +1,29 @@ +{ + "Reload-delay": "30 sec", + "Upgrade-timeout": "60 min", + "System-mac": "00:00:5E:00:01:4E [Mismatched]", + "Admin status": "Disabled", + "MLAG Ports Status Summary": { + "Active-partial": "0", + "Inactive": "0", + "Active-full": "0" + }, + "MLAG IPLs Summary": { + "1": [ + { + "Local IP address": "10.2.2.3", + "Peer IP address": "10.2.2.2", + "Operational State": "Down", + "Vlan Interface": "1002", + "Group Port-Channel": "Po1" + } + ] + }, + "Keepalive-interval": "1 sec", + "MLAG Ports Configuration Summary": { + "Disabled": "0", + "Configured": "0", + "Enabled": "0" + }, + "Operational status": "Down" +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_port_channel_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_port_channel_show.cfg new file mode 100644 index 00000000..e883ecf3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_port_channel_show.cfg @@ -0,0 +1,18 @@ +{ + "MLAG Port-Channel Flags": "D-Down, U-Up, P-Partial UP, S - suspended by MLAG", + "Port Flags": { + "I": "Individual", + "P": "Up in port-channel (members)", + "S": "Suspend in port-channel (members)", + "D": "Down" + }, + "MLAG Port-Channel Summary": { + "1 Mpo33(S)": [ + { + "Local Ports (D/P/S/I)": "Eth1/8(D)", + "Peer Ports (D/P/S/I)": "N/A", + "Type": "LACP" + } + ] + } +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_show.cfg new file mode 100644 index 00000000..1996a6b3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_show.cfg @@ -0,0 +1,18 @@ +{ + "Reload-delay": "30 sec", + "Upgrade-timeout": "60 min", + "System-mac": "00:00:5E:00:01:4E", + "Admin status": "Disabled", + "MLAG Ports Status Summary": { + "Active-partial": "0", + "Inactive": "0", + "Active-full": "0" + }, + "Keepalive-interval": "1 sec", + "MLAG Ports Configuration Summary": { + "Disabled": "0", + "Configured": "0", + "Enabled": "0" + }, + "Operational status": "Down" +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_vip_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_vip_show.cfg new file mode 100644 index 00000000..19bee48f --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_mlag_vip_show.cfg @@ -0,0 +1,19 @@ +{ + "r-neo-sw12": [ + { + "IP Address": "10.209.26.55", + "VIP-State": "standby" + } + ], + "r-smg-sw14": [ + { + "IP Address": "10.209.27.172", + "VIP-State": "master" + } + ], + "MLAG-VIP": { + "MLAG VIP address": "10.209.25.107/24", + "MLAG group name": "neo-mlag-vip-500", + "Active nodes": "2" + } +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ntp_servers_peers_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ntp_servers_peers_show.cfg new file mode 100644 index 00000000..2f5d3c2f --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ntp_servers_peers_show.cfg @@ -0,0 +1,19 @@ +[ + { + "NTP enabled": "yes", + "NTP Authentication enabled": "no" + }, + { + "NTP version": "4", + "Enabled": "yes", + "Key ID": "5", + "header": "NTP peer 1.1.1.1" + }, + { + "NTP version": "4", + "Enabled": "no", + "Trusted": "yes", + "Key ID": "99", + "header": "NTP server 2.2.2.2" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ntp_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ntp_show.cfg new file mode 100644 index 00000000..b0b4a8db --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ntp_show.cfg @@ -0,0 +1,30 @@ +[ +[ + { + "NTP is administratively": "enabled", + "NTP Authentication administratively": "disabled" + }, + { + "Lines": [ + "Clock is unsynchronized." + ] + }, + { + "Active servers and peers": [ + { + "Lines": [ + "No NTP associations present." + ] + } + ] + } +] , +[ + { + "header": "NTP Key 22", + "Encryption Type": "sha1", + "Trusted": "no" + } +] + +]
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ospf_interfaces_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ospf_interfaces_show.cfg new file mode 100644 index 00000000..75663058 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ospf_interfaces_show.cfg @@ -0,0 +1,5 @@ + +OSPF Process ID 2 VRF default +Total number of interface: 1 +Interface Id Area Cost State Neighbors Status +Loopback1 0.0.0.0 1 Enabled 0 Up diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ospf_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ospf_show.cfg new file mode 100644 index 00000000..72e38568 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_ospf_show.cfg @@ -0,0 +1 @@ +Routing Process 2 with ID 10.2.3.4 default diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_pfc_interface_disabled.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_pfc_interface_disabled.cfg new file mode 100644 index 00000000..0d51d4d5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_pfc_interface_disabled.cfg @@ -0,0 +1,26 @@ +{ + "Eth1/1": [ + { + "PFC admin": "Auto", + "PFC oper": "Disabled" + } + ], + "Eth1/1/2": [ + { + "PFC admin": "Auto", + "PFC oper": "Disabled" + } + ], + "Po1": [ + { + "PFC admin": "Auto", + "PFC oper": "Disabled" + } + ], + "Mpo2": [ + { + "PFC admin": "Auto", + "PFC oper": "Disabled" + } + ] +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_pfc_interface_enabled.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_pfc_interface_enabled.cfg new file mode 100644 index 00000000..471edc8c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_pfc_interface_enabled.cfg @@ -0,0 +1,26 @@ +{ + "Eth1/1": [ + { + "PFC admin": "on", + "PFC oper": "Enabled" + } + ], + "Eth1/1/2": [ + { + "PFC admin": "on", + "PFC oper": "Enabled" + } + ], + "Po1": [ + { + "PFC admin": "on", + "PFC oper": "Enabled" + } + ], + "Mpo2": [ + { + "PFC admin": "on", + "PFC oper": "Enabled" + } + ] +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_port_channel_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_port_channel_show.cfg new file mode 100644 index 00000000..805853f4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_port_channel_show.cfg @@ -0,0 +1,15 @@ +{ + "Flags": { + "I": "Individual", + "P": "Up in port-channel (members)", + "S": "Suspend in port-channel (members)", + "U": "Up", + "D": "Down" + }, + "1 Po22(D)": [ + { + "Type": "STATIC", + "Member Ports": "Eth1/7(D)" + } + ] +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_protocols_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_protocols_show.cfg new file mode 100644 index 00000000..fd4549cd --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_protocols_show.cfg @@ -0,0 +1,27 @@ +{ + "pim": "disabled", + "dhcp-relay": "disabled", + "igmp-snooping": "disabled", + "lacp": "disabled", + "ptp": "disabled", + "lldp": "disabled", + "isolation-group": "disabled", + "bfd": "disabled", + "openflow": "disabled", + "telemetry": "disabled", + "vrrp": "disabled", + "spanning-tree": "rst", + "mlag": "disabled", + "magp": "disabled", + "nve": "disabled", + "Ethernet": "enabled", + "IP L3": "enabled", + "ets": "enabled", + "sflow": "disabled", + "dhcp-relay(v6)": "disabled", + "dot1x": "disabled", + "bgp": "disabled", + "priority-flow-control": "disabled", + "ospf": "disabled", + "bfd": "disabled" +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_aaa.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_aaa.cfg new file mode 100644 index 00000000..40abbf21 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_aaa.cfg @@ -0,0 +1,16 @@ +[ + { + "Default User": "admin", + "header": "AAA authorization", + "Fallback on server-err": "yes", + "Map Order": "remote-first" + }, + { + "header": "Authentication method(s)", + "message": "local" + }, + { + "header": "Accounting method(s)", + "message": "No accounting methods configured." + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_bfd.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_bfd.cfg new file mode 100644 index 00000000..2e578eb1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_bfd.cfg @@ -0,0 +1,14 @@ +{ + "Lines": [ + " protocol bfd", + " ip bfd shutdown vrf default", + " ip bfd vrf 3 interval transmit-rate 55 force", + " ip bfd vrf default interval transmit-rate 55 force", + " ip bfd vrf 3 interval min-rx 50 force", + " ip bfd vrf default interval min-rx 50 force", + " ip bfd vrf 3 interval multiplier 7 force", + " ip bfd vrf default interval multiplier 7 force", + " ip route vrf 3 1.1.1.0/24 3.2.2.2 bfd", + " ip route vrf default 1.1.1.0/24 3.2.2.2 bfd" + ] +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_dcb_ets_interface.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_dcb_ets_interface.cfg new file mode 100644 index 00000000..b6bbc30f --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_dcb_ets_interface.cfg @@ -0,0 +1,99 @@ +[ + { + "Eth1/1": [ + { + "Multicast unaware mapping": "disabled", + "Interface Bandwidth Shape [Mbps]": "N/A" + }, + { + "Flags": [ + { + "S.Mode": "Scheduling Mode [Strict/WRR]", + "Bw.Sh": "Bandwidth Shaper", + "D": "-", + "W": "Weight", + "Bw.Gr": "Bandwidth Guaranteed" + } + ] + }, + { + "ETS per TC": [ + { + "1": [ + { + "S.Mode": "WRR", + "BW Sh.(Mbps)": "N/A", + "W(%)": "17", + "BW Gr.(Mbps)": "0", + "W": "13" + } + ], + "0": [ + { + "S.Mode": "WRR", + "BW Sh.(Mbps)": "N/A", + "W(%)": "17", + "BW Gr.(Mbps)": "0", + "W": "12" + } + ], + "3": [ + { + "S.Mode": "Strict", + "BW Sh.(Mbps)": "N/A", + "W(%)": "0", + "BW Gr.(Mbps)": "0", + "W": "0" + } + ], + "2": [ + { + "S.Mode": "Strict", + "BW Sh.(Mbps)": "N/A", + "W(%)": "0", + "BW Gr.(Mbps)": "0", + "W": "0" + } + ], + "5": [ + { + "S.Mode": "WRR", + "BW Sh.(Mbps)": "N/A", + "W(%)": "17", + "BW Gr.(Mbps)": "0", + "W": "13" + } + ], + "4": [ + { + "S.Mode": "WRR", + "BW Sh.(Mbps)": "N/A", + "W(%)": "16", + "BW Gr.(Mbps)": "0", + "W": "12" + } + ], + "7": [ + { + "S.Mode": "WRR", + "BW Sh.(Mbps)": "N/A", + "W(%)": "17", + "BW Gr.(Mbps)": "0", + "W": "13" + } + ], + "6": [ + { + "S.Mode": "WRR", + "BW Sh.(Mbps)": "N/A", + "W(%)": "16", + "BW Gr.(Mbps)": "0", + "W": "12" + } + ] + } + ] + } + ] + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_igmp_interfaces.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_igmp_interfaces.cfg new file mode 100644 index 00000000..22641d8b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_igmp_interfaces.cfg @@ -0,0 +1,162 @@ +{ + "Eth1/31": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/11": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/10": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/13": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/12": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/15": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/14": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/17": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/16": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/19": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/18": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/5": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/4": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/7": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/6": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/1": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/3": [ + { + "leave-mode": "Fast" + } + ], + "Eth1/2": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/9": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/8": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/32": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/24": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/25": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/26": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/27": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/20": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/21": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/22": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/23": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/30": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/28": [ + { + "leave-mode": "Normal" + } + ], + "Eth1/29": [ + { + "leave-mode": "Normal" + } + ] +}
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interface_congestion_control.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interface_congestion_control.cfg new file mode 100644 index 00000000..e4c1207f --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interface_congestion_control.cfg @@ -0,0 +1,46 @@ +[ + { + "Interface ethernet": "1/1", + "ECN marked packets": "0" + }, + { + "header": "TC-0", + "Mode": "none" + }, + { + "header": "TC-1", + "Mode": "none" + }, + { + "Threshold mode": "relative", + "RED dropped packets": "0", + "header": "TC-2", + "Mode": "RED", + "Maximum threshold": "90%", + "Minimum threshold": "9%" + }, + { + "Threshold mode": "absolute", + "RED dropped packets": "0", + "header": "TC-3", + "Mode": "ECN", + "Maximum threshold": "1550 KB", + "Minimum threshold": "500 KB" + }, + { + "header": "TC-4", + "Mode": "none" + }, + { + "header": "TC-5", + "Mode": "none" + }, + { + "header": "TC-6", + "Mode": "none" + }, + { + "header": "TC-7", + "Mode": "none" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interfaces_nve.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interfaces_nve.cfg new file mode 100644 index 00000000..a907d168 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interfaces_nve.cfg @@ -0,0 +1,18 @@ +[ + { + "Mlag tunnel IP": "192.10.10.1", + "Effective tunnel IP": "(not exist)", + "NVE member interfaces": "(not configured)", + "Admin state": "up", + "Source interface": "loopback 1 (ip 0.0.0.0)", + "header": "Interface NVE 1 status", + "Controller mode": "BGP", + "Global Neigh-Suppression": "Enable", + "Counters": { + "dropped NVE-encapsulated packets": "0", + "decapsulated (Rx) NVE packets": "0", + "encapsulated (Tx) NVE packets": "0", + "NVE-encapsulated packets with errors": "0" + } + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interfaces_nve_detail.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interfaces_nve_detail.cfg new file mode 100644 index 00000000..e904bcc3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_interfaces_nve_detail.cfg @@ -0,0 +1,16 @@ +[ + { + "10":[ + { + "Neigh Suppression":"Enable", + "VNI":"10010" + } + ], + "6":[ + { + "Neigh Suppression":"Enable", + "VNI":"10060" + } + ] + } +]
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping.cfg new file mode 100644 index 00000000..975b6723 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping.cfg @@ -0,0 +1,10 @@ +[ + { + "mrouter static port list": "none", + "mrouter dynamic port list": "none", + "header": "Vlan 10 configuration parameters", + "message 1": "IGMP snooping is disabled", + "message 2": "IGMP version is V3", + "message 3": "Snooping switch is acting as Non-Querier" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping_groups.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping_groups.cfg new file mode 100644 index 00000000..3d84667b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping_groups.cfg @@ -0,0 +1,30 @@ +[ + { + "Snooping group information for VLAN 10 and group 224.5.5.1": [ + { + "Group flag": "St", + "Filter Mode": "EXCLUDE", + "V1/V2 Receiver Ports": "eth1/1, eth1/2", + "Exclude sources": "None" + }, + { + "V3 Receiver Ports": [ + { + "Exclude sources": [ + "None", + "None" + ], + "Include sources": [ + "1.1.1.1, 1.1.1.2", + "1.1.1.3" + ], + "Port Number": [ + "eth1/1", + "eth1/2" + ] + } + ] + } + ] + } +]
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping_querier.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping_querier.cfg new file mode 100644 index 00000000..b64c260d --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ip_igmp_snooping_querier.cfg @@ -0,0 +1,20 @@ +[ + { + "Snooping querier information for VLAN 10": [ + { + "Lines": [ + "IGMP Querier Not Present" + ] + }, + { + "Response interval": "100", + "Elected querier IP address": "0.0.0.0", + "Group membership interval": "1", + "Robustness": "2", + "Configured querier IP address": "-", + "Query interval": "125", + "Version": "3" + } + ] + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ntp_configured.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ntp_configured.cfg new file mode 100644 index 00000000..4fa74b30 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ntp_configured.cfg @@ -0,0 +1,8 @@ +[ + { + "message 2": "No NTP servers configured.", + "message 1": "No NTP peers configured.", + "NTP enabled": "no", + "NTP Authentication enabled": "no" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ptp_clock.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ptp_clock.cfg new file mode 100644 index 00000000..93092b4e --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ptp_clock.cfg @@ -0,0 +1,7 @@ +{ + "Priority1": "128", + "Number of PTP ports": "0", + "Domain": "127", + "Priority2": "128", + "Local clock time": "04:50:24 Etc/UTC 2018/09/04" +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ptp_interface.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ptp_interface.cfg new file mode 100644 index 00000000..389612e0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_ptp_interface.cfg @@ -0,0 +1,15 @@ +[ + { + "Transport protocol": "UDP IPv4", + "PTP interface state": "NONE", + "Forced Master": "no", + "Port Clock identity": "N/A", + "Announce interval(log mean)": "-2", + "PTP Port number": "0", + "header": "Interface name: Eth1/1", + "Delay Mechanism": "End to End", + "Sync interval(log mean)": "-3", + "Announce receipt time out": "3", + "Delay request interval(log mean)": "0" + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_snmp_hosts.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_snmp_hosts.cfg new file mode 100644 index 00000000..4a1312cc --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_snmp_hosts.cfg @@ -0,0 +1,38 @@ +[ + { + "Default notification port": "162", + "Default notification community": "public", + "Notifications enabled": "yes" + }, + { + "Notification sinks": [ + { + "1.1.1.1": [ + { + "Enabled": "yes", + "Port": "3", + "Notification type": "SNMP v3 inform", + "Remote engine ID": "" + }, + { + "Username": "sara", + "Authentication password": "(set)", + "Privacy password": "(set)", + "Privacy type": "3des", + "Authentication type": "md5" + } + ] + }, + { + "2.2.2.2": [ + { + "Community": "public (default)", + "Enabled": "yes", + "Port": "5", + "Notification type": "SNMP v2c trap" + } + ] + } + ] + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_snmp_users.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_snmp_users.cfg new file mode 100644 index 00000000..6c957ff0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_show_snmp_users.cfg @@ -0,0 +1,22 @@ +[ + { + "User name sara": [ + { + "Privacy password": "(NOT SET; user disabled)", + "Enabled overall": "yes", + "Authentication password": "(NOT SET; user disabled)", + "Authentication type": "sha", + "Require privacy": "no", + "Privacy type": "aes-128" + }, + { + "SET access": [ + { + "Capability level": "admin", + "Enabled": "yes" + } + ] + } + ] + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_snmp_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_snmp_show.cfg new file mode 100644 index 00000000..c3a16215 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_snmp_show.cfg @@ -0,0 +1,52 @@ +[ +[ + { + "SNMP port": "161", + "System contact": "sara", + "System location": "Jordan", + "SNMP enabled": "yes" + }, + { + "Read-only communities": [ + { + "Lines": [ + "community_1", + "public" + ] + } + ] + }, + { + "Read-write communities": [ + { + "Lines": [ + "community_2" + ] + } + ] + }, + { + "Interface listen enabled": "yes" + }, + { + "Listen Interfaces": [ + { + "Lines": [ + "No Listen Interfaces." + ] + } + ] + } +], +{ + "Lines": [ + " snmp-server community community_1 ro", + " snmp-server community community_2 rw", + " snmp-server contact sara", + " snmp-server location Jordan", + " snmp-server notify port 1", + " snmp-server notify community community_1" + ] +} + +]
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_username_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_username_show.cfg new file mode 100644 index 00000000..d5de67bf --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_username_show.cfg @@ -0,0 +1,51 @@ +{ + "xmladmin": [ + { + "CAPABILITY": "admin", + "ACCOUNT STATUS": "Password set (SHA512)", + "FULL NAME": "XML Admin User" + } + ], + "monitor": [ + { + "CAPABILITY": "monitor", + "ACCOUNT STATUS": "Password set (SHA512)", + "FULL NAME": "System Monitor" + } + ], + "admin": [ + { + "CAPABILITY": "admin", + "ACCOUNT STATUS": "No password required for login", + "FULL NAME": "System Administrator" + } + ], + "anass": [ + { + "CAPABILITY": "admin", + "ACCOUNT STATUS": "Password set (SHA512)", + "FULL NAME": "" + } + ], + "root": [ + { + "CAPABILITY": "admin", + "ACCOUNT STATUS": "No password required for login", + "FULL NAME": "Root User" + } + ], + "anassh": [ + { + "CAPABILITY": "admin", + "ACCOUNT STATUS": "Account disabled", + "FULL NAME": "" + } + ], + "xmluser": [ + { + "CAPABILITY": "monitor", + "ACCOUNT STATUS": "Password set (SHA512)", + "FULL NAME": "XML Monitor User" + } + ] +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_vlan_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_vlan_show.cfg new file mode 100644 index 00000000..d1ae46bf --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_vlan_show.cfg @@ -0,0 +1,14 @@ +{ + "1": { + "Name": "default", + "Ports": "Eth1/1, Eth1/2, Eth1/3, Eth1/4, Eth1/5,\nEth1/6, Eth1/7, Eth1/8, Eth1/9, Eth1/10,\nEth1/11, Eth1/12, Eth1/13, Eth1/14, Eth1/15,\nEth1/16" + }, + "10": { + "Name": "test 10", + "Ports": "" + }, + "20": { + "Name": "test 20", + "Ports": "" + } +} diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_wjh_show.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_wjh_show.cfg new file mode 100644 index 00000000..d50f4976 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/onyx_wjh_show.cfg @@ -0,0 +1,3 @@ + +no what-just-happened auto-export forwarding enable +no what-just-happened forwarding enable diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/show_qos_interface_ethernet.cfg b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/show_qos_interface_ethernet.cfg new file mode 100644 index 00000000..cf2bba8f --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/fixtures/show_qos_interface_ethernet.cfg @@ -0,0 +1,134 @@ +[ + { + "Eth1/1": [ + { + "PCP,DEI rewrite": "enabled", + "Default switch-priority": "0", + "IP PCP;DEI rewrite": "enable", + "Default DEI": "0", + "Default PCP": "0", + "Trust mode": "both", + "DSCP rewrite": "disabled" + }, + { + "PCP(DEI); DSCP to switch-priority mapping": [ + { + "2(0) 2(1)": [ + { + "switch-priority": "2", + "DSCP": "16 17 18 19 20 21 22 23" + } + ], + "3(0) 3(1)": [ + { + "switch-priority": "3", + "DSCP": "24 25 26 27 28 29 30 31" + } + ], + "5(0) 5(1)": [ + { + "switch-priority": "5", + "DSCP": "40 41 42 43 44 45 46 47" + } + ], + "0(0) 0(1)": [ + { + "switch-priority": "0", + "DSCP": "0 1 2 3 4 5 6 7" + } + ], + "7(0) 7(1)": [ + { + "switch-priority": "7", + "DSCP": "56 57 58 59 60 61 62 63" + } + ], + "4(0) 4(1)": [ + { + "switch-priority": "4", + "DSCP": "32 33 34 35 36 37 38 39" + } + ], + "6(0) 6(1)": [ + { + "switch-priority": "6", + "DSCP": "48 49 50 51 52 53 54 55" + } + ], + "1(0) 1(1)": [ + { + "switch-priority": "1", + "DSCP": "8 9 10 11 12 13 14 15" + } + ] + } + ] + }, + { + "PCP(DEI); DSCP rewrite mapping (switch-priority to PCP(DEI); DSCP; traffic-class)": [ + { + "Egress Interface": "Eth1/1" + }, + { + "1": [ + { + "PCP(DEI)": "1(0)", + "TC": "1", + "DSCP": "8" + } + ], + "0": [ + { + "PCP(DEI)": "0(0)", + "TC": "0", + "DSCP": "0" + } + ], + "3": [ + { + "PCP(DEI)": "3(0)", + "TC": "3", + "DSCP": "24" + } + ], + "2": [ + { + "PCP(DEI)": "2(0)", + "TC": "2", + "DSCP": "16" + } + ], + "5": [ + { + "PCP(DEI)": "5(0)", + "TC": "5", + "DSCP": "40" + } + ], + "4": [ + { + "PCP(DEI)": "4(0)", + "TC": "4", + "DSCP": "32" + } + ], + "7": [ + { + "PCP(DEI)": "7(0)", + "TC": "7", + "DSCP": "56" + } + ], + "6": [ + { + "PCP(DEI)": "6(0)", + "TC": "6", + "DSCP": "48" + } + ] + } + ] + } + ] + } +] diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/onyx_module.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/onyx_module.py new file mode 100644 index 00000000..b59401a5 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/onyx_module.py @@ -0,0 +1,91 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json +import os + +from .utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase + +fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures') +fixture_data = {} + + +def load_fixture(name): + path = os.path.join(fixture_path, name) + + if path in fixture_data: + return fixture_data[path] + + with open(path) as f: + data = f.read() + + try: + data = json.loads(data) + except Exception: + pass + + fixture_data[path] = data + return data + + +class TestOnyxModule(ModuleTestCase): + + def execute_module(self, failed=False, changed=False, commands=None, is_updates=False, sort=True, transport='cli'): + + self.load_fixtures(commands, transport=transport) + + if failed: + result = self.failed() + self.assertTrue(result['failed'], result) + else: + result = self.changed(changed) + self.assertEqual(result['changed'], changed, result) + + if commands is not None: + if is_updates: + commands_res = result.get('updates') + else: + commands_res = result.get('commands') + if sort: + self.assertEqual(sorted(commands), sorted(commands_res), commands_res) + else: + self.assertEqual(commands, commands_res, commands_res) + + return result + + def failed(self): + with self.assertRaises(AnsibleFailJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertTrue(result['failed'], result) + return result + + def changed(self, changed=False): + with self.assertRaises(AnsibleExitJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertEqual(result['changed'], changed, result) + return result + + def load_fixtures(self, commands=None, transport='cli'): + pass diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_aaa.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_aaa.py new file mode 100644 index 00000000..6c0fdcfd --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_aaa.py @@ -0,0 +1,74 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_aaa +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxAAAModule(TestOnyxModule): + + module = onyx_aaa + + def setUp(self): + self.enabled = False + super(TestOnyxAAAModule, self).setUp() + self.mock_get_config = patch.object( + onyx_aaa.OnyxAAAModule, "_show_aaa_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxAAAModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_show_aaa.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_aaa_accounting_no_change(self): + set_module_args(dict(tacacs_accounting_enabled=False)) + self.execute_module(changed=False) + + def test_aaa_accounting_with_change(self): + set_module_args(dict(tacacs_accounting_enabled=True)) + commands = ['aaa accounting changes default stop-only tacacs+'] + self.execute_module(changed=True, commands=commands) + + def test_aaa_auth_default_user_no_change(self): + set_module_args(dict(auth_default_user='admin')) + self.execute_module(changed=False) + + def test_aaa_auth_default_user_with_change(self): + set_module_args(dict(auth_default_user='monitor')) + commands = ['aaa authorization map default-user monitor'] + self.execute_module(changed=True, commands=commands) + + def test_aaa_auth_order_no_change(self): + set_module_args(dict(auth_order='remote-first')) + self.execute_module(changed=False) + + def test_aaa_auth_order_with_change(self): + set_module_args(dict(auth_order='local-only')) + commands = ['aaa authorization map order local-only'] + self.execute_module(changed=True, commands=commands) + + def test_aaa_fallback_no_change(self): + set_module_args(dict(auth_fallback_enabled=True)) + self.execute_module(changed=False) + + def test_aaa_fallback_with_change(self): + set_module_args(dict(auth_fallback_enabled=False)) + commands = ['no aaa authorization map fallback server-err'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_bfd.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_bfd.py new file mode 100644 index 00000000..33f8d2d0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_bfd.py @@ -0,0 +1,114 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_bfd +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxBFDModule(TestOnyxModule): + + module = onyx_bfd + + def setUp(self): + self.enabled = False + super(TestOnyxBFDModule, self).setUp() + self.mock_get_config = patch.object( + onyx_bfd.OnyxBFDModule, "_show_bfd_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxBFDModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_show_bfd.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_bfd_shutdown_no_change(self): + set_module_args(dict(shutdown=True)) + self.execute_module(changed=False) + + def test_bfd_shutdown_with_change(self): + set_module_args(dict(shutdown=False)) + commands = ['no ip bfd shutdown'] + self.execute_module(changed=True, commands=commands) + + def test_vrf_bfd_shutdown_no_change(self): + set_module_args(dict(shutdown=False, + vrf='3')) + self.execute_module(changed=False) + + def test_vrf_bfd_shutdown_with_change(self): + set_module_args(dict(shutdown=True, + vrf='3')) + commands = ['ip bfd shutdown vrf 3'] + self.execute_module(changed=True, commands=commands) + + def test_bfd_interval_no_change(self): + set_module_args(dict(interval_min_rx=50, + interval_multiplier=7, + interval_transmit_rate=55)) + self.execute_module(changed=False) + + def test_bfd_interval_with_change(self): + set_module_args(dict(interval_min_rx=55, + interval_multiplier=7, + interval_transmit_rate=100)) + commands = ['ip bfd interval min-rx 55 multiplier 7 transmit-rate 100 force'] + self.execute_module(changed=True, commands=commands) + + def test_vrf_bfd_interval_no_change(self): + set_module_args(dict(interval_min_rx=50, + interval_multiplier=7, + interval_transmit_rate=55, + vrf='3')) + self.execute_module(changed=False) + + def test_vrf_bfd_interval_with_change(self): + set_module_args(dict(interval_min_rx=55, + interval_multiplier=7, + interval_transmit_rate=100, + vrf='3')) + commands = ['ip bfd vrf 3 interval min-rx 55 multiplier 7 transmit-rate 100 force'] + self.execute_module(changed=True, commands=commands) + + def test_bfd_iproute_no_change(self): + set_module_args(dict(iproute_network_prefix='1.1.1.0', + iproute_mask_length=24, + iproute_next_hop='3.2.2.2')) + self.execute_module(changed=False) + + def test_bfd_iproute_with_change(self): + set_module_args(dict(iproute_network_prefix='1.1.1.0', + iproute_mask_length=24, + iproute_next_hop='3.2.2.3')) + commands = ['ip route 1.1.1.0 /24 3.2.2.3 bfd'] + self.execute_module(changed=True, commands=commands) + + def test_vrf_bfd_iproute_no_change(self): + set_module_args(dict(iproute_network_prefix='1.1.1.0', + iproute_mask_length=24, + iproute_next_hop='3.2.2.2', + vrf='3')) + self.execute_module(changed=False) + + def test_vrf_bfd_iproute_with_change(self): + set_module_args(dict(iproute_network_prefix='1.1.1.0', + iproute_mask_length=24, + iproute_next_hop='3.2.2.3', + vrf='3')) + commands = ['ip route vrf 3 1.1.1.0 /24 3.2.2.3 bfd'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_bgp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_bgp.py new file mode 100644 index 00000000..9f9f1b3a --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_bgp.py @@ -0,0 +1,111 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_bgp +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxBgpModule(TestOnyxModule): + + module = onyx_bgp + + def setUp(self): + super(TestOnyxBgpModule, self).setUp() + self.mock_get_config = patch.object( + onyx_bgp.OnyxBgpModule, "_get_bgp_summary") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxBgpModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_bgp_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_bgp_no_change(self): + neighbor = dict(remote_as=322, neighbor='10.2.3.5', multihop=255) + set_module_args(dict(as_number=172, router_id='1.2.3.4', + neighbors=[neighbor], + networks=['172.16.1.0/24'], + evpn=True, fast_external_fallover=True, + max_paths=31, ecmp_bestpath=True, + )) + self.execute_module(changed=False) + + def test_bgp_remove(self): + set_module_args(dict(as_number=172, state='absent')) + commands = ['no router bgp 172'] + self.execute_module(changed=True, commands=commands) + + def test_bgp_with_vrf_changed(self): + set_module_args(dict(as_number=173, vrf='new_vrf')) + commands = ['no router bgp 172 vrf default', 'router bgp 173 vrf new_vrf', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_bgp_change(self): + neighbor = dict(remote_as=173, neighbor='10.2.3.4') + set_module_args(dict(as_number=174, router_id='1.2.3.4', + neighbors=[neighbor], + evpn=False, fast_external_fallover=False, + max_paths=32, ecmp_bestpath=False, + )) + commands = ['no router bgp 172 vrf default', 'router bgp 174 vrf default', 'exit', + 'router bgp 174 vrf default router-id 1.2.3.4 force', + 'router bgp 174 vrf default neighbor 10.2.3.4 remote-as 173', + 'no router bgp 174 vrf default neighbor evpn peer-group', + 'no router bgp 174 vrf default address-family l2vpn-evpn auto-create', + 'router bgp 174 vrf default no bgp fast-external-fallover', + 'router bgp 174 vrf default maximum-paths 32', + 'router bgp 174 vrf default no bestpath as-path multipath-relax force'] + self.execute_module(changed=True, commands=commands) + + def test_bgp_add_neighbor(self): + neighbors = [dict(remote_as=173, neighbor='10.2.3.4'), + dict(remote_as=175, neighbor='10.2.3.5'), + dict(remote_as=175, neighbor='10.2.3.6', multihop=250)] + set_module_args(dict(as_number=172, router_id='1.2.3.4', + neighbors=neighbors, + networks=['172.16.1.0/24'], + evpn=True)) + commands = ['router bgp 172 vrf default neighbor 10.2.3.5 remote-as 175', + 'router bgp 172 vrf default neighbor 10.2.3.6 remote-as 175', + 'router bgp 172 vrf default neighbor 10.2.3.6 ebgp-multihop 250', + 'router bgp 172 vrf default neighbor 10.2.3.6 peer-group evpn', + 'router bgp 172 vrf default neighbor 10.2.3.4 peer-group evpn'] + self.execute_module(changed=True, commands=commands) + + def test_bgp_del_neighbor(self): + set_module_args(dict(as_number=172, + networks=['172.16.1.0/24'], + purge=True)) + commands = ['router bgp 172 vrf default no neighbor 10.2.3.4 remote-as 173', + 'router bgp 172 vrf default no neighbor 10.2.3.5 remote-as 322'] + self.execute_module(changed=True, commands=commands) + + def test_bgp_add_network(self): + neighbors = [dict(remote_as=173, neighbor='10.2.3.4')] + set_module_args(dict(as_number=172, router_id='1.2.3.4', + neighbors=neighbors, + networks=['172.16.1.0/24', '172.16.2.0/24'])) + commands = ['router bgp 172 vrf default network 172.16.2.0 /24'] + self.execute_module(changed=True, commands=commands) + + def test_bgp_del_network(self): + neighbors = [dict(remote_as=173, neighbor='10.2.3.4')] + set_module_args(dict(as_number=172, neighbors=neighbors)) + commands = ['router bgp 172 no network 172.16.1.0 /24'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_buffer_pool.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_buffer_pool.py new file mode 100644 index 00000000..f69926a3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_buffer_pool.py @@ -0,0 +1,78 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_buffer_pool +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxBufferPoolModule(TestOnyxModule): + + module = onyx_buffer_pool + buffer_pool_configured = False + + def setUp(self): + super(TestOnyxBufferPoolModule, self).setUp() + self.mock_get_buffer_pool_config = patch.object( + onyx_buffer_pool.OnyxBufferPoolModule, "_show_traffic_pool") + self.get_buffer_pool_config = self.mock_get_buffer_pool_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxBufferPoolModule, self).tearDown() + self.mock_get_buffer_pool_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + buffer_pool_config_file = 'onyx_buffer_pool.cfg' + self.get_buffer_pool_config.return_value = None + + if self.buffer_pool_configured is True: + buffer_pool_data = load_fixture(buffer_pool_config_file) + self.get_buffer_pool_config.return_value = buffer_pool_data + + self.load_config.return_value = None + + def test_buffer_pool_no_change(self): + self.buffer_pool_configured = True + set_module_args(dict(name="roce", pool_type="lossless", + memory_percent=50.0, switch_priority=3)) + self.execute_module(changed=False) + + def test_buffer_pool_with_change(self): + set_module_args(dict(name="roce", pool_type="lossless", + memory_percent=50.0, switch_priority=3)) + commands = ["traffic pool roce type lossless", + "traffic pool roce memory percent 50.0", + "traffic pool roce map switch-priority 3" + ] + self.execute_module(changed=True, commands=commands) + + def test_memory_percent_with_change(self): + self.buffer_pool_configured = True + set_module_args(dict(name="roce", pool_type="lossless", + memory_percent=60.0, switch_priority=3)) + commands = ["traffic pool roce memory percent 60.0"] + self.execute_module(changed=True, commands=commands) + + def test_switch_priority_with_change(self): + self.buffer_pool_configured = True + set_module_args(dict(name="roce", pool_type="lossless", + memory_percent=50.0, switch_priority=5)) + commands = ["traffic pool roce map switch-priority 5"] + self.execute_module(changed=True, commands=commands) + + def test_pool_type_with_change(self): + self.buffer_pool_configured = True + set_module_args(dict(name="roce", memory_percent=50.0, switch_priority=3)) + commands = ["traffic pool roce type lossy"] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_command.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_command.py new file mode 100644 index 00000000..da447dd0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_command.py @@ -0,0 +1,114 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_command +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxCommandModule(TestOnyxModule): + + module = onyx_command + + def setUp(self): + super(TestOnyxCommandModule, self).setUp() + self.mock_run_commands = patch( + 'ansible_collections.mellanox.onyx.plugins.modules.onyx_command.run_commands') + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestOnyxCommandModule, self).tearDown() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None, transport='cli'): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for item in commands: + try: + obj = json.loads(item['command']) + command = obj['command'] + except ValueError: + command = item['command'] + filename = str(command).replace(' ', '_') + filename = 'onyx_command_%s.txt' % filename + output.append(load_fixture(filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_onyx_command_simple(self): + set_module_args(dict(commands=['show version'])) + result = self.execute_module() + self.assertEqual(len(result['stdout']), 1) + self.assertTrue(result['stdout'][0].startswith('Product name')) + + def test_onyx_command_multiple(self): + set_module_args(dict(commands=['show version', 'show version'])) + result = self.execute_module() + self.assertEqual(len(result['stdout']), 2) + self.assertTrue(result['stdout'][0].startswith('Product name')) + + def test_onyx_command_wait_for(self): + wait_for = 'result[0] contains "MLNX"' + set_module_args(dict(commands=['show version'], wait_for=wait_for)) + self.execute_module() + + def test_onyx_command_wait_for_fails(self): + wait_for = 'result[0] contains "test string"' + set_module_args(dict(commands=['show version'], wait_for=wait_for)) + self.execute_module(failed=True) + self.assertEqual(self.run_commands.call_count, 10) + + def test_onyx_command_retries(self): + wait_for = 'result[0] contains "test string"' + set_module_args( + dict(commands=['show version'], wait_for=wait_for, retries=2)) + self.execute_module(failed=True) + self.assertEqual(self.run_commands.call_count, 2) + + def test_onyx_command_match_any(self): + wait_for = ['result[0] contains "MLNX"', + 'result[0] contains "test string"'] + set_module_args(dict( + commands=['show version'], + wait_for=wait_for, + match='any')) + self.execute_module() + + def test_onyx_command_match_all(self): + wait_for = ['result[0] contains "MLNX"', + 'result[0] contains "Version summary"'] + set_module_args( + dict(commands=['show version'], wait_for=wait_for, match='all')) + self.execute_module() + + def test_onyx_command_match_all_failure(self): + wait_for = ['result[0] contains "MLNX"', + 'result[0] contains "test string"'] + commands = ['show version', 'show version'] + set_module_args( + dict(commands=commands, wait_for=wait_for, match='all')) + self.execute_module(failed=True) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_config.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_config.py new file mode 100644 index 00000000..f118eb07 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_config.py @@ -0,0 +1,113 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_config +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxConfigModule(TestOnyxModule): + + module = onyx_config + + def setUp(self): + super(TestOnyxConfigModule, self).setUp() + + self.mock_get_config = patch('ansible_collections.mellanox.onyx.plugins.modules.onyx_config.get_config') + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch('ansible_collections.mellanox.onyx.plugins.modules.onyx_config.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_run_commands = patch('ansible_collections.mellanox.onyx.plugins.modules.onyx_config.run_commands') + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestOnyxConfigModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_config_config.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_onyx_config_unchanged(self): + src = load_fixture('onyx_config_config.cfg') + set_module_args(dict(src=src)) + self.execute_module() + + def test_onyx_config_src(self): + src = load_fixture('onyx_config_src.cfg') + set_module_args(dict(src=src)) + commands = [ + 'interface mlag-port-channel 2'] + self.execute_module(changed=True, commands=commands, is_updates=True) + + def test_onyx_config_backup(self): + set_module_args(dict(backup=True)) + result = self.execute_module() + self.assertIn('__backup__', result) + + def test_onyx_config_save(self): + set_module_args(dict(lines=['hostname foo'], save='yes')) + self.execute_module(changed=True) + self.assertEqual(self.run_commands.call_count, 0) + self.assertEqual(self.get_config.call_count, 1) + self.assertEqual(self.load_config.call_count, 1) + args = self.load_config.call_args[0][1] + self.assertIn('configuration write', args) + + def test_onyx_config_lines_wo_parents(self): + set_module_args(dict(lines=['hostname foo'])) + commands = ['hostname foo'] + self.execute_module(changed=True, commands=commands, is_updates=True) + + def test_onyx_config_before(self): + set_module_args(dict(lines=['hostname foo'], before=['test1', 'test2'])) + commands = ['test1', 'test2', 'hostname foo'] + self.execute_module(changed=True, commands=commands, sort=False, is_updates=True) + + def test_onyx_config_after(self): + set_module_args(dict(lines=['hostname foo'], after=['test1', 'test2'])) + commands = ['hostname foo', 'test1', 'test2'] + self.execute_module(changed=True, commands=commands, sort=False, is_updates=True) + + def test_onyx_config_before_after(self): + set_module_args(dict(lines=['hostname foo'], + before=['test1', 'test2'], + after=['test3', 'test4'])) + commands = ['test1', 'test2', 'hostname foo', 'test3', 'test4'] + self.execute_module(changed=True, commands=commands, sort=False, is_updates=True) + + def test_onyx_config_config(self): + config = 'hostname localhost' + set_module_args(dict(lines=['hostname router'], config=config)) + commands = ['hostname router'] + self.execute_module(changed=True, commands=commands, is_updates=True) + + def test_onyx_config_match_none(self): + lines = ['hostname router'] + set_module_args(dict(lines=lines, match='none')) + self.execute_module(changed=True, commands=lines, is_updates=True) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_facts.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_facts.py new file mode 100644 index 00000000..bb0d4402 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_facts.py @@ -0,0 +1,71 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture +from ansible_collections.mellanox.onyx.plugins.modules import onyx_facts + + +class TestOnyxFacts(TestOnyxModule): + + module = onyx_facts + + def setUp(self): + super(TestOnyxFacts, self).setUp() + + self.mock_run_command = patch.object( + onyx_facts.FactsBase, "_show_cmd") + self.run_command = self.mock_run_command.start() + + def tearDown(self): + super(TestOnyxFacts, self).tearDown() + + self.mock_run_command.stop() + + def load_fixtures(self, commands=None, transport=None): + + def load_from_file(*args, **kwargs): + command = args[0] + filename = "onyx_facts_%s.cfg" % command + filename = filename.replace(' ', '_') + filename = filename.replace('/', '7') + output = load_fixture(filename) + return output + + self.run_command.side_effect = load_from_file + + def test_onyx_facts_version(self): + set_module_args(dict(gather_subset='version')) + result = self.execute_module() + facts = result.get('ansible_facts') + self.assertEqual(len(facts), 2) + version = facts['ansible_net_version'] + self.assertEqual(version['Product name'], 'MLNX-OS') + + def test_onyx_facts_modules(self): + set_module_args(dict(gather_subset='modules')) + result = self.execute_module() + facts = result.get('ansible_facts') + self.assertEqual(len(facts), 2) + modules = facts['ansible_net_modules'] + self.assertIn("MGMT", modules) + + def test_onyx_facts_interfaces(self): + set_module_args(dict(gather_subset='interfaces')) + result = self.execute_module() + facts = result.get('ansible_facts') + self.assertEqual(len(facts), 2) + interfaces = facts['ansible_net_interfaces'] + self.assertEqual(len(interfaces), 2) + + def test_onyx_facts_all(self): + set_module_args(dict(gather_subset='all')) + result = self.execute_module() + facts = result.get('ansible_facts') + self.assertEqual(len(facts), 4) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp.py new file mode 100644 index 00000000..153b3359 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp.py @@ -0,0 +1,127 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_igmp +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxIgmpModule(TestOnyxModule): + + module = onyx_igmp + enabled = False + + def setUp(self): + self.enabled = False + super(TestOnyxIgmpModule, self).setUp() + self.mock_get_config = patch.object( + onyx_igmp.OnyxIgmpModule, "_show_igmp") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxIgmpModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_igmp_show.cfg' + data = load_fixture(config_file) + if self.enabled: + data[0]['IGMP snooping globally'] = 'enabled' + self.get_config.return_value = data + self.load_config.return_value = None + + def test_igmp_no_change(self): + set_module_args(dict(state='disabled')) + self.execute_module(changed=False) + + def test_igmp_enable(self): + set_module_args(dict(state='enabled')) + commands = ['ip igmp snooping'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_last_member_query_interval(self): + set_module_args(dict(state='enabled', + last_member_query_interval=10)) + commands = ['ip igmp snooping', + 'ip igmp snooping last-member-query-interval 10'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_mrouter_timeout(self): + set_module_args(dict(state='enabled', + mrouter_timeout=100)) + commands = ['ip igmp snooping', + 'ip igmp snooping mrouter-timeout 100'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_port_purge_timeout(self): + set_module_args(dict(state='enabled', + port_purge_timeout=150)) + commands = ['ip igmp snooping', + 'ip igmp snooping port-purge-timeout 150'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_report_suppression_interval(self): + set_module_args(dict(state='enabled', + report_suppression_interval=10)) + commands = ['ip igmp snooping', + 'ip igmp snooping report-suppression-interval 10'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_proxy_reporting_disabled(self): + set_module_args(dict(state='enabled', + proxy_reporting='disabled')) + commands = ['ip igmp snooping'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_proxy_reporting_enabled(self): + set_module_args(dict(state='enabled', + proxy_reporting='enabled')) + commands = ['ip igmp snooping', + 'ip igmp snooping proxy reporting'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_unregistered_multicast_flood(self): + set_module_args(dict(state='enabled', + unregistered_multicast='flood')) + commands = ['ip igmp snooping'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_unregistered_multicast_forward(self): + set_module_args( + dict(state='enabled', + unregistered_multicast='forward-to-mrouter-ports')) + commands = [ + 'ip igmp snooping', + 'ip igmp snooping unregistered multicast forward-to-mrouter-ports' + ] + self.execute_module(changed=True, commands=commands) + + def test_igmp_version_v2(self): + set_module_args(dict(state='enabled', + default_version='V2')) + commands = ['ip igmp snooping', + 'ip igmp snooping version 2'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_version_v3(self): + set_module_args(dict(state='enabled', + default_version='V3')) + commands = ['ip igmp snooping'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_disable(self): + self.enabled = True + set_module_args(dict(state='disabled')) + commands = ['no ip igmp snooping'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp_interface.py new file mode 100644 index 00000000..f3cab2bf --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp_interface.py @@ -0,0 +1,69 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_igmp_interface +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxIgmpInterfaceModule(TestOnyxModule): + + module = onyx_igmp_interface + + def setUp(self): + super(TestOnyxIgmpInterfaceModule, self).setUp() + + self.mock_get_config = patch.object(onyx_igmp_interface.OnyxIgmpInterfaceModule, "_show_igmp_interfaces") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxIgmpInterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_show_igmp_interfaces.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_igmp_interface_enabled_no_change(self): + set_module_args(dict(state='enabled', name='Eth1/3')) + self.execute_module(changed=False) + + def test_igmp_interface_enabled_change(self): + set_module_args(dict(state='enabled', name='Eth1/1')) + commands = ['interface ethernet 1/1 ip igmp snooping fast-leave'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_interface_disabled_no_change(self): + set_module_args(dict(state='disabled', name='Eth1/1')) + self.execute_module(changed=False) + + def test_igmp_interface_disabled_change(self): + set_module_args(dict(state='disabled', name='Eth1/3')) + commands = ['interface ethernet 1/3 no ip igmp snooping fast-leave'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp_vlan.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp_vlan.py new file mode 100644 index 00000000..f535e95e --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_igmp_vlan.py @@ -0,0 +1,190 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_igmp_vlan +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxIgmpVlan(TestOnyxModule): + + module = onyx_igmp_vlan + enabled = False + mrouter_state = False + querier_state = False + static_groups_enabled = False + + def setUp(self): + self.enabled = False + super(TestOnyxIgmpVlan, self).setUp() + self.mock_get_igmp_config = patch.object( + onyx_igmp_vlan.OnyxIgmpVlanModule, "_show_igmp_vlan") + self.get_igmp_config = self.mock_get_igmp_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_igmp_guerier_config = patch.object( + onyx_igmp_vlan.OnyxIgmpVlanModule, "_show_igmp_querier_config") + self.get_igmp_guerier_config = self.mock_get_igmp_guerier_config.start() + + self.mock_get_igmp_static_groups_config = patch.object( + onyx_igmp_vlan.OnyxIgmpVlanModule, "_show_igmp_snooping_groups_config") + self.get_igmp_static_groups_config = self.mock_get_igmp_static_groups_config.start() + + def tearDown(self): + super(TestOnyxIgmpVlan, self).tearDown() + self.mock_get_igmp_config.stop() + self.mock_load_config.stop() + self.mock_get_igmp_guerier_config.stop() + self.mock_get_igmp_static_groups_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + igmp_vlan_config_file = 'onyx_show_ip_igmp_snooping.cfg' + igmp_querier_config_file = 'onyx_show_ip_igmp_snooping_querier.cfg' + igmp_static_groups_file = 'onyx_show_ip_igmp_snooping_groups.cfg' + igmp_vlan_data = load_fixture(igmp_vlan_config_file) + igmp_querier_data = load_fixture(igmp_querier_config_file) + igmp_static_groups_data = None + if self.enabled: + igmp_vlan_data[0]['message 1'] = 'IGMP snooping is enabled' + + if self.querier_state: + igmp_vlan_data[0]['message 3'] = 'Snooping switch is acting as Querier' + + if self.mrouter_state: + igmp_vlan_data[0]['mrouter static port list'] = 'Eth1/1' + + if self.static_groups_enabled: + igmp_static_groups_data = load_fixture(igmp_static_groups_file) + + self.get_igmp_config.return_value = igmp_vlan_data + self.get_igmp_guerier_config = igmp_querier_data + self.get_igmp_static_groups_config = igmp_static_groups_data + self.load_config.return_value = None + + def test_igmp_disabled_no_change(self): + set_module_args(dict(state='disabled', vlan_id=10)) + self.execute_module(changed=False) + + def test_igmp_disabled_with_change(self): + self.enabled = True + set_module_args(dict(state='disabled', vlan_id=10)) + commands = ['vlan 10 no ip igmp snooping'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_enabled_no_change(self): + self.enabled = True + set_module_args(dict(state='enabled', vlan_id=10)) + self.execute_module(changed=False) + + def test_igmp_enabled_with_change(self): + set_module_args(dict(state='enabled', vlan_id=10)) + commands = ['vlan 10 ip igmp snooping'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_mrouter_disabled_no_change(self): + self.enabled = True + set_module_args(dict(vlan_id=10, mrouter=dict(state='disabled', name='Eth1/1'))) + self.execute_module(changed=False) + + def test_igmp_mrouter_disabled_with_change(self): + self.enabled = True + self.mrouter_state = True + set_module_args(dict(vlan_id=10, mrouter=dict(state='disabled', name='Eth1/1'))) + commands = ['vlan 10 no ip igmp snooping mrouter interface ethernet 1/1'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_mrouter_enabled_no_change(self): + self.enabled = True + self.mrouter_state = True + set_module_args(dict(vlan_id=10, mrouter=dict(state='enabled', name='Eth1/1'))) + self.execute_module(changed=False) + + def test_igmp_mrouter_enabled_with_change(self): + self.enabled = True + set_module_args(dict(vlan_id=10, mrouter=dict(state='enabled', name='Eth1/1'))) + commands = ['vlan 10 ip igmp snooping mrouter interface ethernet 1/1'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_mrouter_enabled_withinterface_change(self): + self.enabled = True + self.mrouter_state = True + set_module_args(dict(vlan_id=10, mrouter=dict(state='enabled', name='Eth1/2'))) + commands = ['vlan 10 ip igmp snooping mrouter interface ethernet 1/2'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_querier_disabled_no_change(self): + self.enabled = True + set_module_args(dict(vlan_id=10, querier=dict(state='disabled'))) + self.execute_module(changed=False) + + def test_igmp_querier_disabled_with_change(self): + self.enabled = True + self.querier_state = True + set_module_args(dict(vlan_id=10, querier=dict(state='disabled'))) + commands = ['vlan 10 no ip igmp snooping querier'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_querier_enabled_no_change(self): + self.enabled = True + self.querier_state = True + set_module_args(dict(vlan_id=10, querier=dict(state='enabled'))) + self.execute_module(changed=False) + + def test_igmp_querier_enabled_with_change(self): + self.enabled = True + set_module_args(dict(vlan_id=10, querier=dict(state='enabled'))) + commands = ['vlan 10 ip igmp snooping querier'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_querier_attr_no_change(self): + self.enabled = True + self.querier_state = True + set_module_args(dict(vlan_id=10, querier=dict(state='enabled', interval=125, address='-'))) + self.execute_module(changed=True) + + def test_igmp_querier_attr_with_change(self): + self.enabled = True + self.querier_state = True + set_module_args(dict(vlan_id=10, querier=dict(state='enabled', interval=127, address='10.10.10.1'))) + commands = ['vlan 10 ip igmp snooping querier query-interval 127', + 'vlan 10 ip igmp snooping querier address 10.10.10.1'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_version_no_change(self): + self.enabled = True + set_module_args(dict(vlan_id=10, version='V3')) + self.execute_module(changed=False) + + def test_igmp_version_with_change(self): + self.enabled = True + set_module_args(dict(vlan_id=10, version='V2')) + commands = ['vlan 10 ip igmp snooping version 2'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_static_groups_multicast_ip_address_not_configured(self): + self.enabled = True + set_module_args(dict(vlan_id=10, static_groups=[dict(multicast_ip_address='224.5.5.2', name='Eth1/1', + sources=["1.1.1.2", "1.1.1.3"])])) + commands = ['vlan 10 ip igmp snooping static-group 224.5.5.2 interface ethernet 1/1', + 'vlan 10 ip igmp snooping static-group 224.5.5.2 interface ethernet 1/1 source 1.1.1.2', + 'vlan 10 ip igmp snooping static-group 224.5.5.2 interface ethernet 1/1 source 1.1.1.3'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_static_groups_multicast_ip_address_configured_with_change(self): + self.enabled = True + self.static_groups_enabled = True + set_module_args(dict(vlan_id=10, static_groups=[dict(multicast_ip_address='224.5.5.1', name='Eth1/3', + sources=["1.1.1.1", "1.1.1.2"])])) + commands = ['vlan 10 ip igmp snooping static-group 224.5.5.1 interface ethernet 1/3', + 'vlan 10 ip igmp snooping static-group 224.5.5.1 interface ethernet 1/3 source 1.1.1.1', + 'vlan 10 ip igmp snooping static-group 224.5.5.1 interface ethernet 1/3 source 1.1.1.2'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_interface.py new file mode 100644 index 00000000..a0a7f128 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_interface.py @@ -0,0 +1,125 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_interface +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxInterfaceModule(TestOnyxModule): + + module = onyx_interface + + def setUp(self): + super(TestOnyxInterfaceModule, self).setUp() + self.mock_get_config = patch.object( + onyx_interface.OnyxInterfaceModule, "_get_interfaces_config") + self.get_config = self.mock_get_config.start() + + self.mock_get_interfaces_status = patch.object( + onyx_interface.OnyxInterfaceModule, "_get_interfaces_status") + self.get_interfaces_status = self.mock_get_interfaces_status.start() + + self.mock_get_interfaces_rates = patch.object( + onyx_interface.OnyxInterfaceModule, "_get_interfaces_rates") + self.get_interfaces_rates = self.mock_get_interfaces_rates.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_version = patch.object( + onyx_interface.OnyxInterfaceModule, "_get_os_version") + self.get_version = self.mock_get_version.start() + + def tearDown(self): + super(TestOnyxInterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_interfaces_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_version.return_value = "3.6.5000" + + def test_mtu_no_change(self): + set_module_args(dict(name='Eth1/1', mtu=1500)) + self.execute_module(changed=False) + + def test_mtu_change(self): + set_module_args(dict(name='Eth1/1', mtu=1522)) + commands = ['interface ethernet 1/1', 'mtu 1522 force', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_speed_no_change(self): + set_module_args(dict(name='Eth1/1', speed='40G')) + self.execute_module(changed=False) + + def test_speed_change(self): + set_module_args(dict(name='Eth1/1', speed='100G')) + commands = ['interface ethernet 1/1', 'speed 100G force', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_mtu_speed_change(self): + set_module_args(dict(name='Eth1/1', speed='100G', mtu=1522)) + commands = ['interface ethernet 1/1', 'speed 100G force', + 'mtu 1522 force', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_admin_state_no_change(self): + set_module_args(dict(name='Eth1/1', enabled=True)) + self.execute_module(changed=False) + + def test_admin_state_change(self): + set_module_args(dict(name='Eth1/1', enabled=False)) + commands = ['interface ethernet 1/1', 'shutdown', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_add_loopback_if(self): + set_module_args(dict(name='Loopback 1', description='Loopback test')) + commands = ['interface loopback 1', 'description Loopback test', + 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_add_vlan_if(self): + set_module_args(dict(name='Vlan 101', description='Vlan test', + enabled=True)) + commands = ['interface vlan 101', 'description Vlan test', + 'no shutdown', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_remove_vlan_if(self): + set_module_args(dict(name='Vlan 1002', state='absent')) + commands = ['no interface vlan 1002'] + self.execute_module(changed=True, commands=commands) + + def test_oper_state_check(self): + set_module_args(dict(name='Eth1/1', enabled=True, state='down')) + config_file = 'onyx_interfaces_status.cfg' + self.get_interfaces_status.return_value = load_fixture(config_file) + self.execute_module(changed=False) + + def test_vlan_oper_state_check(self): + set_module_args(dict(name='Vlan 1002', state='down')) + config_file = 'onyx_interfaces_status.cfg' + self.get_interfaces_status.return_value = load_fixture(config_file) + self.execute_module(changed=False) + + def test_rx_rate_check(self): + set_module_args(dict(name='Eth1/1', enabled=True, rx_rate='ge(9000)')) + config_file = 'onyx_interfaces_rates.cfg' + self.get_interfaces_rates.return_value = load_fixture(config_file) + self.execute_module(changed=False) + + def test_tx_rate_check(self): + set_module_args(dict(name='Eth1/1', enabled=True, tx_rate='ge(10000)')) + config_file = 'onyx_interfaces_rates.cfg' + self.get_interfaces_rates.return_value = load_fixture(config_file) + self.execute_module(changed=False) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_l2_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_l2_interface.py new file mode 100644 index 00000000..7c49fb0c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_l2_interface.py @@ -0,0 +1,119 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_l2_interface +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxInterfaceModule(TestOnyxModule): + + module = onyx_l2_interface + + def setUp(self): + super(TestOnyxInterfaceModule, self).setUp() + self.mock_get_config = patch.object( + onyx_l2_interface.OnyxL2InterfaceModule, "_get_switchport_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_version = patch.object( + onyx_l2_interface.OnyxL2InterfaceModule, "_get_os_version") + self.get_version = self.mock_get_version.start() + + def tearDown(self): + super(TestOnyxInterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_l2_interface_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_version.return_value = "3.6.5000" + + def test_access_vlan_no_change(self): + set_module_args(dict(name='Eth1/11', access_vlan=1)) + self.execute_module(changed=False) + + def test_trunk_vlans_no_change(self): + set_module_args(dict(name='Eth1/10', mode='hybrid', access_vlan=1, + trunk_allowed_vlans=[10])) + self.execute_module(changed=False) + + def test_access_vlan_change(self): + set_module_args(dict(name='Eth1/11', access_vlan=10)) + commands = ['interface ethernet 1/11', 'switchport access vlan 10', + 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_trunk_vlan_change(self): + set_module_args(dict(name='Eth1/10', mode='hybrid', access_vlan=1, + trunk_allowed_vlans=[11])) + commands = ['interface ethernet 1/10', + 'switchport hybrid allowed-vlan remove 10', + 'switchport hybrid allowed-vlan add 11', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_trunk_vlan_add(self): + set_module_args(dict(name='Eth1/10', mode='hybrid', access_vlan=1, + trunk_allowed_vlans=[10, 11])) + commands = ['interface ethernet 1/10', + 'switchport hybrid allowed-vlan add 11', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_switch_port_access(self): + set_module_args(dict(name='Eth1/12', mode='access', access_vlan=11)) + commands = ['interface ethernet 1/12', 'switchport mode access', + 'switchport access vlan 11', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_switch_port_trunk(self): + set_module_args(dict(name='Eth1/12', mode='trunk', + trunk_allowed_vlans=[11])) + commands = ['interface ethernet 1/12', 'switchport mode trunk', + 'switchport trunk allowed-vlan add 11', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_switch_port_hybrid(self): + set_module_args(dict(name='Eth1/12', mode='hybrid', access_vlan=10, + trunk_allowed_vlans=[11])) + commands = ['interface ethernet 1/12', 'switchport mode hybrid', + 'switchport access vlan 10', + 'switchport hybrid allowed-vlan add 11', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_aggregate(self): + aggregate = list() + aggregate.append(dict(name='Eth1/10')) + aggregate.append(dict(name='Eth1/12')) + + set_module_args(dict(aggregate=aggregate, access_vlan=10)) + commands = ['interface ethernet 1/10', 'switchport mode access', + 'switchport access vlan 10', 'exit', + 'interface ethernet 1/12', 'switchport mode access', + 'switchport access vlan 10', 'exit'] + self.execute_module(changed=True, commands=commands, sort=False) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_l3_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_l3_interface.py new file mode 100644 index 00000000..bab8c3b7 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_l3_interface.py @@ -0,0 +1,113 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_l3_interface +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxL3InterfaceModule(TestOnyxModule): + + module = onyx_l3_interface + + def setUp(self): + super(TestOnyxL3InterfaceModule, self).setUp() + self.mock_get_config = patch.object( + onyx_l3_interface.OnyxL3InterfaceModule, + "_get_interfaces_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_version = patch.object( + onyx_l3_interface.OnyxL3InterfaceModule, "_get_os_version") + self.get_version = self.mock_get_version.start() + + def tearDown(self): + super(TestOnyxL3InterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def _execute_module(self, failed=False, changed=False, commands=None, sort=True): + if failed: + result = self.failed() + self.assertTrue(result['failed'], result) + else: + result = self.changed(changed) + self.assertEqual(result['changed'], changed, result) + + if commands is not None: + commands_res = result.get('commands') + if sort: + self.assertEqual(sorted(commands), sorted(commands_res), commands_res) + else: + self.assertEqual(commands, commands_res, commands_res) + + return result + + def load_fixture(self, config_file): + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_version.return_value = "3.6.5000" + + def load_eth_ifc_fixture(self): + config_file = 'onyx_l3_interface_show.cfg' + self.load_fixture(config_file) + + def load_vlan_ifc_fixture(self): + config_file = 'onyx_l3_vlan_interface_show.cfg' + self.load_fixture(config_file) + + def test_vlan_ifc_no_change(self): + set_module_args(dict(name='Vlan 1002', state='present', + ipv4='172.3.12.4/24')) + self.load_vlan_ifc_fixture() + self._execute_module(changed=False) + + def test_vlan_ifc_remove(self): + set_module_args(dict(name='Vlan 1002', state='absent')) + commands = ['interface vlan 1002 no ip address'] + self.load_vlan_ifc_fixture() + self._execute_module(changed=True, commands=commands) + + def test_vlan_ifc_update(self): + set_module_args(dict(name='Vlan 1002', state='present', + ipv4='172.3.13.4/24')) + commands = ['interface vlan 1002 ip address 172.3.13.4/24'] + self.load_vlan_ifc_fixture() + self._execute_module(changed=True, commands=commands) + + def test_eth_ifc_no_change(self): + set_module_args(dict(name='Eth1/5', state='present', + ipv4='172.3.12.4/24')) + self.load_eth_ifc_fixture() + self._execute_module(changed=False) + + def test_eth_ifc_remove(self): + set_module_args(dict(name='Eth1/5', state='absent')) + commands = ['interface ethernet 1/5 no ip address'] + self.load_eth_ifc_fixture() + self._execute_module(changed=True, commands=commands) + + def test_eth_ifc_update(self): + set_module_args(dict(name='Eth1/5', state='present', + ipv4='172.3.13.4/24')) + commands = ['interface ethernet 1/5 ip address 172.3.13.4/24'] + self.load_eth_ifc_fixture() + self._execute_module(changed=True, commands=commands) + + def test_eth_ifc_add_ip(self): + set_module_args(dict(name='Eth1/6', state='present', + ipv4='172.3.14.4/24')) + commands = ['interface ethernet 1/6 no switchport force', + 'interface ethernet 1/6 ip address 172.3.14.4/24'] + self.load_eth_ifc_fixture() + self._execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_linkagg.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_linkagg.py new file mode 100644 index 00000000..dc54698b --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_linkagg.py @@ -0,0 +1,116 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_linkagg +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxLinkaggModule(TestOnyxModule): + + module = onyx_linkagg + + def setUp(self): + super(TestOnyxLinkaggModule, self).setUp() + self.mock_get_config = patch.object( + onyx_linkagg.OnyxLinkAggModule, + "_get_port_channels") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + self.mock_get_version = patch.object( + onyx_linkagg.OnyxLinkAggModule, "_get_os_version") + self.get_version = self.mock_get_version.start() + + def tearDown(self): + super(TestOnyxLinkaggModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_get_version.stop() + + def load_fixture(self, config_file): + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_version.return_value = "3.6.5000" + + def load_port_channel_fixture(self): + config_file = 'onyx_port_channel_show.cfg' + self.load_fixture(config_file) + + def load_mlag_port_channel_fixture(self): + config_file = 'onyx_mlag_port_channel_show.cfg' + self.load_fixture(config_file) + + def test_port_channel_no_change(self): + set_module_args(dict(name='Po22', state='present', + members=['Eth1/7'])) + self.load_port_channel_fixture() + self.execute_module(changed=False) + + def test_port_channel_remove(self): + set_module_args(dict(name='Po22', state='absent')) + self.load_port_channel_fixture() + commands = ['no interface port-channel 22'] + self.execute_module(changed=True, commands=commands) + + def test_port_channel_add(self): + set_module_args(dict(name='Po23', state='present', + members=['Eth1/8'])) + self.load_port_channel_fixture() + commands = ['interface port-channel 23', 'exit', + 'interface ethernet 1/8 channel-group 23 mode on'] + self.execute_module(changed=True, commands=commands) + + def test_port_channel_add_member(self): + set_module_args(dict(name='Po22', state='present', + members=['Eth1/7', 'Eth1/8'])) + self.load_port_channel_fixture() + commands = ['interface ethernet 1/8 channel-group 22 mode on'] + self.execute_module(changed=True, commands=commands) + + def test_port_channel_remove_member(self): + set_module_args(dict(name='Po22', state='present')) + self.load_port_channel_fixture() + commands = ['interface ethernet 1/7 no channel-group'] + self.execute_module(changed=True, commands=commands) + + def test_mlag_port_channel_no_change(self): + set_module_args(dict(name='Mpo33', state='present', + members=['Eth1/8'])) + self.load_mlag_port_channel_fixture() + self.execute_module(changed=False) + + def test_mlag_port_channel_remove(self): + set_module_args(dict(name='Mpo33', state='absent')) + self.load_mlag_port_channel_fixture() + commands = ['no interface mlag-port-channel 33'] + self.execute_module(changed=True, commands=commands) + + def test_mlag_port_channel_add(self): + set_module_args(dict(name='Mpo34', state='present', + members=['Eth1/9'])) + self.load_mlag_port_channel_fixture() + commands = ['interface mlag-port-channel 34', 'exit', + 'interface ethernet 1/9 mlag-channel-group 34 mode on'] + self.execute_module(changed=True, commands=commands) + + def test_mlag_port_channel_add_member(self): + set_module_args(dict(name='Mpo33', state='present', + members=['Eth1/8', 'Eth1/9'])) + self.load_mlag_port_channel_fixture() + commands = ['interface ethernet 1/9 mlag-channel-group 33 mode on'] + self.execute_module(changed=True, commands=commands) + + def test_mlag_port_channel_remove_member(self): + set_module_args(dict(name='Mpo33', state='present')) + self.load_mlag_port_channel_fixture() + commands = ['interface ethernet 1/8 no mlag-channel-group'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_lldp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_lldp.py new file mode 100644 index 00000000..e0c1bc0c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_lldp.py @@ -0,0 +1,68 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_lldp +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxInterfaceModule(TestOnyxModule): + + module = onyx_lldp + + def setUp(self): + super(TestOnyxInterfaceModule, self).setUp() + self.mock_get_config = patch.object( + onyx_lldp.OnyxLldpModule, "_get_lldp_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxInterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + if commands == ['lldp']: + self.get_config.return_value = None + else: + config_file = 'onyx_lldp_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_lldp_no_change(self): + set_module_args(dict()) + self.execute_module(changed=False) + + def test_lldp_disable(self): + set_module_args(dict(state='absent')) + commands = ['no lldp'] + self.execute_module(changed=True, commands=commands) + + def test_lldp_enable(self): + set_module_args(dict(state='present')) + commands = ['lldp'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_lldp_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_lldp_interface.py new file mode 100644 index 00000000..934c4e64 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_lldp_interface.py @@ -0,0 +1,76 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_lldp_interface +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxLldpInterfaceModule(TestOnyxModule): + + module = onyx_lldp_interface + + def setUp(self): + super(TestOnyxLldpInterfaceModule, self).setUp() + self.mock_get_config = patch.object( + onyx_lldp_interface.OnyxLldpInterfaceModule, + "_get_lldp_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxLldpInterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_lldp_interface_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_lldp_no_change(self): + set_module_args(dict(name='Eth1/1', state='present')) + self.execute_module(changed=False) + + def test_no_lldp_no_change(self): + set_module_args(dict(name='Eth1/2', state='absent')) + self.execute_module(changed=False) + + def test_no_lldp_change(self): + set_module_args(dict(name='Eth1/2', state='present')) + commands = ['interface ethernet 1/2 lldp receive', + 'interface ethernet 1/2 lldp transmit'] + self.execute_module(changed=True, commands=commands) + + def test_lldp_change(self): + set_module_args(dict(name='Eth1/1', state='absent')) + commands = ['interface ethernet 1/1 no lldp receive', + 'interface ethernet 1/1 no lldp transmit'] + self.execute_module(changed=True, commands=commands) + + def test_lldp_aggregate(self): + aggregate = [dict(name='Eth1/1'), dict(name='Eth1/2')] + set_module_args(dict(aggregate=aggregate, state='present')) + commands = ['interface ethernet 1/2 lldp receive', + 'interface ethernet 1/2 lldp transmit'] + self.execute_module(changed=True, commands=commands) + + def test_lldp_aggregate_purge(self): + aggregate = [dict(name='Eth1/3'), dict(name='Eth1/2')] + set_module_args(dict(aggregate=aggregate, state='present', purge=True)) + commands = ['interface ethernet 1/2 lldp receive', + 'interface ethernet 1/2 lldp transmit', + 'interface ethernet 1/3 lldp receive', + 'interface ethernet 1/3 lldp transmit', + 'interface ethernet 1/1 no lldp receive', + 'interface ethernet 1/1 no lldp transmit'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_magp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_magp.py new file mode 100644 index 00000000..4745af58 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_magp.py @@ -0,0 +1,110 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_magp +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxMagpModule(TestOnyxModule): + + module = onyx_magp + + def setUp(self): + super(TestOnyxMagpModule, self).setUp() + self.mock_get_config = patch.object( + onyx_magp.OnyxMagpModule, + "_get_magp_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_version = patch.object(onyx_magp.OnyxMagpModule, + "_get_os_version") + self.get_version = self.mock_get_version.start() + + def tearDown(self): + super(TestOnyxMagpModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_get_version.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_magp_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_version.return_value = "3.6.5000" + + def test_magp_absent_no_change(self): + set_module_args(dict(interface='Vlan 1002', magp_id=110, + state='absent')) + self.execute_module(changed=False) + + def test_magp_no_change(self): + set_module_args(dict(interface='Vlan 1200', magp_id=103, + state='disabled')) + self.execute_module(changed=False) + + def test_magp_present_no_change(self): + set_module_args(dict(interface='Vlan 1200', magp_id=103)) + self.execute_module(changed=False) + + def test_magp_enable(self): + set_module_args(dict(interface='Vlan 1200', magp_id=103, + state='enabled')) + commands = ['interface vlan 1200 magp 103 no shutdown'] + self.execute_module(changed=True, commands=commands) + + def test_magp_disable(self): + set_module_args(dict(interface='Vlan 1243', magp_id=102, + state='disabled', router_ip='10.0.0.43', + router_mac='01:02:03:04:05:06')) + commands = ['interface vlan 1243 magp 102 shutdown'] + self.execute_module(changed=True, commands=commands) + + def test_magp_change_address(self): + set_module_args(dict(interface='Vlan 1243', magp_id=102, + router_ip='10.0.0.44', + router_mac='01:02:03:04:05:07')) + commands = [ + 'interface vlan 1243 magp 102 ip virtual-router address 10.0.0.44', + 'interface vlan 1243 magp 102 ip virtual-router mac-address 01:02:03:04:05:07'] + self.execute_module(changed=True, commands=commands) + + def test_magp_remove_address(self): + set_module_args(dict(interface='Vlan 1243', magp_id=102)) + commands = [ + 'interface vlan 1243 magp 102 no ip virtual-router address', + 'interface vlan 1243 magp 102 no ip virtual-router mac-address'] + self.execute_module(changed=True, commands=commands) + + def test_magp_add(self): + set_module_args(dict(interface='Vlan 1244', magp_id=104, + router_ip='10.0.0.44', + router_mac='01:02:03:04:05:07')) + commands = [ + 'interface vlan 1244 magp 104', + 'exit', + 'interface vlan 1244 magp 104 ip virtual-router address 10.0.0.44', + 'interface vlan 1244 magp 104 ip virtual-router mac-address 01:02:03:04:05:07'] + self.execute_module(changed=True, commands=commands, sort=False) + + def test_magp_change_vlan(self): + set_module_args(dict(interface='Vlan 1244', magp_id=102, + router_ip='10.0.0.43', + router_mac='01:02:03:04:05:06')) + commands = [ + 'interface vlan 1243 no magp 102', + 'interface vlan 1244 magp 102', + 'exit', + 'interface vlan 1244 magp 102 ip virtual-router address 10.0.0.43', + 'interface vlan 1244 magp 102 ip virtual-router mac-address 01:02:03:04:05:06'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_mlag_ipl.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_mlag_ipl.py new file mode 100644 index 00000000..a5d0f6b3 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_mlag_ipl.py @@ -0,0 +1,86 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_mlag_ipl +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxMlagIplModule(TestOnyxModule): + + module = onyx_mlag_ipl + + def setUp(self): + super(TestOnyxMlagIplModule, self).setUp() + self._mlag_enabled = True + self.mock_get_config = patch.object( + onyx_mlag_ipl.OnyxMlagIplModule, + "_show_mlag_data") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxMlagIplModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + if self._mlag_enabled: + config_file = 'onyx_mlag_ipl_show.cfg' + self.get_config.return_value = load_fixture(config_file) + else: + self.get_config.return_value = None + self.load_config.return_value = None + + def test_no_ipl_no_change(self): + self._mlag_enabled = False + set_module_args(dict(name="Po1", state='absent')) + self.execute_module(changed=False) + + def test_ipl_no_change(self): + self._mlag_enabled = True + set_module_args(dict(name="Po1", state='present', + vlan_interface='Vlan 1002', + peer_address='10.2.2.2')) + self.execute_module(changed=False) + + def test_ipl_add(self): + self._mlag_enabled = False + set_module_args(dict(name="Po1", state='present', + vlan_interface='Vlan 1002', + peer_address='10.2.2.2')) + commands = ['interface port-channel 1 ipl 1', + 'interface vlan 1002 ipl 1 peer-address 10.2.2.2'] + self.execute_module(changed=True, commands=commands) + + def test_ipl_add_peer(self): + self._mlag_enabled = True + set_module_args(dict(name="Po1", state='present', + vlan_interface='Vlan 1002', + peer_address='10.2.2.4')) + commands = ['interface vlan 1002 ipl 1 peer-address 10.2.2.4'] + self.execute_module(changed=True, commands=commands) + + def test_ipl_remove(self): + self._mlag_enabled = True + set_module_args(dict(name="Po1", state='absent')) + commands = ['interface port-channel 1 no ipl 1'] + self.execute_module(changed=True, commands=commands) + + def test_ipl_change_vlan(self): + self._mlag_enabled = True + set_module_args(dict(name="Po1", state='present', + vlan_interface='Vlan 1003', + peer_address='10.2.2.4')) + commands = ['interface vlan 1002 no ipl 1', + 'interface vlan 1003 ipl 1 peer-address 10.2.2.4'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_mlag_vip.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_mlag_vip.py new file mode 100644 index 00000000..44c26fe1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_mlag_vip.py @@ -0,0 +1,84 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_mlag_vip +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxMlagVipModule(TestOnyxModule): + + module = onyx_mlag_vip + + def setUp(self): + super(TestOnyxMlagVipModule, self).setUp() + self._mlag_enabled = True + self.mock_show_mlag = patch.object( + onyx_mlag_vip.OnyxMLagVipModule, + "_show_mlag") + self.show_mlag = self.mock_show_mlag.start() + self.mock_show_mlag_vip = patch.object( + onyx_mlag_vip.OnyxMLagVipModule, + "_show_mlag_vip") + self.show_mlag_vip = self.mock_show_mlag_vip.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxMlagVipModule, self).tearDown() + self.mock_show_mlag.stop() + self.mock_show_mlag_vip.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + if self._mlag_enabled: + config_file = 'onyx_mlag_vip_show.cfg' + self.show_mlag_vip.return_value = load_fixture(config_file) + config_file = 'onyx_mlag_show.cfg' + self.show_mlag.return_value = load_fixture(config_file) + else: + self.show_mlag_vip.return_value = None + self.show_mlag.return_value = None + self.load_config.return_value = None + + def test_mlag_no_change(self): + set_module_args(dict(ipaddress='10.209.25.107/24', + group_name='neo-mlag-vip-500', + mac_address='00:00:5E:00:01:4E')) + self.execute_module(changed=False) + + def test_mlag_change(self): + self._mlag_enabled = False + set_module_args(dict(ipaddress='10.209.25.107/24', + group_name='neo-mlag-vip-500', + mac_address='00:00:5E:00:01:4E', + delay=0)) + commands = ['mlag-vip neo-mlag-vip-500 ip 10.209.25.107 /24 force', + 'mlag system-mac 00:00:5e:00:01:4e', 'no mlag shutdown'] + self.execute_module(changed=True, commands=commands) + + def test_mlag_send_group_name_only_change(self): + self._mlag_enabled = False + set_module_args(dict(group_name='neo-mlag-vip-500', + delay=0)) + commands = ['mlag-vip neo-mlag-vip-500', + 'no mlag shutdown'] + self.execute_module(changed=True, commands=commands) + + def test_mlag_absent_no_change(self): + self._mlag_enabled = False + set_module_args(dict(state='absent')) + self.execute_module(changed=False) + + def test_mlag_absent_change(self): + set_module_args(dict(state='absent', delay=0)) + commands = ['no mlag-vip'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ntp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ntp.py new file mode 100644 index 00000000..2e1b289a --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ntp.py @@ -0,0 +1,76 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_ntp +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxNTP(TestOnyxModule): + + module = onyx_ntp + enabled = False + + def setUp(self): + self.enabled = False + super(TestOnyxNTP, self).setUp() + self.mock_get_config = patch.object( + onyx_ntp.OnyxNTPModule, "_show_ntp_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxNTP, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_ntp_show.cfg' + data = load_fixture(config_file) + self.get_config.return_value = data + self.load_config.return_value = None + + def test_ntp_state_no_change(self): + set_module_args(dict(state='enabled')) + self.execute_module(changed=False) + + def test_ntp_state_with_change(self): + set_module_args(dict(state='disabled')) + commands = ['no ntp enable'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_authenticate_state_no_change(self): + set_module_args(dict(authenticate_state='disabled')) + self.execute_module(changed=False) + + def test_ntp_authenticate_state_with_change(self): + set_module_args(dict(authenticate_state='enabled')) + commands = ['ntp authenticate'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_authentication_key_no_change(self): + set_module_args(dict(ntp_authentication_keys=[dict(auth_key_id='22', + auth_key_encrypt_type='sha1', + auth_key_password='12345')])) + self.execute_module(changed=False) + + def test_ntp_authentication_key_with_change(self): + set_module_args(dict(ntp_authentication_keys=[dict(auth_key_id='22', + auth_key_encrypt_type='md5', + auth_key_password='12345')])) + commands = ['ntp authentication-key 22 md5 12345'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_trusted_keys_with_change(self): + set_module_args(dict(trusted_keys='22')) + commands = ['ntp trusted-key 22'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ntp_servers_peers.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ntp_servers_peers.py new file mode 100644 index 00000000..616cae52 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ntp_servers_peers.py @@ -0,0 +1,134 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_ntp_servers_peers +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxNtpServersPeersModule(TestOnyxModule): + + module = onyx_ntp_servers_peers + enabled = False + + def setUp(self): + self.enabled = False + super(TestOnyxNtpServersPeersModule, self).setUp() + self.mock_get_config = patch.object( + onyx_ntp_servers_peers.OnyxNTPServersPeersModule, "_show_peers_servers_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxNtpServersPeersModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_ntp_servers_peers_show.cfg' + data = load_fixture(config_file) + self.get_config.return_value = data + self.load_config.return_value = None + + def test_ntp_peer_state_no_change(self): + set_module_args(dict(peer=[dict(ip_or_name='1.1.1.1', + enabled='yes')])) + self.execute_module(changed=False) + + def test_ntp_peer_state_with_change(self): + set_module_args(dict(peer=[dict(ip_or_name='1.1.1.1', + enabled='no')])) + commands = ['ntp peer 1.1.1.1 disable'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_peer_version_no_change(self): + set_module_args(dict(peer=[dict(ip_or_name='1.1.1.1', + version='4')])) + self.execute_module(changed=False) + + def test_ntp_peer_version_with_change(self): + set_module_args(dict(peer=[dict(ip_or_name='1.1.1.1', + version='3')])) + commands = ['ntp peer 1.1.1.1 version 3'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_peer_key_id_no_change(self): + set_module_args(dict(peer=[dict(ip_or_name='1.1.1.1', + key_id='5')])) + self.execute_module(changed=False) + + def test_ntp_peer_key_id_with_change(self): + set_module_args(dict(peer=[dict(ip_or_name='1.1.1.1', + key_id='6')])) + commands = ['ntp peer 1.1.1.1 keyID 6'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_peer_delete_with_change(self): + set_module_args(dict(peer=[dict(ip_or_name='1.1.1.1', + state='absent')])) + commands = ['no ntp peer 1.1.1.1'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_server_state_no_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + enabled='no')])) + self.execute_module(changed=False) + + def test_ntp_server_state_with_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + enabled='yes')])) + commands = ['no ntp server 2.2.2.2 disable'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_server_version_no_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + version='4')])) + self.execute_module(changed=False) + + def test_ntp_server_version_with_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + version='3')])) + commands = ['ntp server 2.2.2.2 version 3'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_server_keyID_no_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + key_id='99')])) + self.execute_module(changed=False) + + def test_ntp_server_keyID_with_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + key_id='8')])) + commands = ['ntp server 2.2.2.2 keyID 8'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_server_trusted_state_no_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + trusted_enable='yes')])) + self.execute_module(changed=False) + + def test_ntp_server_trusted_state_with_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + trusted_enable='no')])) + commands = ['no ntp server 2.2.2.2 trusted-enable'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_server_delete_with_change(self): + set_module_args(dict(server=[dict(ip_or_name='2.2.2.2', + state='absent')])) + commands = ['no ntp server 2.2.2.2'] + self.execute_module(changed=True, commands=commands) + + def test_ntpdate_with_change(self): + set_module_args(dict(ntpdate='192.22.1.66')) + commands = ['ntpdate 192.22.1.66'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ospf.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ospf.py new file mode 100644 index 00000000..bb35e6e8 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ospf.py @@ -0,0 +1,106 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_ospf +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxOspfModule(TestOnyxModule): + + module = onyx_ospf + + def setUp(self): + super(TestOnyxOspfModule, self).setUp() + self._ospf_exists = True + self.mock_get_config = patch.object( + onyx_ospf.OnyxOspfModule, + "_get_ospf_config") + self.get_config = self.mock_get_config.start() + + self.mock_get_interfaces_config = patch.object( + onyx_ospf.OnyxOspfModule, + "_get_ospf_interfaces_config") + self.get_interfaces_config = self.mock_get_interfaces_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxOspfModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + if self._ospf_exists: + config_file = 'onyx_ospf_show.cfg' + self.get_config.return_value = load_fixture(config_file) + config_file = 'onyx_ospf_interfaces_show.cfg' + self.get_interfaces_config.return_value = load_fixture(config_file) + else: + self.get_config.return_value = None + self.get_interfaces_config.return_value = None + self.load_config.return_value = None + + def test_ospf_absent_no_change(self): + set_module_args(dict(ospf=3, state='absent')) + self.execute_module(changed=False) + + def test_ospf_present_no_change(self): + interface = dict(name='Loopback 1', area='0.0.0.0') + set_module_args(dict(ospf=2, router_id='10.2.3.4', + interfaces=[interface])) + self.execute_module(changed=False) + + def test_ospf_present_remove(self): + set_module_args(dict(ospf=2, state='absent')) + commands = ['no router ospf 2'] + self.execute_module(changed=True, commands=commands) + + def test_ospf_change_router(self): + interface = dict(name='Loopback 1', area='0.0.0.0') + set_module_args(dict(ospf=2, router_id='10.2.3.5', + interfaces=[interface])) + commands = ['router ospf 2', 'router-id 10.2.3.5', 'exit'] + self.execute_module(changed=True, commands=commands, sort=False) + + def test_ospf_remove_router(self): + interface = dict(name='Loopback 1', area='0.0.0.0') + set_module_args(dict(ospf=2, interfaces=[interface])) + commands = ['router ospf 2', 'no router-id', 'exit'] + self.execute_module(changed=True, commands=commands, sort=False) + + def test_ospf_add_interface(self): + interfaces = [dict(name='Loopback 1', area='0.0.0.0'), + dict(name='Loopback 2', area='0.0.0.0')] + set_module_args(dict(ospf=2, router_id='10.2.3.4', + interfaces=interfaces)) + commands = ['interface loopback 2 ip ospf area 0.0.0.0'] + self.execute_module(changed=True, commands=commands) + + def test_ospf_remove_interface(self): + set_module_args(dict(ospf=2, router_id='10.2.3.4')) + commands = ['interface loopback 1 no ip ospf area'] + self.execute_module(changed=True, commands=commands) + + def test_ospf_add(self): + self._ospf_exists = False + interfaces = [dict(name='Loopback 1', area='0.0.0.0'), + dict(name='Vlan 210', area='0.0.0.0'), + dict(name='Eth1/1', area='0.0.0.0'), + dict(name='Po1', area='0.0.0.0')] + set_module_args(dict(ospf=2, router_id='10.2.3.4', + interfaces=interfaces)) + commands = ['router ospf 2', 'router-id 10.2.3.4', 'exit', + 'interface loopback 1 ip ospf area 0.0.0.0', + 'interface vlan 210 ip ospf area 0.0.0.0', + 'interface ethernet 1/1 ip ospf area 0.0.0.0', + 'interface port-channel 1 ip ospf area 0.0.0.0'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_pfc_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_pfc_interface.py new file mode 100644 index 00000000..ddd5f089 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_pfc_interface.py @@ -0,0 +1,114 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_pfc_interface +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxPfcInterfaceModule(TestOnyxModule): + + module = onyx_pfc_interface + + def setUp(self): + super(TestOnyxPfcInterfaceModule, self).setUp() + self._pfc_enabled = True + self.mock_get_config = patch.object( + onyx_pfc_interface.OnyxPfcInterfaceModule, + "_get_pfc_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + self.mock_get_version = patch.object( + onyx_pfc_interface.OnyxPfcInterfaceModule, "_get_os_version") + self.get_version = self.mock_get_version.start() + + def tearDown(self): + super(TestOnyxPfcInterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_get_version.stop() + + def load_fixtures(self, commands=None, transport='cli'): + if self._pfc_enabled: + suffix = 'enabled' + else: + suffix = 'disabled' + config_file = 'onyx_pfc_interface_%s.cfg' % suffix + + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_version.return_value = "3.6.5000" + + def _test_pfc_if(self, if_name, enabled, changed, commands): + state = 'enabled' if enabled else 'disabled' + set_module_args(dict(name=if_name, state=state)) + self.execute_module(changed=changed, commands=commands) + + def _test_pfc_no_change(self, enabled): + interfaces = ('Eth1/1', 'Eth1/1/2', 'Po1', 'Mpo2') + changed = False + commands = None + for ifc in interfaces: + self._test_pfc_if(ifc, enabled, changed, commands) + + def test_pfc_enabled_no_change(self): + self._pfc_enabled = True + enabled = True + self._test_pfc_no_change(enabled) + + def test_pfc_disabled_no_change(self): + self._pfc_enabled = False + enabled = False + self._test_pfc_no_change(enabled) + + def _test_pfc_change(self, enabled): + cmd_list = [ + ('Eth1/1', 'interface ethernet 1/1'), + ('Eth1/1/2', 'interface ethernet 1/1/2'), + ('Po1', 'interface port-channel 1'), + ('Mpo2', 'interface mlag-port-channel 2'), + ] + changed = True + suffix = ' dcb priority-flow-control mode on force' + if not enabled: + suffix = ' no dcb priority-flow-control mode force' + for (if_name, cmd) in cmd_list: + commands = [cmd + suffix] + self._test_pfc_if(if_name, enabled, changed, commands) + + def test_pfc_disabled_change(self): + self._pfc_enabled = False + enabled = True + self._test_pfc_change(enabled) + + def test_pfc_enabled_change(self): + self._pfc_enabled = True + enabled = False + self._test_pfc_change(enabled) + + def test_pfc_aggregate(self): + self._pfc_enabled = False + aggregate = [dict(name='Eth1/1'), dict(name='Eth1/1/2')] + set_module_args(dict(aggregate=aggregate, state='enabled')) + commands = [ + 'interface ethernet 1/1 dcb priority-flow-control mode on force', + 'interface ethernet 1/1/2 dcb priority-flow-control mode on force'] + self.execute_module(changed=True, commands=commands) + + def test_pfc_aggregate_purge(self): + self._pfc_enabled = True + aggregate = [dict(name='Po1'), dict(name='Mpo2')] + set_module_args(dict(aggregate=aggregate, state='enabled', purge=True)) + commands = [ + 'interface ethernet 1/1 no dcb priority-flow-control mode force', + 'interface ethernet 1/1/2 no dcb priority-flow-control mode force'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_protocol.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_protocol.py new file mode 100644 index 00000000..9750074c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_protocol.py @@ -0,0 +1,152 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_protocol +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxProtocolModule(TestOnyxModule): + + module = onyx_protocol + + def setUp(self): + super(TestOnyxProtocolModule, self).setUp() + self.mock_get_config = patch.object( + onyx_protocol.OnyxProtocolModule, + "_get_protocols") + self.get_config = self.mock_get_config.start() + + self.mock_get_ip_config = patch.object( + onyx_protocol.OnyxProtocolModule, + "_get_ip_routing") + self.get_ip_config = self.mock_get_ip_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxProtocolModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_protocols_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_ip_config.return_value = "IP routing: enabled" + + def test_mlag_enable(self): + set_module_args(dict(mlag='enabled')) + commands = ['protocol mlag'] + self.execute_module(changed=True, commands=commands) + + def test_mlag_disable(self): + set_module_args(dict(mlag='disabled')) + self.execute_module(changed=False) + + def test_magp_enable(self): + set_module_args(dict(magp='enabled')) + commands = ['protocol magp'] + self.execute_module(changed=True, commands=commands) + + def test_magp_disable(self): + set_module_args(dict(magp='disabled')) + self.execute_module(changed=False) + + def test_spanning_tree_enable(self): + set_module_args(dict(spanning_tree='enabled')) + self.execute_module(changed=False) + + def test_spanning_tree_disable(self): + set_module_args(dict(spanning_tree='disabled')) + commands = ['no spanning-tree'] + self.execute_module(changed=True, commands=commands) + + def test_dcb_pfc_enable(self): + set_module_args(dict(dcb_pfc='enabled')) + commands = ['dcb priority-flow-control enable force'] + self.execute_module(changed=True, commands=commands) + + def test_dcb_pfc_disable(self): + set_module_args(dict(dcb_pfc='disabled')) + self.execute_module(changed=False) + + def test_igmp_snooping_enable(self): + set_module_args(dict(igmp_snooping='enabled')) + commands = ['ip igmp snooping'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_snooping_disable(self): + set_module_args(dict(igmp_snooping='disabled')) + self.execute_module(changed=False) + + def test_lacp_enable(self): + set_module_args(dict(lacp='enabled')) + commands = ['lacp'] + self.execute_module(changed=True, commands=commands) + + def test_lacp_disable(self): + set_module_args(dict(lacp='disabled')) + self.execute_module(changed=False) + + def test_ip_routing_enable(self): + set_module_args(dict(ip_routing='enabled')) + self.execute_module(changed=False) + + def test_ip_routing_disable(self): + set_module_args(dict(ip_routing='disabled')) + commands = ['no ip routing'] + self.execute_module(changed=True, commands=commands) + + def test_lldp_enable(self): + set_module_args(dict(lldp='enabled')) + commands = ['lldp'] + self.execute_module(changed=True, commands=commands) + + def test_lldp_disable(self): + set_module_args(dict(lldp='disabled')) + self.execute_module(changed=False) + + def test_bgp_enable(self): + set_module_args(dict(bgp='enabled')) + commands = ['protocol bgp'] + self.execute_module(changed=True, commands=commands) + + def test_bgp_disable(self): + set_module_args(dict(bgp='disabled')) + self.execute_module(changed=False) + + def test_ospf_enable(self): + set_module_args(dict(ospf='enabled')) + commands = ['protocol ospf'] + self.execute_module(changed=True, commands=commands) + + def test_ospf_disable(self): + set_module_args(dict(ospf='disabled')) + self.execute_module(changed=False) + + def test_nve_enable(self): + set_module_args(dict(nve='enabled')) + commands = ['protocol nve'] + self.execute_module(changed=True, commands=commands) + + def test_nve_disabled(self): + set_module_args(dict(nve='disabled')) + self.execute_module(changed=False) + + def test_bfd_enable(self): + set_module_args(dict(bfd='enabled')) + commands = ['protocol bfd'] + self.execute_module(changed=True, commands=commands) + + def test_bfd_disabled(self): + set_module_args(dict(bfd='disabled')) + self.execute_module(changed=False) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_protocols.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_protocols.py new file mode 100644 index 00000000..e438a80d --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_protocols.py @@ -0,0 +1,143 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_protocol +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxProtocolModule(TestOnyxModule): + + module = onyx_protocol + + def setUp(self): + super(TestOnyxProtocolModule, self).setUp() + self.mock_get_config = patch.object( + onyx_protocol.OnyxProtocolModule, + "_get_protocols") + self.get_config = self.mock_get_config.start() + + self.mock_get_ip_config = patch.object( + onyx_protocol.OnyxProtocolModule, + "_get_ip_routing") + self.get_ip_config = self.mock_get_ip_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxProtocolModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_protocols_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_ip_config.return_value = "IP routing: enabled" + + def test_mlag_enable(self): + set_module_args(dict(mlag='enabled')) + commands = ['protocol mlag'] + self.execute_module(changed=True, commands=commands) + + def test_mlag_disable(self): + set_module_args(dict(mlag='disabled')) + self.execute_module(changed=False) + + def test_magp_enable(self): + set_module_args(dict(magp='enabled')) + commands = ['protocol magp'] + self.execute_module(changed=True, commands=commands) + + def test_magp_disable(self): + set_module_args(dict(magp='disabled')) + self.execute_module(changed=False) + + def test_spanning_tree_enable(self): + set_module_args(dict(spanning_tree='enabled')) + self.execute_module(changed=False) + + def test_spanning_tree_disable(self): + set_module_args(dict(spanning_tree='disabled')) + commands = ['no spanning-tree'] + self.execute_module(changed=True, commands=commands) + + def test_dcb_pfc_enable(self): + set_module_args(dict(dcb_pfc='enabled')) + commands = ['dcb priority-flow-control enable force'] + self.execute_module(changed=True, commands=commands) + + def test_dcb_pfc_disable(self): + set_module_args(dict(dcb_pfc='disabled')) + self.execute_module(changed=False) + + def test_igmp_snooping_enable(self): + set_module_args(dict(igmp_snooping='enabled')) + commands = ['ip igmp snooping'] + self.execute_module(changed=True, commands=commands) + + def test_igmp_snooping_disable(self): + set_module_args(dict(igmp_snooping='disabled')) + self.execute_module(changed=False) + + def test_lacp_enable(self): + set_module_args(dict(lacp='enabled')) + commands = ['lacp'] + self.execute_module(changed=True, commands=commands) + + def test_lacp_disable(self): + set_module_args(dict(lacp='disabled')) + self.execute_module(changed=False) + + def test_ip_routing_enable(self): + set_module_args(dict(ip_routing='enabled')) + self.execute_module(changed=False) + + def test_ip_routing_disable(self): + set_module_args(dict(ip_routing='disabled')) + commands = ['no ip routing'] + self.execute_module(changed=True, commands=commands) + + def test_lldp_enable(self): + set_module_args(dict(lldp='enabled')) + commands = ['lldp'] + self.execute_module(changed=True, commands=commands) + + def test_lldp_disable(self): + set_module_args(dict(lldp='disabled')) + self.execute_module(changed=False) + + def test_bgp_enable(self): + set_module_args(dict(bgp='enabled')) + commands = ['protocol bgp'] + self.execute_module(changed=True, commands=commands) + + def test_bgp_disable(self): + set_module_args(dict(bgp='disabled')) + self.execute_module(changed=False) + + def test_ospf_enable(self): + set_module_args(dict(ospf='enabled')) + commands = ['protocol ospf'] + self.execute_module(changed=True, commands=commands) + + def test_ospf_disable(self): + set_module_args(dict(ospf='disabled')) + self.execute_module(changed=False) + + def test_nve_enable(self): + set_module_args(dict(nve='enabled')) + commands = ['protocol nve'] + self.execute_module(changed=True, commands=commands) + + def test_nve_disabled(self): + set_module_args(dict(nve='disabled')) + self.execute_module(changed=False) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp.py new file mode 100644 index 00000000..ca2d2ba0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp.py @@ -0,0 +1,138 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_ptp_global +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxPtpModule(TestOnyxModule): + + module = onyx_ptp_global + + def setUp(self): + self._ptp_enabled = True + self._ntp_enabled = True + super(TestOnyxPtpModule, self).setUp() + + self.mock_get_ptp_config = patch.object(onyx_ptp_global.OnyxPtpGlobalModule, "_show_ptp_config") + self.get_ptp_config = self.mock_get_ptp_config.start() + self.mock_get_ntp_config = patch.object(onyx_ptp_global.OnyxPtpGlobalModule, "_show_ntp_config") + self.get_ntp_config = self.mock_get_ntp_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxPtpModule, self).tearDown() + self.mock_get_ptp_config.stop() + self.mock_get_ntp_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + if self._ptp_enabled: + config_file = 'onyx_show_ptp_clock.cfg' + self.get_ptp_config.return_value = load_fixture(config_file) + else: + self.get_ptp_config.return_value = None + + config_file = 'onyx_show_ntp_configured.cfg' + ret_val = load_fixture(config_file) + if self._ntp_enabled: + ret_val[0]['NTP enabled'] = 'yes' + self.get_ntp_config.return_value = ret_val + self.load_config.return_value = None + + def test_ptp_enabled_no_change(self): + set_module_args(dict(ptp_state='enabled')) + self.execute_module(changed=False) + + def test_ptp_enabled_with_change(self): + self._ptp_enabled = False + set_module_args(dict(ptp_state='enabled')) + commands = ['protocol ptp'] + self.execute_module(changed=True, commands=commands) + + def test_ptp_disabled_no_change(self): + self._ptp_enabled = False + set_module_args(dict(ptp_state='disabled')) + self.execute_module(changed=False) + + def test_ptp_disabled_with_change(self): + set_module_args(dict(ptp_state='disabled')) + commands = ['no protocol ptp'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_enabled_no_change(self): + self._ptp_enabled = False + set_module_args(dict(ntp_state='enabled', + ptp_state='disabled')) + self.execute_module(changed=False) + + def test_ntp_enabled_with_change(self): + self._ptp_enabled = False + self._ntp_enabled = False + set_module_args(dict(ntp_state='enabled', + ptp_state='disabled')) + commands = ['ntp enable'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_disabled_no_change(self): + self._ntp_enabled = False + set_module_args(dict(ntp_state='disabled')) + self.execute_module(changed=False) + + def test_ntp_disabled_with_change(self): + set_module_args(dict(ntp_state='disabled')) + commands = ['no ntp enable'] + self.execute_module(changed=True, commands=commands) + + def test_set_domain_no_change(self): + self._ntp_enabled = False + set_module_args(dict(ntp_state='disabled', + domain=127)) + self.execute_module(changed=False) + + def test_set_domain_with_change(self): + set_module_args(dict(domain=100)) + commands = ['ptp domain 100'] + self.execute_module(changed=True, commands=commands) + + def test_set_primary_priority_no_change(self): + set_module_args(dict(primary_priority=128)) + self.execute_module(changed=False) + + def test_set_primary_priority_with_change(self): + set_module_args(dict(primary_priority=250)) + commands = ['ptp priority1 250'] + self.execute_module(changed=True, commands=commands) + + def test_set_secondary_priority_no_change(self): + set_module_args(dict(secondary_priority=128)) + self.execute_module(changed=False) + + def test_set_secondary_priority_with_change(self): + set_module_args(dict(secondary_priority=190)) + commands = ['ptp priority2 190'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp_global.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp_global.py new file mode 100644 index 00000000..ca2d2ba0 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp_global.py @@ -0,0 +1,138 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_ptp_global +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxPtpModule(TestOnyxModule): + + module = onyx_ptp_global + + def setUp(self): + self._ptp_enabled = True + self._ntp_enabled = True + super(TestOnyxPtpModule, self).setUp() + + self.mock_get_ptp_config = patch.object(onyx_ptp_global.OnyxPtpGlobalModule, "_show_ptp_config") + self.get_ptp_config = self.mock_get_ptp_config.start() + self.mock_get_ntp_config = patch.object(onyx_ptp_global.OnyxPtpGlobalModule, "_show_ntp_config") + self.get_ntp_config = self.mock_get_ntp_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxPtpModule, self).tearDown() + self.mock_get_ptp_config.stop() + self.mock_get_ntp_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + if self._ptp_enabled: + config_file = 'onyx_show_ptp_clock.cfg' + self.get_ptp_config.return_value = load_fixture(config_file) + else: + self.get_ptp_config.return_value = None + + config_file = 'onyx_show_ntp_configured.cfg' + ret_val = load_fixture(config_file) + if self._ntp_enabled: + ret_val[0]['NTP enabled'] = 'yes' + self.get_ntp_config.return_value = ret_val + self.load_config.return_value = None + + def test_ptp_enabled_no_change(self): + set_module_args(dict(ptp_state='enabled')) + self.execute_module(changed=False) + + def test_ptp_enabled_with_change(self): + self._ptp_enabled = False + set_module_args(dict(ptp_state='enabled')) + commands = ['protocol ptp'] + self.execute_module(changed=True, commands=commands) + + def test_ptp_disabled_no_change(self): + self._ptp_enabled = False + set_module_args(dict(ptp_state='disabled')) + self.execute_module(changed=False) + + def test_ptp_disabled_with_change(self): + set_module_args(dict(ptp_state='disabled')) + commands = ['no protocol ptp'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_enabled_no_change(self): + self._ptp_enabled = False + set_module_args(dict(ntp_state='enabled', + ptp_state='disabled')) + self.execute_module(changed=False) + + def test_ntp_enabled_with_change(self): + self._ptp_enabled = False + self._ntp_enabled = False + set_module_args(dict(ntp_state='enabled', + ptp_state='disabled')) + commands = ['ntp enable'] + self.execute_module(changed=True, commands=commands) + + def test_ntp_disabled_no_change(self): + self._ntp_enabled = False + set_module_args(dict(ntp_state='disabled')) + self.execute_module(changed=False) + + def test_ntp_disabled_with_change(self): + set_module_args(dict(ntp_state='disabled')) + commands = ['no ntp enable'] + self.execute_module(changed=True, commands=commands) + + def test_set_domain_no_change(self): + self._ntp_enabled = False + set_module_args(dict(ntp_state='disabled', + domain=127)) + self.execute_module(changed=False) + + def test_set_domain_with_change(self): + set_module_args(dict(domain=100)) + commands = ['ptp domain 100'] + self.execute_module(changed=True, commands=commands) + + def test_set_primary_priority_no_change(self): + set_module_args(dict(primary_priority=128)) + self.execute_module(changed=False) + + def test_set_primary_priority_with_change(self): + set_module_args(dict(primary_priority=250)) + commands = ['ptp priority1 250'] + self.execute_module(changed=True, commands=commands) + + def test_set_secondary_priority_no_change(self): + set_module_args(dict(secondary_priority=128)) + self.execute_module(changed=False) + + def test_set_secondary_priority_with_change(self): + set_module_args(dict(secondary_priority=190)) + commands = ['ptp priority2 190'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp_interface.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp_interface.py new file mode 100644 index 00000000..87f8d9cf --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_ptp_interface.py @@ -0,0 +1,91 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_ptp_interface +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxPtpInterface(TestOnyxModule): + + module = onyx_ptp_interface + enabled = False + interfaces = {'Eth1/1': ('ethernet', '1/1'), 'Vlan 1': ('vlan', '1')} + + def setUp(self): + self.enabled = False + super(TestOnyxPtpInterface, self).setUp() + self.mock_get_config = patch.object( + onyx_ptp_interface.OnyxPtpInterfaceModule, "_show_ptp_interface_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxPtpInterface, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_show_ptp_interface.cfg' + data = None + if self.enabled: + data = load_fixture(config_file) + + self.get_config.return_value = data + self.load_config.return_value = None + + def test_ptp_disabled_no_change(self): + for interface in self.interfaces: + set_module_args(dict(state='disabled', name=interface)) + self.execute_module(changed=False) + + def test_ptp_disabled_with_change(self): + self.enabled = True + for interface in self.interfaces: + set_module_args(dict(state='disabled', name=interface)) + interface_type, interface_id = self.interfaces.get(interface) + commands = ['no interface %s %s ptp enable' % (interface_type, interface_id)] + self.execute_module(changed=True, commands=commands) + + def test_ptp_enabled_no_change(self): + self.enabled = True + for interface in self.interfaces: + set_module_args(dict(state='enabled', name=interface)) + self.execute_module(changed=False) + + def test_ptp_enabled_with_change(self): + for interface in self.interfaces: + set_module_args(dict(state='disabled', name=interface)) + interface_type, interface_id = self.interfaces.get(interface) + set_module_args(dict(state='enabled', name=interface)) + commands = ['interface %s %s ptp enable' % (interface_type, interface_id)] + self.execute_module(changed=True, commands=commands) + + def test_ptp_attributs_no_change(self): + self.enabled = True + for interface in self.interfaces: + set_module_args(dict(state='enabled', name=interface, delay_request=0, + announce_interval=-2, announce_timeout=3, + sync_interval=-3)) + self.execute_module(changed=False) + + def test_ptp_attributs_with_change(self): + self.enabled = True + for interface in self.interfaces: + set_module_args(dict(state='enabled', name=interface, delay_request=2, + announce_interval=-1, announce_timeout=5, sync_interval=-1)) + interface_type, interface_id = self.interfaces.get(interface) + commands = ['interface %s %s ptp delay-req interval 2' % (interface_type, interface_id), + 'interface %s %s ptp announce interval -1' % (interface_type, interface_id), + 'interface %s %s ptp announce timeout 5' % (interface_type, interface_id), + 'interface %s %s ptp sync interval -1' % (interface_type, interface_id)] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_qos.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_qos.py new file mode 100644 index 00000000..12961734 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_qos.py @@ -0,0 +1,52 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_qos +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxQosModule(TestOnyxModule): + + module = onyx_qos + + def setUp(self): + super(TestOnyxQosModule, self).setUp() + self.mock_get_if_qos_config = patch.object( + onyx_qos.OnyxQosModule, "_show_interface_qos") + self.get_if_qos_config = self.mock_get_if_qos_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxQosModule, self).tearDown() + self.mock_get_if_qos_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + qos_interface_ethernet_config_file = 'show_qos_interface_ethernet.cfg' + qos_interface_ethernet_data = load_fixture(qos_interface_ethernet_config_file) + self.get_if_qos_config.return_value = qos_interface_ethernet_data + self.load_config.return_value = None + + def test_qos_interface_ethernet_no_change(self): + set_module_args(dict(interfaces=["Eth1/1"], trust="both", rewrite_pcp="enabled", + rewrite_dscp="disabled")) + self.execute_module(changed=False) + + def test_qos_interface_ethernet_with_change(self): + set_module_args(dict(interfaces=["Eth1/1"], trust="L2", rewrite_pcp="disabled", + rewrite_dscp="enabled")) + commands = ["interface ethernet 1/1 no qos rewrite pcp", + "interface ethernet 1/1 qos trust L2", + "interface ethernet 1/1 qos rewrite dscp" + ] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp.py new file mode 100644 index 00000000..82fbda2f --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp.py @@ -0,0 +1,150 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_snmp +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxSNMPModule(TestOnyxModule): + + module = onyx_snmp + enabled = False + + def setUp(self): + self.enabled = False + super(TestOnyxSNMPModule, self).setUp() + self.mock_get_config = patch.object( + onyx_snmp.OnyxSNMPModule, "_show_snmp_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxSNMPModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_snmp_show.cfg' + data = load_fixture(config_file) + self.get_config.return_value = data + self.load_config.return_value = None + + def test_snmp_state_no_change(self): + set_module_args(dict(state_enabled=True)) + self.execute_module(changed=False) + + def test_snmp_state_with_change(self): + set_module_args(dict(state_enabled=False)) + commands = ['no snmp-server enable'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_contact_no_change(self): + set_module_args(dict(contact_name='sara')) + self.execute_module(changed=False) + + def test_snmp_contact_with_change(self): + set_module_args(dict(contact_name='Omar')) + commands = ['snmp-server contact Omar'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_location_no_change(self): + set_module_args(dict(location='Jordan')) + self.execute_module(changed=False) + + def test_snmp_location_with_change(self): + set_module_args(dict(location='London')) + commands = ['snmp-server location London'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_communities_state_no_change(self): + set_module_args(dict(communities_enabled=True)) + self.execute_module(changed=False) + + def test_snmp_communities_state_with_change(self): + set_module_args(dict(communities_enabled=False)) + commands = ['no snmp-server enable communities'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_multi_communities_state_with_no_change(self): + set_module_args(dict(multi_communities_enabled=True)) + self.execute_module(changed=False) + + def test_snmp_multi_communities_state_with_change(self): + set_module_args(dict(multi_communities_enabled=False)) + commands = ['no snmp-server enable mult-communities'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_communities_no_change(self): + set_module_args(dict(snmp_communities=[dict(community_name='community_2', + community_type='read-write')])) + self.execute_module(changed=False) + + def test_snmp_communities_with_change(self): + set_module_args(dict(snmp_communities=[dict(community_name='community_2', + community_type='read-only')])) + commands = ['snmp-server community community_2 ro'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_communities_delete_with_change(self): + set_module_args(dict(snmp_communities=[dict(community_name='community_1', + state='absent')])) + commands = ['no snmp-server community community_1'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_notify_state_no_change(self): + set_module_args(dict(notify_enabled=True)) + self.execute_module(changed=False) + + def test_snmp_notify_state_with_change(self): + set_module_args(dict(notify_enabled=False)) + commands = ['no snmp-server enable notify'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_notify_port_no_change(self): + set_module_args(dict(notify_port='1')) + self.execute_module(changed=False) + + def test_snmp_notify_port_with_change(self): + set_module_args(dict(notify_port='2')) + commands = ['snmp-server notify port 2'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_notify_community_no_change(self): + set_module_args(dict(notify_community='community_1')) + self.execute_module(changed=False) + + def test_snmp_notify_community_with_change(self): + set_module_args(dict(notify_community='community_2')) + commands = ['snmp-server notify community community_2'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_notify_send_test_with_change(self): + set_module_args(dict(notify_send_test='yes')) + commands = ['snmp-server notify send-test'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_notify_event_with_change(self): + set_module_args(dict(notify_event='interface-up')) + commands = ['snmp-server notify event interface-up'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_permissions_with_change(self): + set_module_args(dict(snmp_permissions=[dict(state_enabled=True, + permission_type='RFC1213-MIB')])) + commands = ['snmp-server enable set-permission RFC1213-MIB'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_engine_id_reset_with_change(self): + set_module_args(dict(engine_id_reset='yes')) + commands = ['snmp-server engineID reset'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp_hosts.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp_hosts.py new file mode 100644 index 00000000..0affdda2 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp_hosts.py @@ -0,0 +1,170 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_snmp_hosts +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxSNMPHostsModule(TestOnyxModule): + + module = onyx_snmp_hosts + + def setUp(self): + self.enabled = False + super(TestOnyxSNMPHostsModule, self).setUp() + self.mock_get_config = patch.object( + onyx_snmp_hosts.OnyxSNMPHostsModule, "_show_hosts_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxSNMPHostsModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_show_snmp_hosts.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_snmp_host_enabled_state_no_change(self): + set_module_args(dict(hosts=[dict(name='1.1.1.1', + enabled=True)])) + self.execute_module(changed=False) + + def test_snmp_host_enabled_state_with_change(self): + set_module_args(dict(hosts=[dict(name='1.1.1.1', + enabled=False)])) + commands = ['snmp-server host 1.1.1.1 disable'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_host_notification_type_no_change(self): + set_module_args(dict(hosts=[dict(name='2.2.2.2', + notification_type='trap', + version='2c', + port='5')])) + self.execute_module(changed=False) + + def test_snmp_host_notification_type_with_change(self): + set_module_args(dict(hosts=[dict(name='2.2.2.2', + notification_type='inform', + version='2c', + port='5')])) + commands = ['snmp-server host 2.2.2.2 informs port 5 version 2c'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_host_version_no_change(self): + set_module_args(dict(hosts=[dict(name='2.2.2.2', + notification_type='trap', + version='2c', + port='5')])) + self.execute_module(changed=False) + + def test_snmp_host_version_with_change(self): + set_module_args(dict(hosts=[dict(name='2.2.2.2', + notification_type='trap', + version='1', + port='5')])) + commands = ['snmp-server host 2.2.2.2 traps port 5 version 1'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_host_port_no_change(self): + set_module_args(dict(hosts=[dict(name='2.2.2.2', + notification_type='trap', + version='2c', + port='5')])) + self.execute_module(changed=False) + + def test_snmp_host_port_with_change(self): + set_module_args(dict(hosts=[dict(name='2.2.2.2', + notification_type='trap', + version='2c', + port='3')])) + commands = ['snmp-server host 2.2.2.2 traps port 3 version 2c'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_host_user_name_no_change(self): + set_module_args(dict(hosts=[dict(name='1.1.1.1', + notification_type='inform', + version='3', + port='3', + user_name='sara', + auth_type='md5', + auth_password='sara123saea1234678')])) + self.execute_module(changed=False) + + def test_snmp_host_user_name_with_change(self): + set_module_args(dict(hosts=[dict(name='1.1.1.1', + notification_type='inform', + version='3', + port='3', + user_name='masa', + auth_type='md5', + auth_password='sara123saea1234678')])) + commands = ['snmp-server host 1.1.1.1 informs port 3 version 3 user masa auth md5 sara123saea1234678'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_host_auth_type_no_change(self): + set_module_args(dict(hosts=[dict(name='1.1.1.1', + notification_type='inform', + version='3', + port='3', + user_name='sara', + auth_type='md5', + auth_password='sara123saea1234678')])) + self.execute_module(changed=False) + + def test_snmp_host_auth_type_with_change(self): + set_module_args(dict(hosts=[dict(name='1.1.1.1', + notification_type='inform', + version='3', + port='3', + user_name='sara', + auth_type='sha', + auth_password='sara123saea1234678')])) + commands = ['snmp-server host 1.1.1.1 informs port 3 version 3 user sara auth sha sara123saea1234678'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_host_privacy_type_no_change(self): + set_module_args(dict(hosts=[dict(name='1.1.1.1', + notification_type='inform', + version='3', + port='3', + user_name='sara', + auth_type='md5', + auth_password='sara123saea1234678', + privacy_type='3des', + privacy_password='pjqriuewjhksjmdoiws')])) + self.execute_module(changed=False) + + def test_snmp_host_privacy_type_with_change(self): + set_module_args(dict(hosts=[dict(name='1.1.1.1', + notification_type='inform', + version='3', + port='3', + user_name='sara', + auth_type='md5', + auth_password='sara123saea1234678', + privacy_type='aes-192', + privacy_password='pjqriuewjhksjmdoiws')])) + commands = ['snmp-server host 1.1.1.1 informs port 3 version 3 user sara auth md5 sara123saea1234678 priv aes-192 pjqriuewjhksjmdoiws'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_host_state_with_change(self): + set_module_args(dict(hosts=[dict(name='2.2.2.2', + notification_type='trap', + version='2c', + port='5', + state='absent')])) + commands = ['no snmp-server host 2.2.2.2'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp_users.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp_users.py new file mode 100644 index 00000000..c2ad4954 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_snmp_users.py @@ -0,0 +1,95 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_snmp_users +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxSNMPUsersModule(TestOnyxModule): + + module = onyx_snmp_users + + def setUp(self): + self.enabled = False + super(TestOnyxSNMPUsersModule, self).setUp() + self.mock_get_config = patch.object( + onyx_snmp_users.OnyxSNMPUsersModule, "_show_users") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxSNMPUsersModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_show_snmp_users.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_snmp_user_state_no_change(self): + set_module_args(dict(users=[dict(name='sara', + enabled='true')])) + self.execute_module(changed=False) + + def test_snmp_user_state_with_change(self): + set_module_args(dict(users=[dict(name='sara', + enabled='false')])) + commands = ['no snmp-server user sara v3 enable'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_user_set_access_state_no_change(self): + set_module_args(dict(users=[dict(name='sara', + set_access_enabled='true')])) + self.execute_module(changed=False) + + def test_snmp_user_set_access_state_with_change(self): + set_module_args(dict(users=[dict(name='sara', + set_access_enabled='false')])) + commands = ['no snmp-server user sara v3 enable sets'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_user_require_privacy_state_no_change(self): + set_module_args(dict(users=[dict(name='sara', + require_privacy='false')])) + self.execute_module(changed=False) + + def test_snmp_user_require_privacy_state_with_change(self): + set_module_args(dict(users=[dict(name='sara', + require_privacy='yes')])) + commands = ['snmp-server user sara v3 require-privacy'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_user_auth_type_no_change(self): + set_module_args(dict(users=[dict(name='sara', + auth_type='sha', + auth_password='12sara123456')])) + self.execute_module(changed=False) + + def test_snmp_user_auth_type_with_change(self): + set_module_args(dict(users=[dict(name='sara', + auth_type='md5', + auth_password='12sara123456')])) + commands = ['snmp-server user sara v3 auth md5 12sara123456'] + self.execute_module(changed=True, commands=commands) + + def test_snmp_user_capability_level_no_change(self): + set_module_args(dict(users=[dict(name='sara', + capability_level='admin')])) + self.execute_module(changed=False) + + def test_snmp_user_capability_level_with_change(self): + set_module_args(dict(users=[dict(name='sara', + capability_level='monitor')])) + commands = ['snmp-server user sara v3 capability monitor'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_syslog_files.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_syslog_files.py new file mode 100644 index 00000000..c7721844 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_syslog_files.py @@ -0,0 +1,113 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_syslog_files +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxSyslogFilesModule(TestOnyxModule): + + module = onyx_syslog_files + + def setUp(self): + self.enabled = False + super(TestOnyxSyslogFilesModule, self).setUp() + self.mock_get_config = patch.object( + onyx_syslog_files.OnyxSyslogFilesModule, "show_logging") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxSyslogFilesModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_logging_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_syslog_files_force_rotate(self): + set_module_args(dict(rotation=dict(force=True))) + commands = ["logging files rotation force"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_files_max_num(self): + set_module_args(dict(rotation=dict(max_num=30))) + commands = ["logging files rotation max-num 30"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_files_freq(self): + set_module_args(dict(rotation=dict(frequency="daily"))) + commands = ["logging files rotation criteria frequency daily"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_files_size(self): + set_module_args(dict(rotation=dict(size=10.5))) + commands = ["logging files rotation criteria size 10.5"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_files_delete(self): + set_module_args(dict(delete_group="oldest")) + commands = ["logging files delete oldest"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_debug_files_force_rotate(self): + set_module_args(dict(rotation=dict(force=True), debug=True)) + commands = ["logging debug-files rotation force"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_debug_files_max_num(self): + set_module_args(dict(rotation=dict(max_num=30), debug=True)) + commands = ["logging debug-files rotation max-num 30"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_debug_files_freq(self): + set_module_args(dict(rotation=dict(frequency="weekly"), debug=True)) + commands = ["logging debug-files rotation criteria frequency weekly"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_debug_files_size(self): + set_module_args(dict(rotation=dict(size=10.5), debug=True)) + commands = ["logging debug-files rotation criteria size 10.5"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_debug_files_delete(self): + set_module_args(dict(delete_group="oldest", debug=True)) + commands = ["logging debug-files delete oldest"] + self.execute_module(changed=True, commands=commands) + + ''' nochange ''' + def test_syslog_files_max_num_no_change(self): + set_module_args(dict(rotation=dict(max_num=10))) + self.execute_module(changed=False) + + def test_syslog_files_freq_no_change(self): + set_module_args(dict(rotation=dict(frequency="weekly"))) + self.execute_module(changed=False) + + def test_syslog_files_size_no_change(self): + set_module_args(dict(rotation=dict(size_pct=10))) + self.execute_module(changed=False) + + def test_syslog_debug_files_max_num_no_change(self): + set_module_args(dict(rotation=dict(max_num=20), debug=True)) + self.execute_module(changed=False) + + def test_syslog_debug_files_freq_no_change(self): + set_module_args(dict(rotation=dict(frequency="daily"), debug=True)) + self.execute_module(changed=False) + + def test_syslog_debug_files_size_no_change(self): + set_module_args(dict(rotation=dict(size=20), debug=True)) + self.execute_module(changed=False) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_syslog_remote.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_syslog_remote.py new file mode 100644 index 00000000..aee71536 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_syslog_remote.py @@ -0,0 +1,91 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_syslog_remote +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxSysLogRemoteModule(TestOnyxModule): + + module = onyx_syslog_remote + + def setUp(self): + self.enabled = False + super(TestOnyxSysLogRemoteModule, self).setUp() + self.mock_get_config = patch.object( + onyx_syslog_remote.OnyxSyslogRemoteModule, "show_logging") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxSysLogRemoteModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_logging_config_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_syslog_new_host(self): + set_module_args(dict(host="10.10.20.20")) + commands = ["logging 10.10.20.20"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_new_host_port(self): + set_module_args(dict(host="10.10.20.20", port=8080)) + commands = ['logging 10.10.20.20', 'logging 10.10.20.20 port 8080'] + self.execute_module(changed=True, commands=commands) + + def test_syslog_override(self): + set_module_args(dict(host="10.10.10.12", trap_override=[dict(override_class="sx-sdk", override_priority='emerg'), + dict(override_class="mgmt-back", override_priority='emerg')])) + commands = ["logging 10.10.10.12 trap override class mgmt-back priority emerg"] # no sx-sdk its already configured + self.execute_module(changed=True, commands=commands) + + def test_syslog_trap(self): + set_module_args(dict(host="10.10.10.10", trap="notice")) + commands = ["logging 10.10.10.10 trap notice"] + self.execute_module(changed=True, commands=commands) + + def test_syslog_include_filter(self): + set_module_args(dict(host="10.10.10.10", filter="include", filter_str=".*ERR.*")) + commands = ['logging 10.10.10.10 filter include .*ERR.*'] + self.execute_module(changed=True, commands=commands) + + def test_syslog_no_override(self): + set_module_args(dict(host="10.10.10.12", trap_override=[dict(override_class="sx-sdk", override_enabled=False), + dict(override_class="mgmt-front", override_enabled=False)])) + commands = ['no logging 10.10.10.12 trap override class sx-sdk'] # no mgmt-front because doesn't configured + self.execute_module(changed=True, commands=commands) + + def test_syslog_no_port(self): + set_module_args(dict(host="10.10.10.12", enabled=False)) + commands = ['no logging 10.10.10.12'] + self.execute_module(changed=True, commands=commands) + + def test_syslog_filter_no_change(self): + set_module_args(dict(host="10.10.10.10", filter="exclude", filter_str=".*ERR.*")) + self.execute_module(changed=False) + + def test_syslog_trap_no_change(self): + set_module_args(dict(host="10.10.10.10", trap="info")) + self.execute_module(changed=False) + + def test_syslog_add_port_no_change(self): + set_module_args(dict(host="10.10.10.12", port=80)) + self.execute_module(changed=False) + + def test_syslog_override_no_change(self): + set_module_args(dict(host="10.10.10.12", trap_override=[dict(override_priority="emerg", override_class="sx-sdk")])) + self.execute_module(changed=False) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_traffic_class.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_traffic_class.py new file mode 100644 index 00000000..da7411e9 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_traffic_class.py @@ -0,0 +1,108 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_traffic_class +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxTrafficClassModule(TestOnyxModule): + + module = onyx_traffic_class + arp_suppression = True + + def setUp(self): + super(TestOnyxTrafficClassModule, self).setUp() + self.mock_get_congestion_control_config = patch.object( + onyx_traffic_class.OnyxTrafficClassModule, "_show_interface_congestion_control") + self.get_congestion_control_config = self.mock_get_congestion_control_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_dcb_config = patch.object( + onyx_traffic_class.OnyxTrafficClassModule, "_show_interface_dcb_ets") + self.get_dcb_config = self.mock_get_dcb_config.start() + + def tearDown(self): + super(TestOnyxTrafficClassModule, self).tearDown() + self.mock_get_congestion_control_config.stop() + self.mock_load_config.stop() + self.mock_get_dcb_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + interfaces_congestion_control_config_file = 'onyx_show_interface_congestion_control.cfg' + interfaces_dcb_config_file = 'onyx_show_dcb_ets_interface.cfg' + interfaces_congestion_control_data = load_fixture(interfaces_congestion_control_config_file) + interfaces_dcb_config_data = load_fixture(interfaces_dcb_config_file) + self.get_congestion_control_config.return_value = interfaces_congestion_control_data + self.get_dcb_config.return_value = interfaces_dcb_config_data + self.load_config.return_value = None + + def test_configure_congestion_control_disabled_with_change(self): + set_module_args(dict(interfaces=["Eth1/1"], tc=1, + congestion_control=dict(control="ecn", threshold_mode="absolute", + min_threshold=500, max_threshold=1500))) + commands = [ + "interface ethernet 1/1 traffic-class 1 congestion-control ecn minimum-absolute 500 maximum-absolute 1500" + ] + self.execute_module(changed=True, commands=commands) + + def test_configure_congestion_control_disabled_with_no_change(self): + set_module_args(dict(state="disabled", interfaces=["Eth1/1"], tc=0)) + + self.execute_module(changed=False) + + def test_configure_congestion_control_with_change(self): + set_module_args(dict(interfaces=["Eth1/1"], tc=2, + congestion_control=dict(control="ecn", threshold_mode="relative", + min_threshold=9, max_threshold=88))) + commands = [ + "interface ethernet 1/1 traffic-class 2 congestion-control ecn minimum-relative 9 maximum-relative 88" + ] + self.execute_module(changed=True, commands=commands) + + def test_configure_congestion_control_absolute_with_change(self): + set_module_args(dict(interfaces=["Eth1/1"], tc=3, + congestion_control=dict(control="ecn", threshold_mode="absolute", + min_threshold=500, max_threshold=1500))) + commands = [ + "interface ethernet 1/1 traffic-class 3 congestion-control ecn minimum-absolute 500 maximum-absolute 1500" + ] + self.execute_module(changed=True, commands=commands) + + def test_configure_congestion_control_with_no_change(self): + set_module_args(dict(interfaces=["Eth1/1"], tc=3, + congestion_control=dict(control="ecn", threshold_mode="absolute", + min_threshold=500, max_threshold=1550))) + self.execute_module(changed=False) + + def test_configure_dcb_mode_with_no_change(self): + set_module_args(dict(interfaces=["Eth1/1"], tc=3, dcb=dict(mode="strict"))) + self.execute_module(changed=False) + + def test_configure_dcb_strict_mode_with_change(self): + set_module_args(dict(interfaces=["Eth1/1"], tc=1, dcb=dict(mode="strict"))) + commands = [ + "interface ethernet 1/1 traffic-class 1 dcb ets strict" + ] + self.execute_module(changed=True, commands=commands) + + def test_configure_dcb_wrr_mode_with_change(self): + set_module_args(dict(interfaces=["Eth1/1"], tc=0, dcb=dict(mode="wrr", weight=10))) + commands = [ + "interface ethernet 1/1 traffic-class 0 dcb ets wrr 10" + ] + self.execute_module(changed=True, commands=commands) + + def test_configure_dcb_wrr_mode_with_no_change(self): + set_module_args(dict(interfaces=["Eth1/1"], tc=0, dcb=dict(mode="wrr", weight=12))) + + self.execute_module(changed=False) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_username.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_username.py new file mode 100644 index 00000000..bfd95b6d --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_username.py @@ -0,0 +1,99 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_username +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxUsernameModule(TestOnyxModule): + + module = onyx_username + + def setUp(self): + self.enabled = False + super(TestOnyxUsernameModule, self).setUp() + self.mock_get_config = patch.object( + onyx_username.OnyxUsernameModule, "_get_username_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxUsernameModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_username_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_new_username(self): + set_module_args(dict(username='test')) + commands = ['username test'] + self.execute_module(changed=True, commands=commands) + + def test_change_full_username(self): + set_module_args(dict(username='anass', full_name="anasshami")) + commands = ['username anass full-name anasshami'] + self.execute_module(changed=True, commands=commands) + + def test_change_username_password(self): + set_module_args(dict(username='anass', password="12345")) + commands = ['username anass password 12345'] + self.execute_module(changed=True, commands=commands) + + def test_change_username_password_encrypted(self): + set_module_args(dict(username='anass', password="12345", encrypted_password=True)) + commands = ['username anass password 7 12345'] + self.execute_module(changed=True, commands=commands) + + def test_disable_username(self): + set_module_args(dict(username='anass', disabled="all")) + commands = ['username anass disable'] + self.execute_module(changed=True, commands=commands) + + def test_disable_username_login(self): + set_module_args(dict(username='anass', disabled="login")) + commands = ['username anass disable login'] + self.execute_module(changed=True, commands=commands) + + def test_disable_username_password(self): + set_module_args(dict(username='anass', disabled="password")) + commands = ['username anass disable password'] + self.execute_module(changed=True, commands=commands) + + def test_change_username_capability(self): + set_module_args(dict(username='anass', capability="monitor")) + commands = ['username anass capability monitor'] + self.execute_module(changed=True, commands=commands) + + def test_disconnect_username(self): + set_module_args(dict(username='anass', disconnected=True)) + commands = ['username anass disconnect'] + self.execute_module(changed=True, commands=commands) + + def test_no_change_username_capability(self): + set_module_args(dict(username='anass', capability="admin")) + self.execute_module(changed=False) + + def test_no_change_username_disabled(self): + set_module_args(dict(username='anassh', disabled="all")) + self.execute_module(changed=False) + + def test_no_change_username_nopass(self): + set_module_args(dict(username='admin', nopassword=True)) + self.execute_module(changed=False) + + def test_no_change_full_username(self): + set_module_args(dict(username='admin', full_name="System Administrator")) + self.execute_module(changed=False) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_vlan.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_vlan.py new file mode 100644 index 00000000..0511b7c1 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_vlan.py @@ -0,0 +1,106 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_vlan +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxVlanModule(TestOnyxModule): + + module = onyx_vlan + + def setUp(self): + super(TestOnyxVlanModule, self).setUp() + self.mock_get_config = patch.object( + onyx_vlan.OnyxVlanModule, "_get_vlan_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_version = patch.object( + onyx_vlan.OnyxVlanModule, "_get_os_version") + self.get_version = self.mock_get_version.start() + + def tearDown(self): + super(TestOnyxVlanModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_get_version.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_vlan_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + self.get_version.return_value = "3.6.5000" + + def test_vlan_no_change(self): + set_module_args(dict(vlan_id=20)) + self.execute_module(changed=False) + + def test_vlan_remove_name(self): + set_module_args(dict(vlan_id=10, name='')) + commands = ['vlan 10 no name'] + self.execute_module(changed=True, commands=commands) + + def test_vlan_change_name(self): + set_module_args(dict(vlan_id=10, name='test-test')) + commands = ['vlan 10 name test-test'] + self.execute_module(changed=True, commands=commands) + + def test_vlan_create(self): + set_module_args(dict(vlan_id=30)) + commands = ['vlan 30', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_vlan_create_with_name(self): + set_module_args(dict(vlan_id=30, name='test-test')) + commands = ['vlan 30', 'exit', 'vlan 30 name test-test'] + self.execute_module(changed=True, commands=commands) + + def test_vlan_remove(self): + set_module_args(dict(vlan_id=20, state='absent')) + commands = ['no vlan 20'] + self.execute_module(changed=True, commands=commands) + + def test_vlan_remove_not_exist(self): + set_module_args(dict(vlan_id=30, state='absent')) + self.execute_module(changed=False) + + def test_vlan_aggregate(self): + aggregate = list() + aggregate.append(dict(vlan_id=30)) + aggregate.append(dict(vlan_id=20)) + set_module_args(dict(aggregate=aggregate)) + commands = ['vlan 30', 'exit'] + self.execute_module(changed=True, commands=commands) + + def test_vlan_aggregate_purge(self): + aggregate = list() + aggregate.append(dict(vlan_id=30)) + aggregate.append(dict(vlan_id=20)) + set_module_args(dict(aggregate=aggregate, purge=True)) + commands = ['vlan 30', 'exit', 'no vlan 10', 'no vlan 1'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_vxlan.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_vxlan.py new file mode 100644 index 00000000..99df6eb6 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_vxlan.py @@ -0,0 +1,101 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_vxlan +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxVxlanModule(TestOnyxModule): + + module = onyx_vxlan + arp_suppression = True + + def setUp(self): + super(TestOnyxVxlanModule, self).setUp() + self.mock_get_vxlan_config = patch.object( + onyx_vxlan.OnyxVxlanModule, "_show_vxlan_config") + self.get_vxlan_config = self.mock_get_vxlan_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_nve_detail = patch.object( + onyx_vxlan.OnyxVxlanModule, "_show_nve_detail") + self.get_nve_detail = self.mock_get_nve_detail.start() + + def tearDown(self): + super(TestOnyxVxlanModule, self).tearDown() + self.mock_get_vxlan_config.stop() + self.mock_load_config.stop() + self.mock_get_nve_detail.stop() + + def load_fixtures(self, commands=None, transport='cli'): + interfaces_nve_config_file = 'onyx_show_interfaces_nve.cfg' + interfaces_nve_detail_config_file = 'onyx_show_interfaces_nve_detail.cfg' + self.get_nve_detail.return_value = None + interfaces_nve_detail_data = load_fixture(interfaces_nve_detail_config_file) + interfaces_nv_data = load_fixture(interfaces_nve_config_file) + self.get_nve_detail.return_value = interfaces_nve_detail_data + if self.arp_suppression is False: + interfaces_nve_detail_data[0]["10"][0]["Neigh Suppression"] = "Disable" + interfaces_nve_detail_data[0]["6"][0]["Neigh Suppression"] = "Disable" + self.get_nve_detail.return_value = interfaces_nve_detail_data + self.get_vxlan_config.return_value = interfaces_nv_data + + self.load_config.return_value = None + + def test_configure_vxlan_no_change(self): + set_module_args(dict(nve_id=1, loopback_id=1, bgp=True, mlag_tunnel_ip='192.10.10.1', + vni_vlan_list=[dict(vlan_id=10, vni_id=10010), dict(vlan_id=6, vni_id=10060)], + arp_suppression=True)) + self.execute_module(changed=False) + + def test_configure_vxlan_with_change(self): + set_module_args(dict(nve_id=2, loopback_id=1, bgp=True, mlag_tunnel_ip='192.10.10.1', + vni_vlan_list=[dict(vlan_id=10, vni_id=10010), dict(vlan_id=6, vni_id=10060)], + arp_suppression=True)) + commands = [ + "no interface nve 1", "interface nve 2", "exit", + "interface nve 2 vxlan source interface loopback 1 ", + "interface nve 2 nve controller bgp", "interface nve 2 vxlan mlag-tunnel-ip 192.10.10.1", + "interface nve 2 nve neigh-suppression", "interface nve 2 nve vni 10010 vlan 10", + "interface vlan 10", "exit", "interface nve 2 nve vni 10060 vlan 6", "interface vlan 6", "exit" + ] + self.execute_module(changed=True, commands=commands) + + def test_loopback_id_with_change(self): + set_module_args(dict(nve_id=1, loopback_id=2, bgp=True, mlag_tunnel_ip='192.10.10.1', + vni_vlan_list=[dict(vlan_id=10, vni_id=10010), dict(vlan_id=6, vni_id=10060)], + arp_suppression=True)) + commands = ["interface nve 1 vxlan source interface loopback 2 "] + self.execute_module(changed=True, commands=commands) + + def test_mlag_tunnel_ip_with_change(self): + set_module_args(dict(nve_id=1, loopback_id=1, bgp=True, mlag_tunnel_ip='192.10.10.10', + vni_vlan_list=[dict(vlan_id=10, vni_id=10010), dict(vlan_id=6, vni_id=10060)], + arp_suppression=True)) + commands = ["interface nve 1 vxlan mlag-tunnel-ip 192.10.10.10"] + self.execute_module(changed=True, commands=commands) + + def test_vni_vlan_list_with_change(self): + set_module_args(dict(nve_id=1, loopback_id=1, bgp=True, mlag_tunnel_ip='192.10.10.1', + vni_vlan_list=[dict(vlan_id=11, vni_id=10011), dict(vlan_id=7, vni_id=10061)], + arp_suppression=False)) + commands = ["interface nve 1 nve vni 10011 vlan 11", "interface nve 1 nve vni 10061 vlan 7"] + self.execute_module(changed=True, commands=commands) + + def test_arp_suppression_with_change(self): + self.arp_suppression = False + set_module_args(dict(nve_id=1, loopback_id=1, bgp=True, mlag_tunnel_ip='192.10.10.1', + vni_vlan_list=[dict(vlan_id=10, vni_id=10010), dict(vlan_id=6, vni_id=10060)], + arp_suppression=True)) + commands = ["interface vlan 10", "exit", "interface vlan 6", "exit"] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_wjh.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_wjh.py new file mode 100644 index 00000000..32fa0e54 --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/test_onyx_wjh.py @@ -0,0 +1,66 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from unittest.mock import patch +from ansible_collections.mellanox.onyx.plugins.modules import onyx_wjh +from .utils import set_module_args +from .onyx_module import TestOnyxModule, load_fixture + + +class TestOnyxWJHModule(TestOnyxModule): + + module = onyx_wjh + + def setUp(self): + self.enabled = False + super(TestOnyxWJHModule, self).setUp() + self.mock_get_config = patch.object( + onyx_wjh.OnyxWJHModule, "_get_wjh_config") + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible_collections.mellanox.onyx.plugins.module_utils.network.onyx.onyx.load_config') + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestOnyxWJHModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport='cli'): + config_file = 'onyx_wjh_show.cfg' + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_wjh_no_change(self): + set_module_args(dict(group='forwarding', enabled=False)) + self.execute_module(changed=False) + + def test_wjh_enable(self): + set_module_args(dict(group='forwarding', enabled=True)) + commands = ['what-just-happened forwarding enable'] + self.execute_module(changed=True, commands=commands) + + def test_wjh_export_no_change(self): + set_module_args(dict(export_group='forwarding', auto_export=False)) + self.execute_module(changed=False) + + def test_wjh_export_enable(self): + set_module_args(dict(export_group='forwarding', auto_export=True)) + commands = ['what-just-happened auto-export forwarding enable'] + self.execute_module(changed=True, commands=commands) + + def test_wjh_export_disable(self): + set_module_args(dict(export_group='all', auto_export=False)) + commands = ['no what-just-happened auto-export all enable'] + self.execute_module(changed=True, commands=commands) + + def test_wjh_clear(self): + set_module_args(dict(clear_group='all')) + commands = ['clear what-just-happened pcap-files all'] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/utils.py b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/utils.py new file mode 100644 index 00000000..07258f8c --- /dev/null +++ b/collections-debian-merged/ansible_collections/mellanox/onyx/tests/unit/modules/utils.py @@ -0,0 +1,56 @@ +# +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import json + +from unittest import TestCase +from unittest.mock import patch + +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + + +def set_module_args(args): + if '_ansible_remote_tmp' not in args: + args['_ansible_remote_tmp'] = '/tmp' + if '_ansible_keep_remote_files' not in args: + args['_ansible_keep_remote_files'] = False + + args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +def exit_json(*args, **kwargs): + if 'changed' not in kwargs: + kwargs['changed'] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + kwargs['failed'] = True + raise AnsibleFailJson(kwargs) + + +class ModuleTestCase(TestCase): + + def setUp(self): + self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json) + self.mock_module.start() + self.mock_sleep = patch('time.sleep') + self.mock_sleep.start() + set_module_args({}) + self.addCleanup(self.mock_module.stop) + self.addCleanup(self.mock_sleep.stop) |