├── .github └── workflows │ ├── CI.yml │ └── FastCI.yml ├── .gitignore ├── CHANGELOG.rst ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── RELEASE_POLICY.md ├── changelogs ├── changelog.yaml ├── config.yaml └── fragments │ └── .keep ├── ciscosmb_commands.yml ├── ciscosmb_gather_facts.yml ├── ciscosmb_inventory_template.yml ├── galaxy-importer.cfg ├── galaxy.yml ├── meta └── runtime.yml ├── plugins ├── cliconf │ └── ciscosmb.py ├── module_utils │ ├── __init__.py │ ├── ciscosmb.py │ └── ciscosmb_canonical_map.py ├── modules │ ├── __init__.py │ ├── command.py │ └── facts.py └── terminal │ └── ciscosmb.py ├── requirements-dev.txt └── tests ├── requirements.yml └── unit ├── __init__.py ├── compat ├── __init__.py ├── builtins.py ├── mock.py └── unittest.py ├── plugins ├── __init__.py └── modules │ ├── __init__.py │ ├── ciscosmb │ ├── __init__.py │ ├── ciscosmb_module.py │ ├── fixtures │ │ ├── ciscosmb_command-C1300-8FP-2G-show_version │ │ ├── ciscosmb_command-CBS350-24P-4G-show_version │ │ ├── ciscosmb_command-SG350-28-K9-show_version │ │ ├── ciscosmb_command-SG500-52-K9-show_version │ │ ├── ciscosmb_command-SG550X-24MP-K9-show_version │ │ ├── ciscosmb_command-stackSG550X-48-show_version │ │ ├── ciscosmb_facts-C1300-8FP-2G-dir │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_cpu_utilization │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_interfaces_configuration │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_interfaces_description │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_interfaces_status │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_inventory │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_ip_interface │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_ip_route │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_ipv6_interface_brief │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_ports_jumbo-frame │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_system │ │ ├── ciscosmb_facts-C1300-8FP-2G-show_version │ │ ├── ciscosmb_facts-CBS350-24P-4G-dir │ │ ├── ciscosmb_facts-CBS350-24P-4G-show_cpu_utilization │ │ ├── ciscosmb_facts-CBS350-24P-4G-show_inventory │ │ ├── ciscosmb_facts-CBS350-24P-4G-show_running-config_detailed │ │ ├── ciscosmb_facts-CBS350-24P-4G-show_system │ │ ├── ciscosmb_facts-CBS350-24P-4G-show_version │ │ ├── ciscosmb_facts-SG350-28-K9-show_cpu_utilization │ │ ├── ciscosmb_facts-SG350-28-K9-show_inventory │ │ ├── ciscosmb_facts-SG350-28-K9-show_system │ │ ├── ciscosmb_facts-SG350-28-K9-show_version │ │ ├── ciscosmb_facts-SG500-52-K9-dir │ │ ├── ciscosmb_facts-SG500-52-K9-show_cpu_utilization │ │ ├── ciscosmb_facts-SG500-52-K9-show_interfaces_configuration │ │ ├── ciscosmb_facts-SG500-52-K9-show_interfaces_description │ │ ├── ciscosmb_facts-SG500-52-K9-show_interfaces_status │ │ ├── ciscosmb_facts-SG500-52-K9-show_inventory │ │ ├── ciscosmb_facts-SG500-52-K9-show_ip_interface │ │ ├── ciscosmb_facts-SG500-52-K9-show_ip_route │ │ ├── ciscosmb_facts-SG500-52-K9-show_ipv6_interface_brief │ │ ├── ciscosmb_facts-SG500-52-K9-show_lldp_neighbors │ │ ├── ciscosmb_facts-SG500-52-K9-show_ports_jumbo-frame │ │ ├── ciscosmb_facts-SG500-52-K9-show_running-config_detailed │ │ ├── ciscosmb_facts-SG500-52-K9-show_system │ │ ├── ciscosmb_facts-SG500-52-K9-show_version │ │ ├── ciscosmb_facts-SG550X-24MP-K9-dir │ │ ├── ciscosmb_facts-SG550X-24MP-K9-show_cpu_utilization │ │ ├── ciscosmb_facts-SG550X-24MP-K9-show_inventory │ │ ├── ciscosmb_facts-SG550X-24MP-K9-show_running-config_detailed │ │ ├── ciscosmb_facts-SG550X-24MP-K9-show_system │ │ ├── ciscosmb_facts-SG550X-24MP-K9-show_version │ │ ├── ciscosmb_facts-SX550X-24F-K9-show_cpu_utilization │ │ ├── ciscosmb_facts-SX550X-24F-K9-show_inventory │ │ ├── ciscosmb_facts-SX550X-24F-K9-show_system │ │ ├── ciscosmb_facts-SX550X-24F-K9-show_version │ │ ├── ciscosmb_facts-stackSG550X-48-dir │ │ ├── ciscosmb_facts-stackSG550X-48-show_cpu_utilization │ │ ├── ciscosmb_facts-stackSG550X-48-show_inventory │ │ ├── ciscosmb_facts-stackSG550X-48-show_system │ │ └── ciscosmb_facts-stackSG550X-48-show_version │ ├── test_ciscosmb_command-C1300-8FP-2G.py │ ├── test_ciscosmb_command-CBS350-24P-4G.py │ ├── test_ciscosmb_command-SG350-28-K9.py │ ├── test_ciscosmb_command-SG500-52-K9.py │ ├── test_ciscosmb_command-SG550X-24MP-K9.py │ ├── test_ciscosmb_command-stackSG550X-48.py │ ├── test_ciscosmb_facts-C1300-8FP-2G.py │ ├── test_ciscosmb_facts-CBS350-24P-4G.py │ ├── test_ciscosmb_facts-SG350-28-K9.py │ ├── test_ciscosmb_facts-SG500-52-K9.py │ ├── test_ciscosmb_facts-SG550X-24MP-K9.py │ ├── test_ciscosmb_facts-SX550X-24F-K9.py │ └── test_ciscosmb_facts-stackSG550X-48.py │ └── utils.py ├── requirements.txt └── requirements.yml /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | # README FIRST 2 | # 1. If you don't have unit tests, remove that section. 3 | # 2. If your collection depends on other collections ensure they are installed, 4 | # add them to the "test-deps" input. 5 | # 3. For the comprehensive list of the inputs supported by the 6 | # ansible-community/ansible-test-gh-action GitHub Action, see 7 | # https://github.com/marketplace/actions/ansible-test. 8 | # 4. If you need help please ask in #ansible-community on the Libera.chat IRC 9 | # network. 10 | 11 | name: CI 12 | on: 13 | # Run CI against all pushes (direct commits, also merged PRs), Pull Requests 14 | push: 15 | branches: 16 | - main 17 | - stable-* 18 | pull_request: 19 | # Run CI once every Sunday (at 06:00 UTC) 20 | # This ensures that even if there haven't been commits that we are still 21 | # testing against latest version of ansible-test for each ansible-core 22 | # version 23 | schedule: 24 | - cron: "0 6 * * 0" 25 | # manual 26 | workflow_dispatch: 27 | 28 | jobs: 29 | ### 30 | # Sanity tests (REQUIRED) 31 | # 32 | # https://docs.ansible.com/ansible/latest/dev_guide/testing_sanity.html 33 | 34 | sanity: 35 | name: Sanity tests 36 | runs-on: ${{ matrix.os }} 37 | strategy: 38 | fail-fast: false 39 | matrix: 40 | # Ansible Support Matrix 41 | # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix 42 | ansible: 43 | - stable-2.14 44 | - stable-2.15 45 | - stable-2.16 46 | - stable-2.19 47 | # - devel - unstable 48 | python: 49 | - "3.9" 50 | - "3.10" 51 | - "3.11" 52 | - "3.12" 53 | - "3.13" 54 | os: 55 | - ubuntu-24.04 56 | exclude: 57 | # no support 58 | - ansible: stable-2.14 59 | python: "3.12" 60 | - ansible: stable-2.14 61 | python: "3.13" 62 | - ansible: stable-2.15 63 | python: "3.12" 64 | - ansible: stable-2.15 65 | python: "3.13" 66 | - ansible: stable-2.16 67 | python: "3.13" 68 | steps: 69 | - name: Sanity testing 70 | uses: ansible-community/ansible-test-gh-action@release/v1 71 | with: 72 | ansible-core-version: ${{ matrix.ansible }} 73 | target-python-version: ${{ matrix.python }} 74 | testing-type: sanity 75 | test-deps: >- 76 | ansible.netcommon ansible.utils community.internal_test_tools 77 | 78 | ### 79 | # Unit tests (OPTIONAL) 80 | # 81 | # https://docs.ansible.com/ansible/latest/dev_guide/testing_units.html 82 | 83 | units: 84 | name: Unit tests (${{ matrix.ansible }}+py${{ matrix.python }}) 85 | runs-on: ${{ matrix.os }} 86 | strategy: 87 | fail-fast: false 88 | matrix: 89 | # Ansible Support matrix 90 | # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix 91 | ansible: 92 | - stable-2.14 93 | - stable-2.15 94 | - stable-2.16 95 | - stable-2.19 96 | - devel 97 | python: 98 | - "3.9" 99 | - "3.10" 100 | - "3.11" 101 | - "3.12" 102 | - "3.13" 103 | os: 104 | - ubuntu-24.04 105 | exclude: 106 | # no support 107 | - ansible: stable-2.14 108 | python: "3.12" 109 | - ansible: stable-2.14 110 | python: "3.13" 111 | - ansible: stable-2.15 112 | python: "3.12" 113 | - ansible: stable-2.15 114 | python: "3.13" 115 | - ansible: stable-2.16 116 | python: "3.13" 117 | steps: 118 | - name: Unit testing 119 | uses: ansible-community/ansible-test-gh-action@release/v1 120 | with: 121 | ansible-core-version: ${{ matrix.ansible }} 122 | target-python-version: ${{ matrix.python }} 123 | testing-type: units 124 | test-deps: >- 125 | ansible.netcommon ansible.utils community.internal_test_tools 126 | -------------------------------------------------------------------------------- /.github/workflows/FastCI.yml: -------------------------------------------------------------------------------- 1 | # README FIRST 2 | # 1. If you don't have unit tests, remove that section. 3 | # 2. If your collection depends on other collections ensure they are installed, 4 | # add them to the "test-deps" input. 5 | # 3. For the comprehensive list of the inputs supported by the 6 | # ansible-community/ansible-test-gh-action GitHub Action, see 7 | # https://github.com/marketplace/actions/ansible-test. 8 | # 4. If you need help please ask in #ansible-community on the Libera.chat IRC 9 | # network. 10 | 11 | name: Fast CI 12 | on: 13 | # Run CI against all pushes 14 | push: 15 | branches-ignore: 16 | - main 17 | pull_request: 18 | branches-ignore: 19 | - main 20 | # manual 21 | workflow_dispatch: 22 | 23 | jobs: 24 | ### 25 | # Sanity tests (REQUIRED) 26 | # 27 | # https://docs.ansible.com/ansible/latest/dev_guide/testing_sanity.html 28 | 29 | sanity: 30 | name: Sanity tests 31 | runs-on: ${{ matrix.os }} 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | # Ansible Support matrix 36 | # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix 37 | ansible: 38 | - stable-2.19 39 | python: 40 | - 3.13 41 | os: 42 | - ubuntu-24.04 43 | 44 | steps: 45 | - name: Sanity testing 46 | uses: ansible-community/ansible-test-gh-action@release/v1 47 | with: 48 | ansible-core-version: ${{ matrix.ansible }} 49 | target-python-version: ${{ matrix.python }} 50 | testing-type: sanity 51 | test-deps: >- 52 | ansible.netcommon ansible.utils community.internal_test_tools 53 | unit: 54 | name: Unit tests 55 | runs-on: ${{ matrix.os }} 56 | strategy: 57 | fail-fast: false 58 | matrix: 59 | # Ansible Support matrix 60 | # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix 61 | ansible: 62 | - stable-2.19 63 | python: 64 | - 3.13 65 | os: 66 | - ubuntu-24.04 67 | 68 | steps: 69 | - name: Unit testing 70 | uses: ansible-community/ansible-test-gh-action@release/v1 71 | with: 72 | ansible-core-version: ${{ matrix.ansible }} 73 | target-python-version: ${{ matrix.python }} 74 | testing-type: units 75 | test-deps: >- 76 | ansible.netcommon ansible.utils community.internal_test_tools 77 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # newer version real inventory 2 | ciscosmb_inventory.yml 3 | 4 | # configs output 5 | configs 6 | 7 | # builded package 8 | community-ciscosmb-*.tar.gz 9 | 10 | # galaxy-importer output 11 | importer_result.json 12 | 13 | # unit test output 14 | tests/output/ 15 | changelogs/.plugin-cache.yaml 16 | 17 | # Byte-compiled / optimized / DLL files 18 | __pycache__/ 19 | *.py[cod] 20 | *$py.class 21 | ansible_collections 22 | # C extensions 23 | *.so 24 | 25 | # Distribution / packaging 26 | .Python 27 | build/ 28 | develop-eggs/ 29 | dist/ 30 | downloads/ 31 | eggs/ 32 | .eggs/ 33 | lib/ 34 | lib64/ 35 | parts/ 36 | sdist/ 37 | var/ 38 | wheels/ 39 | pip-wheel-metadata/ 40 | share/python-wheels/ 41 | *.egg-info/ 42 | .installed.cfg 43 | *.egg 44 | MANIFEST 45 | 46 | # PyInstaller 47 | # Usually these files are written by a python script from a template 48 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 49 | *.manifest 50 | *.spec 51 | 52 | # Installer logs 53 | pip-log.txt 54 | pip-delete-this-directory.txt 55 | 56 | # Unit test / coverage reports 57 | htmlcov/ 58 | .tox/ 59 | .nox/ 60 | .coverage 61 | .coverage.* 62 | .cache 63 | nosetests.xml 64 | coverage.xml 65 | *.cover 66 | *.py,cover 67 | .hypothesis/ 68 | .pytest_cache/ 69 | 70 | # Translations 71 | *.mo 72 | *.pot 73 | 74 | # Django stuff: 75 | *.log 76 | local_settings.py 77 | db.sqlite3 78 | db.sqlite3-journal 79 | 80 | # Flask stuff: 81 | instance/ 82 | .webassets-cache 83 | 84 | # Scrapy stuff: 85 | .scrapy 86 | 87 | # Sphinx documentation 88 | docs/_build/ 89 | 90 | # PyBuilder 91 | target/ 92 | 93 | # Jupyter Notebook 94 | .ipynb_checkpoints 95 | 96 | # IPython 97 | profile_default/ 98 | ipython_config.py 99 | 100 | # pyenv 101 | .python-version 102 | 103 | # pipenv 104 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 105 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 106 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 107 | # install all needed dependencies. 108 | #Pipfile.lock 109 | 110 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 111 | __pypackages__/ 112 | 113 | # Celery stuff 114 | celerybeat-schedule 115 | celerybeat.pid 116 | 117 | # SageMath parsed files 118 | *.sage.py 119 | 120 | # Environments 121 | .env 122 | .venv 123 | env/ 124 | venv/ 125 | ENV/ 126 | env.bak/ 127 | venv.bak/ 128 | 129 | # Spyder project settings 130 | .spyderproject 131 | .spyproject 132 | 133 | # Rope project settings 134 | .ropeproject 135 | 136 | # mkdocs documentation 137 | /site 138 | 139 | # mypy 140 | .mypy_cache/ 141 | .dmypy.json 142 | dmypy.json 143 | 144 | # Pyre type checker 145 | .pyre/ 146 | -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ===================================== 2 | CiscoSMB Ansible module Release Notes 3 | ===================================== 4 | 5 | .. contents:: Topics 6 | 7 | v1.0.11 8 | ======= 9 | 10 | Release Summary 11 | --------------- 12 | 13 | Release Date: 2025-07-14 14 | 15 | Minor Changes 16 | ------------- 17 | 18 | - Update modules to conform core 2.19 and templating changes 19 | - solves 20 | 21 | v1.0.10 22 | ======= 23 | 24 | Release Summary 25 | --------------- 26 | 27 | Release Date: 2024-12-10 28 | Add compatibility with Cisco Catalyst C1300 by solving issue #79 thanx to @alexandrud . 29 | 30 | Minor Changes 31 | ------------- 32 | 33 | - added Catalyst 1300 to supported platforms 34 | - parsing neighbour table allowes empty 4th column to allow Cisco Catalyst 1300 support 35 | 36 | v1.0.9 37 | ====== 38 | 39 | Release Summary 40 | --------------- 41 | 42 | Primarily revert release. Previous release (1.0.8) fixed typo in attribute name, but it was breaking change. 43 | This release brought the typo back (bandwith) and just added the new attribute with correct name "bandwidth" as a copy of the mistypped attribute. 44 | 45 | Attribude "bandwith" will be removed in next minor release. 46 | 47 | Minor Changes 48 | ------------- 49 | 50 | - added additional attribute - add interface 'bandwidth' attribute 51 | - reverted attribute change - keep interface 'bandwith' attribute 52 | 53 | Bugfixes 54 | -------- 55 | 56 | - typo in changelog fragment template 57 | - typo in test script 58 | 59 | v1.0.8 60 | ====== 61 | 62 | Release Summary 63 | --------------- 64 | 65 | Release Date: 2024-04-09 66 | 67 | Minor bugfixes, updated CI 68 | 69 | Minor Changes 70 | ------------- 71 | 72 | - docs - addeed info about SG-250 support and testing 73 | 74 | Breaking Changes / Porting Guide 75 | -------------------------------- 76 | 77 | - in facts of interface 'bandwith' changed to 'bandwidth' 78 | 79 | Bugfixes 80 | -------- 81 | 82 | - issue 83 | - solved issue 84 | 85 | v1.0.7 86 | ====== 87 | 88 | Release Summary 89 | --------------- 90 | 91 | Release Date: 2023-10-30 92 | Fix issue on CSB-350 #69 93 | Clarify configuration doc #66 #64 94 | 95 | Bugfixes 96 | -------- 97 | 98 | - added Cisco device config guide to address issue 99 | - added extra "\n" to sending commands to address issue 100 | 101 | v1.0.6 102 | ====== 103 | 104 | Release Summary 105 | --------------- 106 | 107 | Code cleaning, better documentation 108 | 109 | Minor Changes 110 | ------------- 111 | 112 | - added Ansible playbook examples ``cismosmb_inventory_template.yml``, ``cismosmb_gather_facts.yml``, ``cismosmb_commands.yml`` 113 | - no longer testing for ansible 2.9 and for Python 2.6 / 2.7 114 | - removed unused portion of code in cliconf/ciscosmb.yml 115 | - test Ansible 2.14 116 | 117 | Deprecated Features 118 | ------------------- 119 | 120 | - support for Python 2.6 nad 2.7 121 | - support for ansible 2.9 122 | 123 | Removed Features (previously deprecated) 124 | ---------------------------------------- 125 | 126 | - remove testing for Python 2.6 nad 2.7 127 | - remove testing for ansible 2.9 128 | 129 | v1.0.5 130 | ====== 131 | 132 | Minor Changes 133 | ------------- 134 | 135 | - CI change to name for validate-module 136 | - CI - add ansible 2.13 to test matrix 137 | 138 | v1.0.4 139 | ====== 140 | 141 | Release Summary 142 | --------------- 143 | 144 | Release Date: 2021-09-13 145 | 146 | Bugfixes 147 | -------- 148 | 149 | - Module command does not support check_mode - https://github.com/ansible-collections/community.ciscosmb/pull/45 150 | 151 | v1.0.3 152 | ====== 153 | 154 | Release Summary 155 | --------------- 156 | 157 | Release Date: 2019-10-31 158 | Minor changes in documentation, adding Python 3.6 as a supported version 159 | 160 | Minor Changes 161 | ------------- 162 | 163 | - Add Py 3.6 to supported python versions (https://github.com/ansible-collections/community.ciscosmb/pull/44) 164 | - Fix link to issue tracker in galaxy.yml (https://github.com/ansible-collections/community.ciscosmb/pull/42) 165 | - Misc doc fixes for collection inclusion (https://github.com/ansible-collections/community.ciscosmb/pull/41) 166 | 167 | v1.0.2 168 | ====== 169 | 170 | Release Summary 171 | --------------- 172 | 173 | Release Date: 2021-08-09 bugfix release 174 | 175 | Minor Changes 176 | ------------- 177 | 178 | - remove unnecersary parameters on function re.sub() 179 | 180 | Bugfixes 181 | -------- 182 | 183 | - solves issue 184 | 185 | v1.0.1 186 | ====== 187 | 188 | Release Summary 189 | --------------- 190 | 191 | Minor fixes for ansible collections inclusion 192 | 193 | Minor Changes 194 | ------------- 195 | 196 | - Added Releasing, CoC and Contributing to README.md 197 | - Added author 198 | - Added license header 199 | - Release policy, versioning, deprecation 200 | - Updated CoC, added email address 201 | - more descriptiove Release section on README.md 202 | 203 | v1.0.0 204 | ====== 205 | 206 | Major Changes 207 | ------------- 208 | 209 | - transform collection qaxi.ciscosmb to community.ciscosmb 210 | - transform community.ciscosmb.ciscosmb_command to community.ciscosmb.command 211 | - transform community.ciscosmb.ciscosmb_facts to community.ciscosmb.facts 212 | 213 | Minor Changes 214 | ------------- 215 | 216 | - setup standard Ansible CI 217 | 218 | v0.9.1 219 | ====== 220 | 221 | Minor Changes 222 | ------------- 223 | 224 | - correct version bumping 225 | 226 | v0.9.0 227 | ====== 228 | 229 | Major Changes 230 | ------------- 231 | 232 | - interface name canonicalization 233 | 234 | v0.8.0 235 | ====== 236 | 237 | Major Changes 238 | ------------- 239 | 240 | - add antsibull-changelog support 241 | 242 | Minor Changes 243 | ------------- 244 | 245 | - Python 2.6, 2.7, 3.5 compatibility 246 | - add Code of conduct 247 | - add Contribution 248 | - add required files for community inclusion 249 | - added ansible dev-guide manual test 250 | - better tests requirements 251 | - check tags and add tag switch 252 | - cluter removed 253 | - code cleaning 254 | - update my tests 255 | 256 | v0.1.1 257 | ====== 258 | 259 | Major Changes 260 | ------------- 261 | 262 | - Python 2.6, 2.7, 3.5 is required 263 | - add antsibull-changelog support 264 | 265 | Minor Changes 266 | ------------- 267 | 268 | - add Code of conduct 269 | - add Contribution 270 | - add required files for community inclusion 271 | - check tags and add tag switch 272 | - cluter removed 273 | - code cleaning 274 | 275 | v0.1.0 276 | ====== 277 | 278 | Major Changes 279 | ------------- 280 | 281 | - added facts subset "interfaces" 282 | 283 | Minor Changes 284 | ------------- 285 | 286 | - remove mock warning 287 | 288 | v0.0.6 289 | ====== 290 | 291 | Major Changes 292 | ------------- 293 | 294 | - add CBS350 support 295 | - unit tests for CBS350 296 | 297 | Minor Changes 298 | ------------- 299 | 300 | - doc update 301 | 302 | v0.0.5 303 | ====== 304 | 305 | Major Changes 306 | ------------- 307 | 308 | - add ciscosmb_command 309 | 310 | v0.0.4 311 | ====== 312 | 313 | Minor Changes 314 | ------------- 315 | 316 | - uptime in seconds 317 | 318 | v0.0.2 319 | ====== 320 | 321 | Major Changes 322 | ------------- 323 | 324 | - ciscosmb_facts with default subset and unit tests 325 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies within all project spaces, and it also applies when 49 | an individual is representing the project or its community in public spaces. 50 | Examples of representing a project or community include using an official 51 | project e-mail address, posting via an official social media account, or acting 52 | as an appointed representative at an online or offline event. Representation of 53 | a project may be further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [qaxi@seznam.cz]. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions (pull requests, feature requests, and so on) are accepted on project Github.com page. Creating Issue before pull request is preffered. Acceptation is not automatic, project management can reject it, or request changes. 4 | 5 | Issues (bugs and feature request) reports are accepted on project Github. 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ansible Cisco Small Bussiness Switches (SMB) module 2 | 3 | Thorough project check - 4 | [![CI](https://github.com/ansible-collections/community.ciscosmb/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/ansible-collections/community.ciscosmb/actions/workflows/CI.yml) 5 | 6 | Ansible Galaxy module for Cisco SMB switches - SG250, SG300, SG500, SG350, SG550, CBS350, C1300 7 | 8 | ## Communication 9 | 10 | - Join the Ansible forum: 11 | 12 | - [Get Help](https://forum.ansible.com/c/help/6): get help or help others. 13 | - [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts. 14 | - [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social 15 | events. 16 | 17 | - The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): 18 | used to announce releases and important changes. 19 | 20 | For more information about communication, see the 21 | [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html). 22 | 23 | ## Install 24 | 25 | ``` 26 | ansible-galaxy collection install community.ciscosmb 27 | ``` 28 | 29 | ## Usage examples 30 | 31 | Tested on devices: 32 | 33 | - SG250-10P 34 | - SG350-10-K9 35 | - SG350-28-K9 36 | - SG500-52-K9 37 | - SG550X-24MP-K9 38 | - CBS350-24P-4G 39 | - SG550X-48 stack 40 | - C1300 41 | 42 | Known to be used with broad range of: 43 | 44 | - Cisco 250 Series Smart Switches 45 | - Cisco Business 350 Series Managed Switches 46 | - Cisco 350 Series Stackable Managed Switches 47 | - Cisco 350X Series Stackable Managed Switches 48 | - Cisco 500 Series Stackable Managed Switches 49 | - Cisco 550X Series Stackable Managed Switches 50 | - Cisco Catalyst 1300 Series Switches 51 | 52 | ### Required device configuration 53 | 54 | Access setup 55 | 56 | ``` 57 | ! you should set enable password 58 | enable password level 15 59 | 60 | ! on user you have two choices 61 | ! use unpriviledged user (for example priv. 7) and "become mode" 62 | username user1 privilege 7 63 | 64 | ! or user with full privileges (priv 15) 65 | username user2 privelege 15 66 | ``` 67 | 68 | Cisco's SSH server setup 69 | 70 | ``` 71 | ! you have to enable SSH server 72 | ip ssh server 73 | ! enable password and/or key 74 | ip ssh password-auth 75 | ip ssh pubkey-auth auto-login 76 | ! generate switch ssh key pair if you did not before 77 | crypto key generate rsa 78 | 79 | ! if you use public keys for users login configure that keys 80 | crypto key pubkey-chain ssh 81 | user-key user2 rsa 82 | key-string AAAAB3NzaC1......XYZ== 83 | exit 84 | ``` 85 | 86 | ### Python versions 87 | 88 | Tested on Python versions: 89 | 90 | - 3.6 91 | - 3.7 92 | - 3.8 93 | - 3.9 94 | - 3.10 95 | - 3.11 96 | - 3.12 97 | 98 | ### Running examples 99 | 100 | For your tests or quick startup use files form repository: 101 | [cismosmb_inventory_template.yml](./ciscosmb_inventory_template.yml), 102 | [cismosmb_gather_facts.yml](./ciscosmb_gather_facts.yml), [cismosmb_commands.yml](./ciscosmb_commands.yml) . 103 | 104 | Prepare your inventory file - copy file [cismosmb_inventory_template.yml](./ciscosmb_inventory_template.yml) to 105 | `cismosmb_inventory.yml` and make your changes. 106 | 107 | Then you can run 108 | 109 | ``` 110 | ansible-playbook -i ciscosmb_inventory.yml cismosmb_gather_facts.yml 111 | ``` 112 | 113 | or 114 | 115 | ``` 116 | ansible-playbook -i ciscosmb_inventory.yml cismosmb_commands.yml 117 | ``` 118 | 119 | ## Developement 120 | 121 | ### Setup environment 122 | 123 | ``` 124 | git clone https://github.com/ansible-collections/community.ciscosmb ansible_collections/community/ciscosmb 125 | git clone --depth=1 --single-branch https://github.com/ansible-collections/ansible.netcommon.git ansible_collections/ansible/netcommon 126 | 127 | cd ansible_collections/community/ciscosmb 128 | 129 | python3 -m venv .venv 130 | . .venv/bin/activate 131 | 132 | pip install ansible 133 | pip install -r requirements-dev.txt 134 | pip install -r tests/unit/requirements.txt 135 | 136 | ``` 137 | 138 | ### Develop 139 | 140 | ``` 141 | cd ansible_collections/community/ciscosmb 142 | git pull 143 | . .venv/bin/activate 144 | 145 | # edit files 146 | vim file 147 | cp changelogs/fragments/.keep changelogs/fragments/featureXYZ.yml 148 | vim changelogs/fragments/featureXYZ.yml 149 | 150 | # test your changes see "Testing" 151 | 152 | git commit -m "xxx" file 153 | ``` 154 | 155 | ### Testing 156 | 157 | ``` 158 | cd ansible_collections/community/ciscosmb 159 | . .venv/bin/activate 160 | 161 | # PY="--python 3.8" # set your version or unset 162 | METHOD="--docker" # or --local if you have no Docker installed 163 | ansible-test sanity ${METHOD} ${PY} \ 164 | && ansible-test units ${METHOD} ${PY} \ 165 | && rm -f ./community-ciscosmb-*.tar.gz \ 166 | && ansible-galaxy collection build -v --force \ 167 | && export GALAXY_IMPORTER_CONFIG=./galaxy-importer.cfg \ 168 | && python3 -m galaxy_importer.main ./community-ciscosmb-*.tar.gz \ 169 | && rm -f ./community-ciscosmb-*.tar.gz 170 | ``` 171 | 172 | ### Release 173 | 174 | ``` 175 | cd ansible_collections/community/ciscosmb 176 | git pull 177 | . .venv/bin/activate 178 | 179 | # edit version x.y.z. in galaxy.yml 180 | vim galaxy.yml 181 | 182 | # edit changelog fragments (template in changelogs/fragments/.keep) 183 | cp changelogs/fragments/.keep changelogs/fragments/release-x.y.z.yml 184 | vim changelogs/fragments/release-x.y.z.yml 185 | 186 | # change and generate CHANGELOG.rst 187 | antsibull-changelog lint -v 188 | antsibull-changelog release -v 189 | 190 | git commit -m "version bump to x.y.z" . 191 | git tag x.y.z 192 | git push 193 | ``` 194 | 195 | ## Releasing, Versioning and Deprecation 196 | 197 | See [RELEASE_POLICY.md](https://github.com/ansible-collections/community.ciscosmb/blob/main/RELEASE_POLICY.md) 198 | 199 | ## Code of Conduct 200 | 201 | See [CODE_OF_CONDUCT.md](https://github.com/ansible-collections/community.ciscosmb/blob/main/CODE_OF_CONDUCT.md) 202 | 203 | ## Contributing 204 | 205 | See [CONTRIBUTING.md](https://github.com/ansible-collections/community.ciscosmb/blob/main/CONTRIBUTING.md) 206 | -------------------------------------------------------------------------------- /RELEASE_POLICY.md: -------------------------------------------------------------------------------- 1 | # Releasing, Versioning and Deprecation 2 | 3 | This collection follows Semantic Versioning. More details on versioning can be found in the Ansible docs. 4 | 5 | We plan to regularly release new minor or bugfix versions once new features or bugfixes have been implemented. 6 | 7 | Releasing the current major version happens from the main branch. We will create a stable-1 branch for 1.x.y versions once we start working on a 2.0.0 release, to allow backporting bugfixes and features from the 2.0.0 branch (main) to stable-1. A stable-2 branch will be created once we work on a 3.0.0 release, and so on. 8 | 9 | We currently are not planning any deprecations or new major releases like 2.0.0 containing backwards incompatible changes. If backwards incompatible changes are needed, we plan to deprecate the old behavior as early as possible. We also plan to backport at least bugfixes for the old major version for some time after releasing a new major version. We will not block community members from backporting other bugfixes and features from the latest stable version to older release branches, under the condition that these backports are of reasonable quality. -------------------------------------------------------------------------------- /changelogs/changelog.yaml: -------------------------------------------------------------------------------- 1 | ancestor: null 2 | releases: 3 | 0.0.2: 4 | changes: 5 | major_changes: 6 | - ciscosmb_facts with default subset and unit tests 7 | 0.0.4: 8 | changes: 9 | minor_changes: 10 | - uptime in seconds 11 | release_date: '2021-01-29' 12 | 0.0.5: 13 | changes: 14 | major_changes: 15 | - add ciscosmb_command 16 | release_date: '2021-02-18' 17 | 0.0.6: 18 | changes: 19 | major_changes: 20 | - add CBS350 support 21 | - unit tests for CBS350 22 | minor_changes: 23 | - doc update 24 | release_date: '2021-02-23' 25 | 0.1.0: 26 | changes: 27 | major_changes: 28 | - added facts subset "interfaces" 29 | minor_changes: 30 | - remove mock warning 31 | release_date: '2021-04-06' 32 | 0.1.1: 33 | changes: 34 | major_changes: 35 | - Python 2.6, 2.7, 3.5 is required 36 | - add antsibull-changelog support 37 | minor_changes: 38 | - add Code of conduct 39 | - add Contribution 40 | - add required files for community inclusion 41 | - check tags and add tag switch 42 | - cluter removed 43 | - code cleaning 44 | fragments: 45 | - 0.1.1-code_cleaning.yml 46 | - 0.1.1-prepare_for_community.yml 47 | release_date: '2021-04-06' 48 | 0.8.0: 49 | changes: 50 | major_changes: 51 | - add antsibull-changelog support 52 | minor_changes: 53 | - Python 2.6, 2.7, 3.5 compatibility 54 | - add Code of conduct 55 | - add Contribution 56 | - add required files for community inclusion 57 | - added ansible dev-guide manual test 58 | - better tests requirements 59 | - check tags and add tag switch 60 | - cluter removed 61 | - code cleaning 62 | - update my tests 63 | fragments: 64 | - 0.8.0-code_cleaning.yml 65 | - 0.8.0-prepare_for_community.yml 66 | - 0.8.0-py27.yml 67 | - 0.8.0-tests.yml 68 | release_date: '2021-04-07' 69 | 0.9.0: 70 | changes: 71 | major_changes: 72 | - interface name canonicalization 73 | fragments: 74 | - interface_canoticalization.yml 75 | release_date: '2021-04-08' 76 | 0.9.1: 77 | changes: 78 | minor_changes: 79 | - correct version bumping 80 | fragments: 81 | - correct_changelog.yml 82 | release_date: '2021-04-08' 83 | 1.0.0: 84 | changes: 85 | major_changes: 86 | - transform collection qaxi.ciscosmb to community.ciscosmb 87 | - transform community.ciscosmb.ciscosmb_command to community.ciscosmb.command 88 | - transform community.ciscosmb.ciscosmb_facts to community.ciscosmb.facts 89 | minor_changes: 90 | - setup standard Ansible CI 91 | fragments: 92 | - CI.yaml 93 | - shorten_module_name.yaml 94 | - transform2community.yml 95 | release_date: '2021-06-04' 96 | 1.0.1: 97 | changes: 98 | minor_changes: 99 | - Added Releasing, CoC and Contributing to README.md 100 | - Added author 101 | - Added license header 102 | - Release policy, versioning, deprecation 103 | - Updated CoC, added email address 104 | - more descriptiove Release section on README.md 105 | release_summary: Minor fixes for ansible collections inclusion 106 | fragments: 107 | - ansible_collections_inclusion.yml 108 | release_date: '2021-07-20' 109 | 1.0.10: 110 | changes: 111 | minor_changes: 112 | - added Catalyst 1300 to supported platforms 113 | - parsing neighbour table allowes empty 4th column to allow Cisco Catalyst 1300 114 | support 115 | release_summary: 'Release Date: 2024-12-10 116 | 117 | Add compatibility with Cisco Catalyst C1300 by solving issue #79 thanx to 118 | @alexandrud . 119 | 120 | ' 121 | fragments: 122 | - 0-readme.yml 123 | - release-1.0.10.yml 124 | - suportforC1300.yml 125 | release_date: '2024-12-10' 126 | 1.0.11: 127 | changes: 128 | minor_changes: 129 | - Update modules to conform core 2.19 and templating changes 130 | - solves 131 | release_summary: 'Release Date: 2025-07-14 132 | 133 | ' 134 | fragments: 135 | - feature-C1300.yml 136 | - feature-core-2.19.yml 137 | - release-1.0.11.yml 138 | release_date: '2025-07-14' 139 | 1.0.2: 140 | changes: 141 | bugfixes: 142 | - solves issue 143 | minor_changes: 144 | - remove unnecersary parameters on function re.sub() 145 | release_summary: 'Release Date: 2021-08-09 bugfix release' 146 | fragments: 147 | - release-1.0.2.yml 148 | - unnecesary_re_M.yml 149 | release_date: '2021-08-09' 150 | 1.0.3: 151 | changes: 152 | minor_changes: 153 | - Add Py 3.6 to supported python versions (https://github.com/ansible-collections/community.ciscosmb/pull/44) 154 | - Fix link to issue tracker in galaxy.yml (https://github.com/ansible-collections/community.ciscosmb/pull/42) 155 | - Misc doc fixes for collection inclusion (https://github.com/ansible-collections/community.ciscosmb/pull/41) 156 | release_summary: 'Release Date: 2019-10-31 157 | 158 | Minor changes in documentation, adding Python 3.6 as a supported version 159 | 160 | ' 161 | fragments: 162 | - 41-doc_fixes.yml 163 | - 42-fix_galaxy_issue_url.yml 164 | - 44-add_py_36.yml 165 | - release-1.0.3.yml 166 | release_date: '2021-09-10' 167 | 1.0.4: 168 | changes: 169 | bugfixes: 170 | - Module command does not support check_mode - https://github.com/ansible-collections/community.ciscosmb/pull/45 171 | release_summary: 'Release Date: 2021-09-13 172 | 173 | ' 174 | fragments: 175 | - 45-no_check_mode.yml 176 | release_date: '2021-09-13' 177 | 1.0.5: 178 | changes: 179 | minor_changes: 180 | - CI change to name for validate-module 181 | - CI - add ansible 2.13 to test matrix 182 | fragments: 183 | - CI-ansible-2.13.yml 184 | - CI-validate-modules.yml 185 | release_date: '2022-04-29' 186 | 1.0.6: 187 | changes: 188 | deprecated_features: 189 | - support for Python 2.6 nad 2.7 190 | - support for ansible 2.9 191 | minor_changes: 192 | - added Ansible playbook examples ``cismosmb_inventory_template.yml``, ``cismosmb_gather_facts.yml``, 193 | ``cismosmb_commands.yml`` 194 | - no longer testing for ansible 2.9 and for Python 2.6 / 2.7 195 | - removed unused portion of code in cliconf/ciscosmb.yml 196 | - test Ansible 2.14 197 | release_summary: "Code cleaning, better documentation \n" 198 | removed_features: 199 | - remove testing for Python 2.6 nad 2.7 200 | - remove testing for ansible 2.9 201 | fragments: 202 | - CIchanges.yml 203 | - cliconf.yml 204 | - playbook_examples.yml 205 | - release-1.0.6.yml 206 | release_date: '2023-05-23' 207 | 1.0.7: 208 | changes: 209 | bugfixes: 210 | - added Cisco device config guide to address issue 211 | - added extra "\n" to sending commands to address issue 212 | release_summary: 'Release Date: 2023-10-30 213 | 214 | Fix issue on CSB-350 #69 215 | 216 | Clarify configuration doc #66 #64 217 | 218 | ' 219 | fragments: 220 | - issue66.yml 221 | - issue69.yml 222 | - release-1.0.7.yml 223 | release_date: '2023-10-30' 224 | 1.0.8: 225 | changes: 226 | breaking_changes: 227 | - in facts of interface 'bandwith' changed to 'bandwidth' 228 | bugfixes: 229 | - issue 230 | - solved issue 231 | minor_changes: 232 | - docs - addeed info about SG-250 support and testing 233 | release_summary: "Release Date: 2024-04-09\n\n Minor bugfixes, updated CI\n" 234 | fragments: 235 | - CI.yml 236 | - add-SG250.yml 237 | - bandwidth.yml 238 | - on_become.yml 239 | - release-1.0.8.yml 240 | release_date: '2024-04-09' 241 | 1.0.9: 242 | changes: 243 | bugfixes: 244 | - typo in changelog fragment template 245 | - typo in test script 246 | minor_changes: 247 | - added additional attribute - add interface 'bandwidth' attribute 248 | - reverted attribute change - keep interface 'bandwith' attribute 249 | release_summary: 'Primarily revert release. Previous release (1.0.8) fixed typo 250 | in attribute name, but it was breaking change. 251 | 252 | This release brought the typo back (bandwith) and just added the new attribute 253 | with correct name "bandwidth" as a copy of the mistypped attribute. 254 | 255 | 256 | Attribude "bandwith" will be removed in next minor release. 257 | 258 | ' 259 | fragments: 260 | - 75-versioning_violation.yml 261 | release_date: '2024-05-03' 262 | -------------------------------------------------------------------------------- /changelogs/config.yaml: -------------------------------------------------------------------------------- 1 | changelog_filename_template: ../CHANGELOG.rst 2 | changelog_filename_version_depth: 0 3 | changes_file: changelog.yaml 4 | changes_format: combined 5 | ignore_other_fragment_extensions: true 6 | keep_fragments: false 7 | mention_ancestor: true 8 | new_plugins_after_name: removed_features 9 | notesdir: fragments 10 | prelude_section_name: release_summary 11 | prelude_section_title: Release Summary 12 | sanitize_changelog: true 13 | sections: 14 | - - major_changes 15 | - Major Changes 16 | - - minor_changes 17 | - Minor Changes 18 | - - breaking_changes 19 | - Breaking Changes / Porting Guide 20 | - - deprecated_features 21 | - Deprecated Features 22 | - - removed_features 23 | - Removed Features (previously deprecated) 24 | - - security_fixes 25 | - Security Fixes 26 | - - bugfixes 27 | - Bugfixes 28 | - - known_issues 29 | - Known Issues 30 | title: CiscoSMB Ansible module 31 | trivial_section_name: trivial 32 | use_fqcn: true 33 | -------------------------------------------------------------------------------- /changelogs/fragments/.keep: -------------------------------------------------------------------------------- 1 | # fragment.yml 2 | release_summary: | 3 | Release Date: 2019-10-31 4 | `Porting Guide ` 5 | 6 | major_changes: 7 | - docker_container - the ``trust_image_content`` option will be removed. 8 | 9 | minor_changes: 10 | - docker_container - the ``trust_image_content`` option will be removed. 11 | 12 | security_fixes: 13 | bugfixes: 14 | 15 | breaking_changes: 16 | removed_features: 17 | deprecated_features: 18 | known_issues: 19 | trivial: 20 | -------------------------------------------------------------------------------- /ciscosmb_commands.yml: -------------------------------------------------------------------------------- 1 | - name: CiscoSMB - test commands 2 | gather_facts: no 3 | hosts: all 4 | # vars: 5 | # ansible_become: yes 6 | 7 | tasks: 8 | - name: CiscoSMB - show clock 9 | community.ciscosmb.command: 10 | commands: 11 | - show version 12 | - show clock 13 | register: show_clock 14 | 15 | - name: show output 16 | ansible.builtin.debug: 17 | var: show_clock 18 | 19 | 20 | - name: CiscoSMB - set timezone 21 | community.ciscosmb.command: 22 | commands: 23 | - configure terminal 24 | - clock timezone CET +1 25 | vars: 26 | ansible_become: yes 27 | register: set_timezone 28 | 29 | - name: show output 30 | ansible.builtin.debug: 31 | var: set_timezone 32 | -------------------------------------------------------------------------------- /ciscosmb_gather_facts.yml: -------------------------------------------------------------------------------- 1 | - name: Gather Facts 2 | gather_facts: yes 3 | hosts: all 4 | vars: 5 | - configs_dir: configs 6 | 7 | tasks: 8 | 9 | - name: Host info 10 | ansible.builtin.debug: 11 | verbosity: 3 12 | var: "hostvars" 13 | 14 | ### 15 | # Collect data 16 | # 17 | - name: CiscoSMB - Gather Facts - subset default 18 | community.ciscosmb.facts: 19 | gather_subset: 20 | - default 21 | # when: ansible_network_os == 'community.ciscosmb.ciscosmb' 22 | 23 | # - name: CiscoSMB - Gather Facts - subset config 24 | # community.ciscosmb.facts: 25 | # gather_subset: 26 | # - config 27 | # vars: 28 | # ansible_become: yes 29 | # # when: ansible_network_os == 'community.ciscosmb.ciscosmb' 30 | 31 | - name: CSV output 32 | ansible.builtin.debug: 33 | verbosity: 1 34 | msg: 35 | - "{{ ansible_facts['net_hostname'] }};{{ ansible_facts['net_model'] }};{{ ansible_facts['net_serialnum'] }};{{ ansible_facts['net_version'] }};{{ ansible_facts['net_hw_version'] }}" 36 | 37 | - name: Verbose output 38 | ansible.builtin.debug: 39 | verbosity: 2 40 | msg: 41 | - "Hostname: {{ ansible_facts['net_hostname'] }}" 42 | - "Model: {{ ansible_facts['net_model'] }}" 43 | - "SN: {{ ansible_facts['net_serialnum'] }}" 44 | - "SW version {{ ansible_facts['net_version'] }}" 45 | - "HW version: {{ ansible_facts['net_hw_version'] }}" 46 | - "config: {{ ansible_facts['net_config'] | default('') }}" 47 | 48 | # - name: Create configuration directory 49 | # local_action: file path={{ configs_dir }} state=directory 50 | # run_once: true 51 | # check_mode: no 52 | # changed_when: no 53 | # 54 | # - name: Save running config 55 | # local_action: copy content={{ ansible_net_config }} dest={{ configs_dir }}/{{ inventory_hostname }}_net_config 56 | -------------------------------------------------------------------------------- /ciscosmb_inventory_template.yml: -------------------------------------------------------------------------------- 1 | all: 2 | vars: 3 | ansible_connection: network_cli 4 | ansible_network_cli_ssh_type: paramiko 5 | #ansible_network_cli_ssh_type: libssh 6 | ### change what you need 7 | # ansible_ssh_private_key_file: /dir/private.key 8 | # ansible_ssh_user: user 9 | # ansible_ssh_pass: password 10 | # ansible_become_method: enable 11 | # ansible_become_password: password 12 | # 13 | ### Enable become globaly, by host, by playbook or by task 14 | # ansible_become: yes 15 | 16 | hosts: 17 | switch1: 18 | ansible_host: AAA.BBB.CCC.DDD 19 | ansible_network_os: community.ciscosmb.ciscosmb 20 | # ansible_become: yes 21 | switch2: 22 | ansible_host: WWW.XXX.YYY.ZZZ 23 | ansible_network_os: community.ciscosmb.ciscosmb 24 | -------------------------------------------------------------------------------- /galaxy-importer.cfg: -------------------------------------------------------------------------------- 1 | [galaxy-importer] 2 | LOG_LEVEL_MAIN = DEBUG 3 | RUN_FLAKE8 = False 4 | RUN_ANSIBLE_DOC = True 5 | RUN_ANSIBLE_LINT = False 6 | RUN_ANSIBLE_TEST = False 7 | ANSIBLE_TEST_LOCAL_IMAGE = False 8 | LOCAL_IMAGE_DOCKER = True 9 | INFRA_OSD = False 10 | TMP_ROOT_DIR = /tmp 11 | ANSIBLE_LOCAL_TMP = /tmp/ansible 12 | -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | ### REQUIRED 2 | # The namespace of the collection. This can be a company/brand/organization or product namespace under which all 3 | # content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with 4 | # underscores or numbers and cannot contain consecutive underscores 5 | namespace: community 6 | 7 | # The name of the collection. Has the same character restrictions as 'namespace' 8 | name: ciscosmb 9 | 10 | # The version of the collection. Must be compatible with semantic versioning 11 | version: 1.0.11 12 | 13 | # The path to the Markdown (.md) readme file. This path is relative to the root of the collection 14 | readme: README.md 15 | 16 | # A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) 17 | # @nicks:irc/im.site#channel' 18 | authors: 19 | - Petr Klíma 20 | 21 | ### OPTIONAL but strongly recommended 22 | # A short summary description of the collection 23 | description: Cisco SMB switches - SG300, SG500, SG350, SG550, CBS350, C1300 24 | 25 | # The path to the license file for the collection. This path is relative to the root of the collection. This key is 26 | # mutually exclusive with 'license' 27 | license_file: "LICENSE" 28 | 29 | # A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character 30 | # requirements as 'namespace' and 'name' 31 | tags: [network, switch, ciscosmb, cisco, sg300, sg500, sg350, sg550, cbs350, c1300, smb, small_bussiness] 32 | 33 | # Collections that this collection requires to be installed for it to be usable. The key of the dict is the 34 | # collection label 'namespace.name'. The value is a version range 35 | # L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version 36 | # range specifiers can be set and are separated by ',' 37 | dependencies: 38 | ansible.netcommon: ">=1.5.0" 39 | 40 | # The URL of the originating SCM repository 41 | repository: https://github.com/ansible-collections/community.ciscosmb 42 | 43 | # The URL to any online docs 44 | #documentation: http://docs.example.com 45 | 46 | # The URL to the homepage of the collection/project 47 | #homepage: http://example.com 48 | 49 | # The URL to the collection issue tracker 50 | issues: https://github.com/ansible-collections/community.ciscosmb/issues 51 | 52 | # A list of file glob-like patterns used to filter any files or directories that should not be included in the build 53 | # artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This 54 | # uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', 55 | # and '.git' are always filtered 56 | build_ignore: [".venv", ".pytest_cache", "*.gz", "ciscosmb_*.yml", "configs"] 57 | -------------------------------------------------------------------------------- /meta/runtime.yml: -------------------------------------------------------------------------------- 1 | --- 2 | requires_ansible: ">=2.14" 3 | -------------------------------------------------------------------------------- /plugins/cliconf/ciscosmb.py: -------------------------------------------------------------------------------- 1 | # 2 | # (c) 2017 Red Hat Inc. 3 | # 4 | # This file is part of Ansible 5 | # 6 | # Ansible is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Ansible is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Ansible. If not, see . 18 | # 19 | from __future__ import absolute_import, division, print_function 20 | 21 | __metaclass__ = type 22 | 23 | DOCUMENTATION = """ 24 | --- 25 | author: Egor Zaitsev (@heuels) 26 | name: ciscosmb 27 | short_description: Use ciscosmb cliconf to run command on Cisco SMB network devices 28 | description: 29 | - This ciscosmb plugin provides low level abstraction apis for 30 | sending and receiving CLI commands from Cisco SMB network devices. 31 | """ 32 | 33 | import json 34 | 35 | from ansible.plugins.cliconf import CliconfBase, enable_mode 36 | 37 | 38 | class Cliconf(CliconfBase): 39 | 40 | def get_device_info(self): 41 | device_info = {} 42 | device_info["network_os"] = "ciscosmb" 43 | 44 | return device_info 45 | 46 | @enable_mode 47 | def get_config(self, source="running", flags=None, format=None): 48 | if source not in ("running", "startup"): 49 | raise ValueError("fetching configuration from %s is not supported" % source) 50 | 51 | if format: 52 | raise ValueError( 53 | "'format' value %s is not supported for get_config" % format 54 | ) 55 | 56 | if flags: 57 | raise ValueError("'flags' value %s is not supported for get_config" % flags) 58 | 59 | if source == "running": 60 | cmd = "show running-config " 61 | else: 62 | cmd = "show startup-config " 63 | 64 | return self.send_command(cmd) 65 | 66 | def edit_config(self, command): 67 | return 68 | 69 | def get( 70 | self, 71 | command, 72 | prompt=None, 73 | answer=None, 74 | sendonly=False, 75 | newline=True, 76 | check_all=False, 77 | ): 78 | return self.send_command( 79 | command=command + "\n", 80 | prompt=prompt, 81 | answer=answer, 82 | sendonly=sendonly, 83 | newline=newline, 84 | check_all=check_all, 85 | ) 86 | 87 | def get_capabilities(self): 88 | result = super().get_capabilities() 89 | return json.dumps(result) 90 | 91 | def get_serialization_profile(self, command=None): 92 | return "ciscosmb" # This must match a profile defined elsewhere 93 | -------------------------------------------------------------------------------- /plugins/module_utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/plugins/module_utils/__init__.py -------------------------------------------------------------------------------- /plugins/module_utils/ciscosmb.py: -------------------------------------------------------------------------------- 1 | # This code is part of Ansible, but is an independent component. 2 | # This particular file snippet, and this file snippet only, is BSD licensed. 3 | # Modules you write using this snippet, which is embedded dynamically by Ansible 4 | # still belong to the author of the module, and may assign their own license 5 | # to the complete work. 6 | # 7 | # (c) 2016 Red Hat Inc. 8 | # 9 | # Redistribution and use in source and binary forms, with or without modification, 10 | # are permitted provided that the following conditions are met: 11 | # 12 | # * Redistributions of source code must retain the above copyright 13 | # notice, this list of conditions and the following disclaimer. 14 | # * Redistributions in binary form must reproduce the above copyright notice, 15 | # this list of conditions and the following disclaimer in the documentation 16 | # and/or other materials provided with the distribution. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 26 | # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | # 28 | 29 | from __future__ import absolute_import, division, print_function 30 | __metaclass__ = type 31 | 32 | import json 33 | import re 34 | 35 | from ansible.module_utils._text import to_text, to_native 36 | from ansible.module_utils.basic import env_fallback 37 | from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list, ComplexList 38 | from ansible.module_utils.connection import Connection, ConnectionError 39 | 40 | # copy of https://github.com/napalm-automation/napalm/blob/develop/napalm/base/canonical_map.py 41 | from ansible_collections.community.ciscosmb.plugins.module_utils.ciscosmb_canonical_map import base_interfaces 42 | 43 | _DEVICE_CONFIGS = {} 44 | 45 | ciscosmb_provider_spec = { 46 | 'host': dict(), 47 | 'port': dict(type='int'), 48 | 'username': dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])), 49 | 'password': dict(fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD']), no_log=True), 50 | 'ssh_keyfile': dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE']), type='path'), 51 | 'timeout': dict(type='int') 52 | } 53 | ciscosmb_argument_spec = {} 54 | 55 | 56 | def ciscosmb_split_to_tables(data): 57 | TABLE_HEADER = re.compile(r"^---+ +-+.*$") 58 | EMPTY_LINE = re.compile(r"^ *$") 59 | 60 | tables = dict() 61 | tableno = -1 62 | lineno = 0 63 | tabledataget = False 64 | 65 | for line in data.splitlines(): 66 | if re.match(EMPTY_LINE, line): 67 | tabledataget = False 68 | continue 69 | 70 | if re.match(TABLE_HEADER, line): 71 | tableno += 1 72 | tabledataget = True 73 | lineno = 0 74 | tables[tableno] = dict() 75 | tables[tableno]["header"] = line 76 | tables[tableno]["data"] = dict() 77 | continue 78 | 79 | if tabledataget: 80 | tables[tableno]["data"][lineno] = line 81 | lineno += 1 82 | continue 83 | 84 | return tables 85 | 86 | 87 | def ciscosmb_parse_table(table, allow_overflow=True, allow_empty_fields=None): 88 | 89 | if allow_empty_fields is None: 90 | allow_empty_fields = list() 91 | 92 | fields_end = __get_table_columns_end(table["header"]) 93 | data = __get_table_data( 94 | table["data"], fields_end, allow_overflow, allow_empty_fields 95 | ) 96 | 97 | return data 98 | 99 | 100 | def __get_table_columns_end(headerline): 101 | """ fields length are diferent device to device, detect them on horizontal lin """ 102 | fields_end = [m.start() for m in re.finditer(" *", headerline.strip())] 103 | # fields_position.insert(0,0) 104 | # fields_end.append(len(headerline)) 105 | fields_end.append(10000) # allow "long" last field 106 | 107 | return fields_end 108 | 109 | 110 | def __line_to_fields(line, fields_end): 111 | """ dynamic fields lenghts """ 112 | line_elems = {} 113 | index = 0 114 | f_start = 0 115 | for f_end in fields_end: 116 | line_elems[index] = line[f_start:f_end].strip() 117 | index += 1 118 | f_start = f_end 119 | 120 | return line_elems 121 | 122 | 123 | def __get_table_data( 124 | tabledata, fields_end, allow_overflow=True, allow_empty_fields=None 125 | ): 126 | 127 | if allow_empty_fields is None: 128 | allow_empty_fields = list() 129 | data = dict() 130 | 131 | dataindex = 0 132 | for lineno in tabledata: 133 | owerflownfields = list() 134 | owerflow = False 135 | 136 | line = tabledata[lineno] 137 | line_elems = __line_to_fields(line, fields_end) 138 | 139 | if allow_overflow: 140 | # search for overflown fields 141 | for elemno in line_elems: 142 | if elemno not in allow_empty_fields and line_elems[elemno] == "": 143 | owerflow = True 144 | else: 145 | owerflownfields.append(elemno) 146 | 147 | if owerflow: 148 | # concat owerflown elements to previous data 149 | for fieldno in owerflownfields: 150 | data[dataindex - 1][fieldno] += line_elems[fieldno] 151 | 152 | else: 153 | data[dataindex] = line_elems 154 | dataindex += 1 155 | else: 156 | data[dataindex] = line_elems 157 | dataindex += 1 158 | 159 | return data 160 | 161 | 162 | def ciscosmb_merge_dicts(a, b, path=None): 163 | "merges b into a" 164 | if path is None: 165 | path = [] 166 | 167 | # is b empty? 168 | if not bool(b): 169 | return a 170 | 171 | for key in b: 172 | if key in a: 173 | if isinstance(a[key], dict) and isinstance(b[key], dict): 174 | ciscosmb_merge_dicts(a[key], b[key], path + [str(key)]) 175 | elif a[key] == b[key]: 176 | pass # same leaf value 177 | else: 178 | raise Exception("Conflict at %s" % ".".join(path + [str(key)])) 179 | else: 180 | a[key] = b[key] 181 | return a 182 | 183 | 184 | def interface_canonical_name(interface): 185 | iftype = interface.rstrip(r"/\0123456789. ") 186 | ifno = interface[len(iftype):].lstrip() 187 | 188 | if iftype in base_interfaces: 189 | iftype = base_interfaces[iftype] 190 | 191 | interface = iftype + str(ifno) 192 | 193 | return interface 194 | 195 | 196 | def get_provider_argspec(): 197 | return ciscosmb_provider_spec 198 | 199 | 200 | def get_connection(module): 201 | if hasattr(module, '_ciscosmb_connection'): 202 | return module._ciscosmb_connection 203 | 204 | capabilities = get_capabilities(module) 205 | network_api = capabilities.get('network_api') 206 | if network_api == 'cliconf': 207 | module._ciscosmb_connection = Connection(module._socket_path) 208 | else: 209 | module.fail_json(msg='Invalid connection type %s' % network_api) 210 | 211 | return module._ciscosmb_connection 212 | 213 | 214 | def get_capabilities(module): 215 | if hasattr(module, '_ciscosmb_capabilities'): 216 | return module._ciscosmb_capabilities 217 | 218 | try: 219 | capabilities = Connection(module._socket_path).get_capabilities() 220 | module._ciscosmb_capabilities = json.loads(capabilities) 221 | return module._ciscosmb_capabilities 222 | except ConnectionError as exc: 223 | module.fail_json(msg=to_native(exc, errors='surrogate_then_replace')) 224 | 225 | 226 | def get_defaults_flag(module): 227 | connection = get_connection(module) 228 | 229 | try: 230 | out = connection.get('/system default-configuration print') 231 | except ConnectionError as exc: 232 | module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) 233 | 234 | out = to_text(out, errors='surrogate_then_replace') 235 | 236 | commands = set() 237 | for line in out.splitlines(): 238 | if line.strip(): 239 | commands.add(line.strip().split()[0]) 240 | 241 | if 'all' in commands: 242 | return ['all'] 243 | else: 244 | return ['full'] 245 | 246 | 247 | def get_config(module, flags=None): 248 | flag_str = ' '.join(to_list(flags)) 249 | 250 | try: 251 | return _DEVICE_CONFIGS[flag_str] 252 | except KeyError: 253 | connection = get_connection(module) 254 | 255 | try: 256 | out = connection.get_config(flags=flags) 257 | except ConnectionError as exc: 258 | module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) 259 | 260 | cfg = to_text(out, errors='surrogate_then_replace').strip() 261 | _DEVICE_CONFIGS[flag_str] = cfg 262 | return cfg 263 | 264 | 265 | def to_commands(module, commands): 266 | spec = { 267 | 'command': dict(key=True), 268 | 'prompt': dict(), 269 | 'answer': dict() 270 | } 271 | transform = ComplexList(spec, module) 272 | return transform(commands) 273 | 274 | 275 | def run_commands(module, commands, check_rc=True): 276 | responses = list() 277 | connection = get_connection(module) 278 | 279 | for cmd in to_list(commands): 280 | if isinstance(cmd, dict): 281 | command = cmd['command'] 282 | prompt = cmd['prompt'] 283 | answer = cmd['answer'] 284 | else: 285 | command = cmd 286 | prompt = None 287 | answer = None 288 | 289 | try: 290 | out = connection.get(command, prompt, answer) 291 | except ConnectionError as exc: 292 | module.fail_json(msg=to_text(exc, errors='surrogate_then_replace')) 293 | 294 | try: 295 | out = to_text(out, errors='surrogate_or_strict') 296 | except UnicodeError: 297 | module.fail_json( 298 | msg=u'Failed to decode output from %s: %s' % (cmd, to_text(out))) 299 | 300 | responses.append(out) 301 | 302 | return responses 303 | -------------------------------------------------------------------------------- /plugins/module_utils/ciscosmb_canonical_map.py: -------------------------------------------------------------------------------- 1 | # The contents of this file are licensed under the Apache License, Version 2.0 2 | # (the "License"); you may not use this file except in compliance with the 3 | # License. You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations under 11 | # the License. 12 | 13 | base_interfaces = { 14 | "ATM": "ATM", 15 | "AT": "ATM", 16 | "B": "Bdi", 17 | "Bd": "Bdi", 18 | "Bdi": "Bdi", 19 | "EOBC": "EOBC", 20 | "EO": "EOBC", 21 | "Ethernet": "Ethernet", 22 | "Eth": "Ethernet", 23 | "eth": "Ethernet", 24 | "Et": "Ethernet", 25 | "et": "Ethernet", 26 | "FastEthernet": "FastEthernet", 27 | "FastEth": "FastEthernet", 28 | "FastE": "FastEthernet", 29 | "Fast": "FastEthernet", 30 | "Fas": "FastEthernet", 31 | "FE": "FastEthernet", 32 | "Fa": "FastEthernet", 33 | "fa": "FastEthernet", 34 | "Fddi": "Fddi", 35 | "FD": "Fddi", 36 | "FortyGigabitEthernet": "FortyGigabitEthernet", 37 | "FortyGigEthernet": "FortyGigabitEthernet", 38 | "FortyGigEth": "FortyGigabitEthernet", 39 | "FortyGigE": "FortyGigabitEthernet", 40 | "FortyGig": "FortyGigabitEthernet", 41 | "FGE": "FortyGigabitEthernet", 42 | "FO": "FortyGigabitEthernet", 43 | "Fo": "FortyGigabitEthernet", 44 | "FiftyGigabitEthernet": "FiftyGigabitEthernet", 45 | "FiftyGigEthernet": "FiftyGigabitEthernet", 46 | "FiftyGigEth": "FiftyGigabitEthernet", 47 | "FiftyGigE": "FiftyGigabitEthernet", 48 | "FI": "FiftyGigabitEthernet", 49 | "Fi": "FiftyGigabitEthernet", 50 | "fi": "FiftyGigabitEthernet", 51 | "GigabitEthernet": "GigabitEthernet", 52 | "GigEthernet": "GigabitEthernet", 53 | "GigEth": "GigabitEthernet", 54 | "GigE": "GigabitEthernet", 55 | "Gig": "GigabitEthernet", 56 | "GE": "GigabitEthernet", 57 | "Ge": "GigabitEthernet", 58 | "ge": "GigabitEthernet", 59 | "Gi": "GigabitEthernet", 60 | "gi": "GigabitEthernet", 61 | "HundredGigabitEthernet": "HundredGigabitEthernet", 62 | "HundredGigEthernet": "HundredGigabitEthernet", 63 | "HundredGigEth": "HundredGigabitEthernet", 64 | "HundredGigE": "HundredGigabitEthernet", 65 | "HundredGig": "HundredGigabitEthernet", 66 | "Hu": "HundredGigabitEthernet", 67 | "TwentyFiveGigabitEthernet": "TwentyFiveGigabitEthernet", 68 | "TwentyFiveGigEthernet": "TwentyFiveGigabitEthernet", 69 | "TwentyFiveGigEth": "TwentyFiveGigabitEthernet", 70 | "TwentyFiveGigE": "TwentyFiveGigabitEthernet", 71 | "TwentyFiveGig": "TwentyFiveGigabitEthernet", 72 | "TF": "TwentyFiveGigabitEthernet", 73 | "Tf": "TwentyFiveGigabitEthernet", 74 | "tf": "TwentyFiveGigabitEthernet", 75 | "TwoHundredGigabitEthernet": "TwoHundredGigabitEthernet", 76 | "TwoHundredGigEthernet": "TwoHundredGigabitEthernet", 77 | "TwoHundredGigEth": "TwoHundredGigabitEthernet", 78 | "TwoHundredGigE": "TwoHundredGigabitEthernet", 79 | "TwoHundredGig": "TwoHundredGigabitEthernet", 80 | "TH": "TwoHundredGigabitEthernet", 81 | "Th": "TwoHundredGigabitEthernet", 82 | "th": "TwoHundredGigabitEthernet", 83 | "FourHundredGigabitEthernet": "FourHundredGigabitEthernet", 84 | "FourHundredGigEthernet": "FourHundredGigabitEthernet", 85 | "FourHundredGigEth": "FourHundredGigabitEthernet", 86 | "FourHundredGigE": "FourHundredGigabitEthernet", 87 | "FourHundredGig": "FourHundredGigabitEthernet", 88 | "F": "FourHundredGigabitEthernet", 89 | "f": "FourHundredGigabitEthernet", 90 | "Loopback": "Loopback", 91 | "loopback": "Loopback", 92 | "Lo": "Loopback", 93 | "lo": "Loopback", 94 | "Management": "Management", 95 | "Mgmt": "Management", 96 | "mgmt": "Management", 97 | "Ma": "Management", 98 | "Management_short": "Ma", 99 | "MFR": "MFR", 100 | "Multilink": "Multilink", 101 | "Mu": "Multilink", 102 | "n": "nve", 103 | "nv": "nve", 104 | "nve": "nve", 105 | "PortChannel": "Port-channel", 106 | "Port-channel": "Port-channel", 107 | "Port-Channel": "Port-channel", 108 | "port-channel": "Port-channel", 109 | "po": "Port-channel", 110 | "Po": "Port-channel", 111 | "POS": "POS", 112 | "PO": "POS", 113 | "Serial": "Serial", 114 | "Se": "Serial", 115 | "S": "Serial", 116 | "TenGigabitEthernet": "TenGigabitEthernet", 117 | "TenGigEthernet": "TenGigabitEthernet", 118 | "TenGigEth": "TenGigabitEthernet", 119 | "TenGig": "TenGigabitEthernet", 120 | "TeGig": "TenGigabitEthernet", 121 | "Ten": "TenGigabitEthernet", 122 | "T": "TenGigabitEthernet", 123 | "Te": "TenGigabitEthernet", 124 | "te": "TenGigabitEthernet", 125 | "Tunnel": "Tunnel", 126 | "Tun": "Tunnel", 127 | "Tu": "Tunnel", 128 | "Twe": "TwentyFiveGigE", 129 | "Tw": "TwoGigabitEthernet", 130 | "Two": "TwoGigabitEthernet", 131 | "Virtual-Access": "Virtual-Access", 132 | "Vi": "Virtual-Access", 133 | "Virtual-Template": "Virtual-Template", 134 | "Vt": "Virtual-Template", 135 | "VLAN": "VLAN", 136 | "V": "VLAN", 137 | "Vl": "VLAN", 138 | "Wlan-GigabitEthernet": "Wlan-GigabitEthernet", 139 | } 140 | 141 | reverse_mapping = { 142 | "ATM": "At", 143 | "EOBC": "EO", 144 | "Ethernet": "Et", 145 | "FastEthernet": "Fa", 146 | "Fddi": "FD", 147 | "FortyGigabitEthernet": "Fo", 148 | "GigabitEthernet": "Gi", 149 | "HundredGigabitEthernet": "Hu", 150 | "Loopback": "Lo", 151 | "Management": "Ma", 152 | "MFR": "MFR", 153 | "Multilink": "Mu", 154 | "Port-channel": "Po", 155 | "POS": "PO", 156 | "Serial": "Se", 157 | "TenGigabitEthernet": "Te", 158 | "Tunnel": "Tu", 159 | "TwoGigabitEthernet": "Two", 160 | "TwentyFiveGigE": "Twe", 161 | "Virtual-Access": "Vi", 162 | "Virtual-Template": "Vt", 163 | "VLAN": "Vl", 164 | "Wlan-GigabitEthernet": "Wl-Gi", 165 | } 166 | -------------------------------------------------------------------------------- /plugins/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/plugins/modules/__init__.py -------------------------------------------------------------------------------- /plugins/modules/command.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | 5 | from __future__ import (absolute_import, division, print_function) 6 | __metaclass__ = type 7 | 8 | DOCUMENTATION = ''' 9 | --- 10 | module: command 11 | author: "Petr Klima (@qaxi)" 12 | short_description: Run commands on remote Cisco SMB devices 13 | description: 14 | - Sends arbitrary commands to an Cisco SMB node and returns the results 15 | read from the device. This module includes an 16 | argument that will cause the module to wait for a specific condition 17 | before returning or timing out if the condition is not met. 18 | options: 19 | commands: 20 | description: 21 | - List of commands to send to the remote Cisco SMB device over the 22 | configured provider. The resulting output from the command 23 | is returned. If the I(wait_for) argument is provided, the 24 | module is not returned until the condition is satisfied or 25 | the number of retries has expired. 26 | required: true 27 | type: list 28 | elements: str 29 | wait_for: 30 | description: 31 | - List of conditions to evaluate against the output of the 32 | command. The task will wait for each condition to be true 33 | before moving forward. If the conditional is not true 34 | within the configured number of retries, the task fails. 35 | See examples. 36 | type: list 37 | elements: str 38 | match: 39 | description: 40 | - The I(match) argument is used in conjunction with the 41 | I(wait_for) argument to specify the match policy. Valid 42 | values are C(all) or C(any). If the value is set to C(all) 43 | then all conditionals in the wait_for must be satisfied. If 44 | the value is set to C(any) then only one of the values must be 45 | satisfied. 46 | default: all 47 | type: str 48 | choices: ['any', 'all'] 49 | retries: 50 | description: 51 | - Specifies the number of retries a command should by tried 52 | before it is considered failed. The command is run on the 53 | target device every retry and evaluated against the 54 | I(wait_for) conditions. 55 | default: 10 56 | type: int 57 | interval: 58 | description: 59 | - Configures the interval in seconds to wait between retries 60 | of the command. If the command does not pass the specified 61 | conditions, the interval indicates how long to wait before 62 | trying the command again. 63 | default: 1 64 | type: int 65 | ''' 66 | 67 | EXAMPLES = """ 68 | - name: Run command on remote devices 69 | community.ciscosmb.command: 70 | commands: show version 71 | 72 | - name: Run command and check to see if output contains PID 73 | community.ciscosmb.command: 74 | commands: show inventory 75 | wait_for: result[0] contains PID 76 | 77 | - name: Run multiple commands on remote nodes 78 | community.ciscosmb.command: 79 | commands: 80 | - show version 81 | - show system 82 | 83 | - name: Run multiple commands and evaluate the output 84 | community.ciscosmb.command: 85 | commands: 86 | - show version 87 | - show system 88 | wait_for: 89 | - result[0] contains Active-image 90 | - result[1] contains "System Up Time" 91 | """ 92 | 93 | RETURN = """ 94 | stdout: 95 | description: The set of responses from the commands. 96 | returned: always apart from low level errors (such as action plugin) 97 | type: list 98 | sample: ['...', '...'] 99 | stdout_lines: 100 | description: The value of stdout split into a list. 101 | returned: always apart from low level errors (such as action plugin) 102 | type: list 103 | sample: [['...', '...'], ['...'], ['...']] 104 | failed_conditions: 105 | description: The list of conditionals that have failed. 106 | returned: failed 107 | type: list 108 | sample: ['...', '...'] 109 | """ 110 | 111 | import time 112 | 113 | from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import Conditional 114 | from ansible_collections.community.ciscosmb.plugins.module_utils.ciscosmb import run_commands 115 | from ansible_collections.community.ciscosmb.plugins.module_utils.ciscosmb import ciscosmb_argument_spec 116 | from ansible.module_utils.basic import AnsibleModule 117 | from ansible.module_utils.six import string_types 118 | 119 | 120 | def to_lines(stdout): 121 | for item in stdout: 122 | if isinstance(item, string_types): 123 | item = str(item).split('\n') 124 | yield item 125 | 126 | 127 | def main(): 128 | """main entry point for module execution 129 | """ 130 | argument_spec = dict( 131 | commands=dict(type='list', elements='str', required=True), 132 | 133 | wait_for=dict(type='list', elements='str'), 134 | match=dict(default='all', choices=['all', 'any']), 135 | 136 | retries=dict(default=10, type='int'), 137 | interval=dict(default=1, type='int') 138 | ) 139 | 140 | argument_spec.update(ciscosmb_argument_spec) 141 | 142 | module = AnsibleModule(argument_spec=argument_spec, 143 | supports_check_mode=False) 144 | 145 | result = {'changed': False} 146 | 147 | wait_for = module.params['wait_for'] or list() 148 | conditionals = [Conditional(c) for c in wait_for] 149 | 150 | retries = module.params['retries'] 151 | interval = module.params['interval'] 152 | match = module.params['match'] 153 | 154 | while retries > 0: 155 | responses = run_commands(module, module.params['commands']) 156 | 157 | for item in list(conditionals): 158 | if item(responses): 159 | if match == 'any': 160 | conditionals = list() 161 | break 162 | conditionals.remove(item) 163 | 164 | if not conditionals: 165 | break 166 | 167 | time.sleep(interval) 168 | retries -= 1 169 | 170 | if conditionals: 171 | failed_conditions = [item.raw for item in conditionals] 172 | msg = 'One or more conditional statements have not been satisfied' 173 | module.fail_json(msg=msg, failed_conditions=failed_conditions) 174 | 175 | result.update({ 176 | 'changed': False, 177 | 'stdout': responses, 178 | 'stdout_lines': list(to_lines(responses)) 179 | }) 180 | 181 | module.exit_json(**result) 182 | 183 | 184 | if __name__ == '__main__': 185 | main() 186 | -------------------------------------------------------------------------------- /plugins/terminal/ciscosmb.py: -------------------------------------------------------------------------------- 1 | # 2 | # (c) 2016 Red Hat Inc. 3 | # 4 | # This file is part of Ansible 5 | # 6 | # Ansible is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Ansible is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Ansible. If not, see . 18 | # 19 | 20 | from __future__ import (absolute_import, division, print_function) 21 | __metaclass__ = type 22 | 23 | # Py 2.7 compat. 24 | from ansible.module_utils.six import raise_from 25 | 26 | import json 27 | import re 28 | 29 | from ansible.errors import AnsibleConnectionFailure 30 | from ansible.module_utils._text import to_text, to_bytes 31 | from ansible.plugins.terminal import TerminalBase 32 | from ansible.utils.display import Display 33 | 34 | display = Display() 35 | 36 | 37 | class TerminalModule(TerminalBase): 38 | 39 | # https://docs.ansible.com/ansible/latest/collections/ansible/netcommon/network_cli_connection.html 40 | 41 | terminal_stdout_re = [ 42 | re.compile(br"[\r\n]?[\w\+\-\.:\/\[\]]+(?:\([^\)]+\)){0,3}(?:[>#]) ?$") 43 | ] 44 | 45 | terminal_stderr_re = [ 46 | re.compile(br"% ?Error"), 47 | re.compile(br"^% \w+", re.M), 48 | re.compile(br"% ?Bad secret"), 49 | re.compile(br"[\r\n%] Bad passwords"), 50 | re.compile(br"invalid input", re.I), 51 | re.compile(br"(?:incomplete|ambiguous) command", re.I), 52 | re.compile(br"connection timed out", re.I), 53 | re.compile(br"[^\r\n]+ not found"), 54 | re.compile(br"'[^']' +returned error code: ?\d+"), 55 | re.compile(br"Bad mask", re.I), 56 | re.compile(br"% ?(\S+) ?overlaps with ?(\S+)", re.I), 57 | re.compile(br"[%\S] ?Error: ?[\s]+", re.I), 58 | re.compile(br"[%\S] ?Informational: ?[\s]+", re.I), 59 | re.compile(br"Command authorization failed"), 60 | ] 61 | 62 | def on_open_shell(self): 63 | try: 64 | self._exec_cli_command(b"terminal datadump") 65 | except AnsibleConnectionFailure as e: 66 | raise_from(AnsibleConnectionFailure("unable to set terminal parameters"), e) 67 | 68 | try: 69 | self._exec_cli_command(b"terminal width 0") 70 | except AnsibleConnectionFailure: 71 | display.display( 72 | "WARNING: Unable to set terminal width, command responses may be truncated" 73 | ) 74 | 75 | try: 76 | self._exec_cli_command(b"terminal no prompt") 77 | except AnsibleConnectionFailure: 78 | display.display( 79 | "WARNING: Unable disable prompt, command responses may fail" 80 | ) 81 | 82 | def on_become(self, passwd=None): 83 | cmd = {u"command": u"enable"} 84 | if passwd: 85 | # Note: python-3.5 cannot combine u"" and r"" together. Thus make 86 | # an r string and use to_text to ensure it's text on both py2 and py3. 87 | cmd[u"prompt"] = to_text( 88 | r"[\r\n]?(?:.*)?[Pp]assword: ?$", errors="surrogate_or_strict" 89 | ) 90 | cmd[u"answer"] = passwd 91 | cmd[u"prompt_retry_check"] = True 92 | try: 93 | self._exec_cli_command( 94 | to_bytes(json.dumps(cmd), errors="surrogate_or_strict") 95 | ) 96 | prompt = self._get_prompt() 97 | if prompt is None or not prompt.endswith(b"#"): 98 | raise AnsibleConnectionFailure( 99 | "failed to elevate privilege to enable mode still at prompt [%s]" 100 | % prompt 101 | ) 102 | except AnsibleConnectionFailure as e: 103 | prompt = self._get_prompt() 104 | raise_from(AnsibleConnectionFailure( 105 | "unable to elevate privilege to enable mode, at prompt [%s] with error: %s" 106 | % (prompt, e.message) 107 | ), e) 108 | 109 | def on_unbecome(self): 110 | prompt = self._get_prompt() 111 | if prompt is None: 112 | # if prompt is None most likely the terminal is hung up at a prompt 113 | return 114 | 115 | if b"(config" in prompt: 116 | self._exec_cli_command(b"end") 117 | self._exec_cli_command(b"disable") 118 | 119 | elif prompt.endswith(b"#"): 120 | self._exec_cli_command(b"disable") 121 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | # connection libraries 2 | paramiko 3 | ansible-pylibssh 4 | 5 | # sanity tests 6 | pycodestyle 7 | pylint 8 | voluptuous 9 | 10 | # units 11 | pytest 12 | pytest-xdist 13 | pytest-mock 14 | mock 15 | 16 | # utils 17 | yamllint 18 | galaxy_importer 19 | antsibull-changelog 20 | setuptools 21 | -------------------------------------------------------------------------------- /tests/requirements.yml: -------------------------------------------------------------------------------- 1 | integration_tests_dependencies: 2 | - ansible.netcommon 3 | unit_tests_dependencies: 4 | - ansible.netcommon 5 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/tests/unit/__init__.py -------------------------------------------------------------------------------- /tests/unit/compat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/tests/unit/compat/__init__.py -------------------------------------------------------------------------------- /tests/unit/compat/builtins.py: -------------------------------------------------------------------------------- 1 | # (c) 2014, Toshio Kuratomi 2 | # 3 | # This file is part of Ansible 4 | # 5 | # Ansible is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Ansible is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Ansible. If not, see . 17 | 18 | # Make coding more python3-ish 19 | from __future__ import (absolute_import, division, print_function) 20 | __metaclass__ = type 21 | -------------------------------------------------------------------------------- /tests/unit/compat/mock.py: -------------------------------------------------------------------------------- 1 | # (c) 2014, Toshio Kuratomi 2 | # 3 | # This file is part of Ansible 4 | # 5 | # Ansible is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Ansible is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Ansible. If not, see . 17 | 18 | # Make coding more python3-ish 19 | from __future__ import (absolute_import, division, print_function) 20 | __metaclass__ = type 21 | 22 | ''' 23 | Compat module for Python3.x's unittest.mock module 24 | ''' 25 | import sys 26 | 27 | # Python 2.7 28 | 29 | # Note: Could use the pypi mock library on python3.x as well as python2.x. It 30 | # is the same as the python3 stdlib mock library 31 | 32 | try: 33 | # Allow wildcard import because we really do want to import all of mock's 34 | # symbols into this compat shim 35 | # pylint: disable=wildcard-import,unused-wildcard-import 36 | from unittest.mock import * 37 | except ImportError: 38 | # Python 2 39 | # pylint: disable=wildcard-import,unused-wildcard-import 40 | try: 41 | from mock import * 42 | except ImportError: 43 | print('You need the mock library installed on python2.x to run tests') 44 | 45 | 46 | # Prior to 3.4.4, mock_open cannot handle binary read_data 47 | if sys.version_info >= (3,) and sys.version_info < (3, 4, 4): 48 | file_spec = None 49 | 50 | def _iterate_read_data(read_data): 51 | # Helper for mock_open: 52 | # Retrieve lines from read_data via a generator so that separate calls to 53 | # readline, read, and readlines are properly interleaved 54 | sep = b'\n' if isinstance(read_data, bytes) else '\n' 55 | data_as_list = [l + sep for l in read_data.split(sep)] 56 | 57 | if data_as_list[-1] == sep: 58 | # If the last line ended in a newline, the list comprehension will have an 59 | # extra entry that's just a newline. Remove this. 60 | data_as_list = data_as_list[:-1] 61 | else: 62 | # If there wasn't an extra newline by itself, then the file being 63 | # emulated doesn't have a newline to end the last line remove the 64 | # newline that our naive format() added 65 | data_as_list[-1] = data_as_list[-1][:-1] 66 | 67 | yield data_as_list 68 | 69 | def mock_open(mock=None, read_data=''): 70 | """ 71 | A helper function to create a mock to replace the use of `open`. It works 72 | for `open` called directly or used as a context manager. 73 | 74 | The `mock` argument is the mock object to configure. If `None` (the 75 | default) then a `MagicMock` will be created for you, with the API limited 76 | to methods or attributes available on standard file handles. 77 | 78 | `read_data` is a string for the `read` methoddline`, and `readlines` of the 79 | file handle to return. This is an empty string by default. 80 | """ 81 | def _readlines_side_effect(*args, **kwargs): 82 | if handle.readlines.return_value is not None: 83 | return handle.readlines.return_value 84 | return list(_data) 85 | 86 | def _read_side_effect(*args, **kwargs): 87 | if handle.read.return_value is not None: 88 | return handle.read.return_value 89 | return type(read_data)().join(_data) 90 | 91 | def _readline_side_effect(): 92 | if handle.readline.return_value is not None: 93 | while True: 94 | yield handle.readline.return_value 95 | yield _data 96 | 97 | global file_spec 98 | if file_spec is None: 99 | import _io 100 | file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO)))) 101 | 102 | if mock is None: 103 | mock = MagicMock(name='open', spec=open) 104 | 105 | handle = MagicMock(spec=file_spec) 106 | handle.__enter__.return_value = handle 107 | 108 | _data = _iterate_read_data(read_data) 109 | 110 | handle.write.return_value = None 111 | handle.read.return_value = None 112 | handle.readline.return_value = None 113 | handle.readlines.return_value = None 114 | 115 | handle.read.side_effect = _read_side_effect 116 | handle.readline.side_effect = _readline_side_effect() 117 | handle.readlines.side_effect = _readlines_side_effect 118 | 119 | mock.return_value = handle 120 | return mock 121 | -------------------------------------------------------------------------------- /tests/unit/compat/unittest.py: -------------------------------------------------------------------------------- 1 | # (c) 2014, Toshio Kuratomi 2 | # 3 | # This file is part of Ansible 4 | # 5 | # Ansible is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Ansible is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Ansible. If not, see . 17 | 18 | # Make coding more python3-ish 19 | from __future__ import (absolute_import, division, print_function) 20 | __metaclass__ = type 21 | 22 | ''' 23 | Compat module for Python2.7's unittest module 24 | ''' 25 | 26 | import sys 27 | 28 | # Allow wildcard import because we really do want to import all of 29 | # unittests's symbols into this compat shim 30 | # pylint: disable=wildcard-import,unused-wildcard-import 31 | if sys.version_info < (2, 7): 32 | try: 33 | # Need unittest2 on python2.6 34 | from unittest2 import * 35 | except ImportError: 36 | print('You need unittest2 installed on python2.6.x to run tests') 37 | else: 38 | from unittest import * 39 | -------------------------------------------------------------------------------- /tests/unit/plugins/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/tests/unit/plugins/__init__.py -------------------------------------------------------------------------------- /tests/unit/plugins/modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/tests/unit/plugins/modules/__init__.py -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/tests/unit/plugins/modules/ciscosmb/__init__.py -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/ciscosmb_module.py: -------------------------------------------------------------------------------- 1 | # (c) 2016 Red Hat Inc. 2 | # 3 | # This file is part of Ansible 4 | # 5 | # Ansible is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Ansible is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Ansible. If not, see . 17 | 18 | # Make coding more python3-ish 19 | from __future__ import (absolute_import, division, print_function) 20 | __metaclass__ = type 21 | 22 | import os 23 | import json 24 | 25 | from ansible_collections.community.ciscosmb.tests.unit.plugins.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase 26 | 27 | 28 | fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures') 29 | fixture_data = {} 30 | 31 | 32 | def load_fixture(name): 33 | path = os.path.join(fixture_path, name) 34 | 35 | if path in fixture_data: 36 | return fixture_data[path] 37 | 38 | with open(path) as f: 39 | data = f.read() 40 | 41 | try: 42 | data = json.loads(data) 43 | except Exception: 44 | pass 45 | 46 | fixture_data[path] = data 47 | return data 48 | 49 | 50 | class TestCiscoSMBModule(ModuleTestCase): 51 | 52 | def execute_module(self, failed=False, changed=False, commands=None, sort=True, defaults=False): 53 | 54 | self.load_fixtures(commands) 55 | 56 | if failed: 57 | result = self.failed() 58 | self.assertTrue(result['failed'], result) 59 | else: 60 | result = self.changed(changed) 61 | self.assertEqual(result['changed'], changed, result) 62 | 63 | if commands is not None: 64 | if sort: 65 | self.assertEqual(sorted(commands), sorted(result['commands']), result['commands']) 66 | else: 67 | self.assertEqual(commands, result['commands'], result['commands']) 68 | 69 | return result 70 | 71 | def failed(self): 72 | with self.assertRaises(AnsibleFailJson) as exc: 73 | self.module.main() 74 | 75 | result = exc.exception.args[0] 76 | self.assertTrue(result['failed'], result) 77 | return result 78 | 79 | def changed(self, changed=False): 80 | with self.assertRaises(AnsibleExitJson) as exc: 81 | self.module.main() 82 | 83 | result = exc.exception.args[0] 84 | self.assertEqual(result['changed'], changed, result) 85 | return result 86 | 87 | def load_fixtures(self, commands=None): 88 | pass 89 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_command-C1300-8FP-2G-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/image_c1300_4.1.6.54_official_key.bin 2 | Version: 4.1.6.54 3 | MD5 Digest: 9ebbfe128965ba857b81fb75292c84ec 4 | Date: 18-Feb-2025 5 | Time: 07:02:12 6 | Inactive-image: flash://system/images/image_4.1.3.36.bin 7 | Version: 4.1.3.36 8 | MD5 Digest: 90803a985c9110cef9aa4d576206b629 9 | Date: 19-May-2024 10 | Time: 08:17:26 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_command-CBS350-24P-4G-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/image1.bin 2 | Version: 3.0.0.61 3 | MD5 Digest: 9703a2dea9e4c07c5cb22bc6c0235bcf 4 | Date: 18-Jun-2020 5 | Time: 20:38:40 6 | Inactive-image: flash://system/images/_image1.bin 7 | Version: 3.0.0.61 8 | MD5 Digest: 9703a2dea9e4c07c5cb22bc6c0235bcf 9 | Date: 18-Jun-2020 10 | Time: 20:38:40 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_command-SG350-28-K9-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/image_tesla_hybrid_2.4.5.71_release_cisco_signed.bin 2 | Version: 2.4.5.71 3 | MD5 Digest: 2dff89efdb2a0ec2f9a2c414ff7d401c 4 | Date: 04-Nov-2018 5 | Time: 19:46:16 6 | Inactive-image: flash://system/images/image1.bin 7 | Version: 2.2.8.4 8 | MD5 Digest: d75d9f2e1a06e99ba793af2418470df1 9 | Date: 21-Dec-2016 10 | Time: 22:03:09 11 | 12 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_command-SG500-52-K9-show_version: -------------------------------------------------------------------------------- 1 | SW version 1.4.8.6 ( date 10-Jul-2017 time 17:07:33 ) 2 | Boot version 1.3.7.01 ( date 04-Dec-2013 time 13:48:27 ) 3 | HW version V02 4 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_command-SG550X-24MP-K9-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/sx550X_tesla_hybrid_2.4.5.71_release_cisco_signed.bin 2 | Version: 2.4.5.71 3 | MD5 Digest: 2dff89efdb2a0ec2f9a2c414ff7d401c 4 | Date: 04-Nov-2018 5 | Time: 19:46:16 6 | Inactive-image: flash://system/images/image1.bin 7 | Version: 2.3.0.130 8 | MD5 Digest: 079b10248b0cc997da651d255ac0ed15 9 | Date: 10-May-2017 10 | Time: 01:08:28 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_command-stackSG550X-48-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/image1.bin 2 | Version: 2.5.0.83 3 | MD5 Digest: 07968d912499cff5e8b07fdc24779854 4 | Date: 18-Jun-2019 5 | Time: 16:49:35 6 | Inactive-image: flash://system/images/_image1.bin 7 | Version: 2.5.0.83 8 | MD5 Digest: 07968d912499cff5e8b07fdc24779854 9 | Date: 18-Jun-2019 10 | Time: 16:49:35 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-dir: -------------------------------------------------------------------------------- 1 | Permissions 2 | d-directory 3 | r-readable 4 | w-writable 5 | x-executable 6 | 165100K of 305484K are free 7 | Directory of flash:// 8 | 9 | Permission File Size Last Modified File Name 10 | ---------- --------- -------------------- -------------------------------------- 11 | dr-- 1608 18-Feb-2025 06:34:16 system 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_cpu_utilization: -------------------------------------------------------------------------------- 1 | CPU utilization service is on. 2 | 3 | CPU utilization 4 | --------------- 5 | five seconds: 1%; one minute: 0%; five minutes: 1% 6 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_interfaces_configuration: -------------------------------------------------------------------------------- 1 | Flow Admin Back Mdix 2 | Port Type Duplex Speed Neg control State Pressure Mode 3 | --------- ------------ ------ ----- -------- ------- ----- -------- ---- 4 | gi1 1G-Copper Full 1000 Enabled Off Up Disabled Auto 5 | gi2 1G-Copper Full 1000 Enabled Off Up Disabled Auto 6 | gi3 1G-Copper Full 1000 Enabled Off Up Disabled Auto 7 | gi4 1G-Copper Full 1000 Enabled Off Up Disabled Auto 8 | gi5 1G-Copper Full 1000 Enabled Off Up Disabled Auto 9 | gi6 1G-Copper Full 1000 Enabled Off Up Disabled Auto 10 | gi7 1G-Copper Full 1000 Enabled Off Up Disabled Auto 11 | gi8 1G-Copper Full 1000 Enabled Off Up Disabled Auto 12 | gi9 1G-Combo-C Full 1000 Enabled Off Up Disabled Auto 13 | gi10 1G-Combo-C Full 1000 Enabled Off Up Disabled Auto 14 | 15 | Flow Admin 16 | Ch Type Speed Neg control State 17 | -------- ------- ----- -------- ------- ----- 18 | Po1 -- -- Enabled Off Up 19 | Po2 -- -- Enabled Off Up 20 | Po3 -- -- Enabled Off Up 21 | Po4 -- -- Enabled Off Up 22 | Po5 -- -- Enabled Off Up 23 | Po6 -- -- Enabled Off Up 24 | Po7 -- -- Enabled Off Up 25 | Po8 -- -- Enabled Off Up 26 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_interfaces_description: -------------------------------------------------------------------------------- 1 | Port Description 2 | ------- ----------- 3 | gi1 4 | gi2 5 | gi3 6 | gi4 7 | gi5 8 | gi6 9 | gi7 10 | gi8 11 | gi9 12 | gi10 13 | 14 | Ch Description 15 | ------- ----------- 16 | Po1 17 | Po2 18 | Po3 19 | Po4 20 | Po5 21 | Po6 22 | Po7 23 | Po8 24 | 25 | Bluetooth Description 26 | ------------ ----------- 27 | bluetooth 0 28 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_interfaces_status: -------------------------------------------------------------------------------- 1 | Flow Link Back Mdix 2 | Port Type Duplex Speed Neg ctrl State Pressure Mode 3 | --------- ------------ ------ ----- -------- ---- ----------- -------- ------- 4 | gi1 1G-Copper Full 1000 Enabled Off Up Disabled On 5 | gi2 1G-Copper Full 100 Enabled Off Up Disabled On 6 | gi3 1G-Copper Full 1000 Enabled Off Up Disabled On 7 | gi4 1G-Copper Full 1000 Enabled Off Up Disabled On 8 | gi5 1G-Copper -- -- -- -- Down -- -- 9 | gi6 1G-Copper -- -- -- -- Down -- -- 10 | gi7 1G-Copper -- -- -- -- Down -- -- 11 | gi8 1G-Copper -- -- -- -- Down -- -- 12 | gi9 1G-Combo-C -- -- -- -- Down -- -- 13 | gi10 1G-Combo-C Full 100 Enabled Off Up Disabled Off 14 | 15 | Flow Link 16 | Ch Type Duplex Speed Neg control State 17 | -------- ------- ------ ----- -------- ------- ----------- 18 | Po1 -- -- -- -- -- Not Present 19 | Po2 -- -- -- -- -- Not Present 20 | Po3 -- -- -- -- -- Not Present 21 | Po4 -- -- -- -- -- Not Present 22 | Po5 -- -- -- -- -- Not Present 23 | Po6 -- -- -- -- -- Not Present 24 | Po7 -- -- -- -- -- Not Present 25 | Po8 -- -- -- -- -- Not Present 26 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_inventory: -------------------------------------------------------------------------------- 1 | 2 | NAME: "1" DESCR: "Catalyst 1300 Series Managed Switch, 8-port GE, Full PoE, 2x1G Combo (C1300-8FP-2G)" 3 | PID: C1300-8FP-2G VID: V02 SN: FOC2222291D 4 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_ip_interface: -------------------------------------------------------------------------------- 1 | 2 | 3 | IP Address I/F I/F Status Type Directed Prec Redirect Status 4 | admin/oper Broadcast 5 | ------------------ --------- ---------- ------- --------- ---- -------- ------ 6 | 0.0.0.0/32 vlan 1 UP/DOWN DHCP disable No enable Not 7 | receiv 8 | ed 9 | 10.10.10.2/24 vlan 999 UP/UP Static disable No enable Valid 10 | 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_ip_route: -------------------------------------------------------------------------------- 1 | Maximum Parallel Paths: 1 (1 after reset) 2 | IP Forwarding: enabled 3 | Codes: > - best, C - connected, S - static 4 | R - RIP 5 | 6 | 7 | S 0.0.0.0/0 [1/4] via 10.10.10.1, 459:17:17, vlan 999 8 | C 10.10.10.0/24 is directly connected, vlan 999 9 | 10 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_ipv6_interface_brief: -------------------------------------------------------------------------------- 1 | 2 | Interface Interface IPv6 Link Local MLD Number of 3 | State State IPv6 Address Version Global Addresses 4 | ---------- --------- --------- ------------------------- ------- ---------------- 5 | vlan 1 up/down enabled fe80::960d:41ff:ffcf:1e71 2 0 6 | 7 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_ports_jumbo-frame: -------------------------------------------------------------------------------- 1 | 2 | Jumbo frames are disabled 3 | Jumbo frames will be disabled after reset 4 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_system: -------------------------------------------------------------------------------- 1 | System Description: Catalyst 1300 Series Managed Switch, 8-port GE, Full PoE, 2x1G Combo (C1300-8FP-2G) 2 | System Up Time (days,hour:min:sec): 43,23:42:25 3 | System Contact: 4 | System Name: hostname 5 | System Location: 6 | System MAC Address: 94:0d:4b:0A:0A:0A 7 | System Object ID: 1.3.6.1.4.1.9.1.3228 8 | 9 | Unit Type 10 | ---- ---------------------- 11 | 1 C1300-8FP-2G 12 | 13 | 14 | Unit Temperature (Celsius) Status 15 | ---- --------------------- ---------- 16 | 1 45 OK 17 | 18 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-C1300-8FP-2G-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/image_c1300_4.1.6.54_official_key.bin 2 | Version: 4.1.6.54 3 | MD5 Digest: 9ebbfe128965ba857b81fb75292c84ec 4 | Date: 18-Feb-2025 5 | Time: 07:02:12 6 | Inactive-image: flash://system/images/image_4.1.3.36.bin 7 | Version: 4.1.3.36 8 | MD5 Digest: 90803a985c9110cef9aa4d576206b629 9 | Date: 19-May-2024 10 | Time: 08:17:26 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-CBS350-24P-4G-dir: -------------------------------------------------------------------------------- 1 | Permissions 2 | d-directory 3 | r-readable 4 | w-writable 5 | x-executable 6 | 125856K of 223636K are free 7 | Directory of flash:// 8 | 9 | Permission File Size Last Modified File Name 10 | ---------- --------- -------------------- -------------------------------------- 11 | dr-- 1312 05-Feb-2021 11:01:04 system 12 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-CBS350-24P-4G-show_cpu_utilization: -------------------------------------------------------------------------------- 1 | CPU utilization service is on. 2 | 3 | CPU utilization 4 | --------------- 5 | five seconds: 20%; one minute: 8%; five minutes: 3% 6 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-CBS350-24P-4G-show_inventory: -------------------------------------------------------------------------------- 1 | NAME: 1 DESCR: CBS350-24P-4G 24-Port Gigabit PoE Managed Switch 2 | PID: CBS350-24P-4G VID: V01 SN: FOC2222291D 3 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-CBS350-24P-4G-show_system: -------------------------------------------------------------------------------- 1 | System Description: CBS350-24P-4G 24-Port Gigabit PoE Managed Switch 2 | System Up Time (days,hour:min:sec): 21,05:26:26 3 | System Contact: Somemail@example.com 4 | System Name: sw-example 5 | System Location: 6 | System MAC Address: aa:bb:11:22:3c:4d 7 | System Object ID: 1.3.6.1.4.1.9.6.1.1004.28.5 8 | 9 | Unit Type 10 | ---- ---------------------- 11 | 1 CBS350-24P-4G 12 | 13 | 14 | Unit Fans Status 15 | ---- ------------------------------------- 16 | 1 Fans status is N/A 17 | 18 | Unit Temperature (Celsius) Status 19 | ---- --------------------- ---------- 20 | 1 63 OK 21 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-CBS350-24P-4G-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/image1.bin 2 | Version: 3.0.0.61 3 | MD5 Digest: 9703a2dea9e4c07c5cb22bc6c0235bcf 4 | Date: 18-Jun-2020 5 | Time: 20:38:40 6 | Inactive-image: flash://system/images/_image1.bin 7 | Version: 3.0.0.61 8 | MD5 Digest: 9703a2dea9e4c07c5cb22bc6c0235bcf 9 | Date: 18-Jun-2020 10 | Time: 20:38:40 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG350-28-K9-show_cpu_utilization: -------------------------------------------------------------------------------- 1 | CPU utilization service is on. 2 | 3 | CPU utilization 4 | --------------- 5 | five seconds: 11%; one minute: 10%; five minutes: 10% 6 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG350-28-K9-show_inventory: -------------------------------------------------------------------------------- 1 | 2 | NAME: "1" DESCR: "SG350-28 28-Port Gigabit Managed Switch" 3 | PID: SG350-28-K9 VID: V01 SN: ABC1234567A 4 | 5 | 6 | NAME: "GigabitEthernet28" DESCR: "SFP-1000Base-SX" 7 | PID: SFP-1000-SX VID: Information Unavailable SN: A123456 8 | 9 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG350-28-K9-show_system: -------------------------------------------------------------------------------- 1 | System Description: SG350-28 28-Port Gigabit Managed Switch 2 | System Up Time (days,hour:min:sec): 10,07:27:25 3 | System Contact: 4 | System Name: sw-ab-abcdefg-1 5 | System Location: Abcde Fghijk - Lmnop 6 | System MAC Address: aa:11:bb:22:c3:4d 7 | System Object ID: 1.3.6.1.4.1.9.6.1.95.28.1 8 | 9 | Unit Type 10 | ---- ---------------------- 11 | 1 SG350-28 12 | 13 | 14 | Unit Fans Status 15 | ---- ------------------------------------- 16 | 1 Fans status is N/A 17 | 18 | Unit Temperature (Celsius) Status 19 | ---- --------------------- ---------- 20 | 1 53 OK 21 | 22 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG350-28-K9-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/image_tesla_hybrid_2.4.5.71_release_cisco_signed.bin 2 | Version: 2.4.5.71 3 | MD5 Digest: 2dff89efdb2a0ec2f9a2c414ff7d401c 4 | Date: 04-Nov-2018 5 | Time: 19:46:16 6 | Inactive-image: flash://system/images/image1.bin 7 | Version: 2.2.8.4 8 | MD5 Digest: d75d9f2e1a06e99ba793af2418470df1 9 | Date: 21-Dec-2016 10 | Time: 22:03:09 11 | 12 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-dir: -------------------------------------------------------------------------------- 1 | Directory of flash: 2 | 3 | File Name Permission Flash Size Data Size Modified 4 | ------------------- ---------- ---------- --------- ----------------------- 5 | backuplo rw 655200 26 12-Jan-2014 18:08:41 6 | debug rw 65520 65520 03-Jun-2018 23:53:59 7 | dhcpdb.sys r- 65520 -- 12-Jan-2014 18:08:23 8 | dhcpsn.prv -- 65520 -- 12-Jan-2014 18:08:23 9 | directry.prv -- 65520 -- 12-Jan-2014 18:08:23 10 | image-1 rw 10009546 10009546 02-May-2013 14:56:48 11 | image-2 rw 10558664 10558664 12-Jan-2014 18:16:50 12 | mirror-config rw 1048320 6551 01-Jul-2018 05:26:13 13 | startup-config rw 1048320 19079 30-Jun-2018 05:26:18 14 | syslog1.sys r- 131040 -- 02-May-2013 14:56:48 15 | syslog2.sys r- 131040 -- 02-May-2013 14:56:48 16 | 17 | Total size of flash: 32899072 bytes 18 | Free size of flash: 7154750 bytes 19 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_cpu_utilization: -------------------------------------------------------------------------------- 1 | CPU utilization service is on. 2 | 3 | CPU utilization 4 | --------------- 5 | five seconds: 6%; one minute: 7%; five minutes: 5% 6 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_interfaces_configuration: -------------------------------------------------------------------------------- 1 | Flow Admin Back Mdix 2 | Port Type Duplex Speed Neg control State Pressure Mode 3 | -------- ------------ ------ ----- -------- ------- ----- -------- ---- 4 | gi1/1 1G-Copper Full 1000 Enabled Off Up Disabled Auto 5 | gi1/2 1G-Copper Full 1000 Enabled Off Up Disabled Auto 6 | gi1/3 1G-Copper Full 1000 Enabled Off Up Disabled Auto 7 | gi1/4 1G-Copper Full 1000 Enabled Off Up Disabled Auto 8 | gi1/5 1G-Copper Full 1000 Enabled Off Up Disabled Auto 9 | gi1/6 1G-Copper Full 1000 Enabled Off Up Disabled Auto 10 | gi1/7 1G-Copper Full 1000 Enabled Off Up Disabled Auto 11 | gi1/8 1G-Copper Full 1000 Enabled Off Up Disabled Auto 12 | gi1/9 1G-Copper Full 1000 Enabled Off Up Disabled Auto 13 | gi1/10 1G-Copper Full 1000 Enabled Off Up Disabled Auto 14 | gi1/11 1G-Copper Full 1000 Enabled Off Up Disabled Auto 15 | gi1/12 1G-Copper Full 1000 Enabled Off Up Disabled Auto 16 | gi1/13 1G-Copper Full 1000 Enabled Off Up Disabled Auto 17 | gi1/14 1G-Copper Full 1000 Enabled Off Up Disabled Auto 18 | gi1/15 1G-Copper Full 1000 Enabled Off Up Disabled Auto 19 | gi1/16 1G-Copper Full 1000 Enabled Off Up Disabled Auto 20 | gi1/17 1G-Copper Full 1000 Enabled Off Up Disabled Auto 21 | gi1/18 1G-Copper Full 1000 Enabled Off Up Disabled Auto 22 | gi1/19 1G-Copper Full 1000 Enabled Off Up Disabled Auto 23 | gi1/20 1G-Copper Full 1000 Enabled Off Up Disabled Auto 24 | gi1/21 1G-Copper Full 1000 Enabled Off Up Disabled Auto 25 | gi1/22 1G-Copper Full 1000 Enabled Off Up Disabled Auto 26 | gi1/23 1G-Copper Full 1000 Enabled Off Up Disabled Auto 27 | gi1/24 1G-Copper Full 1000 Enabled Off Up Disabled Auto 28 | gi1/25 1G-Copper Full 1000 Enabled Off Up Disabled Auto 29 | gi1/26 1G-Copper Full 1000 Enabled Off Up Disabled Auto 30 | gi1/27 1G-Copper Full 1000 Enabled Off Up Disabled Auto 31 | gi1/28 1G-Copper Full 1000 Enabled Off Up Disabled Auto 32 | gi1/29 1G-Copper Full 1000 Enabled Off Up Disabled Auto 33 | gi1/30 1G-Copper Full 1000 Enabled Off Up Disabled Auto 34 | gi1/31 1G-Copper Full 1000 Enabled Off Up Disabled Auto 35 | gi1/32 1G-Copper Full 1000 Enabled Off Up Disabled Auto 36 | gi1/33 1G-Copper Full 1000 Enabled Off Up Disabled Auto 37 | gi1/34 1G-Copper Full 1000 Enabled Off Up Disabled Auto 38 | gi1/35 1G-Copper Full 1000 Enabled Off Up Disabled Auto 39 | gi1/36 1G-Copper Full 1000 Enabled Off Up Disabled Auto 40 | gi1/37 1G-Copper Full 1000 Enabled Off Up Disabled Auto 41 | gi1/38 1G-Copper Full 1000 Enabled Off Up Disabled Auto 42 | gi1/39 1G-Copper Full 1000 Enabled Off Up Disabled Auto 43 | gi1/40 1G-Copper Full 1000 Enabled Off Up Disabled Auto 44 | gi1/41 1G-Copper Full 1000 Enabled Off Up Disabled Auto 45 | gi1/42 1G-Copper Full 1000 Enabled Off Up Disabled Auto 46 | gi1/43 1G-Copper Full 1000 Enabled Off Up Disabled Auto 47 | gi1/44 1G-Copper Full 1000 Enabled Off Up Disabled Auto 48 | gi1/45 1G-Copper Full 1000 Enabled Off Up Disabled Auto 49 | gi1/46 1G-Copper Full 1000 Enabled Off Up Disabled Auto 50 | gi1/47 1G-Copper Full 1000 Enabled Off Up Disabled Auto 51 | gi1/48 1G-Copper Full 1000 Enabled Off Up Disabled Auto 52 | gi1/49 1G-Combo-C Full 1000 Enabled Off Up Disabled Auto 53 | gi1/50 1G-Combo-C Full 1000 Enabled Off Up Disabled Auto 54 | gi1/51 1G-Fiber Full 1000 Disabled Off Up Disabled Auto 55 | gi1/52 1G-Fiber Full 1000 Disabled Off Up Disabled Auto 56 | 57 | Flow Admin 58 | Ch Type Speed Neg control State 59 | -------- ------- ----- -------- ------- ----- 60 | Po1 1G 1000 Enabled Off Up 61 | Po2 -- -- Enabled Off Up 62 | Po3 -- -- Enabled Off Up 63 | Po4 -- -- Enabled Off Up 64 | Po5 -- -- Enabled Off Up 65 | Po6 -- -- Enabled Off Up 66 | Po7 -- -- Enabled Off Up 67 | Po8 -- -- Enabled Off Up 68 | Po9 -- -- Enabled Off Up 69 | Po10 -- -- Enabled Off Up 70 | Po11 -- -- Enabled Off Up 71 | Po12 -- -- Enabled Off Up 72 | Po13 -- -- Enabled Off Up 73 | Po14 -- -- Enabled Off Up 74 | Po15 -- -- Enabled Off Up 75 | Po16 -- -- Enabled Off Up 76 | Po17 -- -- Enabled Off Up 77 | Po18 -- -- Enabled Off Up 78 | Po19 -- -- Enabled Off Up 79 | Po20 -- -- Enabled Off Up 80 | Po21 -- -- Enabled Off Up 81 | Po22 -- -- Enabled Off Up 82 | Po23 -- -- Enabled Off Up 83 | Po24 -- -- Enabled Off Up 84 | Po25 -- -- Enabled Off Up 85 | Po26 -- -- Enabled Off Up 86 | Po27 -- -- Enabled Off Up 87 | Po28 -- -- Enabled Off Up 88 | Po29 -- -- Enabled Off Up 89 | Po30 -- -- Enabled Off Up 90 | Po31 -- -- Enabled Off Up 91 | Po32 -- -- Enabled Off Up 92 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_interfaces_description: -------------------------------------------------------------------------------- 1 | Port Description 2 | ------- ----------- 3 | gi1/1 Wifi Controller 4 | gi1/2 WiFi AP 5 | gi1/3 WiFi AP 6 | gi1/4 WiFi AP 7 | gi1/5 Access port 8 | gi1/6 Access port 9 | gi1/7 Access port 10 | gi1/8 Access port 11 | gi1/9 Access port 12 | gi1/10 Access port 13 | gi1/11 Plain VoIP 14 | gi1/12 Access port 15 | gi1/13 Access port 16 | gi1/14 Access port 17 | gi1/15 Access port 18 | gi1/16 Access port 19 | gi1/17 Access port 20 | gi1/18 Plug 7B - sw tests 21 | gi1/19 Access port 22 | gi1/20 23 | gi1/21 Access port 24 | gi1/22 Access port 25 | gi1/23 Access port 26 | gi1/24 Access port 27 | gi1/25 Access port 28 | gi1/26 Access port 29 | gi1/27 Access port 30 | gi1/28 Access port 31 | gi1/29 Access port 32 | gi1/30 Access port 33 | gi1/31 Access port 34 | gi1/32 Access port 35 | gi1/33 Access port 36 | gi1/34 Access port 37 | gi1/35 Access port 38 | gi1/36 Access port 39 | gi1/37 Access port 40 | gi1/38 Access port 41 | gi1/39 Access port 42 | gi1/40 Plug 7A dock 43 | gi1/41 Access port 44 | gi1/42 Access port 45 | gi1/43 Access port 46 | gi1/44 Access port 47 | gi1/45 Access port 48 | gi1/46 Access port 49 | gi1/47 Access port 50 | gi1/48 Access port 51 | gi1/49 Po1 to sw-ab-cdef-1 52 | gi1/50 Po1 to sw-ab-cdef-1 53 | gi1/51 Access port 54 | gi1/52 Access port 55 | 56 | Ch Description 57 | ------- ----------- 58 | Po1 Trunk sw-ab-cdef-1 59 | Po2 60 | Po3 61 | Po4 62 | Po5 63 | Po6 64 | Po7 65 | Po8 66 | Po9 67 | Po10 68 | Po11 69 | Po12 70 | Po13 71 | Po14 72 | Po15 73 | Po16 74 | Po17 75 | Po18 76 | Po19 77 | Po20 78 | Po21 79 | Po22 80 | Po23 81 | Po24 82 | Po25 83 | Po26 84 | Po27 85 | Po28 86 | Po29 87 | Po30 88 | Po31 89 | Po32 90 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_interfaces_status: -------------------------------------------------------------------------------- 1 | Flow Link Back Mdix 2 | Port Type Duplex Speed Neg ctrl State Pressure Mode 3 | -------- ------------ ------ ----- -------- ---- ----------- -------- ------- 4 | gi1/1 1G-Copper Full 1000 Enabled Off Up Disabled Off 5 | gi1/2 1G-Copper -- -- -- -- Down -- -- 6 | gi1/3 1G-Copper -- -- -- -- Down -- -- 7 | gi1/4 1G-Copper Full 1000 Enabled Off Up Disabled On 8 | gi1/5 1G-Copper Full 1000 Enabled Off Up Disabled Off 9 | gi1/6 1G-Copper Full 100 Enabled Off Up Disabled On 10 | gi1/7 1G-Copper -- -- -- -- Down -- -- 11 | gi1/8 1G-Copper -- -- -- -- Down -- -- 12 | gi1/9 1G-Copper -- -- -- -- Down -- -- 13 | gi1/10 1G-Copper -- -- -- -- Down -- -- 14 | gi1/11 1G-Copper -- -- -- -- Down -- -- 15 | gi1/12 1G-Copper -- -- -- -- Down -- -- 16 | gi1/13 1G-Copper -- -- -- -- Down -- -- 17 | gi1/14 1G-Copper -- -- -- -- Down -- -- 18 | gi1/15 1G-Copper -- -- -- -- Down -- -- 19 | gi1/16 1G-Copper Full 100 Enabled Off Up Disabled On 20 | gi1/17 1G-Copper -- -- -- -- Down -- -- 21 | gi1/18 1G-Copper Full 1000 Enabled Off Up Disabled On 22 | gi1/19 1G-Copper -- -- -- -- Down -- -- 23 | gi1/20 1G-Copper Full 1000 Enabled Off Up Disabled On 24 | gi1/21 1G-Copper -- -- -- -- Down -- -- 25 | gi1/22 1G-Copper Full 100 Enabled Off Up Disabled On 26 | gi1/23 1G-Copper Full 1000 Enabled Off Up Disabled On 27 | gi1/24 1G-Copper -- -- -- -- Down -- -- 28 | gi1/25 1G-Copper Full 1000 Enabled Off Up Disabled Off 29 | gi1/26 1G-Copper Full 10 Enabled Off Up Disabled Off 30 | gi1/27 1G-Copper -- -- -- -- Down -- -- 31 | gi1/28 1G-Copper Full 100 Enabled Off Up Disabled Off 32 | gi1/29 1G-Copper -- -- -- -- Down -- -- 33 | gi1/30 1G-Copper -- -- -- -- Down -- -- 34 | gi1/31 1G-Copper -- -- -- -- Down -- -- 35 | gi1/32 1G-Copper -- -- -- -- Down -- -- 36 | gi1/33 1G-Copper -- -- -- -- Down -- -- 37 | gi1/34 1G-Copper -- -- -- -- Down -- -- 38 | gi1/35 1G-Copper -- -- -- -- Down -- -- 39 | gi1/36 1G-Copper -- -- -- -- Down -- -- 40 | gi1/37 1G-Copper -- -- -- -- Down -- -- 41 | gi1/38 1G-Copper -- -- -- -- Down -- -- 42 | gi1/39 1G-Copper Full 1000 Enabled Off Up Disabled Off 43 | gi1/40 1G-Copper -- -- -- -- Down -- -- 44 | gi1/41 1G-Copper -- -- -- -- Down -- -- 45 | gi1/42 1G-Copper Full 1000 Enabled Off Up Disabled On 46 | gi1/43 1G-Copper -- -- -- -- Down -- -- 47 | gi1/44 1G-Copper -- -- -- -- Down -- -- 48 | gi1/45 1G-Copper -- -- -- -- Down -- -- 49 | gi1/46 1G-Copper -- -- -- -- Down -- -- 50 | gi1/47 1G-Copper Full 100 Enabled Off Up Disabled On 51 | gi1/48 1G-Copper -- -- -- -- Down -- -- 52 | gi1/49 1G-Combo-C Full 1000 Enabled Off Up Disabled Off 53 | gi1/50 1G-Combo-C Full 1000 Enabled Off Up Disabled On 54 | gi1/51 1G-Fiber -- -- -- -- Down -- -- 55 | gi1/52 1G-Fiber -- -- -- -- Down -- -- 56 | 57 | Flow Link 58 | Ch Type Duplex Speed Neg control State 59 | -------- ------- ------ ----- -------- ------- ----------- 60 | Po1 1G Full 1000 Enabled Off Up 61 | Po2 -- -- -- -- -- Not Present 62 | Po3 -- -- -- -- -- Not Present 63 | Po4 -- -- -- -- -- Not Present 64 | Po5 -- -- -- -- -- Not Present 65 | Po6 -- -- -- -- -- Not Present 66 | Po7 -- -- -- -- -- Not Present 67 | Po8 -- -- -- -- -- Not Present 68 | Po9 -- -- -- -- -- Not Present 69 | Po10 -- -- -- -- -- Not Present 70 | Po11 -- -- -- -- -- Not Present 71 | Po12 -- -- -- -- -- Not Present 72 | Po13 -- -- -- -- -- Not Present 73 | Po14 -- -- -- -- -- Not Present 74 | Po15 -- -- -- -- -- Not Present 75 | Po16 -- -- -- -- -- Not Present 76 | Po17 -- -- -- -- -- Not Present 77 | Po18 -- -- -- -- -- Not Present 78 | Po19 -- -- -- -- -- Not Present 79 | Po20 -- -- -- -- -- Not Present 80 | Po21 -- -- -- -- -- Not Present 81 | Po22 -- -- -- -- -- Not Present 82 | Po23 -- -- -- -- -- Not Present 83 | Po24 -- -- -- -- -- Not Present 84 | Po25 -- -- -- -- -- Not Present 85 | Po26 -- -- -- -- -- Not Present 86 | Po27 -- -- -- -- -- Not Present 87 | Po28 -- -- -- -- -- Not Present 88 | Po29 -- -- -- -- -- Not Present 89 | Po30 -- -- -- -- -- Not Present 90 | Po31 -- -- -- -- -- Not Present 91 | Po32 -- -- -- -- -- Not Present 92 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_inventory: -------------------------------------------------------------------------------- 1 | 2 | NAME: "1" DESCR: "SG500-52 52-Port Gigabit Stackable Managed Switch" 3 | PID: SG500-52-K9 VID: V02 SN: ABC12345678 4 | 5 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_ip_interface: -------------------------------------------------------------------------------- 1 | 2 | 3 | IP Address I/F I/F Status Type Redirect Status 4 | admin/oper 5 | ------------------ --------- ---------- ------- -------- ------ 6 | 11.30.5.12/18 vlan 1 UP/UP Static enable Valid 7 | 8 | 9 | Gateway IP Address Type 10 | ----------------------- -------- 11 | 11.30.5.11 static 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_ip_route: -------------------------------------------------------------------------------- 1 | Maximum Parallel Paths: 1 (1 after reset) 2 | IP Forwarding: disabled 3 | Codes: > - best, C - connected, S - static 4 | 5 | 6 | S 0.0.0.0/0 [1/1] via 11.13.1.1, 26:03:44, vlan 1 7 | C 11.13.1.0/18 is directly connected, vlan 1 8 | 9 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_ipv6_interface_brief: -------------------------------------------------------------------------------- 1 | 2 | Interface Interface IPv6 Link Local MLD Number of 3 | State State IPv6 Address Version Global Addresses 4 | ---------- --------- --------- ------------------------- ------- ---------------- 5 | vlan 1 up/up enabled fe80::36db:fdff:fe64:5bce 2 0 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_lldp_neighbors: -------------------------------------------------------------------------------- 1 | 2 | System capability legend: 3 | B - Bridge; R - Router; W - Wlan Access Point; T - telephone; 4 | D - DOCSIS Cable Device; H - Host; r - Repeater; 5 | TP - Two Ports MAC Relay; S - S-VLAN; C - C-VLAN; O - Other 6 | 7 | Port Device ID Port ID System Name Capabilities TTL 8 | --------- ----------------- ------------- ----------------- ------------ ----- 9 | gi1/4 b0:ba:6a:c2:41:80 b0:ba:6a:c2:4 b0:ba:6a:c2:41:80 W 106 10 | 1:80 11 | gi1/5 3a:e6:da:4a:52:1e 3a:e6:da:4a:5 O 3092 12 | 2:1e 13 | gi1/18 00:1a:a9:49:2d:80 Gi0/2 sw-xy-zxxqwe-4.es B 119 14 | .example.com 15 | gi1/20 dc:4a:3e:56:8d:45 dc:4a:3e:56:8 O 2690 16 | d:45 17 | gi1/23 aa:4c:ca:91:06:f2 aa:4c:ca:91:0 O 2816 18 | 6:f2 19 | gi1/39 aa:1f:72:91:f9:a2 aa:1f:72:91:f O 3495 20 | 9:a2 21 | gi1/47 ea:5a:ea:8c:ad:1b ea:5a:ea:8c:a O 2692 22 | d:1b 23 | gi1/49 bc:ea:fa:ba:1a:a0 Ten-GigabitEt sw-ab-cdef-1 B, R, C 101 24 | hernet1/0/44 25 | gi1/50 bc:ea:fa:ba:1a:a0 Ten-GigabitEt sw-ab-cdef-1 B, R, C 100 26 | hernet2/0/44 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_ports_jumbo-frame: -------------------------------------------------------------------------------- 1 | 2 | Jumbo frames are disabled 3 | Jumbo frames will be disabled after reset 4 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_system: -------------------------------------------------------------------------------- 1 | System Description: SG500-52 52-Port Gigabit Stackable Managed Switch 2 | System Up Time (days,hour:min:sec): 483,01:39:47 3 | System Contact: 4 | System Name: sw-abcdefg-1 5 | System Location: Abc Dedgh - Ijklmnd 23 6 | System MAC Address: aa:11:bb:22:3c:d4 7 | System Object ID: 1.3.6.1.4.1.9.6.1.81.52.1 8 | 9 | Fans Status: OK 10 | 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG500-52-K9-show_version: -------------------------------------------------------------------------------- 1 | SW version 1.4.8.6 ( date 10-Jul-2017 time 17:07:33 ) 2 | Boot version 1.3.7.01 ( date 04-Dec-2013 time 13:48:27 ) 3 | HW version V02 4 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG550X-24MP-K9-dir: -------------------------------------------------------------------------------- 1 | Permissions 2 | d-directory 3 | r-readable 4 | w-writable 5 | x-executable 6 | 125468K of 224552K are free 7 | Directory of flash:// 8 | 9 | Permission File Size Last Modified File Name 10 | ---------- --------- -------------------- -------------------------------------- 11 | dr-- 1376 04-Nov-2018 07:42:07 system 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG550X-24MP-K9-show_cpu_utilization: -------------------------------------------------------------------------------- 1 | CPU utilization service is on. 2 | 3 | CPU utilization 4 | --------------- 5 | five seconds: 8%; one minute: 8%; five minutes: 9% 6 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG550X-24MP-K9-show_inventory: -------------------------------------------------------------------------------- 1 | 2 | NAME: "1" DESCR: "SG550X-24MP 24-Port Gigabit PoE Stackable Managed Switch" 3 | PID: SG550X-24MP-K9 VID: V02 SN: ABC123456AB 4 | 5 | 6 | NAME: "TengigabitEthernet1/0/3" DESCR: "SFP-1000Base-SX" 7 | PID: SFP-1000-SX VID: Information Unavailable SN: A1234567890 8 | 9 | 10 | NAME: "TengigabitEthernet1/0/4" DESCR: "SFP-1000Base-SX" 11 | PID: SFP-1000-SX VID: Information Unavailable SN: A123456789 12 | 13 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG550X-24MP-K9-show_system: -------------------------------------------------------------------------------- 1 | System Description: SG550X-24MP 24-Port Gigabit PoE Stackable Managed Switch 2 | System Up Time (days,hour:min:sec): 105,15:23:35 3 | System Contact: 4 | System Name: sw-abcdefgh 5 | System Location: Abcd Efghijk - Lmnop 12 6 | System MAC Address: aa:11:bb:22:c3:4d 7 | System Object ID: 1.3.6.1.4.1.9.6.1.93.24.6 8 | 9 | Unit Type 10 | ---- ---------------------- 11 | 1 SG550X-24MP 12 | 13 | 14 | Unit Main Power Supply Redundant Power Supply 15 | ---- ----------------- ---------------------- 16 | 1 Active Not Connected 17 | 18 | Unit Fans Status 19 | ---- ------------------------------------- 20 | 1 FANs OK, redundant fan Ready 21 | 22 | Unit Temperature (Celsius) Status 23 | ---- --------------------- ---------- 24 | 1 37 OK 25 | 26 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SG550X-24MP-K9-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/sx550X_tesla_hybrid_2.4.5.71_release_cisco_signed.bin 2 | Version: 2.4.5.71 3 | MD5 Digest: 2dff89efdb2a0ec2f9a2c414ff7d401c 4 | Date: 04-Nov-2018 5 | Time: 19:46:16 6 | Inactive-image: flash://system/images/image1.bin 7 | Version: 2.3.0.130 8 | MD5 Digest: 079b10248b0cc997da651d255ac0ed15 9 | Date: 10-May-2017 10 | Time: 01:08:28 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SX550X-24F-K9-show_cpu_utilization: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SX550X-24F-K9-show_cpu_utilization -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SX550X-24F-K9-show_inventory: -------------------------------------------------------------------------------- 1 | NAME: "1" DESCR: "SX550X-24F 24-Port 10G SFP+ Stackable Managed Switch" 2 | PID: SX550X-24F-K9 VID: V02 SN: DNI22500E5F 3 | 4 | 5 | NAME: "TenGigabitEthernet1/0/11" DESCR: "SFP-10G-LR" 6 | PID: SFP-10G-LR VID: V02 SN: CS101K63284 7 | 8 | 9 | NAME: "TenGigabitEthernet1/0/14" DESCR: "SFP-10GBase-SR" 10 | PID: SFP-10G-SR VID: V03 SN: CSG101KB2848 11 | 12 | 13 | NAME: "TenGigabitEthernet1/0/15" DESCR: "SFP-10GBase-SR" 14 | PID: SFP-10G-SR VID: V03 SN: CSSSRJC2101 15 | 16 | 17 | NAME: "TenGigabitEthernet1/0/16" DESCR: "SFP-10GBase-SR" 18 | PID: SFP-10G-SR VID: V03 SN: CSSSRJC2119 19 | 20 | 21 | NAME: "TenGigabitEthernet1/0/17" DESCR: "SFP-10G-LR" 22 | PID: SFP-10G-LR VID: V02 SN: CSS2003194730 23 | 24 | 25 | NAME: "TenGigabitEthernet1/0/18" DESCR: "SFP-10G-LR" 26 | PID: SFP-10G-LR VID: V02 SN: CSS2003194736 27 | 28 | 29 | NAME: "TenGigabitEthernet1/0/19" DESCR: "SFP-10GBase-SR" 30 | PID: SFP-10G-SR VID: V03 SN: CSSSRJC2093 31 | 32 | 33 | NAME: "TenGigabitEthernet1/0/20" DESCR: "SFP-10GBase-SR" 34 | PID: SFP-10G-SR VID: V03 SN: CSSSRJC2115 35 | 36 | 37 | NAME: "TenGigabitEthernet1/0/22" DESCR: "Cisco SFP-10Gbase-CX1" 38 | PID: SFP-H10GB-CU3M VID: V03 SN: MOC1906A079 39 | 40 | 41 | NAME: "TenGigabitEthernet1/0/23" DESCR: "SFP-10G-LR" 42 | PID: SFP-10G-LR VID: V02 SN: CSS2003194783 43 | 44 | 45 | NAME: "TenGigabitEthernet1/0/24" DESCR: "SFP-10G-LR" 46 | PID: SFP-10G-LR VID: V02 SN: CSS2003194782 -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SX550X-24F-K9-show_system: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SX550X-24F-K9-show_system -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SX550X-24F-K9-show_version: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ansible-collections/community.ciscosmb/e72aaf263e564ea398be55872ffda95072e043b1/tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-SX550X-24F-K9-show_version -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-stackSG550X-48-dir: -------------------------------------------------------------------------------- 1 | Permissions 2 | d-directory 3 | r-readable 4 | w-writable 5 | x-executable 6 | 109064K of 224324K are free 7 | Directory of flash:// 8 | 9 | Permission File Size Last Modified File Name 10 | ---------- --------- -------------------- -------------------------------------- 11 | -rw- 1960 27-Jul-2020 07:40:50 sw-pl-s5hlavni-1.conf 12 | dr-- 1376 21-Feb-2021 05:32:07 system 13 | -rw- 18055 18-Jun-2019 05:17:35 zaloha.conf 14 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-stackSG550X-48-show_cpu_utilization: -------------------------------------------------------------------------------- 1 | CPU utilization service is on. 2 | 3 | CPU utilization 4 | --------------- 5 | five seconds: 9%; one minute: 10%; five minutes: 10% 6 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-stackSG550X-48-show_inventory: -------------------------------------------------------------------------------- 1 | 2 | NAME: "1" DESCR: "SG550X-48P 48-Port Gigabit PoE Stackable Managed Switch" 3 | PID: SG550X-48P-K9 VID: V04 SN: ABC1234567A 4 | 5 | 6 | NAME: "TenGigabitEthernet1/0/1" DESCR: "SFP-10G-LR" 7 | PID: SFP-10G-LR VID: V03 SN: AB12345678 8 | 9 | 10 | NAME: "TenGigabitEthernet1/0/2" DESCR: "SFP-1000Base-LX" 11 | PID: GLC-LH-SMD VID: Information Unavailable SN: AB12345678 12 | 13 | 14 | NAME: "2" DESCR: "SG550X-48 48-Port Gigabit Stackable Managed Switch" 15 | PID: SG550X-48-K9 VID: V02 SN: ABC123456AB 16 | 17 | 18 | NAME: "TenGigabitEthernet2/0/1" DESCR: "SFP-10G-LR" 19 | PID: SFP-10G-LR VID: V03 SN: AB12345678 20 | 21 | 22 | NAME: "TenGigabitEthernet2/0/2" DESCR: "SFP-1000Base-LX" 23 | PID: GLC-LH-SMD VID: Information Unavailable SN: AB12345678 24 | 25 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-stackSG550X-48-show_system: -------------------------------------------------------------------------------- 1 | System Description: SG550X-48P 48-Port Gigabit PoE Stackable Managed Switch 2 | System Up Time (days,hour:min:sec): 64,02:08:19 3 | System Contact: 4 | System Name: sw-abcdefgh-1 5 | System Location: 6 | System MAC Address: 11:aa:22:bb:3c:d4 7 | System Object ID: 1.3.6.1.4.1.9.6.1.93.48.5 8 | 9 | Unit Type 10 | ---- ---------------------- 11 | 1 SG550X-48P 12 | 2 SG550X-48 13 | 14 | 15 | Unit Main Power Supply Redundant Power Supply 16 | ---- ----------------- ---------------------- 17 | 1 Active Not Connected 18 | 2 Active Not Connected 19 | 20 | Unit Fans Status 21 | ---- ------------------------------------- 22 | 1 FANs OK, redundant fan Ready 23 | 2 FANs OK, redundant fan Ready 24 | 25 | Unit Temperature (Celsius) Status 26 | ---- --------------------- ---------- 27 | 1 55 OK 28 | 2 67 OK 29 | 30 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/fixtures/ciscosmb_facts-stackSG550X-48-show_version: -------------------------------------------------------------------------------- 1 | Active-image: flash://system/images/image1.bin 2 | Version: 2.5.0.83 3 | MD5 Digest: 07968d912499cff5e8b07fdc24779854 4 | Date: 18-Jun-2019 5 | Time: 16:49:35 6 | Inactive-image: flash://system/images/_image1.bin 7 | Version: 2.5.0.83 8 | MD5 Digest: 07968d912499cff5e8b07fdc24779854 9 | Date: 18-Jun-2019 10 | Time: 16:49:35 11 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_command-C1300-8FP-2G.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 29 | from ansible_collections.community.ciscosmb.plugins.modules import command 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = command 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.command.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module, commands = args 50 | output = list() 51 | 52 | for command in commands: 53 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 54 | output.append( 55 | load_fixture("ciscosmb_command-C1300-8FP-2G-%s" % filename) 56 | ) 57 | return output 58 | 59 | self.run_commands.side_effect = load_from_file 60 | 61 | def test_ciscosmb_command_simple(self): 62 | with set_module_args(dict(commands=["show version"])): 63 | result = self.execute_module() 64 | 65 | self.assertEqual(len(result["stdout"]), 1) 66 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 67 | 68 | def test_ciscosmb_command_multiple(self): 69 | with set_module_args(dict(commands=["show version", "show version"])): 70 | result = self.execute_module() 71 | 72 | self.assertEqual(len(result["stdout"]), 2) 73 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 74 | 75 | def test_ciscosmb_command_wait_for(self): 76 | wait_for = 'result[0] contains "system/images/image"' 77 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 78 | self.execute_module() 79 | 80 | def test_ciscosmb_command_wait_for_fails(self): 81 | wait_for = 'result[0] contains "test string"' 82 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 83 | self.execute_module(failed=True) 84 | 85 | self.assertEqual(self.run_commands.call_count, 10) 86 | 87 | def test_ciscosmb_command_retries(self): 88 | wait_for = 'result[0] contains "test string"' 89 | with set_module_args( 90 | dict(commands=["show version"], wait_for=wait_for, retries=2) 91 | ): 92 | self.execute_module(failed=True) 93 | 94 | self.assertEqual(self.run_commands.call_count, 2) 95 | 96 | def test_ciscosmb_command_match_any(self): 97 | wait_for = [ 98 | 'result[0] contains "system/images/image"', 99 | 'result[0] contains "test string"', 100 | ] 101 | with set_module_args( 102 | dict(commands=["show version"], wait_for=wait_for, match="any") 103 | ): 104 | self.execute_module() 105 | 106 | def test_ciscosmb_command_match_all(self): 107 | wait_for = [ 108 | 'result[0] contains "Active-image"', 109 | 'result[0] contains "system/images/image"', 110 | ] 111 | with set_module_args( 112 | dict(commands=["show version"], wait_for=wait_for, match="all") 113 | ): 114 | self.execute_module() 115 | 116 | def test_ciscosmb_command_match_all_failure(self): 117 | wait_for = [ 118 | 'result[0] contains "system/images/image"', 119 | 'result[0] contains "test string"', 120 | ] 121 | commands = ["show version", "show version"] 122 | with set_module_args(dict(commands=commands, wait_for=wait_for, match="all")): 123 | self.execute_module(failed=True) 124 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_command-CBS350-24P-4G.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 29 | from ansible_collections.community.ciscosmb.plugins.modules import command 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = command 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.command.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module, commands = args 50 | output = list() 51 | 52 | for command in commands: 53 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 54 | output.append( 55 | load_fixture("ciscosmb_command-CBS350-24P-4G-%s" % filename) 56 | ) 57 | return output 58 | 59 | self.run_commands.side_effect = load_from_file 60 | 61 | def test_ciscosmb_command_simple(self): 62 | with set_module_args(dict(commands=["show version"])): 63 | result = self.execute_module() 64 | 65 | self.assertEqual(len(result["stdout"]), 1) 66 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 67 | 68 | def test_ciscosmb_command_multiple(self): 69 | with set_module_args(dict(commands=["show version", "show version"])): 70 | result = self.execute_module() 71 | 72 | self.assertEqual(len(result["stdout"]), 2) 73 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 74 | 75 | def test_ciscosmb_command_wait_for(self): 76 | wait_for = 'result[0] contains "3.0.0.61"' 77 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 78 | self.execute_module() 79 | 80 | def test_ciscosmb_command_wait_for_fails(self): 81 | wait_for = 'result[0] contains "test string"' 82 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 83 | self.execute_module(failed=True) 84 | 85 | self.assertEqual(self.run_commands.call_count, 10) 86 | 87 | def test_ciscosmb_command_retries(self): 88 | wait_for = 'result[0] contains "test string"' 89 | with set_module_args( 90 | dict(commands=["show version"], wait_for=wait_for, retries=2) 91 | ): 92 | self.execute_module(failed=True) 93 | 94 | self.assertEqual(self.run_commands.call_count, 2) 95 | 96 | def test_ciscosmb_command_match_any(self): 97 | wait_for = [ 98 | 'result[0] contains "3.0.0.61"', 99 | 'result[0] contains "test string"', 100 | ] 101 | with set_module_args( 102 | dict(commands=["show version"], wait_for=wait_for, match="any") 103 | ): 104 | self.execute_module() 105 | 106 | def test_ciscosmb_command_match_all(self): 107 | wait_for = [ 108 | 'result[0] contains "Active-image"', 109 | 'result[0] contains "3.0.0.61"', 110 | ] 111 | with set_module_args( 112 | dict(commands=["show version"], wait_for=wait_for, match="all") 113 | ): 114 | self.execute_module() 115 | 116 | def test_ciscosmb_command_match_all_failure(self): 117 | wait_for = [ 118 | 'result[0] contains "3.0.0.61"', 119 | 'result[0] contains "test string"', 120 | ] 121 | commands = ["show version", "show version"] 122 | with set_module_args(dict(commands=commands, wait_for=wait_for, match="all")): 123 | self.execute_module(failed=True) 124 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_command-SG350-28-K9.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 29 | from ansible_collections.community.ciscosmb.plugins.modules import command 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = command 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.command.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module, commands = args 50 | output = list() 51 | 52 | for command in commands: 53 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 54 | output.append( 55 | load_fixture("ciscosmb_command-SG350-28-K9-%s" % filename) 56 | ) 57 | return output 58 | 59 | self.run_commands.side_effect = load_from_file 60 | 61 | def test_ciscosmb_command_simple(self): 62 | with set_module_args(dict(commands=["show version"])): 63 | result = self.execute_module() 64 | 65 | self.assertEqual(len(result["stdout"]), 1) 66 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 67 | 68 | def test_ciscosmb_command_multiple(self): 69 | with set_module_args(dict(commands=["show version", "show version"])): 70 | result = self.execute_module() 71 | 72 | self.assertEqual(len(result["stdout"]), 2) 73 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 74 | 75 | def test_ciscosmb_command_wait_for(self): 76 | wait_for = 'result[0] contains "image_tesla"' 77 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 78 | self.execute_module() 79 | 80 | def test_ciscosmb_command_wait_for_fails(self): 81 | wait_for = 'result[0] contains "test string"' 82 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 83 | self.execute_module(failed=True) 84 | 85 | self.assertEqual(self.run_commands.call_count, 10) 86 | 87 | def test_ciscosmb_command_retries(self): 88 | wait_for = 'result[0] contains "test string"' 89 | with set_module_args( 90 | dict(commands=["show version"], wait_for=wait_for, retries=2) 91 | ): 92 | self.execute_module(failed=True) 93 | 94 | self.assertEqual(self.run_commands.call_count, 2) 95 | 96 | def test_ciscosmb_command_match_any(self): 97 | wait_for = [ 98 | 'result[0] contains "image_tesla"', 99 | 'result[0] contains "test string"', 100 | ] 101 | with set_module_args( 102 | dict(commands=["show version"], wait_for=wait_for, match="any") 103 | ): 104 | self.execute_module() 105 | 106 | def test_ciscosmb_command_match_all(self): 107 | wait_for = [ 108 | 'result[0] contains "Active-image"', 109 | 'result[0] contains "image_tesla"', 110 | ] 111 | with set_module_args( 112 | dict(commands=["show version"], wait_for=wait_for, match="all") 113 | ): 114 | self.execute_module() 115 | 116 | def test_ciscosmb_command_match_all_failure(self): 117 | wait_for = [ 118 | 'result[0] contains "image_tesla"', 119 | 'result[0] contains "test string"', 120 | ] 121 | commands = ["show version", "show version"] 122 | with set_module_args(dict(commands=commands, wait_for=wait_for, match="all")): 123 | self.execute_module(failed=True) 124 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_command-SG500-52-K9.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 29 | from ansible_collections.community.ciscosmb.plugins.modules import command 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = command 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.command.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module, commands = args 50 | output = list() 51 | 52 | for command in commands: 53 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 54 | output.append( 55 | load_fixture("ciscosmb_command-SG500-52-K9-%s" % filename) 56 | ) 57 | return output 58 | 59 | self.run_commands.side_effect = load_from_file 60 | 61 | def test_ciscosmb_command_simple(self): 62 | with set_module_args(dict(commands=["show version"])): 63 | result = self.execute_module() 64 | 65 | self.assertEqual(len(result["stdout"]), 1) 66 | self.assertTrue(result["stdout"][0].startswith("SW version")) 67 | 68 | def test_ciscosmb_command_multiple(self): 69 | with set_module_args(dict(commands=["show version", "show version"])): 70 | result = self.execute_module() 71 | 72 | self.assertEqual(len(result["stdout"]), 2) 73 | self.assertTrue(result["stdout"][0].startswith("SW version")) 74 | 75 | def test_ciscosmb_command_wait_for(self): 76 | wait_for = 'result[0] contains "Boot version"' 77 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 78 | self.execute_module() 79 | 80 | def test_ciscosmb_command_wait_for_fails(self): 81 | wait_for = 'result[0] contains "test string"' 82 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 83 | self.execute_module(failed=True) 84 | 85 | self.assertEqual(self.run_commands.call_count, 10) 86 | 87 | def test_ciscosmb_command_retries(self): 88 | wait_for = 'result[0] contains "test string"' 89 | with set_module_args( 90 | dict(commands=["show version"], wait_for=wait_for, retries=2) 91 | ): 92 | self.execute_module(failed=True) 93 | 94 | self.assertEqual(self.run_commands.call_count, 2) 95 | 96 | def test_ciscosmb_command_match_any(self): 97 | wait_for = [ 98 | 'result[0] contains "Boot version"', 99 | 'result[0] contains "test string"', 100 | ] 101 | with set_module_args( 102 | dict(commands=["show version"], wait_for=wait_for, match="any") 103 | ): 104 | self.execute_module() 105 | 106 | def test_ciscosmb_command_match_all(self): 107 | wait_for = [ 108 | 'result[0] contains "SW version"', 109 | 'result[0] contains "Boot version"', 110 | ] 111 | with set_module_args( 112 | dict(commands=["show version"], wait_for=wait_for, match="all") 113 | ): 114 | self.execute_module() 115 | 116 | def test_ciscosmb_command_match_all_failure(self): 117 | wait_for = [ 118 | 'result[0] contains "Boot version"', 119 | 'result[0] contains "test string"', 120 | ] 121 | commands = ["show version", "show version"] 122 | with set_module_args(dict(commands=commands, wait_for=wait_for, match="all")): 123 | self.execute_module(failed=True) 124 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_command-SG550X-24MP-K9.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 29 | from ansible_collections.community.ciscosmb.plugins.modules import command 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = command 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.command.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module, commands = args 50 | output = list() 51 | 52 | for command in commands: 53 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 54 | output.append( 55 | load_fixture("ciscosmb_command-SG550X-24MP-K9-%s" % filename) 56 | ) 57 | return output 58 | 59 | self.run_commands.side_effect = load_from_file 60 | 61 | def test_ciscosmb_command_simple(self): 62 | with set_module_args(dict(commands=["show version"])): 63 | result = self.execute_module() 64 | 65 | self.assertEqual(len(result["stdout"]), 1) 66 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 67 | 68 | def test_ciscosmb_command_multiple(self): 69 | with set_module_args(dict(commands=["show version", "show version"])): 70 | result = self.execute_module() 71 | 72 | self.assertEqual(len(result["stdout"]), 2) 73 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 74 | 75 | def test_ciscosmb_command_wait_for(self): 76 | wait_for = 'result[0] contains "tesla_hybrid"' 77 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 78 | self.execute_module() 79 | 80 | def test_ciscosmb_command_wait_for_fails(self): 81 | wait_for = 'result[0] contains "test string"' 82 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 83 | self.execute_module(failed=True) 84 | 85 | self.assertEqual(self.run_commands.call_count, 10) 86 | 87 | def test_ciscosmb_command_retries(self): 88 | wait_for = 'result[0] contains "test string"' 89 | with set_module_args( 90 | dict(commands=["show version"], wait_for=wait_for, retries=2) 91 | ): 92 | self.execute_module(failed=True) 93 | 94 | self.assertEqual(self.run_commands.call_count, 2) 95 | 96 | def test_ciscosmb_command_match_any(self): 97 | wait_for = [ 98 | 'result[0] contains "tesla_hybrid"', 99 | 'result[0] contains "test string"', 100 | ] 101 | with set_module_args( 102 | dict(commands=["show version"], wait_for=wait_for, match="any") 103 | ): 104 | self.execute_module() 105 | 106 | def test_ciscosmb_command_match_all(self): 107 | wait_for = [ 108 | 'result[0] contains "Active-image"', 109 | 'result[0] contains "tesla_hybrid"', 110 | ] 111 | with set_module_args( 112 | dict(commands=["show version"], wait_for=wait_for, match="all") 113 | ): 114 | self.execute_module() 115 | 116 | def test_ciscosmb_command_match_all_failure(self): 117 | wait_for = [ 118 | 'result[0] contains "tesla_hybrid"', 119 | 'result[0] contains "test string"', 120 | ] 121 | commands = ["show version", "show version"] 122 | with set_module_args(dict(commands=commands, wait_for=wait_for, match="all")): 123 | self.execute_module(failed=True) 124 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_command-stackSG550X-48.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 29 | from ansible_collections.community.ciscosmb.plugins.modules import command 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = command 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.command.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module, commands = args 50 | output = list() 51 | 52 | for command in commands: 53 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 54 | output.append( 55 | load_fixture("ciscosmb_command-stackSG550X-48-%s" % filename) 56 | ) 57 | return output 58 | 59 | self.run_commands.side_effect = load_from_file 60 | 61 | def test_ciscosmb_command_simple(self): 62 | with set_module_args(dict(commands=["show version"])): 63 | result = self.execute_module() 64 | 65 | self.assertEqual(len(result["stdout"]), 1) 66 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 67 | 68 | def test_ciscosmb_command_multiple(self): 69 | with set_module_args(dict(commands=["show version", "show version"])): 70 | result = self.execute_module() 71 | 72 | self.assertEqual(len(result["stdout"]), 2) 73 | self.assertTrue(result["stdout"][0].startswith("Active-image: flash:")) 74 | 75 | def test_ciscosmb_command_wait_for(self): 76 | wait_for = 'result[0] contains "system/images"' 77 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 78 | self.execute_module() 79 | 80 | def test_ciscosmb_command_wait_for_fails(self): 81 | wait_for = 'result[0] contains "test string"' 82 | with set_module_args(dict(commands=["show version"], wait_for=wait_for)): 83 | self.execute_module(failed=True) 84 | 85 | self.assertEqual(self.run_commands.call_count, 10) 86 | 87 | def test_ciscosmb_command_retries(self): 88 | wait_for = 'result[0] contains "test string"' 89 | with set_module_args( 90 | dict(commands=["show version"], wait_for=wait_for, retries=2) 91 | ): 92 | self.execute_module(failed=True) 93 | 94 | self.assertEqual(self.run_commands.call_count, 2) 95 | 96 | def test_ciscosmb_command_match_any(self): 97 | wait_for = [ 98 | 'result[0] contains "Active-image"', 99 | 'result[0] contains "test string"', 100 | ] 101 | with set_module_args( 102 | dict(commands=["show version"], wait_for=wait_for, match="any") 103 | ): 104 | self.execute_module() 105 | 106 | def test_ciscosmb_command_match_all(self): 107 | wait_for = [ 108 | 'result[0] contains "Active-image"', 109 | 'result[0] contains "system/images"', 110 | ] 111 | with set_module_args( 112 | dict(commands=["show version"], wait_for=wait_for, match="all") 113 | ): 114 | self.execute_module() 115 | 116 | def test_ciscosmb_command_match_all_failure(self): 117 | wait_for = [ 118 | 'result[0] contains "system/images"', 119 | 'result[0] contains "test string"', 120 | ] 121 | commands = ["show version", "show version"] 122 | with set_module_args(dict(commands=commands, wait_for=wait_for, match="all")): 123 | self.execute_module(failed=True) 124 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-C1300-8FP-2G.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from ansible_collections.community.ciscosmb.plugins.modules import facts 29 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = facts 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.facts.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module = args 50 | commands = kwargs["commands"] 51 | output = list() 52 | 53 | for command in commands: 54 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 55 | output.append(load_fixture("ciscosmb_facts-C1300-8FP-2G-%s" % filename)) 56 | return output 57 | 58 | self.run_commands.side_effect = load_from_file 59 | 60 | def test_ciscosmb_facts_default(self): 61 | with set_module_args(dict(gather_subset="default")): 62 | result = self.execute_module() 63 | 64 | self.assertEqual(result["ansible_facts"]["ansible_net_hw_version"], "V02") 65 | self.assertEqual(result["ansible_facts"]["ansible_net_model"], "C1300-8FP-2G") 66 | self.assertEqual( 67 | result["ansible_facts"]["ansible_net_serialnum"], "FOC2222291D" 68 | ) 69 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-CBS350-24P-4G.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from ansible_collections.community.ciscosmb.plugins.modules import facts 29 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = facts 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.facts.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module = args 50 | commands = kwargs["commands"] 51 | output = list() 52 | 53 | for command in commands: 54 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 55 | output.append( 56 | load_fixture("ciscosmb_facts-CBS350-24P-4G-%s" % filename) 57 | ) 58 | return output 59 | 60 | self.run_commands.side_effect = load_from_file 61 | 62 | def test_ciscosmb_facts_default_version(self): 63 | with set_module_args(dict(gather_subset="default")): 64 | result = self.execute_module() 65 | 66 | self.assertEqual(result["ansible_facts"]["ansible_net_version"], "3.0.0.61") 67 | self.assertEqual(result["ansible_facts"]["ansible_net_hw_version"], "V01") 68 | 69 | def test_ciscosmb_facts_default_system_info(self): 70 | with set_module_args(dict(gather_subset="default")): 71 | result = self.execute_module() 72 | 73 | self.assertEqual(result["ansible_facts"]["ansible_net_uptime"], 1833986) 74 | self.assertEqual(result["ansible_facts"]["ansible_net_hostname"], "sw-example") 75 | self.assertEqual(result["ansible_facts"]["ansible_net_cpu_load"], "8") 76 | 77 | def test_ciscosmb_facts_default_inventory(self): 78 | with set_module_args(dict(gather_subset="default")): 79 | result = self.execute_module() 80 | 81 | self.assertEqual(result["ansible_facts"]["ansible_net_model"], "CBS350-24P-4G") 82 | self.assertEqual( 83 | result["ansible_facts"]["ansible_net_serialnum"], "FOC2222291D" 84 | ) 85 | 86 | def test_ciscosmb_facts_hardware(self): 87 | with set_module_args(dict(gather_subset="hardware")): 88 | result = self.execute_module() 89 | 90 | self.assertEqual(result["ansible_facts"]["ansible_net_spacefree_mb"], 122.9) 91 | self.assertEqual(result["ansible_facts"]["ansible_net_spacetotal_mb"], 218.4) 92 | 93 | def test_ciscosmb_facts_config(self): 94 | with set_module_args(dict(gather_subset="config")): 95 | result = self.execute_module() 96 | 97 | self.assertIsInstance(result["ansible_facts"]["ansible_net_config"], str) 98 | 99 | 100 | # def test_ciscosmb_facts_interfaces(self): 101 | # with set_module_args(dict(gather_subset='interfaces')): 102 | # result = self.execute_module() 103 | # 104 | # self.assertIn( 105 | # result['ansible_facts']['ansible_net_all_ipv4_addresses'][0], ['10.37.129.3', '10.37.0.0', '192.168.88.1'] 106 | # ) 107 | # self.assertEqual( 108 | # result['ansible_facts']['ansible_net_all_ipv6_addresses'], ['fe80::21c:42ff:fe36:5290'] 109 | # ) 110 | # self.assertEqual( 111 | # result['ansible_facts']['ansible_net_all_ipv6_addresses'][0], 112 | # result['ansible_facts']['ansible_net_interfaces']['ether1']['ipv6'][0]['address'] 113 | # ) 114 | # self.assertEqual( 115 | # len(result['ansible_facts']['ansible_net_interfaces'].keys()), 11 116 | # ) 117 | # self.assertEqual( 118 | # len(result['ansible_facts']['ansible_net_neighbors']), 4 119 | # ) 120 | # 121 | # def test_ciscosmb_facts_interfaces_no_ipv6(self): 122 | # fixture = load_fixture( 123 | # 'ciscosmb_facts/ipv6_address_print_detail_without-paging_no-ipv6' 124 | # ) 125 | # interfaces = self.module.Interfaces(module=self.module) 126 | # addresses = interfaces.parse_detail(data=fixture) 127 | # result = interfaces.populate_addresses(data=addresses, family='ipv6') 128 | # 129 | # self.assertEqual(result, None) 130 | # 131 | # def test_ciscosmb_facts_routing(self): 132 | # with set_module_args(dict(gather_subset='routing')): 133 | # result = self.execute_module() 134 | # 135 | # self.assertIn( 136 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['name'], ['iBGP_BRAS.TYRMA'] 137 | # ) 138 | # self.assertIn( 139 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['instance'], ['MAIN_AS_STARKDV'] 140 | # ) 141 | # self.assertIn( 142 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remote-address'], ['10.10.100.1'] 143 | # ) 144 | # self.assertIn( 145 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remote-as'], ['64520'] 146 | # ) 147 | # self.assertIn( 148 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['nexthop-choice'], ['default'] 149 | # ) 150 | # self.assertIn( 151 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['multihop'], ['no'] 152 | # ) 153 | # self.assertIn( 154 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['route-reflect'], ['yes'] 155 | # ) 156 | # self.assertIn( 157 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['hold-time'], ['3m'] 158 | # ) 159 | # self.assertIn( 160 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['ttl'], ['default'] 161 | # ) 162 | # self.assertIn( 163 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['address-families'], ['ip'] 164 | # ) 165 | # self.assertIn( 166 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['update-source'], ['LAN_KHV'] 167 | # ) 168 | # self.assertIn( 169 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['default-originate'], ['never'] 170 | # ) 171 | # self.assertIn( 172 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remove-private-as'], ['no'] 173 | # ) 174 | # self.assertIn( 175 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['as-override'], ['no'] 176 | # ) 177 | # self.assertIn( 178 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['passive'], ['no'] 179 | # ) 180 | # self.assertIn( 181 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['use-bfd'], ['yes'] 182 | # ) 183 | # self.assertIn( 184 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['route-distinguisher'], ['64520:666'] 185 | # ) 186 | # self.assertIn( 187 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['dst-address'], ['10.10.66.8/30'] 188 | # ) 189 | # self.assertIn( 190 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['gateway'], ['10.10.100.1'] 191 | # ) 192 | # self.assertIn( 193 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['interface'], ['GRE_TYRMA'] 194 | # ) 195 | # self.assertIn( 196 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['in-label'], ['6136'] 197 | # ) 198 | # self.assertIn( 199 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['out-label'], ['6136'] 200 | # ) 201 | # self.assertIn( 202 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-local-pref'], ['100'] 203 | # ) 204 | # self.assertIn( 205 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-origin'], ['incomplete'] 206 | # ) 207 | # self.assertIn( 208 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-ext-communities'], ['RT:64520:666'] 209 | # ) 210 | # self.assertIn( 211 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['name'], ['default'] 212 | # ) 213 | # self.assertIn( 214 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['as'], ['65530'] 215 | # ) 216 | # self.assertIn( 217 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['router-id'], ['0.0.0.0'] 218 | # ) 219 | # self.assertIn( 220 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-connected'], ['no'] 221 | # ) 222 | # self.assertIn( 223 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-static'], ['no'] 224 | # ) 225 | # self.assertIn( 226 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-rip'], ['no'] 227 | # ) 228 | # self.assertIn( 229 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-ospf'], ['no'] 230 | # ) 231 | # self.assertIn( 232 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-other-bgp'], ['no'] 233 | # ) 234 | # self.assertIn( 235 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['client-to-client-reflection'], ['yes'] 236 | # ) 237 | # self.assertIn( 238 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['ignore-as-path-len'], ['no'] 239 | # ) 240 | # self.assertIn( 241 | # result['ansible_facts']['ansible_net_route']['altegro']['dst-address'], ['10.10.66.0/30'] 242 | # ) 243 | # self.assertIn( 244 | # result['ansible_facts']['ansible_net_route']['altegro']['pref-src'], ['10.10.66.1'] 245 | # ) 246 | # self.assertIn( 247 | # result['ansible_facts']['ansible_net_route']['altegro']['gateway'], ['bridge1'] 248 | # ) 249 | # self.assertIn( 250 | # result['ansible_facts']['ansible_net_route']['altegro']['gateway-status'], ['bridge1'] 251 | # ) 252 | # self.assertIn( 253 | # result['ansible_facts']['ansible_net_route']['altegro']['distance'], ['0'] 254 | # ) 255 | # self.assertIn( 256 | # result['ansible_facts']['ansible_net_route']['altegro']['scope'], ['10'] 257 | # ) 258 | # self.assertIn( 259 | # result['ansible_facts']['ansible_net_route']['altegro']['routing-mark'], ['altegro'] 260 | # ) 261 | # self.assertIn( 262 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['name'], ['default'] 263 | # ) 264 | # self.assertIn( 265 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['router-id'], ['10.10.50.1'] 266 | # ) 267 | # self.assertIn( 268 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['distribute-default'], ['never'] 269 | # ) 270 | # self.assertIn( 271 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-connected'], ['no'] 272 | # ) 273 | # self.assertIn( 274 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-static'], ['no'] 275 | # ) 276 | # self.assertIn( 277 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-rip'], ['no'] 278 | # ) 279 | # self.assertIn( 280 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-bgp'], ['no'] 281 | # ) 282 | # self.assertIn( 283 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-other-ospf'], ['no'] 284 | # ) 285 | # self.assertIn( 286 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-default'], ['1'] 287 | # ) 288 | # self.assertIn( 289 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-connected'], ['20'] 290 | # ) 291 | # self.assertIn( 292 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-static'], ['20'] 293 | # ) 294 | # self.assertIn( 295 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-rip'], ['20'] 296 | # ) 297 | # self.assertIn( 298 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-bgp'], ['auto'] 299 | # ) 300 | # self.assertIn( 301 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-other-ospf'], ['auto'] 302 | # ) 303 | # self.assertIn( 304 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['in-filter'], ['ospf-in'] 305 | # ) 306 | # self.assertIn( 307 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['out-filter'], ['ospf-out'] 308 | # ) 309 | # self.assertIn( 310 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['instance'], ['default'] 311 | # ) 312 | # self.assertIn( 313 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['router-id'], ['10.10.100.1'] 314 | # ) 315 | # self.assertIn( 316 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['address'], ['10.10.1.2'] 317 | # ) 318 | # self.assertIn( 319 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['interface'], ['GRE_TYRMA'] 320 | # ) 321 | # self.assertIn( 322 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['priority'], ['1'] 323 | # ) 324 | # self.assertIn( 325 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['dr-address'], ['0.0.0.0'] 326 | # ) 327 | # self.assertIn( 328 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['backup-dr-address'], ['0.0.0.0'] 329 | # ) 330 | # self.assertIn( 331 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['state'], ['Full'] 332 | # ) 333 | # self.assertIn( 334 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['state-changes'], ['15'] 335 | # ) 336 | # self.assertIn( 337 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['ls-retransmits'], ['0'] 338 | # ) 339 | # self.assertIn( 340 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['ls-requests'], ['0'] 341 | # ) 342 | # self.assertIn( 343 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['db-summaries'], ['0'] 344 | # ) 345 | # self.assertIn( 346 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['adjacency'], ['6h8m46s'] 347 | # ) 348 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SG500-52-K9.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from ansible_collections.community.ciscosmb.plugins.modules import facts 29 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = facts 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.facts.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module = args 50 | commands = kwargs["commands"] 51 | output = list() 52 | 53 | for command in commands: 54 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 55 | output.append(load_fixture("ciscosmb_facts-SG500-52-K9-%s" % filename)) 56 | return output 57 | 58 | self.run_commands.side_effect = load_from_file 59 | 60 | def test_ciscosmb_facts_default(self): 61 | with set_module_args(dict(gather_subset="default")): 62 | result = self.execute_module() 63 | 64 | self.assertEqual(result["ansible_facts"]["ansible_net_version"], "1.4.8.6") 65 | self.assertEqual( 66 | result["ansible_facts"]["ansible_net_boot_version"], "1.3.7.01" 67 | ) 68 | self.assertEqual(result["ansible_facts"]["ansible_net_hw_version"], "V02") 69 | self.assertEqual(result["ansible_facts"]["ansible_net_uptime"], 41737187) 70 | self.assertEqual( 71 | result["ansible_facts"]["ansible_net_hostname"], "sw-abcdefg-1" 72 | ) 73 | self.assertEqual(result["ansible_facts"]["ansible_net_cpu_load"], "7") 74 | self.assertEqual(result["ansible_facts"]["ansible_net_model"], "SG500-52-K9") 75 | self.assertEqual( 76 | result["ansible_facts"]["ansible_net_serialnum"], "ABC12345678" 77 | ) 78 | 79 | def test_ciscosmb_facts_hardware(self): 80 | with set_module_args(dict(gather_subset="hardware")): 81 | result = self.execute_module() 82 | 83 | self.assertEqual(result["ansible_facts"]["ansible_net_spacefree_mb"], 6.8) 84 | self.assertEqual(result["ansible_facts"]["ansible_net_spacetotal_mb"], 31.4) 85 | 86 | def test_ciscosmb_facts_config(self): 87 | with set_module_args(dict(gather_subset="config")): 88 | result = self.execute_module() 89 | 90 | self.assertIsInstance(result["ansible_facts"]["ansible_net_config"], str) 91 | 92 | def test_ciscosmb_facts_interfaces(self): 93 | with set_module_args(dict(gather_subset="interfaces")): 94 | result = self.execute_module() 95 | 96 | self.assertIn( 97 | result["ansible_facts"]["ansible_net_all_ipv4_addresses"][0], ["11.30.5.12"] 98 | ) 99 | self.assertEqual( 100 | result["ansible_facts"]["ansible_net_all_ipv6_addresses"], 101 | ["fe80::36db:fdff:fe64:5bce"], 102 | ) 103 | self.assertEqual( 104 | result["ansible_facts"]["ansible_net_all_ipv6_addresses"][0], 105 | result["ansible_facts"]["ansible_net_interfaces"]["vlan1"]["ipv6"][0][ 106 | "address" 107 | ], 108 | ) 109 | self.assertEqual( 110 | len(result["ansible_facts"]["ansible_net_interfaces"].keys()), 85 111 | ) 112 | self.assertEqual(len(result["ansible_facts"]["ansible_net_neighbors"]), 9) 113 | 114 | interfaces = result["ansible_facts"]["ansible_net_interfaces"] 115 | ge42 = interfaces["GigabitEthernet1/42"] 116 | 117 | self.assertEqual(ge42["bandwidth"], 1000000) 118 | self.assertEqual(ge42["bandwidth"], ge42["bandwith"]) 119 | 120 | 121 | # def test_ciscosmb_facts_routing(self): 122 | # with set_module_args(dict(gather_subset='routing')): 123 | # result = self.execute_module() 124 | # 125 | # self.assertIn( 126 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['name'], ['iBGP_BRAS.TYRMA'] 127 | # ) 128 | # self.assertIn( 129 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['instance'], ['MAIN_AS_STARKDV'] 130 | # ) 131 | # self.assertIn( 132 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remote-address'], ['10.10.100.1'] 133 | # ) 134 | # self.assertIn( 135 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remote-as'], ['64520'] 136 | # ) 137 | # self.assertIn( 138 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['nexthop-choice'], ['default'] 139 | # ) 140 | # self.assertIn( 141 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['multihop'], ['no'] 142 | # ) 143 | # self.assertIn( 144 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['route-reflect'], ['yes'] 145 | # ) 146 | # self.assertIn( 147 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['hold-time'], ['3m'] 148 | # ) 149 | # self.assertIn( 150 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['ttl'], ['default'] 151 | # ) 152 | # self.assertIn( 153 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['address-families'], ['ip'] 154 | # ) 155 | # self.assertIn( 156 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['update-source'], ['LAN_KHV'] 157 | # ) 158 | # self.assertIn( 159 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['default-originate'], ['never'] 160 | # ) 161 | # self.assertIn( 162 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remove-private-as'], ['no'] 163 | # ) 164 | # self.assertIn( 165 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['as-override'], ['no'] 166 | # ) 167 | # self.assertIn( 168 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['passive'], ['no'] 169 | # ) 170 | # self.assertIn( 171 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['use-bfd'], ['yes'] 172 | # ) 173 | # self.assertIn( 174 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['route-distinguisher'], ['64520:666'] 175 | # ) 176 | # self.assertIn( 177 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['dst-address'], ['10.10.66.8/30'] 178 | # ) 179 | # self.assertIn( 180 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['gateway'], ['10.10.100.1'] 181 | # ) 182 | # self.assertIn( 183 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['interface'], ['GRE_TYRMA'] 184 | # ) 185 | # self.assertIn( 186 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['in-label'], ['6136'] 187 | # ) 188 | # self.assertIn( 189 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['out-label'], ['6136'] 190 | # ) 191 | # self.assertIn( 192 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-local-pref'], ['100'] 193 | # ) 194 | # self.assertIn( 195 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-origin'], ['incomplete'] 196 | # ) 197 | # self.assertIn( 198 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-ext-communities'], ['RT:64520:666'] 199 | # ) 200 | # self.assertIn( 201 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['name'], ['default'] 202 | # ) 203 | # self.assertIn( 204 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['as'], ['65530'] 205 | # ) 206 | # self.assertIn( 207 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['router-id'], ['0.0.0.0'] 208 | # ) 209 | # self.assertIn( 210 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-connected'], ['no'] 211 | # ) 212 | # self.assertIn( 213 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-static'], ['no'] 214 | # ) 215 | # self.assertIn( 216 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-rip'], ['no'] 217 | # ) 218 | # self.assertIn( 219 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-ospf'], ['no'] 220 | # ) 221 | # self.assertIn( 222 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-other-bgp'], ['no'] 223 | # ) 224 | # self.assertIn( 225 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['client-to-client-reflection'], ['yes'] 226 | # ) 227 | # self.assertIn( 228 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['ignore-as-path-len'], ['no'] 229 | # ) 230 | # self.assertIn( 231 | # result['ansible_facts']['ansible_net_route']['altegro']['dst-address'], ['10.10.66.0/30'] 232 | # ) 233 | # self.assertIn( 234 | # result['ansible_facts']['ansible_net_route']['altegro']['pref-src'], ['10.10.66.1'] 235 | # ) 236 | # self.assertIn( 237 | # result['ansible_facts']['ansible_net_route']['altegro']['gateway'], ['bridge1'] 238 | # ) 239 | # self.assertIn( 240 | # result['ansible_facts']['ansible_net_route']['altegro']['gateway-status'], ['bridge1'] 241 | # ) 242 | # self.assertIn( 243 | # result['ansible_facts']['ansible_net_route']['altegro']['distance'], ['0'] 244 | # ) 245 | # self.assertIn( 246 | # result['ansible_facts']['ansible_net_route']['altegro']['scope'], ['10'] 247 | # ) 248 | # self.assertIn( 249 | # result['ansible_facts']['ansible_net_route']['altegro']['routing-mark'], ['altegro'] 250 | # ) 251 | # self.assertIn( 252 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['name'], ['default'] 253 | # ) 254 | # self.assertIn( 255 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['router-id'], ['10.10.50.1'] 256 | # ) 257 | # self.assertIn( 258 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['distribute-default'], ['never'] 259 | # ) 260 | # self.assertIn( 261 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-connected'], ['no'] 262 | # ) 263 | # self.assertIn( 264 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-static'], ['no'] 265 | # ) 266 | # self.assertIn( 267 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-rip'], ['no'] 268 | # ) 269 | # self.assertIn( 270 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-bgp'], ['no'] 271 | # ) 272 | # self.assertIn( 273 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-other-ospf'], ['no'] 274 | # ) 275 | # self.assertIn( 276 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-default'], ['1'] 277 | # ) 278 | # self.assertIn( 279 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-connected'], ['20'] 280 | # ) 281 | # self.assertIn( 282 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-static'], ['20'] 283 | # ) 284 | # self.assertIn( 285 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-rip'], ['20'] 286 | # ) 287 | # self.assertIn( 288 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-bgp'], ['auto'] 289 | # ) 290 | # self.assertIn( 291 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-other-ospf'], ['auto'] 292 | # ) 293 | # self.assertIn( 294 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['in-filter'], ['ospf-in'] 295 | # ) 296 | # self.assertIn( 297 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['out-filter'], ['ospf-out'] 298 | # ) 299 | # self.assertIn( 300 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['instance'], ['default'] 301 | # ) 302 | # self.assertIn( 303 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['router-id'], ['10.10.100.1'] 304 | # ) 305 | # self.assertIn( 306 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['address'], ['10.10.1.2'] 307 | # ) 308 | # self.assertIn( 309 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['interface'], ['GRE_TYRMA'] 310 | # ) 311 | # self.assertIn( 312 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['priority'], ['1'] 313 | # ) 314 | # self.assertIn( 315 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['dr-address'], ['0.0.0.0'] 316 | # ) 317 | # self.assertIn( 318 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['backup-dr-address'], ['0.0.0.0'] 319 | # ) 320 | # self.assertIn( 321 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['state'], ['Full'] 322 | # ) 323 | # self.assertIn( 324 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['state-changes'], ['15'] 325 | # ) 326 | # self.assertIn( 327 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['ls-retransmits'], ['0'] 328 | # ) 329 | # self.assertIn( 330 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['ls-requests'], ['0'] 331 | # ) 332 | # self.assertIn( 333 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['db-summaries'], ['0'] 334 | # ) 335 | # self.assertIn( 336 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['adjacency'], ['6h8m46s'] 337 | # ) 338 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SG550X-24MP-K9.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from ansible_collections.community.ciscosmb.plugins.modules import facts 29 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = facts 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.facts.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module = args 50 | commands = kwargs["commands"] 51 | output = list() 52 | 53 | for command in commands: 54 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 55 | output.append( 56 | load_fixture("ciscosmb_facts-SG550X-24MP-K9-%s" % filename) 57 | ) 58 | return output 59 | 60 | self.run_commands.side_effect = load_from_file 61 | 62 | def test_ciscosmb_facts_default(self): 63 | with set_module_args(dict(gather_subset="default")): 64 | result = self.execute_module() 65 | 66 | self.assertEqual(result["ansible_facts"]["ansible_net_version"], "2.4.5.71") 67 | self.assertEqual(result["ansible_facts"]["ansible_net_hw_version"], "V02") 68 | self.assertEqual(result["ansible_facts"]["ansible_net_uptime"], 9127415) 69 | self.assertEqual(result["ansible_facts"]["ansible_net_hostname"], "sw-abcdefgh") 70 | self.assertEqual(result["ansible_facts"]["ansible_net_cpu_load"], "8") 71 | self.assertEqual(result["ansible_facts"]["ansible_net_model"], "SG550X-24MP-K9") 72 | self.assertEqual( 73 | result["ansible_facts"]["ansible_net_serialnum"], "ABC123456AB" 74 | ) 75 | 76 | def test_ciscosmb_facts_hardware(self): 77 | with set_module_args(dict(gather_subset="hardware")): 78 | result = self.execute_module() 79 | 80 | self.assertEqual(result["ansible_facts"]["ansible_net_spacefree_mb"], 122.5) 81 | self.assertEqual(result["ansible_facts"]["ansible_net_spacetotal_mb"], 219.3) 82 | 83 | def test_ciscosmb_facts_config(self): 84 | with set_module_args(dict(gather_subset="config")): 85 | result = self.execute_module() 86 | 87 | self.assertIsInstance(result["ansible_facts"]["ansible_net_config"], str) 88 | 89 | 90 | # def test_ciscosmb_facts_interfaces(self): 91 | # with set_module_args(dict(gather_subset='interfaces')): 92 | # result = self.execute_module() 93 | # 94 | # self.assertIn( 95 | # result['ansible_facts']['ansible_net_all_ipv4_addresses'][0], ['10.37.129.3', '10.37.0.0', '192.168.88.1'] 96 | # ) 97 | # self.assertEqual( 98 | # result['ansible_facts']['ansible_net_all_ipv6_addresses'], ['fe80::21c:42ff:fe36:5290'] 99 | # ) 100 | # self.assertEqual( 101 | # result['ansible_facts']['ansible_net_all_ipv6_addresses'][0], 102 | # result['ansible_facts']['ansible_net_interfaces']['ether1']['ipv6'][0]['address'] 103 | # ) 104 | # self.assertEqual( 105 | # len(result['ansible_facts']['ansible_net_interfaces'].keys()), 11 106 | # ) 107 | # self.assertEqual( 108 | # len(result['ansible_facts']['ansible_net_neighbors']), 4 109 | # ) 110 | # 111 | # def test_ciscosmb_facts_interfaces_no_ipv6(self): 112 | # fixture = load_fixture( 113 | # 'ciscosmb_facts/ipv6_address_print_detail_without-paging_no-ipv6' 114 | # ) 115 | # interfaces = self.module.Interfaces(module=self.module) 116 | # addresses = interfaces.parse_detail(data=fixture) 117 | # result = interfaces.populate_addresses(data=addresses, family='ipv6') 118 | # 119 | # self.assertEqual(result, None) 120 | # 121 | # def test_ciscosmb_facts_routing(self): 122 | # with set_module_args(dict(gather_subset='routing')): 123 | # result = self.execute_module() 124 | # 125 | # self.assertIn( 126 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['name'], ['iBGP_BRAS.TYRMA'] 127 | # ) 128 | # self.assertIn( 129 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['instance'], ['MAIN_AS_STARKDV'] 130 | # ) 131 | # self.assertIn( 132 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remote-address'], ['10.10.100.1'] 133 | # ) 134 | # self.assertIn( 135 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remote-as'], ['64520'] 136 | # ) 137 | # self.assertIn( 138 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['nexthop-choice'], ['default'] 139 | # ) 140 | # self.assertIn( 141 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['multihop'], ['no'] 142 | # ) 143 | # self.assertIn( 144 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['route-reflect'], ['yes'] 145 | # ) 146 | # self.assertIn( 147 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['hold-time'], ['3m'] 148 | # ) 149 | # self.assertIn( 150 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['ttl'], ['default'] 151 | # ) 152 | # self.assertIn( 153 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['address-families'], ['ip'] 154 | # ) 155 | # self.assertIn( 156 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['update-source'], ['LAN_KHV'] 157 | # ) 158 | # self.assertIn( 159 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['default-originate'], ['never'] 160 | # ) 161 | # self.assertIn( 162 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['remove-private-as'], ['no'] 163 | # ) 164 | # self.assertIn( 165 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['as-override'], ['no'] 166 | # ) 167 | # self.assertIn( 168 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['passive'], ['no'] 169 | # ) 170 | # self.assertIn( 171 | # result['ansible_facts']['ansible_net_bgp_peer']['iBGP_BRAS.TYRMA']['use-bfd'], ['yes'] 172 | # ) 173 | # self.assertIn( 174 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['route-distinguisher'], ['64520:666'] 175 | # ) 176 | # self.assertIn( 177 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['dst-address'], ['10.10.66.8/30'] 178 | # ) 179 | # self.assertIn( 180 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['gateway'], ['10.10.100.1'] 181 | # ) 182 | # self.assertIn( 183 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['interface'], ['GRE_TYRMA'] 184 | # ) 185 | # self.assertIn( 186 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['in-label'], ['6136'] 187 | # ) 188 | # self.assertIn( 189 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['out-label'], ['6136'] 190 | # ) 191 | # self.assertIn( 192 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-local-pref'], ['100'] 193 | # ) 194 | # self.assertIn( 195 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-origin'], ['incomplete'] 196 | # ) 197 | # self.assertIn( 198 | # result['ansible_facts']['ansible_net_bgp_vpnv4_route']['GRE_TYRMA']['bgp-ext-communities'], ['RT:64520:666'] 199 | # ) 200 | # self.assertIn( 201 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['name'], ['default'] 202 | # ) 203 | # self.assertIn( 204 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['as'], ['65530'] 205 | # ) 206 | # self.assertIn( 207 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['router-id'], ['0.0.0.0'] 208 | # ) 209 | # self.assertIn( 210 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-connected'], ['no'] 211 | # ) 212 | # self.assertIn( 213 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-static'], ['no'] 214 | # ) 215 | # self.assertIn( 216 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-rip'], ['no'] 217 | # ) 218 | # self.assertIn( 219 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-ospf'], ['no'] 220 | # ) 221 | # self.assertIn( 222 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['redistribute-other-bgp'], ['no'] 223 | # ) 224 | # self.assertIn( 225 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['client-to-client-reflection'], ['yes'] 226 | # ) 227 | # self.assertIn( 228 | # result['ansible_facts']['ansible_net_bgp_instance']['default']['ignore-as-path-len'], ['no'] 229 | # ) 230 | # self.assertIn( 231 | # result['ansible_facts']['ansible_net_route']['altegro']['dst-address'], ['10.10.66.0/30'] 232 | # ) 233 | # self.assertIn( 234 | # result['ansible_facts']['ansible_net_route']['altegro']['pref-src'], ['10.10.66.1'] 235 | # ) 236 | # self.assertIn( 237 | # result['ansible_facts']['ansible_net_route']['altegro']['gateway'], ['bridge1'] 238 | # ) 239 | # self.assertIn( 240 | # result['ansible_facts']['ansible_net_route']['altegro']['gateway-status'], ['bridge1'] 241 | # ) 242 | # self.assertIn( 243 | # result['ansible_facts']['ansible_net_route']['altegro']['distance'], ['0'] 244 | # ) 245 | # self.assertIn( 246 | # result['ansible_facts']['ansible_net_route']['altegro']['scope'], ['10'] 247 | # ) 248 | # self.assertIn( 249 | # result['ansible_facts']['ansible_net_route']['altegro']['routing-mark'], ['altegro'] 250 | # ) 251 | # self.assertIn( 252 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['name'], ['default'] 253 | # ) 254 | # self.assertIn( 255 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['router-id'], ['10.10.50.1'] 256 | # ) 257 | # self.assertIn( 258 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['distribute-default'], ['never'] 259 | # ) 260 | # self.assertIn( 261 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-connected'], ['no'] 262 | # ) 263 | # self.assertIn( 264 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-static'], ['no'] 265 | # ) 266 | # self.assertIn( 267 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-rip'], ['no'] 268 | # ) 269 | # self.assertIn( 270 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-bgp'], ['no'] 271 | # ) 272 | # self.assertIn( 273 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['redistribute-other-ospf'], ['no'] 274 | # ) 275 | # self.assertIn( 276 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-default'], ['1'] 277 | # ) 278 | # self.assertIn( 279 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-connected'], ['20'] 280 | # ) 281 | # self.assertIn( 282 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-static'], ['20'] 283 | # ) 284 | # self.assertIn( 285 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-rip'], ['20'] 286 | # ) 287 | # self.assertIn( 288 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-bgp'], ['auto'] 289 | # ) 290 | # self.assertIn( 291 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['metric-other-ospf'], ['auto'] 292 | # ) 293 | # self.assertIn( 294 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['in-filter'], ['ospf-in'] 295 | # ) 296 | # self.assertIn( 297 | # result['ansible_facts']['ansible_net_ospf_instance']['default']['out-filter'], ['ospf-out'] 298 | # ) 299 | # self.assertIn( 300 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['instance'], ['default'] 301 | # ) 302 | # self.assertIn( 303 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['router-id'], ['10.10.100.1'] 304 | # ) 305 | # self.assertIn( 306 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['address'], ['10.10.1.2'] 307 | # ) 308 | # self.assertIn( 309 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['interface'], ['GRE_TYRMA'] 310 | # ) 311 | # self.assertIn( 312 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['priority'], ['1'] 313 | # ) 314 | # self.assertIn( 315 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['dr-address'], ['0.0.0.0'] 316 | # ) 317 | # self.assertIn( 318 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['backup-dr-address'], ['0.0.0.0'] 319 | # ) 320 | # self.assertIn( 321 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['state'], ['Full'] 322 | # ) 323 | # self.assertIn( 324 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['state-changes'], ['15'] 325 | # ) 326 | # self.assertIn( 327 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['ls-retransmits'], ['0'] 328 | # ) 329 | # self.assertIn( 330 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['ls-requests'], ['0'] 331 | # ) 332 | # self.assertIn( 333 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['db-summaries'], ['0'] 334 | # ) 335 | # self.assertIn( 336 | # result['ansible_facts']['ansible_net_ospf_neighbor']['default']['adjacency'], ['6h8m46s'] 337 | # ) 338 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/ciscosmb/test_ciscosmb_facts-SX550X-24F-K9.py: -------------------------------------------------------------------------------- 1 | # This file is part of Ansible 2 | # 3 | # Ansible is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # Ansible is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with Ansible. If not, see . 15 | 16 | # Make coding more python3-ish 17 | from __future__ import absolute_import, division, print_function 18 | 19 | __metaclass__ = type 20 | 21 | from ansible_collections.community.internal_test_tools.tests.unit.compat.mock import ( 22 | patch, 23 | ) 24 | from ansible_collections.community.internal_test_tools.tests.unit.plugins.modules.utils import ( 25 | set_module_args, 26 | ) 27 | 28 | from ansible_collections.community.ciscosmb.plugins.modules import facts 29 | from .ciscosmb_module import TestCiscoSMBModule, load_fixture 30 | 31 | 32 | class TestCiscoSMBFactsModule(TestCiscoSMBModule): 33 | 34 | module = facts 35 | 36 | def setUp(self): 37 | super(TestCiscoSMBFactsModule, self).setUp() 38 | self.mock_run_commands = patch( 39 | "ansible_collections.community.ciscosmb.plugins.modules.facts.run_commands" 40 | ) 41 | self.run_commands = self.mock_run_commands.start() 42 | 43 | def tearDown(self): 44 | super(TestCiscoSMBFactsModule, self).tearDown() 45 | self.mock_run_commands.stop() 46 | 47 | def load_fixtures(self, commands=None): 48 | def load_from_file(*args, **kwargs): 49 | module = args 50 | commands = kwargs["commands"] 51 | output = list() 52 | 53 | for command in commands: 54 | filename = str(command).split(" | ", 1)[0].replace(" ", "_") 55 | output.append( 56 | load_fixture("ciscosmb_facts-SX550X-24F-K9-%s" % filename) 57 | ) 58 | return output 59 | 60 | self.run_commands.side_effect = load_from_file 61 | 62 | def test_ciscosmb_facts_default(self): 63 | with set_module_args(dict(gather_subset="default")): 64 | result = self.execute_module() 65 | 66 | self.assertEqual(result["ansible_facts"]["ansible_net_hw_version"], "V02") 67 | self.assertEqual(result["ansible_facts"]["ansible_net_model"], "SX550X-24F-K9") 68 | self.assertEqual( 69 | result["ansible_facts"]["ansible_net_serialnum"], "DNI22500E5F" 70 | ) 71 | -------------------------------------------------------------------------------- /tests/unit/plugins/modules/utils.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function 2 | __metaclass__ = type 3 | 4 | import json 5 | 6 | from ansible_collections.community.ciscosmb.tests.unit.compat import unittest 7 | from ansible_collections.community.ciscosmb.tests.unit.compat.mock import patch 8 | from ansible.module_utils import basic 9 | from ansible.module_utils._text import to_bytes 10 | 11 | 12 | def set_module_args(args): 13 | if '_ansible_remote_tmp' not in args: 14 | args['_ansible_remote_tmp'] = '/tmp' 15 | if '_ansible_keep_remote_files' not in args: 16 | args['_ansible_keep_remote_files'] = False 17 | 18 | args = json.dumps({'ANSIBLE_MODULE_ARGS': args}) 19 | basic._ANSIBLE_ARGS = to_bytes(args) 20 | 21 | 22 | class AnsibleExitJson(Exception): 23 | pass 24 | 25 | 26 | class AnsibleFailJson(Exception): 27 | pass 28 | 29 | 30 | def exit_json(*args, **kwargs): 31 | if 'changed' not in kwargs: 32 | kwargs['changed'] = False 33 | raise AnsibleExitJson(kwargs) 34 | 35 | 36 | def fail_json(*args, **kwargs): 37 | kwargs['failed'] = True 38 | raise AnsibleFailJson(kwargs) 39 | 40 | 41 | class ModuleTestCase(unittest.TestCase): 42 | 43 | def setUp(self): 44 | self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json) 45 | self.mock_module.start() 46 | self.mock_sleep = patch('time.sleep') 47 | self.mock_sleep.start() 48 | set_module_args({}) 49 | self.addCleanup(self.mock_module.stop) 50 | self.addCleanup(self.mock_sleep.stop) 51 | -------------------------------------------------------------------------------- /tests/unit/requirements.txt: -------------------------------------------------------------------------------- 1 | unittest2 ; python_version <= '2.6' 2 | ordereddict ; python_version <= '2.6' 3 | 4 | -------------------------------------------------------------------------------- /tests/unit/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Copyright (c) Ansible Project 3 | # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) 4 | # SPDX-License-Identifier: GPL-3.0-or-later 5 | 6 | collections: 7 | - community.internal_test_tools 8 | --------------------------------------------------------------------------------