├── .github └── workflows │ └── main.yml ├── .gitignore ├── Development.md ├── LICENSE.txt ├── README.md ├── galaxy.yml ├── meta └── runtime.yml ├── misc ├── Impact DNW07 UCS Ansible Collection Lab Guide.pdf └── README.md ├── playbooks ├── example_playbook.yml ├── fw_download_config_hfp.yml ├── inventory ├── roles │ └── servers │ │ ├── defaults │ │ └── tasks │ │ │ └── main.yml │ │ ├── service_profile_templates │ │ └── tasks │ │ │ └── main.yml │ │ └── service_profiles │ │ └── tasks │ │ └── main.yml ├── sandbox_inventory ├── server_deploy.yml ├── ucs_disk_group_policy.yml ├── ucs_dns_server.yml ├── ucs_graphics_card_policy.yml ├── ucs_ip_pool.yml ├── ucs_ipv4_pool_only.yml ├── ucs_lan_connectivity.yml ├── ucs_mac_pool.yml ├── ucs_managed_objects.yml ├── ucs_ntp_server.yml ├── ucs_org.yml ├── ucs_query.yml ├── ucs_san_connectivity.yml ├── ucs_scrub_policy.yml ├── ucs_serial_over_lan_policy.yml ├── ucs_server_maintenance.yml ├── ucs_service_profile_association.yml ├── ucs_service_profile_from_template.yml ├── ucs_service_profile_template.yml ├── ucs_sp_vnic_order.yml ├── ucs_storage_profile.yml ├── ucs_system_qos.yml ├── ucs_timezone.yml ├── ucs_uuid_pool.yml ├── ucs_vhba_template.yml ├── ucs_vlan_find.yml ├── ucs_vlan_to_group.yml ├── ucs_vlans.yml ├── ucs_vnic_template.yml ├── ucs_vsans.yml └── ucs_wwn_pool.yml ├── plugins ├── README.md ├── doc_fragments │ └── ucs.py ├── module_utils │ └── ucs.py └── modules │ ├── ucs_disk_group_policy.py │ ├── ucs_dns_server.py │ ├── ucs_graphics_card_policy.py │ ├── ucs_ip_pool.py │ ├── ucs_lan_connectivity.py │ ├── ucs_mac_pool.py │ ├── ucs_managed_objects.py │ ├── ucs_ntp_server.py │ ├── ucs_org.py │ ├── ucs_query.py │ ├── ucs_san_connectivity.py │ ├── ucs_scrub_policy.py │ ├── ucs_serial_over_lan_policy.py │ ├── ucs_server_maintenance.py │ ├── ucs_service_profile_association.py │ ├── ucs_service_profile_from_template.py │ ├── ucs_service_profile_template.py │ ├── ucs_sp_vnic_order.py │ ├── ucs_storage_profile.py │ ├── ucs_system_qos.py │ ├── ucs_timezone.py │ ├── ucs_uuid_pool.py │ ├── ucs_vhba_template.py │ ├── ucs_vlan_find.py │ ├── ucs_vlan_to_group.py │ ├── ucs_vlans.py │ ├── ucs_vnic_template.py │ ├── ucs_vsans.py │ └── ucs_wwn_pool.py ├── releases ├── README.md ├── cisco-ucs-1.1.0.tar.gz ├── cisco-ucs-1.10.0.tar.gz ├── cisco-ucs-1.11.0.tar.gz ├── cisco-ucs-1.12.0.tar.gz ├── cisco-ucs-1.14.0.tar.gz ├── cisco-ucs-1.15.0.tar.gz ├── cisco-ucs-1.16.0.tar.gz ├── cisco-ucs-1.2.0.tar.gz ├── cisco-ucs-1.3.0.tar.gz ├── cisco-ucs-1.4.0.tar.gz ├── cisco-ucs-1.5.0.tar.gz ├── cisco-ucs-1.6.0.tar.gz ├── cisco-ucs-1.7.0.tar.gz ├── cisco-ucs-1.8.0.tar.gz └── cisco-ucs-1.9.0.tar.gz ├── requirements.txt └── tests └── config.yml /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # README FIRST 3 | # 1. Subscribe to https://github.com/ansible-collections/news-for-maintainers 4 | # (click the Watch button on the homepage > Custom > Issues) 5 | # and keep this matrix up to date in accordance to related announcements. 6 | # Timely add new ansible-core versions and consider dropping support 7 | # and testing against its EOL versions. 8 | # 2. If your collection repository is under the ansible-collections org, 9 | # please keep in mind that the number of GHA jobs is limited 10 | # and shared across all the collections in the org. 11 | # So, focusing on good test coverage of your collection, 12 | # please avoid testing against unnecessary entities such as 13 | # ansible-core EOL versions your collection does not support 14 | # or ansible-core versions that are not EOL yet but not supported by the collection. 15 | # 3. If you don't have unit or integration tests, remove corresponding sections. 16 | # 4. If your collection depends on other collections ensure they are installed, 17 | # add them to the "test-deps" input. 18 | # 5. For the comprehensive list of the inputs supported by the 19 | # ansible-community/ansible-test-gh-action GitHub Action, see 20 | # https://github.com/marketplace/actions/ansible-test. 21 | # 6. If you want to prevent merging PRs that do not pass all tests, 22 | # make sure to add the "check" job to your repository branch 23 | # protection once this workflow is added. 24 | # It is also possible to tweak which jobs are allowed to fail. See 25 | # https://github.com/marketplace/actions/alls-green#gotchas for more detail. 26 | # 7. If you need help please ask in #community:ansible.com on Matrix 27 | # or in bridged #ansible-community on the Libera.Chat IRC channel. 28 | # See https://docs.ansible.com/ansible/devel/community/communication.html 29 | # for details. 30 | # 8. If your collection is [going to get] included in the Ansible package, 31 | # it has to adhere to Python compatibility and CI testing requirements described in 32 | # https://docs.ansible.com/ansible/latest/community/collection_contributors/collection_requirements.html. 33 | 34 | name: CI 35 | on: 36 | # Run CI against all pushes (direct commits, also merged PRs), Pull Requests 37 | push: 38 | branches: 39 | - main 40 | pull_request: 41 | # Run CI once per day (at 06:00 UTC) 42 | # This ensures that even if there haven't been commits that we are still 43 | # testing against latest version of ansible-test for each ansible-core 44 | # version 45 | schedule: 46 | - cron: '0 6 * * *' 47 | 48 | concurrency: 49 | group: >- 50 | ${{ github.workflow }}-${{ 51 | github.event.pull_request.number || github.sha 52 | }} 53 | cancel-in-progress: true 54 | 55 | jobs: 56 | 57 | ### 58 | # Sanity tests (REQUIRED) 59 | # 60 | # https://docs.ansible.com/ansible/latest/dev_guide/testing_sanity.html 61 | 62 | sanity: 63 | name: Sanity (Ⓐ${{ matrix.ansible }}) 64 | strategy: 65 | matrix: 66 | ansible: 67 | # It's important that Sanity is tested against all stable-X.Y branches 68 | # Testing against `devel` may fail as new tests are added. 69 | # An alternative to `devel` is the `milestone` branch with 70 | # gets synchronized with `devel` every few weeks and therefore 71 | # tends to be a more stable target. Be aware that it is not updated 72 | # around creation of a new stable branch, this might cause a problem 73 | # that two different versions of ansible-test use the same sanity test 74 | # ignore.txt file. 75 | # Add new versions announced in 76 | # https://github.com/ansible-collections/news-for-maintainers in a timely manner, 77 | # consider dropping testing against EOL versions and versions you don't support. 78 | - stable-2.16 79 | - stable-2.17 80 | - stable-2.18 81 | - stable-2.19 82 | # Ansible-test on various stable branches does not yet work well with cgroups v2. 83 | # Since ubuntu-latest now uses Ubuntu 22.04, we need to fall back to the ubuntu-20.04 84 | # image for these stable branches. The list of branches where this is necessary will 85 | # shrink over time, check out https://github.com/ansible-collections/news-for-maintainers/issues/28 86 | # for the latest list. 87 | runs-on: >- 88 | ${{ contains(fromJson( 89 | '["stable-2.9", "stable-2.10", "stable-2.11"]' 90 | ), matrix.ansible) && 'ubuntu-20.04' || 'ubuntu-latest' }} 91 | steps: 92 | # Run sanity tests inside a Docker container. 93 | # The docker container has all the pinned dependencies that are 94 | # required and all Python versions Ansible supports. 95 | - name: Perform sanity testing 96 | # See the documentation for the following GitHub action on 97 | # https://github.com/ansible-community/ansible-test-gh-action/blob/main/README.md 98 | uses: ansible-community/ansible-test-gh-action@release/v1 99 | with: 100 | ansible-core-version: ${{ matrix.ansible }} 101 | testing-type: sanity 102 | # OPTIONAL If your sanity tests require code 103 | # from other collections, install them like this 104 | # test-deps: >- 105 | # ansible.netcommon 106 | # ansible.utils 107 | # OPTIONAL If set to true, will test only against changed files, 108 | # which should improve CI performance. See limitations on 109 | # https://github.com/ansible-community/ansible-test-gh-action#pull-request-change-detection 110 | pull-request-change-detection: false 111 | 112 | check: # This job does nothing and is only used for the branch protection 113 | # or multi-stage CI jobs, like making sure that all tests pass before 114 | # a publishing job is started. 115 | if: always() 116 | 117 | needs: 118 | - sanity 119 | 120 | runs-on: ubuntu-latest 121 | 122 | steps: 123 | - name: Decide whether the needed jobs succeeded or failed 124 | uses: re-actors/alls-green@release/v1 125 | with: 126 | jobs: ${{ toJSON(needs) }} 127 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Editor 10 | .vscode/ 11 | collections/ 12 | ansible.cfg 13 | args/ 14 | 15 | # Distribution / packaging 16 | .Python 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | wheels/ 29 | pip-wheel-metadata/ 30 | share/python-wheels/ 31 | *.egg-info/ 32 | .installed.cfg 33 | *.egg 34 | MANIFEST 35 | 36 | # PyInstaller 37 | # Usually these files are written by a python script from a template 38 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 39 | *.manifest 40 | *.spec 41 | 42 | # Installer logs 43 | pip-log.txt 44 | pip-delete-this-directory.txt 45 | 46 | # Unit test / coverage reports 47 | htmlcov/ 48 | .tox/ 49 | .nox/ 50 | .coverage 51 | .coverage.* 52 | .cache 53 | nosetests.xml 54 | coverage.xml 55 | *.cover 56 | *.py,cover 57 | .hypothesis/ 58 | .pytest_cache/ 59 | 60 | # Translations 61 | *.mo 62 | *.pot 63 | 64 | # Django stuff: 65 | *.log 66 | local_settings.py 67 | db.sqlite3 68 | db.sqlite3-journal 69 | 70 | # Flask stuff: 71 | instance/ 72 | .webassets-cache 73 | 74 | # Scrapy stuff: 75 | .scrapy 76 | 77 | # Sphinx documentation 78 | docs/_build/ 79 | 80 | # PyBuilder 81 | target/ 82 | 83 | # Jupyter Notebook 84 | .ipynb_checkpoints 85 | 86 | # IPython 87 | profile_default/ 88 | ipython_config.py 89 | 90 | # pyenv 91 | .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 101 | __pypackages__/ 102 | 103 | # Celery stuff 104 | celerybeat-schedule 105 | celerybeat.pid 106 | 107 | # SageMath parsed files 108 | *.sage.py 109 | 110 | # Environments 111 | .env 112 | .venv 113 | env/ 114 | venv/ 115 | ENV/ 116 | env.bak/ 117 | venv.bak/ 118 | 119 | # Spyder project settings 120 | .spyderproject 121 | .spyproject 122 | 123 | # Rope project settings 124 | .ropeproject 125 | 126 | # mkdocs documentation 127 | /site 128 | 129 | # mypy 130 | .mypy_cache/ 131 | .dmypy.json 132 | dmypy.json 133 | 134 | # Pyre type checker 135 | .pyre/ 136 | -------------------------------------------------------------------------------- /Development.md: -------------------------------------------------------------------------------- 1 | # cisco.ucs Collection Development Notes 2 | 3 | ### Current Development Status 4 | 5 | These object specific modules cover a very small set of UCS Manager managed objects. For UCS objects that do not 6 | have a specific module below use `ucs_managed_objects`. This module accepts either JSON or YAML 7 | when used as a task in a playbook. Review `playbooks/ucs_managed_objects` playbook for examples. 8 | 9 | | Configuration Category | Configuration Task | Module Name | 10 | | ---------------------- | ------------------ | ----------- | 11 | | Objects | | | 12 | | | Any UCS Object | cisco.ucs.ucs_managed_objects | 13 | | Query | | | 14 | | | Query Classes or DNs | cisco.ucs.ucs_query | 15 | | | VLAN Find | cisco.ucs.ucs_vlan_find 16 | | Organizations | | | 17 | | | Organizations | cisco.ucs.ucs_org | 18 | | Servers | | | 19 | | | Graphics Card Policy | cisco.ucs.ucs_graphics_card_policy | 20 | | | Scrub Policy | cisco.ucs.ucs_scrub_policy | 21 | | | Serial Over Lan Policy | cisco.ucs.ucs_serial_over_lan_policy | 22 | | | Service Profile Template | cisco.ucs.ucs_service_profile_template | 23 | | | Service Profile from Template | cisco.ucs.ucs_service_profile_from_template | 24 | | | UUID Suffix Pool | cisco.ucs.ucs_uuid_pool | 25 | | LAN | | | 26 | | | IP Addresses for KVM Access | cisco.ucs.ucs_ip_pool | 27 | | | LAN Connectivity Policy | cisco.ucs.ucs_lan_connectivity | 28 | | | MAC Address Pools | cisco.ucs.ucs_mac_pool | 29 | | | System QOS | cisco.ucs.ucs_system_qos | 30 | | | vNIC Template | cisco.ucs.ucs_vnic_template | 31 | | | VLANs | cisco.ucs.ucs_vlans | 32 | | SAN | | | 33 | | | SAN Connectivity Policy | cisco.ucs.ucs_san_connectivity | 34 | | | vHBA Template | cisco.ucs.ucs_vhba_template | 35 | | | VSANs | cisco.ucs.ucs_vsans | 36 | | | WWN Pool | cisco.ucs.ucs_wwn_pool | 37 | | Storage | | | 38 | | | Disk Group Policy | cisco.ucs.ucs_disk_group_policy | 39 | | | Storage Profile | cisco.ucs.ucs_storage_profile | 40 | | Admin | | | 41 | | | DNS Server | cisco.ucs.ucs_dns_server | 42 | | | NTP Server | cisco.ucs.ucs_ntp_server | 43 | | | Time Zone | cisco.ucs.ucs_timezone | 44 | 45 | ### Ansible Development Notes 46 | 47 | Modules in development follow processes documented at http://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html. The modules support ansible-doc and should eventually have integration tests. 48 | 49 | When developing modules in this repository, here are a few helpful commands to sanity check the code and documentation (replace module_name with your module (e.g., intersight_objects)). Ansible modules won't generally be pylint or pycodestyle (PEP8) clean without disabling several of the checks: 50 | ``` 51 | pylint --disable=invalid-name,no-member,too-many-nested-blocks,redefined-variable-type,too-many-statements,too-many-branches,broad-except,line-too-long,missing-docstring,wrong-import-position,too-many-locals,import-error .py 52 | 53 | pycodestyle --max-line-length 160 --config /dev/null --ignore E402 .py 54 | 55 | ansible-doc 56 | ``` 57 | 58 | # Community: 59 | 60 | * We are on Slack (https://ciscoucs.slack.com/) - Slack requires registration, but the ucspython team is open invitation to 61 | anyone. Click [here](https://ucspython.herokuapp.com) to register 62 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Cisco Systems, Inc. and/or its affiliates 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ansible Collection - cisco.ucs 2 | 3 | Ansible collection for managing and automing Cisco UCS Manager envrionments. Modules and roles are provided for common Cisco UCS Manager tasks. 4 | 5 | * Note: This collection is not compatible with versions of Ansible before v2.8. 6 | 7 | ## Requirements 8 | 9 | - Ansible v2.8 or newer 10 | - UCSM Python SDK (ucsmsdk) 11 | 12 | ## Install 13 | - ansible must be installed 14 | ``` 15 | sudo pip install ansible 16 | ``` 17 | - ucsmsdk must be installed 18 | ``` 19 | sudo pip install ucsmsdk 20 | ``` 21 | We recommend verifying the ucsmsdk can connect to the domains you want to manage with Ansible. Here is an example connection test using python: 22 | ``` 23 | # python 24 | Python 2.7.14 (default, Apr 27 2018, 14:31:56) 25 | [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2 26 | Type "help", "copyright", "credits" or "license" for more information. 27 | >>> from ucsmsdk import ucshandle 28 | >>> handle = ucshandle.UcsHandle(ip='172.22.250.236', username='admin', password='password') 29 | >>> handle.login() 30 | True 31 | ``` 32 | 33 | ## Usage 34 | Once Ansible is installed you can create inventory files and playbooks to manage your UCS domains. Each module supports ansible-doc which includes example usage: 35 | ``` 36 | # ansible-doc cisco.ucs.ucs_vlans 37 | 38 | EXAMPLES: 39 | - name: Configure VLAN 40 | cisco.ucs.ucs_vlans: 41 | hostname: 172.16.143.150 42 | username: admin 43 | password: password 44 | name: vlan2 45 | id: '2' 46 | native: 'yes' 47 | ``` 48 | This repository includes a playbooks directory with examples including an inventory file that can be edited with information for the UCSM domain you want to configure: 49 | ``` 50 | # vi inventory 51 | [ucs] 52 | 13.58.22.56 53 | 54 | [ucs:vars] 55 | username=admin 56 | password=password 57 | ``` 58 | An example_playbook.yml playbook is included to test VLAN configuration on the UCSM domain given in the inventory file: 59 | ``` 60 | # vi example_playbook.yml 61 | 62 | --- 63 | # Example Playbook: VLAN configuration using the [ucs] hosts group 64 | - hosts: ucs 65 | connection: local 66 | collections: 67 | - cisco.ucs 68 | gather_facts: false 69 | tasks: 70 | - name: Configure VLAN 71 | ucs_vlans: 72 | hostname: "{{ inventory_hostname }}" 73 | username: "{{ username | default(omit) }}" 74 | password: "{{ password }}" 75 | state: "{{ state | default(omit) }}" 76 | name: vlan2 77 | id: '2' 78 | native: 'no' 79 | delegate_to: localhost 80 | ``` 81 | Ansible will use data from the inventory file for the hostname and other variables above. Multiple UCSM domains can be listed in the inventory file and Ansible will configure all the listed domains in parallel using host specific data. 82 | 83 | The ansible-playbook command can be used to run the above playbook and inventory file: 84 | ``` 85 | # ansible-playbook -i inventory example_playbook.yml 86 | 87 | PLAY [ucs] ********************************************************************* 88 | 89 | TASK [Configure VLAN] ********************************************************** 90 | ok: [13.58.22.56 -> localhost] 91 | 92 | PLAY RECAP ********************************************************************* 93 | 13.58.22.56 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 94 | ``` 95 | 96 | A more detailed configuration example is provided in the server_deploy.yml playbook. 97 | 98 | # Support: 99 | 100 | Please file Issues in this repository for any defects, feature requests, or questions on usage. 101 | -------------------------------------------------------------------------------- /galaxy.yml: -------------------------------------------------------------------------------- 1 | ### REQUIRED 2 | 3 | # The namespace of the collection. This can be a company/brand/organization or product namespace under which all 4 | # content lives. May only contain alphanumeric characters and underscores. Additionally namespaces cannot start with 5 | # underscores or numbers and cannot contain consecutive underscores 6 | namespace: cisco 7 | 8 | # The name of the collection. Has the same character restrictions as 'namespace' 9 | name: ucs 10 | 11 | # The version of the collection. Must be compatible with semantic versioning 12 | version: 1.16.0 13 | 14 | # The path to the Markdown (.md) readme file. This path is relative to the root of the collection 15 | readme: README.md 16 | 17 | # A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) 18 | # @nicks:irc/im.site#channel' 19 | authors: 20 | - David Soper (@dsoper2) 21 | - John McDonough (@movinalot) 22 | 23 | 24 | ### OPTIONAL but strongly recommended 25 | 26 | # A short summary description of the collection 27 | description: modules for Cisco UCS Manager 28 | 29 | # Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only 30 | # accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' 31 | license: 32 | - GPL-3.0-or-later 33 | 34 | # The path to the license file for the collection. This path is relative to the root of the collection. This key is 35 | # mutually exclusive with 'license' 36 | # license_file: '' 37 | 38 | # A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character 39 | # requirements as 'namespace' and 'name' 40 | tags: [cisco, ucs] 41 | 42 | # Collections that this collection requires to be installed for it to be usable. The key of the dict is the 43 | # collection label 'namespace.name'. The value is a version range 44 | # L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version 45 | # range specifiers can be set and are separated by ',' 46 | dependencies: {} 47 | 48 | # The URL of the originating SCM repository 49 | repository: https://github.com/CiscoDevNet/ansible-ucs 50 | 51 | # The URL to any online docs 52 | documentation: https://developer.cisco.com/site/ucs-dev-center 53 | 54 | # The URL to the homepage of the collection/project 55 | homepage: https://github.com/CiscoDevNet/ansible-ucs 56 | 57 | # The URL to the collection issue tracker 58 | issues: https://github.com/CiscoDevNet/ansible-ucs 59 | 60 | # Exclude the following from the build (supported in Ansible 2.10) 61 | build_ignore: 62 | - releases 63 | - playbooks/collections 64 | - 'playbooks/*tme*' 65 | -------------------------------------------------------------------------------- /meta/runtime.yml: -------------------------------------------------------------------------------- 1 | requires_ansible: ">=2.9" 2 | -------------------------------------------------------------------------------- /misc/Impact DNW07 UCS Ansible Collection Lab Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/misc/Impact DNW07 UCS Ansible Collection Lab Guide.pdf -------------------------------------------------------------------------------- /misc/README.md: -------------------------------------------------------------------------------- 1 | # Miscellaneous Items 2 | 3 | This folder contains miscellaneous items related to the collection. Trainings, DevNet Workshop giudes, etc. -------------------------------------------------------------------------------- /playbooks/example_playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: VLAN configuration using the [ucs] hosts group 3 | - hosts: ucs 4 | connection: local 5 | collections: 6 | - cisco.ucs 7 | gather_facts: false 8 | tasks: 9 | - name: Configure VLAN 10 | ucs_vlans: 11 | hostname: "{{ inventory_hostname }}" 12 | username: "{{ username | default(omit) }}" 13 | password: "{{ password }}" 14 | state: "{{ state | default(omit) }}" 15 | name: vlan2 16 | id: '2' 17 | native: 'no' 18 | delegate_to: localhost 19 | -------------------------------------------------------------------------------- /playbooks/fw_download_config_hfp.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # 3 | # Download firmware to the FI and configure Host Firmware Packages (HFP). 4 | # Uses remote fileshare and scp for FW download (server, remote_path, etc. provided through variables): 5 | # Example vars: 6 | # [ucs:vars] 7 | # remote_ip_address=172.28.224.77 8 | # remote_fw_path=/mnt/SHARE/ISOS/UCS_Code/4.1 9 | # remote_username=... 10 | # 11 | # The fw_bundles variable is a list that can be passed on the command line. 12 | # Example: 13 | # ansible-playbook ... -e '{"fw_bundles": ["ucs-k9-bundle-b-series.4.1.2b.B.bin"]}' 14 | # 15 | - hosts: ucs 16 | connection: local 17 | gather_facts: false 18 | vars: 19 | login_info: &login_info 20 | hostname: "{{ inventory_hostname }}" 21 | username: "{{ username | default(omit) }}" 22 | password: "{{ password }}" 23 | tasks: 24 | - name: Download FW to FI 25 | ucs_managed_objects: 26 | <<: *login_info 27 | objects: 28 | - module: ucsmsdk.mometa.firmware.FirmwareCatalogue 29 | class: FirmwareCatalogue 30 | properties: 31 | parent_mo_or_dn: sys 32 | children: 33 | - module: ucsmsdk.mometa.firmware.FirmwareDownloader 34 | class: FirmwareDownloader 35 | properties: 36 | protocol: scp 37 | server: "{{ remote_ip_address }}" 38 | remote_path: "{{ remote_fw_path }}" 39 | file_name: "{{ item }}" 40 | user: "{{ remote_username }}" 41 | pwd: "{{ remote_password }}" 42 | loop: "{{ fw_bundles }}" 43 | delegate_to: localhost 44 | register: download_result 45 | - name: Query and wait for download if needed 46 | cisco.ucs.ucs_query: 47 | <<: *login_info 48 | distinguished_names: "{{ fw_download_dn }}" 49 | loop: "{{ fw_bundles }}" 50 | vars: 51 | fw_download_dn: "sys/fw-catalogue/dnld-{{ item }}" 52 | delegate_to: localhost 53 | register: query_response 54 | # works with warnings: 55 | # until: query_response['objects']["{{ fw_download_dn }}"]['transfer_state'] == 'downloaded' 56 | until: query_response.objects is search('downloaded') 57 | # retry every 60 seconds for 20 minutes 58 | delay: 60 59 | retries: 20 60 | # regular escapes in a set variable 61 | - set_fact: 62 | match_str: 'ucs-.*?\.(?P\d\.\d)\.(?P.*)\.' 63 | # escape the escapes when used directly in strings 64 | - set_fact: 65 | blade_version: "{{ item | regex_replace(match_str + 'B\\.bin', '\\g(\\g)B') }}" 66 | loop: "{{ fw_bundles }}" 67 | when: item | regex_search(match_str + 'B\\.bin') 68 | - set_fact: 69 | rack_version: "{{ item | regex_replace(match_str + 'C\\.bin', '\\g(\\g)C') }}" 70 | loop: "{{ fw_bundles }}" 71 | when: item | regex_search(match_str + 'C\\.bin') 72 | - name: Config Host FW Package 73 | ucs_managed_objects: 74 | <<: *login_info 75 | objects: 76 | - module: ucsmsdk.mometa.firmware.FirmwareComputeHostPack 77 | class: FirmwareComputeHostPack 78 | properties: 79 | parent_mo_or_dn: org-root 80 | name: ansible-latest 81 | blade_bundle_version: "{{ blade_version | default(omit) }}" 82 | rack_bundle_version: "{{ rack_version | default(omit) }}" 83 | delegate_to: localhost 84 | -------------------------------------------------------------------------------- /playbooks/inventory: -------------------------------------------------------------------------------- 1 | [ucs] 2 | 13.58.22.56 3 | 4 | [ucs:vars] 5 | username=admin 6 | password=password 7 | -------------------------------------------------------------------------------- /playbooks/roles/servers/defaults/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Configure default IP Pool" 3 | vars: 4 | # Create an anchor for login_info that can be used throughout the file 5 | login_info: &login_info 6 | hostname: "{{ hostname }}" 7 | username: "{{ username | default(omit) }}" 8 | password: "{{ password | default('password') }}" 9 | state: "{{ state | default(omit) }}" 10 | cisco.ucs.ucs_ip_pool: 11 | <<: *login_info 12 | name: ext-mgmt 13 | ipv4_blocks: 14 | - first_addr: 198.18.0.20 15 | last_addr: 198.18.0.40 16 | subnet_mask: 255.255.255.0 17 | default_gw: 198.18.0.1 18 | tags: ip_pool 19 | - name: "Configure default MAC Pool" 20 | cisco.ucs.ucs_mac_pool: 21 | <<: *login_info 22 | name: default 23 | first_addr: 00:25:B5:DE:30:00 24 | last_addr: 00:25:B5:DE:32:FF 25 | tags: mac_pool 26 | - name: "Configure default UUID Pool" 27 | cisco.ucs.ucs_uuid_pool: 28 | <<: *login_info 29 | name: default 30 | first_uuid: 0000-000000000001 31 | last_uuid: 0000-000000000078 32 | tags: uuid_pool 33 | - name: "Configure default Virtual Media Policy" 34 | cisco.ucs.ucs_managed_objects: 35 | <<: *login_info 36 | objects: 37 | - module: ucsmsdk.mometa.cimcvmedia.CimcvmediaMountConfigPolicy 38 | class: CimcvmediaMountConfigPolicy 39 | properties: 40 | parent_mo_or_dn: org-root 41 | name: "{{ vmedia_policy }}" 42 | children: 43 | - module: ucsmsdk.mometa.cimcvmedia.CimcvmediaConfigMountEntry 44 | class: CimcvmediaConfigMountEntry 45 | properties: 46 | device_type: cdd 47 | image_file_name: "{{ image_file_name | default('centos7.2-boot-ks.iso') }}" 48 | image_path: "{{ image_path | default('/home/public') }}" 49 | mapping_name: cdd-nfs 50 | mount_protocol: nfs 51 | remote_ip_address: "{{ remote_ip_address | default('198.18.134.242') }}" 52 | tags: virtual_media 53 | - name: "Configure default Boot Order Policy" 54 | cisco.ucs.ucs_managed_objects: 55 | <<: *login_info 56 | objects: 57 | - module: ucsmsdk.mometa.lsboot.LsbootPolicy 58 | class: LsbootPolicy 59 | properties: 60 | parent_mo_or_dn: org-root 61 | boot_mode: legacy 62 | enforce_vnic_name: 'yes' 63 | name: vmedia-local 64 | reboot_on_update: 'no' 65 | children: 66 | - module: ucsmsdk.mometa.lsboot.LsbootVirtualMedia 67 | class: LsbootVirtualMedia 68 | properties: 69 | access: read-only-remote-cimc 70 | lun_id: '0' 71 | order: '1' 72 | - module: ucsmsdk.mometa.lsboot.LsbootStorage 73 | class: LsbootStorage 74 | properties: 75 | order: '2' 76 | children: 77 | - module: ucsmsdk.mometa.lsboot.LsbootLocalStorage 78 | class: LsbootLocalStorage 79 | properties: {} 80 | children: 81 | - module: ucsmsdk.mometa.lsboot.LsbootDefaultLocalImage 82 | class: LsbootDefaultLocalImage 83 | properties: 84 | order: '2' 85 | tags: boot_order 86 | - name: "Configure default Server Pool" 87 | cisco.ucs.ucs_managed_objects: 88 | <<: *login_info 89 | objects: 90 | - module: ucsmsdk.mometa.compute.ComputePool 91 | class: ComputePool 92 | properties: 93 | parent_mo_or_dn: org-root 94 | name: default 95 | children: 96 | - module: ucsmsdk.mometa.compute.ComputePooledSlot 97 | class: ComputePooledSlot 98 | properties: 99 | chassis_id: '4' 100 | slot_id: '1' 101 | - module: ucsmsdk.mometa.compute.ComputePooledSlot 102 | class: ComputePooledSlot 103 | properties: 104 | chassis_id: '4' 105 | slot_id: '2' 106 | tags: server_pool 107 | -------------------------------------------------------------------------------- /playbooks/roles/servers/service_profile_templates/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Configure {{ template_name }} Service Profile Template" 3 | vars: 4 | # Create an anchor for login_info that can be used throughout the file 5 | login_info: &login_info 6 | hostname: "{{ hostname }}" 7 | username: "{{ username | default(omit) }}" 8 | password: "{{ password | default('password') }}" 9 | state: "{{ state | default(omit) }}" 10 | cisco.ucs.ucs_service_profile_template: 11 | <<: *login_info 12 | name: "{{ template_name }}" 13 | template_type: "{{ template_type }}" 14 | host_firmware_package: "{{ host_firmware_package }}" 15 | server_pool: default 16 | vmedia_policy: "{{ vmedia_policy }}" 17 | boot_policy: vmedia-local 18 | maintenance_policy: "{{ maintenance_policy }}" 19 | -------------------------------------------------------------------------------- /playbooks/roles/servers/service_profiles/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Configure {{ profile_name }} Service Profiles from template {{ template_name }}" 3 | vars: 4 | # Create an anchor for login_info that can be used throughout the file 5 | login_info: &login_info 6 | hostname: "{{ hostname }}" 7 | username: "{{ username | default(omit) }}" 8 | password: "{{ password | default('password') }}" 9 | state: "{{ state | default(omit) }}" 10 | cisco.ucs.ucs_service_profile_from_template: 11 | <<: *login_info 12 | name: "{{ profile_name }}-{{ '%d' | format(item) }}" 13 | source_template: "{{ template_name }}" 14 | loop: "{{ range(1, num_profiles|int + 1) | list }}" 15 | -------------------------------------------------------------------------------- /playbooks/sandbox_inventory: -------------------------------------------------------------------------------- 1 | [ucs] 2 | ucs1 ucs_hostname=sandbox-ucsm1.cisco.com 3 | 4 | [ucs:vars] 5 | ucs_username=admin 6 | ucs_password=C1sco12345 7 | -------------------------------------------------------------------------------- /playbooks/server_deploy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # 3 | # Configure UCS, Associate Service Profiles, and Install OS 4 | # 5 | # The hosts group used is provided by the group variable or defaulted to 'ucs'. 6 | # You can specify a specific host (or host group) on the command line: 7 | # ansible-playbook ... -e group= 8 | # e.g., ansible-playbook server_profiles.yml -e group=TME_Demo 9 | # 10 | - hosts: "{{ group | default('ucs') }}" 11 | connection: local 12 | gather_facts: false 13 | vars: 14 | # The UCS domain hostname can be set in the inventory or on the command line as needed 15 | hostname: "{{ inventory_hostname }}" 16 | # Names for Service Profiles, Policies, and number of Profiles 17 | template_name: auto-template 18 | template_type: updating-template 19 | host_firmware_package: ansible-latest 20 | maintenance_policy: user-ack 21 | vmedia_policy: cdd-nfs 22 | profile_name: auto-profile 23 | num_profiles: 2 24 | tasks: 25 | - block: 26 | # Configure default pools and other settings 27 | - import_role: 28 | name: servers/defaults 29 | tags: defaults 30 | # Configure Service Profile Template with default settings 31 | - import_role: 32 | name: servers/service_profile_templates 33 | tags: templates 34 | # Create Service Profiles from template and associate 35 | - import_role: 36 | name: servers/service_profiles 37 | tags: profiles 38 | # Use the localhost's environment and Python 39 | delegate_to: localhost 40 | -------------------------------------------------------------------------------- /playbooks/ucs_disk_group_policy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_disk_group_policy 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure Disk Group Policy 30 | cisco.ucs.ucs_disk_group_policy: 31 | <<: *login_info 32 | name: DEE-DG 33 | raid_level: mirror 34 | configuration_mode: manual 35 | manual_disks: 36 | - slot_num: '1' 37 | role: normal 38 | - slot_num: '2' 39 | role: normal 40 | org_dn: org-root/org-level1 41 | delegate_to: localhost 42 | 43 | - name: Remove Disk from Policy 44 | cisco.ucs.ucs_disk_group_policy: 45 | <<: *login_info 46 | name: DEE-DG 47 | description: Testing Ansible 48 | raid_level: stripe 49 | configuration_mode: manual 50 | manual_disks: 51 | - slot_num: '1' 52 | role: normal 53 | - slot_num: '2' 54 | role: normal 55 | state: absent 56 | virtual_drive: 57 | access_policy: platform-default 58 | io_policy: direct 59 | strip_size: 64KB 60 | org_dn: org-root/org-level1 61 | delegate_to: localhost 62 | 63 | - name: Remove Disk Group Policy 64 | cisco.ucs.ucs_disk_group_policy: 65 | <<: *login_info 66 | name: DEE-DG 67 | state: absent 68 | org_dn: org-root/org-level1 69 | delegate_to: localhost 70 | 71 | - name: Remove UCS Organization 72 | cisco.ucs.ucs_org: 73 | <<: *login_info 74 | org_name: level1 75 | parent_org_path: root 76 | state: absent 77 | delegate_to: localhost -------------------------------------------------------------------------------- /playbooks/ucs_dns_server.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_dns_server 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Configure DNS server 21 | cisco.ucs.ucs_dns_server: 22 | <<: *login_info 23 | dns_server: 10.10.10.10 24 | description: DNS Server IP address 25 | state: present 26 | delegate_to: localhost 27 | 28 | - name: Remove DNS server 29 | cisco.ucs.ucs_dns_server: 30 | <<: *login_info 31 | dns_server: 10.10.10.10 32 | state: absent 33 | delegate_to: localhost -------------------------------------------------------------------------------- /playbooks/ucs_graphics_card_policy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs_graphics_card_policy 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | vars: 8 | org: AnsibleOrg 9 | 10 | tasks: 11 | - name: Test that we have a UCS hostname, UCS username, and UCS password 12 | fail: 13 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 14 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 15 | vars: 16 | # use "<<: *login_info" to substite the information below in each task 17 | # this is not required, however it makes the playbook shorter. 18 | login_info: &login_info 19 | hostname: "{{ ucs_hostname }}" 20 | username: "{{ ucs_username }}" 21 | password: "{{ ucs_password }}" 22 | 23 | - name: Add UCS Organization 24 | cisco.ucs.ucs_org: 25 | <<: *login_info 26 | org_name: "{{ org }}" 27 | parent_org_path: root 28 | description: "Org {{ org }}" 29 | state: present 30 | delegate_to: localhost 31 | 32 | - name: Add Graphics Card Policy 33 | cisco.ucs.ucs_graphics_card_policy: 34 | <<: *login_info 35 | state: present 36 | org_dn: "org-root/org-{{ org }}" 37 | description: Any Graphics Mode Policy 38 | name: prod_graphics 39 | graphics_card_mode: any-configuration 40 | delegate_to: localhost 41 | 42 | - name: Check Graphics Card Policy 43 | cisco.ucs.ucs_graphics_card_policy: 44 | <<: *login_info 45 | state: present 46 | org_dn: "org-root/org-{{ org }}" 47 | description: Any Graphics Mode Policy 48 | name: prod_graphics 49 | graphics_card_mode: any-configuration 50 | delegate_to: localhost 51 | check_mode: True 52 | 53 | - name: Add Graphics Card Policy 54 | cisco.ucs.ucs_graphics_card_policy: 55 | <<: *login_info 56 | state: present 57 | description: Any Graphics Mode Policy 58 | name: any_graphics 59 | graphics_card_mode: any-configuration 60 | delegate_to: localhost 61 | 62 | - name: Idempotent Graphics Card Policy 63 | cisco.ucs.ucs_graphics_card_policy: 64 | <<: *login_info 65 | state: present 66 | description: Any Graphics Mode Policy 67 | name: any_graphics 68 | graphics_card_mode: any-configuration 69 | delegate_to: localhost 70 | 71 | - name: Check Create/Update Graphics Card Policy 72 | cisco.ucs.ucs_graphics_card_policy: 73 | <<: *login_info 74 | state: present 75 | org_dn: "org-root/org-{{ org }}" 76 | description: Compute Graphics Mode Policy 77 | name: prod_graphics 78 | graphics_card_mode: compute 79 | delegate_to: localhost 80 | check_mode: true 81 | 82 | - name: Create/Update Graphics Card Policy 83 | cisco.ucs.ucs_graphics_card_policy: 84 | <<: *login_info 85 | state: present 86 | org_dn: "org-root/org-{{ org }}" 87 | description: Compute Graphics Mode Policy 88 | name: prod_graphics 89 | graphics_card_mode: compute 90 | delegate_to: localhost 91 | 92 | - name: Delete Graphics Card Policy 93 | cisco.ucs.ucs_graphics_card_policy: 94 | <<: *login_info 95 | state: absent 96 | name: any_graphics 97 | delegate_to: localhost 98 | 99 | - name: Remove UCS Organization 100 | cisco.ucs.ucs_org: 101 | <<: *login_info 102 | org_name: "{{ org }}" 103 | parent_org_path: root 104 | state: absent 105 | delegate_to: localhost -------------------------------------------------------------------------------- /playbooks/ucs_ip_pool.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_ip_pool 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure IPv4 and IPv6 address pool 30 | cisco.ucs.ucs_ip_pool: 31 | <<: *login_info 32 | name: ip-pool-01 33 | org_dn: org-root/org-level1 34 | ipv4_blocks: 35 | - first_addr: 192.168.10.1 36 | last_addr: 192.168.10.20 37 | subnet_mask: 255.255.255.128 38 | default_gw: 192.168.10.2 39 | - first_addr: 192.168.11.1 40 | last_addr: 192.168.11.20 41 | subnet_mask: 255.255.255.128 42 | default_gw: 192.168.11.2 43 | ipv6_blocks: 44 | - ipv6_first_addr: fe80::1cae:7992:d7a1:ed07 45 | ipv6_last_addr: fe80::1cae:7992:d7a1:edfe 46 | ipv6_default_gw: fe80::1cae:7992:d7a1:ecff 47 | - ipv6_first_addr: fe80::1cae:7992:d7a1:ec07 48 | ipv6_last_addr: fe80::1cae:7992:d7a1:ecfe 49 | ipv6_default_gw: fe80::1cae:7992:d7a1:ecff 50 | delegate_to: localhost 51 | 52 | - name: Remove IPv4 and IPv6 address pool blocks 53 | cisco.ucs.ucs_ip_pool: 54 | <<: *login_info 55 | name: ip-pool-01 56 | org_dn: org-root/org-level1 57 | ipv4_blocks: 58 | - first_addr: 192.168.10.1 59 | last_addr: 192.168.10.20 60 | state: absent 61 | ipv6_blocks: 62 | - ipv6_first_addr: fe80::1cae:7992:d7a1:ec07 63 | ipv6_last_addr: fe80::1cae:7992:d7a1:ecfe 64 | state: absent 65 | delegate_to: localhost 66 | 67 | - name: Remove IPv4 and IPv6 address pool 68 | cisco.ucs.ucs_ip_pool: 69 | <<: *login_info 70 | name: ip-pool-01 71 | org_dn: org-root/org-level1 72 | state: absent 73 | delegate_to: localhost 74 | 75 | - name: IP Pool - CIMC 76 | cisco.ucs.ucs_ip_pool: 77 | <<: *login_info 78 | name: ext-mgmt-testing 79 | org_dn: org-root/org-level1 80 | description: CIMC IP Pool 81 | ipv4_blocks: 82 | - first_addr: 10.12.34.56 83 | last_addr: 10.12.34.78 84 | subnet_mask: 255.255.255.0 85 | default_gw: 10.12.34.1 86 | primary_dns: 4.2.2.2 87 | secondary_dns: 8.8.8.8 88 | delegate_to: localhost 89 | 90 | - name: Idempotent IP Pool - CIMC 91 | cisco.ucs.ucs_ip_pool: 92 | <<: *login_info 93 | name: ext-mgmt-testing 94 | org_dn: org-root/org-level1 95 | description: CIMC IP Pool 96 | ipv4_blocks: 97 | - first_addr: 10.12.34.56 98 | last_addr: 10.12.34.78 99 | subnet_mask: 255.255.255.0 100 | default_gw: 10.12.34.1 101 | primary_dns: 4.2.2.2 102 | secondary_dns: 8.8.8.8 103 | delegate_to: localhost 104 | 105 | - name: Remove IP Pool - CIMC 106 | cisco.ucs.ucs_ip_pool: 107 | <<: *login_info 108 | name: ext-mgmt-testing 109 | org_dn: org-root/org-level1 110 | state: absent 111 | delegate_to: localhost 112 | 113 | - name: Remove UCS Organization 114 | cisco.ucs.ucs_org: 115 | <<: *login_info 116 | org_name: level1 117 | parent_org_path: root 118 | state: absent 119 | delegate_to: localhost 120 | -------------------------------------------------------------------------------- /playbooks/ucs_ipv4_pool_only.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_ip_pool 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure IPv4 address pool 30 | cisco.ucs.ucs_ip_pool: 31 | <<: *login_info 32 | name: ext-mgmt 33 | org_dn: org-root/org-level1 34 | description: CIMC IP Pool 35 | ipv4_blocks: 36 | - first_addr: 192.168.10.1 37 | last_addr: 192.168.10.20 38 | subnet_mask: 255.255.255.128 39 | default_gw: 192.168.10.2 40 | - first_addr: 192.168.11.1 41 | last_addr: 192.168.11.20 42 | subnet_mask: 255.255.255.128 43 | default_gw: 192.168.11.2 44 | delegate_to: localhost 45 | 46 | - name: Remove IPv4 address pool blocks 47 | cisco.ucs.ucs_ip_pool: 48 | <<: *login_info 49 | name: ext-mgmt 50 | org_dn: org-root/org-level1 51 | ipv4_blocks: 52 | - first_addr: 192.168.10.1 53 | last_addr: 192.168.10.20 54 | state: absent 55 | delegate_to: localhost 56 | 57 | - name: Remove IPv4 address pool 58 | cisco.ucs.ucs_ip_pool: 59 | <<: *login_info 60 | name: ext-mgmt 61 | org_dn: org-root/org-level1 62 | state: absent 63 | delegate_to: localhost 64 | 65 | - name: Remove UCS Organization 66 | cisco.ucs.ucs_org: 67 | <<: *login_info 68 | org_name: level1 69 | parent_org_path: root 70 | state: absent 71 | delegate_to: localhost 72 | -------------------------------------------------------------------------------- /playbooks/ucs_lan_connectivity.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_lan_connectivity 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure LAN Connectivity Policy 30 | cisco.ucs.ucs_lan_connectivity: 31 | <<: *login_info 32 | name: Cntr-FC-Boot 33 | org_dn: org-root/org-level1 34 | vnic_list: 35 | - name: eno1 36 | vnic_template: Cntr-Template 37 | adapter_policy: Linux 38 | - name: eno2 39 | vnic_template: Container-NFS-A 40 | adapter_policy: Linux 41 | - name: eno3 42 | vnic_template: Container-NFS-B 43 | adapter_policy: Linux 44 | iscsi_vnic_list: 45 | - name: iSCSIa 46 | overlay_vnic: eno1 47 | iscsi_adapter_policy: default 48 | vlan_name: Container-MGMT-VLAN 49 | - name: iSCSIb 50 | overlay_vnic: eno3 51 | iscsi_adapter_policy: default 52 | vlan_name: Container-TNT-A-NFS 53 | delegate_to: localhost 54 | 55 | - name: Remove LAN Connectivity Policy 56 | cisco.ucs.ucs_lan_connectivity: 57 | <<: *login_info 58 | name: Cntr-FC-Boot 59 | org_dn: org-root/org-level1 60 | state: absent 61 | delegate_to: localhost 62 | 63 | - name: Remove UCS Organization 64 | cisco.ucs.ucs_org: 65 | <<: *login_info 66 | org_name: level1 67 | parent_org_path: root 68 | state: absent 69 | delegate_to: localhost 70 | -------------------------------------------------------------------------------- /playbooks/ucs_mac_pool.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_mac_pool 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure MAC address pool 30 | cisco.ucs.ucs_mac_pool: 31 | <<: *login_info 32 | name: mac-A 33 | description: MAC Pool A 34 | org_dn: org-root/org-level1 35 | first_addr: 00:25:B5:00:66:00 36 | last_addr: 00:25:B5:00:67:F3 37 | order: sequential 38 | delegate_to: localhost 39 | 40 | - name: Remove MAC address pool 41 | cisco.ucs.ucs_mac_pool: 42 | <<: *login_info 43 | name: mac-A 44 | org_dn: org-root/org-level1 45 | state: absent 46 | delegate_to: localhost 47 | 48 | - name: Remove UCS Organization 49 | cisco.ucs.ucs_org: 50 | <<: *login_info 51 | org_name: level1 52 | parent_org_path: root 53 | state: absent 54 | delegate_to: localhost 55 | -------------------------------------------------------------------------------- /playbooks/ucs_managed_objects.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_managed_objects 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure Network Control Policy 30 | cisco.ucs.ucs_managed_objects: 31 | <<: *login_info 32 | objects: 33 | - module: ucsmsdk.mometa.nwctrl.NwctrlDefinition 34 | class: NwctrlDefinition 35 | properties: 36 | parent_mo_or_dn: org-root/org-level1 37 | cdp: enabled 38 | descr: '' 39 | lldp_receive: enabled 40 | lldp_transmit: enabled 41 | name: Enable-CDP-LLDP 42 | delegate_to: localhost 43 | 44 | - name: Remove Network Control Policy 45 | cisco.ucs.ucs_managed_objects: 46 | <<: *login_info 47 | objects: 48 | - module: ucsmsdk.mometa.nwctrl.NwctrlDefinition 49 | class: NwctrlDefinition 50 | properties: 51 | parent_mo_or_dn: org-root/org-level1 52 | name: Enable-CDP-LLDP 53 | state: absent 54 | delegate_to: localhost 55 | 56 | - name: Configure Boot Policy Using JSON objects list with children 57 | cisco.ucs.ucs_managed_objects: 58 | <<: *login_info 59 | objects: 60 | - { 61 | "module": "ucsmsdk.mometa.lsboot.LsbootPolicy", 62 | "class": "LsbootPolicy", 63 | "properties": { 64 | "parent_mo_or_dn": "org-root/org-level1", 65 | "name": "Python_SDS", 66 | "enforce_vnic_name": "yes", 67 | "boot_mode": "legacy", 68 | "reboot_on_update": "no" 69 | }, 70 | "children": [ 71 | { 72 | "module": "ucsmsdk.mometa.lsboot.LsbootVirtualMedia", 73 | "class": "LsbootVirtualMedia", 74 | "properties": { 75 | "access": "read-only-local", 76 | "lun_id": "0", 77 | "order": "2" 78 | } 79 | }, 80 | { 81 | "module": "ucsmsdk.mometa.lsboot.LsbootStorage", 82 | "class": "LsbootStorage", 83 | "properties": { 84 | "order": "1" 85 | }, 86 | "children": [ 87 | { 88 | "module": "ucsmsdk.mometa.lsboot.LsbootLocalStorage", 89 | "class": "LsbootLocalStorage", 90 | "properties": {}, 91 | "children": [ 92 | { 93 | "module": "ucsmsdk.mometa.lsboot.LsbootDefaultLocalImage", 94 | "class": "LsbootDefaultLocalImage", 95 | "properties": { 96 | "order": "1" 97 | } 98 | } 99 | ] 100 | } 101 | ] 102 | } 103 | ] 104 | } 105 | delegate_to: localhost 106 | 107 | - name: Remove Boot Policy Using JSON objects list 108 | cisco.ucs.ucs_managed_objects: 109 | <<: *login_info 110 | objects: 111 | - { 112 | "module": "ucsmsdk.mometa.lsboot.LsbootPolicy", 113 | "class": "LsbootPolicy", 114 | "properties": { 115 | "parent_mo_or_dn": "org-root/org-level1", 116 | "name": "Python_SDS" 117 | } 118 | } 119 | state: absent 120 | delegate_to: localhost 121 | 122 | - name: Remove UCS Organization 123 | cisco.ucs.ucs_org: 124 | <<: *login_info 125 | org_name: level1 126 | parent_org_path: root 127 | state: absent 128 | delegate_to: localhost 129 | -------------------------------------------------------------------------------- /playbooks/ucs_ntp_server.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_dns_server 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Configure NTP server 21 | cisco.ucs.ucs_ntp_server: 22 | <<: *login_info 23 | ntp_server: 10.10.10.10 24 | description: Internal NTP Server by IP address 25 | state: present 26 | delegate_to: localhost 27 | 28 | - name: Configure NTP server 29 | cisco.ucs.ucs_ntp_server: 30 | <<: *login_info 31 | ntp_server: pool.ntp.org 32 | description: External NTP Server by hostname 33 | state: present 34 | delegate_to: localhost 35 | 36 | - name: Remove NTP server 37 | cisco.ucs.ucs_ntp_server: 38 | <<: *login_info 39 | ntp_server: 10.10.10.10 40 | state: absent 41 | delegate_to: localhost 42 | 43 | - name: Remove NTP server 44 | cisco.ucs.ucs_ntp_server: 45 | <<: *login_info 46 | ntp_server: pool.ntp.org 47 | state: absent 48 | delegate_to: localhost -------------------------------------------------------------------------------- /playbooks/ucs_org.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_org 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: test 24 | description: testing org 25 | state: present 26 | delegate_to: localhost 27 | 28 | - name: Update UCS Organization 29 | cisco.ucs.ucs_org: 30 | <<: *login_info 31 | org_name: test 32 | description: Testing org 33 | state: present 34 | delegate_to: localhost 35 | 36 | - name: Remove UCS Organization 37 | cisco.ucs.ucs_org: 38 | <<: *login_info 39 | org_name: test 40 | state: absent 41 | delegate_to: localhost 42 | 43 | - name: Add UCS Organization 44 | cisco.ucs.ucs_org: 45 | <<: *login_info 46 | org_name: level1 47 | parent_org_path: root 48 | description: level1 org 49 | state: present 50 | delegate_to: localhost 51 | 52 | - name: Add UCS Organization 53 | cisco.ucs.ucs_org: 54 | <<: *login_info 55 | org_name: level2 56 | parent_org_path: root/level1 57 | description: level2 org 58 | state: present 59 | delegate_to: localhost 60 | 61 | - name: Add UCS Organization 62 | cisco.ucs.ucs_org: 63 | <<: *login_info 64 | org_name: level3 65 | parent_org_path: root/level1/level2 66 | description: level3 org 67 | state: present 68 | delegate_to: localhost 69 | 70 | - name: Remove UCS Organization 71 | cisco.ucs.ucs_org: 72 | <<: *login_info 73 | org_name: level2 74 | parent_org_path: root/level1 75 | state: absent 76 | delegate_to: localhost 77 | -------------------------------------------------------------------------------- /playbooks/ucs_query.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_query 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Query UCS Class ID 21 | cisco.ucs.ucs_query: 22 | <<: *login_info 23 | class_ids: computeBlade 24 | delegate_to: localhost 25 | register: response 26 | 27 | - name: show response 28 | debug: 29 | msg: "{{ response }}" 30 | 31 | - name: Query UCS Class IDs 32 | cisco.ucs.ucs_query: 33 | <<: *login_info 34 | class_ids: computeBlade, fabricVlan 35 | delegate_to: localhost 36 | register: response 37 | 38 | - name: show response 39 | debug: 40 | msg: "{{ response }}" 41 | 42 | - name: Query UCS Distinguished Name 43 | cisco.ucs.ucs_query: 44 | <<: *login_info 45 | distinguished_names: org-root 46 | delegate_to: localhost 47 | register: response 48 | 49 | - name: show response 50 | debug: 51 | msg: "{{ response }}" 52 | 53 | - name: Query UCS Distinguished Names 54 | cisco.ucs.ucs_query: 55 | <<: *login_info 56 | distinguished_names: org-root, sys/rack-unit-1, sys/chassis-1/blade-2 57 | delegate_to: localhost 58 | register: response 59 | 60 | - name: show response 61 | debug: 62 | msg: "{{ response }}" -------------------------------------------------------------------------------- /playbooks/ucs_san_connectivity.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_san_connectivity 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure SAN Connectivity Policy 30 | cisco.ucs.ucs_san_connectivity: 31 | <<: *login_info 32 | name: Cntr-FC-Boot 33 | description: FC Boot Policy 34 | org_dn: org-root/org-level1 35 | wwnn_pool: WWNN-Pool 36 | vhba_list: 37 | - name: Fabric-A 38 | vhba_template: vHBA-Template-A 39 | adapter_policy: Linux 40 | - name: Fabric-B 41 | vhba_template: vHBA-Template-B 42 | adapter_policy: Linux 43 | delegate_to: localhost 44 | 45 | - name: Remove SAN Connectivity Policy 46 | cisco.ucs.ucs_san_connectivity: 47 | <<: *login_info 48 | name: Cntr-FC-Boot 49 | org_dn: org-root/org-level1 50 | state: absent 51 | delegate_to: localhost 52 | 53 | - name: Remove UCS Organization 54 | cisco.ucs.ucs_org: 55 | <<: *login_info 56 | org_name: level1 57 | parent_org_path: root 58 | state: absent 59 | delegate_to: localhost 60 | -------------------------------------------------------------------------------- /playbooks/ucs_scrub_policy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_scrub_policy 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | vars: 8 | org: AnsibleOrg 9 | 10 | tasks: 11 | - name: Test that we have a UCS hostname, UCS username, and UCS password 12 | fail: 13 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 14 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 15 | vars: 16 | # use "<<: *login_info" to substite the information below in each task 17 | # this is not required, however it makes the playbook shorter. 18 | login_info: &login_info 19 | hostname: "{{ ucs_hostname }}" 20 | username: "{{ ucs_username }}" 21 | password: "{{ ucs_password }}" 22 | 23 | - name: Add UCS Organization 24 | cisco.ucs.ucs_org: 25 | <<: *login_info 26 | org_name: "{{ org }}" 27 | parent_org_path: root 28 | description: "Org {{ org }}" 29 | state: present 30 | delegate_to: localhost 31 | 32 | - name: Add Scrub Policy 33 | cisco.ucs.ucs_scrub_policy: 34 | <<: *login_info 35 | state: present 36 | org_dn: "org-root/org-{{ org }}" 37 | description: Scrub All Policy 38 | name: all_scrub 39 | bios_settings_scrub: "yes" 40 | disk_scrub: "yes" 41 | flex_flash_scrub: "yes" 42 | persistent_memory_scrub: "yes" 43 | delegate_to: localhost 44 | 45 | - name: Check Scrub Policy 46 | cisco.ucs.ucs_scrub_policy: 47 | <<: *login_info 48 | state: present 49 | org_dn: "org-root/org-{{ org }}" 50 | description: Scrub All Policy 51 | name: all_scrub 52 | bios_settings_scrub: "yes" 53 | disk_scrub: "yes" 54 | flex_flash_scrub: "yes" 55 | persistent_memory_scrub: "yes" 56 | delegate_to: localhost 57 | check_mode: True 58 | 59 | - name: Add Scrub Policy 60 | cisco.ucs.ucs_scrub_policy: 61 | <<: *login_info 62 | state: present 63 | description: Scrub All Policy 64 | name: all_scrub 65 | bios_settings_scrub: "yes" 66 | disk_scrub: "yes" 67 | flex_flash_scrub: "yes" 68 | persistent_memory_scrub: "yes" 69 | delegate_to: localhost 70 | 71 | - name: Idempotent Scrub Policy 72 | cisco.ucs.ucs_scrub_policy: 73 | <<: *login_info 74 | state: present 75 | description: Scrub All Policy 76 | name: all_scrub 77 | bios_settings_scrub: "yes" 78 | disk_scrub: "yes" 79 | flex_flash_scrub: "yes" 80 | persistent_memory_scrub: "yes" 81 | delegate_to: localhost 82 | 83 | - name: Check Create/Update Scrub Policy 84 | cisco.ucs.ucs_scrub_policy: 85 | <<: *login_info 86 | state: present 87 | org_dn: "org-root/org-{{ org }}" 88 | name: BD_scrub 89 | description: Scrub BIOS and Disk Policy 90 | bios_settings_scrub: "yes" 91 | disk_scrub: "yes" 92 | flex_flash_scrub: "no" 93 | persistent_memory_scrub: "no" 94 | delegate_to: localhost 95 | check_mode: true 96 | 97 | - name: Create/Update Scrub Policy 98 | cisco.ucs.ucs_scrub_policy: 99 | <<: *login_info 100 | state: present 101 | org_dn: "org-root/org-{{ org }}" 102 | name: BD_scrub 103 | description: Scrub BIOS and Disk Policy 104 | bios_settings_scrub: "yes" 105 | disk_scrub: "yes" 106 | flex_flash_scrub: "no" 107 | persistent_memory_scrub: "no" 108 | delegate_to: localhost 109 | 110 | - name: Delete Scrub Policy 111 | cisco.ucs.ucs_scrub_policy: 112 | <<: *login_info 113 | state: absent 114 | name: all_scrub 115 | delegate_to: localhost 116 | 117 | - name: Remove UCS Organization 118 | cisco.ucs.ucs_org: 119 | <<: *login_info 120 | org_name: "{{ org }}" 121 | parent_org_path: root 122 | state: absent 123 | delegate_to: localhost -------------------------------------------------------------------------------- /playbooks/ucs_serial_over_lan_policy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_serial_over_lan_policy 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | vars: 8 | org: AnsibleOrg 9 | 10 | tasks: 11 | - name: Test that we have a UCS hostname, UCS username, and UCS password 12 | fail: 13 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 14 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 15 | vars: 16 | # use "<<: *login_info" to substite the information below in each task 17 | # this is not required, however it makes the playbook shorter. 18 | login_info: &login_info 19 | hostname: "{{ ucs_hostname }}" 20 | username: "{{ ucs_username }}" 21 | password: "{{ ucs_password }}" 22 | 23 | - name: Add UCS Organization 24 | cisco.ucs.ucs_org: 25 | <<: *login_info 26 | org_name: "{{ org }}" 27 | parent_org_path: root 28 | description: "Org {{ org }}" 29 | state: present 30 | delegate_to: localhost 31 | 32 | - name: Add UCS Serial Over Lan Policy 33 | cisco.ucs.ucs_serial_over_lan_policy: 34 | <<: *login_info 35 | state: present 36 | org_dn: "org-root/org-{{ org }}" 37 | name: sol_pol 38 | description: "Serial Over Lan for Org {{ org }} servers" 39 | admin_state: enable 40 | speed: "38400" 41 | delegate_to: localhost 42 | 43 | - name: Check Serial Over Lan 44 | cisco.ucs.ucs_serial_over_lan_policy: 45 | <<: *login_info 46 | state: present 47 | org_dn: "org-root/org-{{ org }}" 48 | name: sol_pol 49 | description: "Serial Over Lan for Org {{ org }} servers" 50 | admin_state: enable 51 | speed: "38400" 52 | delegate_to: localhost 53 | check_mode: True 54 | 55 | - name: Add Serial Over Lan 56 | cisco.ucs.ucs_serial_over_lan_policy: 57 | <<: *login_info 58 | state: present 59 | name: sol_pol 60 | description: Serial Over Lan for Org Root servers 61 | admin_state: enable 62 | speed: "57600" 63 | delegate_to: localhost 64 | 65 | - name: Idempotent Serial Over Lan 66 | cisco.ucs.ucs_serial_over_lan_policy: 67 | <<: *login_info 68 | state: present 69 | name: sol_pol 70 | description: Serial Over Lan for Org Root servers 71 | admin_state: enable 72 | speed: "57600" 73 | delegate_to: localhost 74 | 75 | - name: Check Update Serial Over Lan 76 | cisco.ucs.ucs_serial_over_lan_policy: 77 | <<: *login_info 78 | state: present 79 | name: sol_pol 80 | description: Serial Over Lan for Org Root servers 81 | admin_state: enable 82 | speed: "57600" 83 | delegate_to: localhost 84 | check_mode: true 85 | 86 | - name: Update Serial Over Lan 87 | cisco.ucs.ucs_serial_over_lan_policy: 88 | <<: *login_info 89 | state: present 90 | name: sol_pol 91 | description: Serial Over Lan for Org Root servers 92 | admin_state: enable 93 | speed: "57600" 94 | delegate_to: localhost 95 | 96 | - name: Delete Serial Over Lan 97 | cisco.ucs.ucs_serial_over_lan_policy: 98 | <<: *login_info 99 | state: absent 100 | name: sol_pol 101 | delegate_to: localhost 102 | 103 | - name: Remove UCS Organization 104 | cisco.ucs.ucs_org: 105 | <<: *login_info 106 | org_name: "{{ org }}" 107 | parent_org_path: root 108 | state: absent 109 | delegate_to: localhost -------------------------------------------------------------------------------- /playbooks/ucs_server_maintenance.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_server_maintenance 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add Server Maintenance Policy (check_mode) 21 | cisco.ucs.ucs_server_maintenance: 22 | <<: *login_info 23 | name: user-ack 24 | uptime_disr: user-ack 25 | trigger_config: on-next-boot 26 | delegate_to: localhost 27 | check_mode: true 28 | 29 | - name: Add Server Maintenance Policy 30 | cisco.ucs.ucs_server_maintenance: 31 | <<: *login_info 32 | name: user-ack 33 | uptime_disr: user-ack 34 | trigger_config: on-next-boot 35 | delegate_to: localhost 36 | 37 | - name: Idempotent Add Server Maintenance Policy 38 | cisco.ucs.ucs_server_maintenance: 39 | <<: *login_info 40 | name: user-ack 41 | uptime_disr: user-ack 42 | trigger_config: on-next-boot 43 | delegate_to: localhost 44 | -------------------------------------------------------------------------------- /playbooks/ucs_service_profile_association.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_ucs_service_profile_association 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Change Service Profile Association to Existing Server 21 | cisco.ucs.ucs_service_profile_association: 22 | <<: *login_info 23 | service_profile_name: auto-profile-2 24 | server_assignment: server 25 | server_dn: sys/chassis-6/blade-1 26 | delegate_to: localhost 27 | register: result 28 | until: result.assign_state == 'assigned' and result.assoc_state == 'associated' 29 | retries: 1 30 | delay: 2 31 | ignore_errors: true 32 | 33 | - name: Change Service Profile Association to Pool 34 | cisco.ucs.ucs_service_profile_association: 35 | <<: *login_info 36 | service_profile_name: auto-profile-2 37 | server_assignment: pool 38 | server_pool_name: default 39 | delegate_to: localhost 40 | register: result 41 | until: result.assign_state == 'assigned' and result.assoc_state == 'associated' 42 | retries: 1 43 | delay: 2 44 | ignore_errors: true 45 | 46 | - name: Disassociate Service Profile 47 | cisco.ucs.ucs_service_profile_association: 48 | <<: *login_info 49 | service_profile_name: auto-profile-2 50 | state: absent 51 | delegate_to: localhost 52 | register: result 53 | until: result.assign_state == 'unassigned' and result.assoc_state == 'unassociated' 54 | retries: 1 55 | delay: 2 56 | ignore_errors: true 57 | -------------------------------------------------------------------------------- /playbooks/ucs_service_profile_from_template.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_service_profile_from_template 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure Service Profile Template with LAN/SAN Connectivity and all other options defaulted 30 | cisco.ucs.ucs_service_profile_template: 31 | <<: *login_info 32 | name: sp-template 33 | org_dn: org-root/org-level1 34 | template_type: updating-template 35 | uuid_pool: UUID-Pool 36 | storage_profile: DEE-StgProf 37 | lan_connectivity_policy: Cntr-FC-Boot 38 | iqn_pool: iSCSI-Boot-A 39 | san_connectivity_policy: Cntr-FC-Boot 40 | boot_policy: DEE-vMedia 41 | maintenance_policy: default 42 | server_pool: Container-Pool 43 | host_firmware_package: 3.1.2b 44 | bios_policy: Docker 45 | delegate_to: localhost 46 | 47 | - name: Configure Service Profile from Template 48 | cisco.ucs.ucs_service_profile_from_template: 49 | <<: *login_info 50 | name: sp-instance-1 51 | org_dn: org-root/org-level1 52 | user_label: SP Instance 53 | power_state: down 54 | source_template: sp-template 55 | delegate_to: localhost 56 | 57 | - name: Remove Service Profile Template 58 | cisco.ucs.ucs_service_profile_template: 59 | <<: *login_info 60 | name: sp-template 61 | org_dn: org-root/org-level1 62 | state: absent 63 | delegate_to: localhost 64 | 65 | - name: Remove UCS Organization 66 | cisco.ucs.ucs_org: 67 | <<: *login_info 68 | org_name: level1 69 | parent_org_path: root 70 | state: absent 71 | delegate_to: localhost 72 | -------------------------------------------------------------------------------- /playbooks/ucs_service_profile_template.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_service_profile_template 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure Service Profile Template with LAN/SAN Connectivity and all other options defaulted 30 | cisco.ucs.ucs_service_profile_template: 31 | <<: *login_info 32 | name: sp-template 33 | org_dn: org-root/org-level1 34 | template_type: updating-template 35 | uuid_pool: UUID-Pool 36 | storage_profile: DEE-StgProf 37 | lan_connectivity_policy: Cntr-FC-Boot 38 | iqn_pool: iSCSI-Boot-A 39 | san_connectivity_policy: Cntr-FC-Boot 40 | boot_policy: DEE-vMedia 41 | maintenance_policy: default 42 | server_pool: Container-Pool 43 | host_firmware_package: 3.1.2b 44 | bios_policy: Docker 45 | delegate_to: localhost 46 | 47 | - name: Remove Service Profile Template 48 | cisco.ucs.ucs_service_profile_template: 49 | <<: *login_info 50 | name: sp-template 51 | org_dn: org-root/org-level1 52 | state: absent 53 | delegate_to: localhost 54 | 55 | - name: Remove UCS Organization 56 | cisco.ucs.ucs_org: 57 | <<: *login_info 58 | org_name: level1 59 | parent_org_path: root 60 | state: absent 61 | delegate_to: localhost 62 | -------------------------------------------------------------------------------- /playbooks/ucs_sp_vnic_order.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_sp_vnic_order 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Configure vnic order 21 | cisco.ucs.ucs_sp_vnic_order: 22 | <<: *login_info 23 | sp_name: DEE-Ctrl-02 24 | vnics: 25 | - name: eno1 26 | admin_vcon: '1' 27 | order: '1' 28 | transport: ethernet 29 | delegate_to: localhost 30 | -------------------------------------------------------------------------------- /playbooks/ucs_storage_profile.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_storage_profile 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure Storage Profile 30 | cisco.ucs.ucs_storage_profile: 31 | <<: *login_info 32 | name: DEE-StgProf 33 | org_dn: org-root/org-level1 34 | local_luns: 35 | - name: Boot-LUN 36 | size: '60' 37 | disk_policy_name: DEE-DG 38 | - name: Data-LUN 39 | size: '200' 40 | disk_policy_name: DEE-DG 41 | delegate_to: localhost 42 | 43 | - name: Remove Local LUN from Storage Profile 44 | cisco.ucs.ucs_storage_profile: 45 | <<: *login_info 46 | name: DEE-StgProf 47 | org_dn: org-root/org-level1 48 | local_luns: 49 | - name: Data-LUN 50 | state: absent 51 | delegate_to: localhost 52 | 53 | - name: Remove Storage Profile 54 | cisco.ucs.ucs_storage_profile: 55 | <<: *login_info 56 | name: DEE-StgProf 57 | org_dn: org-root/org-level1 58 | state: absent 59 | delegate_to: localhost 60 | 61 | - name: Remove UCS Organization 62 | cisco.ucs.ucs_org: 63 | <<: *login_info 64 | org_name: level1 65 | parent_org_path: root 66 | state: absent 67 | delegate_to: localhost 68 | -------------------------------------------------------------------------------- /playbooks/ucs_system_qos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_system_qos 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Check QoS System Class 21 | cisco.ucs.ucs_system_qos: 22 | <<: *login_info 23 | priority: platinum 24 | cos: '5' 25 | weight: '10' 26 | delegate_to: localhost 27 | check_mode: true 28 | 29 | - name: Add QoS System Class 30 | cisco.ucs.ucs_system_qos: 31 | <<: *login_info 32 | priority: platinum 33 | cos: '5' 34 | weight: '10' 35 | delegate_to: localhost 36 | 37 | - name: Idempotent Add QoS System Class 38 | cisco.ucs.ucs_system_qos: 39 | <<: *login_info 40 | priority: platinum 41 | cos: '5' 42 | weight: '10' 43 | delegate_to: localhost 44 | 45 | - name: Check Update QoS System Class 46 | cisco.ucs.ucs_system_qos: 47 | <<: *login_info 48 | priority: platinum 49 | cos: '5' 50 | weight: '10' 51 | mtu: '9216' 52 | delegate_to: localhost 53 | check_mode: true 54 | 55 | - name: Update QoS System Class 56 | cisco.ucs.ucs_system_qos: 57 | <<: *login_info 58 | priority: platinum 59 | cos: '5' 60 | weight: '10' 61 | mtu: '9216' 62 | delegate_to: localhost 63 | 64 | - name: Idempotent Update QoS System Class 65 | cisco.ucs.ucs_system_qos: 66 | <<: *login_info 67 | priority: platinum 68 | cos: '5' 69 | weight: '10' 70 | mtu: '9216' 71 | delegate_to: localhost 72 | -------------------------------------------------------------------------------- /playbooks/ucs_timezone.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_timezone 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Configure Time Zone 21 | cisco.ucs.ucs_timezone: 22 | <<: *login_info 23 | state: present 24 | admin_state: enabled 25 | timezone: America/Phoenix 26 | delegate_to: localhost 27 | 28 | - name: Unconfigure Time Zone 29 | cisco.ucs.ucs_timezone: 30 | <<: *login_info 31 | state: absent 32 | admin_state: disabled 33 | delegate_to: localhost -------------------------------------------------------------------------------- /playbooks/ucs_uuid_pool.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_uuid_pool 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure UUID address pool 30 | cisco.ucs.ucs_uuid_pool: 31 | <<: *login_info 32 | name: UUID-Pool 33 | org_dn: org-root/org-level1 34 | order: sequential 35 | first_uuid: 0000-000000000001 36 | last_uuid: 0000-000000000078 37 | delegate_to: localhost 38 | 39 | - name: Remove UUID address pool 40 | cisco.ucs.ucs_uuid_pool: 41 | <<: *login_info 42 | name: UUID-Pool 43 | org_dn: org-root/org-level1 44 | state: absent 45 | delegate_to: localhost 46 | 47 | - name: Remove UCS Organization 48 | cisco.ucs.ucs_org: 49 | <<: *login_info 50 | org_name: level1 51 | parent_org_path: root 52 | state: absent 53 | delegate_to: localhost 54 | -------------------------------------------------------------------------------- /playbooks/ucs_vhba_template.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_vhba_template 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure vHBA template 30 | cisco.ucs.ucs_vhba_template: 31 | <<: *login_info 32 | name: vHBA-A 33 | org_dn: org-root/org-level1 34 | fabric: A 35 | vsan: VSAN-A 36 | wwpn_pool: WWPN-Pool-A 37 | delegate_to: localhost 38 | 39 | - name: Remote vHBA template 40 | cisco.ucs.ucs_vhba_template: 41 | <<: *login_info 42 | name: vHBA-A 43 | org_dn: org-root/org-level1 44 | state: absent 45 | delegate_to: localhost 46 | 47 | - name: Remove UCS Organization 48 | cisco.ucs.ucs_org: 49 | <<: *login_info 50 | org_name: level1 51 | parent_org_path: root 52 | state: absent 53 | delegate_to: localhost 54 | -------------------------------------------------------------------------------- /playbooks/ucs_vlan_find.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_vlan_find 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Get all vlans in fabric A 21 | cisco.ucs.ucs_vlan_find: 22 | <<: *login_info 23 | fabric: 'common' 24 | pattern: '.' 25 | register: response 26 | delegate_to: localhost 27 | 28 | - name: show response 29 | debug: 30 | msg: "{{ response }}" 31 | 32 | - name: Confirm if vlan 15 is present 33 | cisco.ucs.ucs_vlan_find: 34 | <<: *login_info 35 | vlanid: '200' 36 | register: response 37 | delegate_to: localhost 38 | 39 | - name: show response 40 | debug: 41 | msg: "{{ response }}" 42 | -------------------------------------------------------------------------------- /playbooks/ucs_vlan_to_group.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_vlan_to_group 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add VLAN to existing VLAN group 21 | cisco.ucs.ucs_vlan_to_group: 22 | <<: *login_info 23 | vlangroup: inband 24 | vlanname: vlan244 25 | delegate_to: localhost 26 | -------------------------------------------------------------------------------- /playbooks/ucs_vlans.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_vlans 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Configure VLAN 21 | cisco.ucs.ucs_vlans: 22 | <<: *login_info 23 | name: vlan300 24 | id: '300' 25 | native: 'no' 26 | delegate_to: localhost 27 | 28 | - name: Remove VLAN 29 | cisco.ucs.ucs_vlans: 30 | <<: *login_info 31 | name: vlan300 32 | state: absent 33 | delegate_to: localhost 34 | -------------------------------------------------------------------------------- /playbooks/ucs_vnic_template.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_vnic_template 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure vNIC template 30 | cisco.ucs.ucs_vnic_template: 31 | <<: *login_info 32 | name: vNIC-A 33 | org_dn: org-root/org-level1 34 | fabric: A 35 | vlans_list: 36 | - name: default 37 | native: 'yes' 38 | - name: vlan200 39 | native: 'no' 40 | multicast_policy: default 41 | fabric: A 42 | id: '200' 43 | sharing: none 44 | delegate_to: localhost 45 | 46 | - name: Remove VLAN from template 47 | cisco.ucs.ucs_vnic_template: 48 | <<: *login_info 49 | name: vNIC-A 50 | org_dn: org-root/org-level1 51 | fabric: A 52 | vlans_list: 53 | - name: vlan200 54 | state: absent 55 | delegate_to: localhost 56 | 57 | - name: Configure vNIC template for failover 58 | cisco.ucs.ucs_vnic_template: 59 | <<: *login_info 60 | name: vNIC-A-B 61 | org_dn: org-root/org-level1 62 | fabric: A-B 63 | redundancy_type: primary 64 | vlans_list: 65 | - name: default 66 | native: 'yes' 67 | - name: vlan200 68 | native: 'no' 69 | delegate_to: localhost 70 | 71 | - name: Configure vNIC template for failover 72 | cisco.ucs.ucs_vnic_template: 73 | <<: *login_info 74 | name: vNIC-B-A 75 | org_dn: org-root/org-level1 76 | fabric: B-A 77 | redundancy_type: secondary 78 | vlans_list: 79 | - name: default 80 | native: 'yes' 81 | - name: vlan200 82 | native: 'no' 83 | delegate_to: localhost 84 | 85 | 86 | - name: Remove vNIC template 87 | cisco.ucs.ucs_vnic_template: 88 | <<: *login_info 89 | name: vNIC-A-B 90 | org_dn: org-root/org-level1 91 | state: absent 92 | delegate_to: localhost 93 | 94 | - name: Remove vNIC template 95 | cisco.ucs.ucs_vnic_template: 96 | <<: *login_info 97 | name: vNIC-B-A 98 | org_dn: org-root/org-level1 99 | state: absent 100 | delegate_to: localhost 101 | 102 | - name: Remove UCS Organization 103 | cisco.ucs.ucs_org: 104 | <<: *login_info 105 | org_name: level1 106 | parent_org_path: root 107 | state: absent 108 | delegate_to: localhost 109 | -------------------------------------------------------------------------------- /playbooks/ucs_vsans.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_vsans 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Configure VSAN 21 | cisco.ucs.ucs_vsans: 22 | <<: *login_info 23 | name: vsan110 24 | fabric: common 25 | vsan_id: '110' 26 | vlan_id: '110' 27 | delegate_to: localhost 28 | 29 | - name: Remove VSAN 30 | cisco.ucs.ucs_vsans: 31 | <<: *login_info 32 | name: vsan110 33 | state: absent 34 | delegate_to: localhost 35 | -------------------------------------------------------------------------------- /playbooks/ucs_wwn_pool.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Example Playbook: cisco.ucs.ucs_wwn_pool 3 | - hosts: ucs 4 | connection: local 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: Test that we have a UCS hostname, UCS username, and UCS password 9 | fail: 10 | msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.' 11 | when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined 12 | vars: 13 | # use "<<: *login_info" to substite the information below in each task 14 | # this is not required, however it makes the playbook shorter. 15 | login_info: &login_info 16 | hostname: "{{ ucs_hostname }}" 17 | username: "{{ ucs_username }}" 18 | password: "{{ ucs_password }}" 19 | 20 | - name: Add UCS Organization 21 | cisco.ucs.ucs_org: 22 | <<: *login_info 23 | org_name: level1 24 | parent_org_path: root 25 | description: level1 org 26 | state: present 27 | delegate_to: localhost 28 | 29 | - name: Configure WWNN pool 30 | cisco.ucs.ucs_wwn_pool: 31 | <<: *login_info 32 | name: WWNN-Pool 33 | org_dn: org-root/org-level1 34 | purpose: node 35 | first_addr: 20:00:00:25:B5:48:00:00 36 | last_addr: 20:00:00:25:B5:48:00:0F 37 | delegate_to: localhost 38 | 39 | - name: Configure WWPN A pool 40 | cisco.ucs.ucs_wwn_pool: 41 | <<: *login_info 42 | name: WWPN-Pool-A 43 | org_dn: org-root/org-level1 44 | purpose: port 45 | order: sequential 46 | first_addr: 20:00:00:25:B5:48:0A:00 47 | last_addr: 20:00:00:25:B5:48:0A:0F 48 | delegate_to: localhost 49 | 50 | - name: Configure WWPN Bpool 51 | cisco.ucs.ucs_wwn_pool: 52 | <<: *login_info 53 | name: WWPN-Pool-B 54 | org_dn: org-root/org-level1 55 | purpose: port 56 | order: sequential 57 | first_addr: 20:00:00:25:B5:48:0B:00 58 | last_addr: 20:00:00:25:B5:48:0B:0F 59 | delegate_to: localhost 60 | 61 | - name: Remove WWNN pool 62 | cisco.ucs.ucs_wwn_pool: 63 | <<: *login_info 64 | org_dn: org-root/org-level1 65 | name: WWNN-Pool 66 | state: absent 67 | delegate_to: localhost 68 | 69 | - name: Remove WWPN pool 70 | cisco.ucs.ucs_wwn_pool: 71 | <<: *login_info 72 | name: WWPN-Pool-A 73 | org_dn: org-root/org-level1 74 | state: absent 75 | delegate_to: localhost 76 | 77 | - name: Remove WWPN pool 78 | cisco.ucs.ucs_wwn_pool: 79 | <<: *login_info 80 | name: WWPN-Pool-B 81 | org_dn: org-root/org-level1 82 | state: absent 83 | delegate_to: localhost 84 | 85 | - name: Remove UCS Organization 86 | cisco.ucs.ucs_org: 87 | <<: *login_info 88 | org_name: level1 89 | parent_org_path: root 90 | state: absent 91 | delegate_to: localhost 92 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # Collections Plugins Directory 2 | 3 | This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that 4 | is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that 5 | would contain module utils and modules respectively. 6 | 7 | Here is an example directory of the majority of plugins currently supported by Ansible: 8 | 9 | ``` 10 | └── plugins 11 | ├── action 12 | ├── become 13 | ├── cache 14 | ├── callback 15 | ├── cliconf 16 | ├── connection 17 | ├── filter 18 | ├── httpapi 19 | ├── inventory 20 | ├── lookup 21 | ├── module_utils 22 | ├── modules 23 | ├── netconf 24 | ├── shell 25 | ├── strategy 26 | ├── terminal 27 | ├── test 28 | └── vars 29 | ``` 30 | 31 | A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible/2.9/plugins/plugins.html). -------------------------------------------------------------------------------- /plugins/doc_fragments/ucs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # This code is part of Ansible, but is an independent component. 4 | # This particular file snippet, and this file snippet only, is BSD licensed. 5 | # Modules you write using this snippet, which is embedded dynamically by Ansible 6 | # still belong to the author of the module, and may assign their own license 7 | # to the complete work. 8 | # 9 | # (c) 2016 Red Hat Inc. 10 | # (c) 2017 Cisco Systems Inc. 11 | # 12 | # Redistribution and use in source and binary forms, with or without modification, 13 | # are permitted provided that the following conditions are met: 14 | # 15 | # * Redistributions of source code must retain the above copyright 16 | # notice, this list of conditions and the following disclaimer. 17 | # * Redistributions in binary form must reproduce the above copyright notice, 18 | # this list of conditions and the following disclaimer in the documentation 19 | # and/or other materials provided with the distribution. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 | # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 29 | # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | # 31 | 32 | 33 | class ModuleDocFragment(object): 34 | # Cisco UCS doc fragment 35 | DOCUMENTATION = ''' 36 | options: 37 | hostname: 38 | description: 39 | - IP address or hostname of Cisco UCS Manager. 40 | - Modules can be used with the UCS Platform Emulator U(https://cs.co/ucspe) 41 | type: str 42 | required: yes 43 | username: 44 | description: 45 | - Username for Cisco UCS Manager authentication. 46 | type: str 47 | default: admin 48 | password: 49 | description: 50 | - Password for Cisco UCS Manager authentication. 51 | type: str 52 | required: yes 53 | port: 54 | description: 55 | - Port number to be used during connection (by default uses 443 for https and 80 for http connection). 56 | type: int 57 | use_ssl: 58 | description: 59 | - If C(no), an HTTP connection will be used instead of the default HTTPS connection. 60 | type: bool 61 | default: yes 62 | use_proxy: 63 | description: 64 | - If C(no), will not use the proxy as defined by system environment variable. 65 | type: bool 66 | default: yes 67 | proxy: 68 | description: 69 | - If use_proxy is no, specfies proxy to be used for connection. 70 | e.g. 'http://proxy.xy.z:8080' 71 | type: str 72 | ''' 73 | -------------------------------------------------------------------------------- /plugins/module_utils/ucs.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 | # (c) 2019 Cisco Systems Inc. 9 | # 10 | # Redistribution and use in source and binary forms, with or without modification, 11 | # are permitted provided that the following conditions are met: 12 | # 13 | # * Redistributions of source code must retain the above copyright 14 | # notice, this list of conditions and the following disclaimer. 15 | # * Redistributions in binary form must reproduce the above copyright notice, 16 | # this list of conditions and the following disclaimer in the documentation 17 | # and/or other materials provided with the distribution. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 27 | # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | from __future__ import (absolute_import, division, print_function) 31 | __metaclass__ = type 32 | import traceback 33 | 34 | from ansible.module_utils.basic import missing_required_lib 35 | 36 | UCSMSDK_IMP_ERR = None 37 | try: 38 | # import done here to provide common import check for all modules 39 | # pylint: disable=unused-import 40 | import ucsmsdk 41 | HAS_UCSMSDK = True 42 | except Exception: 43 | UCSMSDK_IMP_ERR = traceback.format_exc() 44 | HAS_UCSMSDK = False 45 | 46 | ucs_argument_spec = dict( 47 | hostname=dict(type='str', required=True), 48 | username=dict(type='str', default='admin'), 49 | password=dict(type='str', required=True, no_log=True), 50 | port=dict(type='int', default=None), 51 | use_ssl=dict(type='bool', default=True), 52 | use_proxy=dict(type='bool', default=True), 53 | proxy=dict(type='str', default=None), 54 | ) 55 | 56 | 57 | class UCSModule(): 58 | 59 | def __init__(self, module): 60 | self.module = module 61 | self.result = {} 62 | if not HAS_UCSMSDK: 63 | self.module.fail_json(msg=missing_required_lib('ucsmsdk'), exception=UCSMSDK_IMP_ERR) 64 | self.login() 65 | 66 | def __del__(self): 67 | self.logout() 68 | 69 | def login(self): 70 | from ucsmsdk.ucshandle import UcsHandle 71 | 72 | # use_proxy=yes (default) and proxy=None (default) should be using the system defined proxy 73 | # use_proxy=yes (default) and proxy=value should use the provided proxy 74 | # use_proxy=no (user) should not be using a proxy 75 | if self.module.params['use_proxy']: 76 | proxy = self.module.params['proxy'] 77 | else: 78 | # force no proxy to be used. Note that proxy=None in UcsHandle will 79 | # use the system proxy so we must set to something else 80 | proxy = {} 81 | 82 | try: 83 | handle = UcsHandle( 84 | ip=self.module.params['hostname'], 85 | username=self.module.params['username'], 86 | password=self.module.params['password'], 87 | port=self.module.params['port'], 88 | secure=self.module.params['use_ssl'], 89 | proxy=proxy 90 | ) 91 | handle.login() 92 | except Exception as e: 93 | self.result['msg'] = str(e) 94 | self.module.fail_json(**self.result) 95 | self.login_handle = handle 96 | 97 | def logout(self): 98 | if hasattr(self, 'login_handle'): 99 | self.login_handle.logout() 100 | return True 101 | return False 102 | -------------------------------------------------------------------------------- /plugins/modules/ucs_dns_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_dns_server 16 | short_description: Configure DNS servers on Cisco UCS Manager 17 | description: 18 | - Configure DNS servers on Cisco UCS Manager. 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | state: 22 | description: 23 | - If C(absent), will remove a DNS server. 24 | - If C(present), will add or update a DNS server. 25 | choices: [absent, present] 26 | default: present 27 | type: str 28 | 29 | dns_server: 30 | description: 31 | - DNS server IP address. 32 | - Enter a valid IPV4 Address. 33 | - UCS Manager supports up to 4 DNS Servers 34 | aliases: [ name ] 35 | type: str 36 | 37 | description: 38 | description: 39 | - A user-defined description of the DNS server. 40 | - Enter up to 256 characters. 41 | - "You can use any characters or spaces except the following:" 42 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)." 43 | aliases: [ descr ] 44 | type: str 45 | 46 | delegate_to: 47 | description: 48 | - Where the module will be run 49 | default: localhost 50 | type: str 51 | 52 | requirements: 53 | - ucsmsdk 54 | 55 | author: 56 | - David Soper (@dsoper2) 57 | - John McDonough (@movinalot) 58 | - CiscoUcs (@CiscoUcs) 59 | ''' 60 | 61 | EXAMPLES = r''' 62 | - name: Configure DNS server 63 | cisco.ucs.ucs_dns_server: 64 | hostname: 172.16.143.150 65 | username: admin 66 | password: password 67 | dns_server: 10.10.10.10 68 | description: DNS Server IP address 69 | state: present 70 | delegate_to: localhost 71 | 72 | - name: Remove DNS server 73 | cisco.ucs.ucs_dns_server: 74 | hostname: 172.16.143.150 75 | username: admin 76 | password: password 77 | dns_server: 10.10.10.10 78 | state: absent 79 | delegate_to: localhost 80 | ''' 81 | 82 | RETURN = r''' 83 | # 84 | ''' 85 | 86 | from ansible.module_utils.basic import AnsibleModule 87 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 88 | 89 | 90 | def run_module(): 91 | argument_spec = ucs_argument_spec.copy() 92 | argument_spec.update( 93 | dns_server=dict(type='str', aliases=['name']), 94 | description=dict(type='str', aliases=['descr']), 95 | state=dict(type='str', default='present', choices=['present', 'absent']), 96 | delegate_to=dict(type='str', default='localhost'), 97 | ) 98 | 99 | module = AnsibleModule( 100 | argument_spec, 101 | supports_check_mode=True, 102 | required_if=[ 103 | ['state', 'present', ['dns_server']], 104 | ], 105 | ) 106 | # UCSModule verifies ucsmsdk is present and exits on failure. 107 | # Imports are below for UCS object creation. 108 | ucs = UCSModule(module) 109 | from ucsmsdk.mometa.comm.CommDnsProvider import CommDnsProvider 110 | 111 | err = False 112 | changed = False 113 | 114 | try: 115 | mo_exists = False 116 | props_match = False 117 | 118 | dn = 'sys/svc-ext/dns-svc/dns-' + module.params['dns_server'] 119 | 120 | mo = ucs.login_handle.query_dn(dn) 121 | if mo: 122 | mo_exists = True 123 | 124 | if module.params['state'] == 'absent': 125 | if mo_exists: 126 | if not module.check_mode: 127 | ucs.login_handle.remove_mo(mo) 128 | ucs.login_handle.commit() 129 | changed = True 130 | else: 131 | if mo_exists: 132 | # check top-level mo props 133 | kwargs = dict(descr=module.params['description']) 134 | if mo.check_prop_match(**kwargs): 135 | props_match = True 136 | 137 | if not props_match: 138 | if not module.check_mode: 139 | # update/add mo 140 | mo = CommDnsProvider(parent_mo_or_dn='sys/svc-ext/dns-svc', 141 | name=module.params['dns_server'], 142 | descr=module.params['description']) 143 | ucs.login_handle.add_mo(mo, modify_present=True) 144 | ucs.login_handle.commit() 145 | changed = True 146 | 147 | except Exception as e: 148 | err = True 149 | ucs.result['msg'] = "setup error: %s " % str(e) 150 | 151 | ucs.result['changed'] = changed 152 | if err: 153 | module.fail_json(**ucs.result) 154 | module.exit_json(**ucs.result) 155 | 156 | 157 | def main(): 158 | run_module() 159 | 160 | 161 | if __name__ == '__main__': 162 | main() 163 | -------------------------------------------------------------------------------- /plugins/modules/ucs_graphics_card_policy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | ANSIBLE_METADATA = {'metadata_version': '1.1', 11 | 'status': ['preview'], 12 | 'supported_by': 'community'} 13 | 14 | DOCUMENTATION = r''' 15 | --- 16 | module: ucs_graphics_card_policy 17 | 18 | short_description: Manages UCS Graphics Card Policies on UCS Manager 19 | 20 | description: 21 | - Manages UCS Graphics Card Policies on UCS Manager. 22 | 23 | extends_documentation_fragment: cisco.ucs.ucs 24 | 25 | options: 26 | state: 27 | description: 28 | - If C(absent), will remove organization. 29 | - If C(present), will create or update organization. 30 | choices: [absent, present] 31 | default: present 32 | type: str 33 | 34 | name: 35 | description: 36 | - The name of the organization. 37 | - Enter up to 16 characters. 38 | - "You can use any characters or spaces except the following:" 39 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote)" 40 | - "= (equal sign), > (greater than), < (less than), ' (single quote)." 41 | required: true 42 | type: str 43 | 44 | description: 45 | description: 46 | - A user-defined description of the organization. 47 | - Enter up to 256 characters. 48 | - "You can use any characters or spaces except the following:" 49 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote)" 50 | - "= (equal sign), > (greater than), < (less than), ' (single quote)." 51 | aliases: [ descr ] 52 | type: str 53 | 54 | graphics_card_mode: 55 | description: 56 | - Set the Graphics Card Mode. 57 | choices: [any-configuration, compute, graphics] 58 | type: str 59 | 60 | org_dn: 61 | description: 62 | - Org dn (distinguished name) 63 | default: org-root 64 | type: str 65 | 66 | requirements: 67 | - ucsmsdk 68 | 69 | author: 70 | - John McDonough (@movinalot) 71 | ''' 72 | 73 | EXAMPLES = r''' 74 | - name: Add UCS Graphics Card Policy 75 | cisco.ucs.ucs_graphics_card_policy: 76 | hostname: "{{ ucs_hostname }}" 77 | username: "{{ ucs_username }}" 78 | password: "{{ ucs_password }}" 79 | state: present 80 | description: Any Graphics Mode Policy 81 | name: any_graphics 82 | graphics_card_mode: any-configuration 83 | delegate_to: localhost 84 | 85 | - name: Add UCS Graphics Card Policy in an Organization 86 | cisco.ucs.ucs_graphics_card_policy: 87 | hostname: "{{ ucs_hostname }}" 88 | username: "{{ ucs_username }}" 89 | password: "{{ ucs_password }}" 90 | state: present 91 | org_dn: org-root/org-prod 92 | description: Any Graphics Mode Policy 93 | name: prod_graphics 94 | graphics_card_mode: any-configuration 95 | delegate_to: localhost 96 | 97 | - name: Update UCS Graphics Card Policy in an Organization 98 | cisco.ucs.ucs_graphics_card_policy: 99 | hostname: "{{ ucs_hostname }}" 100 | username: "{{ ucs_username }}" 101 | password: "{{ ucs_password }}" 102 | state: present 103 | org_dn: org-root/org-prod 104 | description: Graphics Mode Policy 105 | name: prod_graphics 106 | graphics_card_mode: graphics 107 | delegate_to: localhost 108 | 109 | - name: Update UCS Graphics Card Policy in an Organization 110 | cisco.ucs.ucs_graphics_card_policy: 111 | hostname: "{{ ucs_hostname }}" 112 | username: "{{ ucs_username }}" 113 | password: "{{ ucs_password }}" 114 | state: present 115 | org_dn: org-root/org-prod 116 | description: Compute Mode Policy 117 | name: prod_graphics 118 | graphics_card_mode: compute 119 | delegate_to: localhost 120 | 121 | - name: Delete UCS Graphics Card Policy in an Organization 122 | cisco.ucs.ucs_graphics_card_policy: 123 | hostname: "{{ ucs_hostname }}" 124 | username: "{{ ucs_username }}" 125 | password: "{{ ucs_password }}" 126 | state: absent 127 | org_dn: org-root/org-prod 128 | name: prod_graphics 129 | delegate_to: localhost 130 | 131 | - name: Delete UCS Graphics Card Policy 132 | cisco.ucs.ucs_graphics_card_policy: 133 | hostname: "{{ ucs_hostname }}" 134 | username: "{{ ucs_username }}" 135 | password: "{{ ucs_password }}" 136 | state: absent 137 | name: any_graphics 138 | delegate_to: localhost 139 | ''' 140 | 141 | RETURN = r''' 142 | # 143 | ''' 144 | 145 | from ansible.module_utils.basic import AnsibleModule 146 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import ( 147 | UCSModule, 148 | ucs_argument_spec 149 | ) 150 | 151 | 152 | def main(): 153 | argument_spec = ucs_argument_spec.copy() 154 | argument_spec.update( 155 | org_dn=dict(type='str', default='org-root'), 156 | name=dict(required=True, type='str'), 157 | description=dict(type='str', aliases=['descr']), 158 | graphics_card_mode=dict(type='str', choices=[ 159 | 'any-configuration', 160 | 'compute', 161 | 'graphics' 162 | ]), 163 | state=dict( 164 | type='str', default='present', 165 | choices=['present', 'absent'] 166 | ), 167 | ) 168 | 169 | module = AnsibleModule( 170 | argument_spec, 171 | supports_check_mode=True, 172 | required_if=[ 173 | ['state', 'present', ['name']], 174 | ], 175 | ) 176 | 177 | # UCSModule verifies ucsmsdk is present and exits on failure. 178 | # Imports are below for UCS object creation. 179 | ucs = UCSModule(module) 180 | from importlib import import_module 181 | from ucsmsdk.ucscoreutils import get_meta_info 182 | 183 | # The Class(es) this module is managing 184 | module_file = 'ucsmsdk.mometa.compute.ComputeGraphicsCardPolicy' 185 | module_class = 'ComputeGraphicsCardPolicy' 186 | mo_module = import_module(module_file) 187 | mo_class = getattr(mo_module, module_class) 188 | 189 | META = get_meta_info(class_id=module_class) 190 | 191 | err = False 192 | changed = False 193 | requested_state = module.params['state'] 194 | 195 | kwargs = dict() 196 | 197 | # Manage Attributes 198 | for attribute in [ 199 | 'graphics_card_mode', 'description']: 200 | if module.params[attribute] is not None: 201 | kwargs[attribute] = module.params[attribute] 202 | 203 | try: 204 | dn = ( 205 | module.params['org_dn'] + '/' + 206 | META.rn[0:META.rn.rindex('-') + 1] + 207 | module.params['name'] 208 | ) 209 | mo = ucs.login_handle.query_dn(dn) 210 | 211 | # Determine state change 212 | if mo: 213 | # Object exists, if it should exist has anything changed? 214 | if requested_state == 'present': 215 | # Do some or all Object properties not match, that is a change 216 | 217 | if not mo.check_prop_match(**kwargs): 218 | changed = True 219 | 220 | # Object does not exist but should, that is a change 221 | else: 222 | if requested_state == 'present': 223 | changed = True 224 | 225 | # Object exists but should not, that is a change 226 | if mo and requested_state == 'absent': 227 | changed = True 228 | 229 | # Apply state if not check_mode 230 | if changed and not module.check_mode: 231 | if requested_state == 'absent': 232 | ucs.login_handle.remove_mo(mo) 233 | else: 234 | kwargs['parent_mo_or_dn'] = module.params['org_dn'] 235 | kwargs['name'] = module.params['name'] 236 | 237 | mo = mo_class(**kwargs) 238 | ucs.login_handle.add_mo(mo, modify_present=True) 239 | ucs.login_handle.commit() 240 | 241 | except Exception as e: 242 | err = True 243 | ucs.result['msg'] = "setup error: %s " % str(e) 244 | 245 | ucs.result['changed'] = changed 246 | if err: 247 | module.fail_json(**ucs.result) 248 | 249 | module.exit_json(**ucs.result) 250 | 251 | 252 | if __name__ == '__main__': 253 | main() 254 | -------------------------------------------------------------------------------- /plugins/modules/ucs_mac_pool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'certified'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_mac_pool 16 | short_description: Configures MAC address pools on Cisco UCS Manager 17 | description: 18 | - Configures MAC address pools and MAC address blocks on Cisco UCS Manager. 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | state: 22 | description: 23 | - If C(present), will verify MAC pool is present and will create if needed. 24 | - If C(absent), will verify MAC pool is absent and will delete if needed. 25 | choices: [present, absent] 26 | default: present 27 | type: str 28 | name: 29 | description: 30 | - The name of the MAC pool. 31 | - This name can be between 1 and 32 alphanumeric characters. 32 | - "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)." 33 | - You cannot change this name after the MAC pool is created. 34 | required: true 35 | type: str 36 | description: 37 | description: 38 | - A description of the MAC pool. 39 | - Enter up to 256 characters. 40 | - "You can use any characters or spaces except the following:" 41 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)." 42 | aliases: [ descr ] 43 | type: str 44 | order: 45 | description: 46 | - The Assignment Order field. 47 | - "This can be one of the following:" 48 | - "default - Cisco UCS Manager selects a random identity from the pool." 49 | - "sequential - Cisco UCS Manager selects the lowest available identity from the pool." 50 | choices: [default, sequential] 51 | default: default 52 | type: str 53 | first_addr: 54 | description: 55 | - The first MAC address in the block of addresses. 56 | - This is the From field in the UCS Manager MAC Blocks menu. 57 | type: str 58 | last_addr: 59 | description: 60 | - The last MAC address in the block of addresses. 61 | - This is the To field in the UCS Manager Add MAC Blocks menu. 62 | type: str 63 | org_dn: 64 | description: 65 | - The distinguished name (dn) of the organization where the resource is assigned. 66 | default: org-root 67 | type: str 68 | requirements: 69 | - ucsmsdk 70 | author: 71 | - David Soper (@dsoper2) 72 | - CiscoUcs (@CiscoUcs) 73 | ''' 74 | 75 | EXAMPLES = r''' 76 | - name: Configure MAC address pool 77 | cisco.ucs.ucs_mac_pool: 78 | hostname: 172.16.143.150 79 | username: admin 80 | password: password 81 | name: mac-A 82 | first_addr: 00:25:B5:00:66:00 83 | last_addr: 00:25:B5:00:67:F3 84 | order: sequential 85 | 86 | - name: Remove MAC address pool 87 | cisco.ucs.ucs_mac_pool: 88 | hostname: 172.16.143.150 89 | username: admin 90 | password: password 91 | name: mac-A 92 | state: absent 93 | ''' 94 | 95 | RETURN = r''' 96 | # 97 | ''' 98 | 99 | from ansible.module_utils.basic import AnsibleModule 100 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 101 | 102 | 103 | def main(): 104 | argument_spec = ucs_argument_spec.copy() 105 | argument_spec.update( 106 | org_dn=dict(type='str', default='org-root'), 107 | name=dict(type='str', required=True), 108 | description=dict(type='str', aliases=['descr']), 109 | order=dict(type='str', default='default', choices=['default', 'sequential']), 110 | first_addr=dict(type='str'), 111 | last_addr=dict(type='str'), 112 | state=dict(default='present', choices=['present', 'absent'], type='str'), 113 | ) 114 | module = AnsibleModule( 115 | argument_spec, 116 | supports_check_mode=True, 117 | ) 118 | # UCSModule verifies ucsmsdk is present and exits on failure. Imports are below ucs object creation. 119 | ucs = UCSModule(module) 120 | 121 | err = False 122 | 123 | from ucsmsdk.mometa.macpool.MacpoolPool import MacpoolPool 124 | from ucsmsdk.mometa.macpool.MacpoolBlock import MacpoolBlock 125 | 126 | changed = False 127 | try: 128 | mo_exists = False 129 | props_match = False 130 | # dn is /mac-pool- 131 | dn = module.params['org_dn'] + '/mac-pool-' + module.params['name'] 132 | mo = ucs.login_handle.query_dn(dn) 133 | if mo: 134 | mo_exists = True 135 | 136 | if module.params['state'] == 'absent': 137 | if mo_exists: 138 | if not module.check_mode: 139 | ucs.login_handle.remove_mo(mo) 140 | ucs.login_handle.commit() 141 | changed = True 142 | else: 143 | if mo_exists: 144 | # check top-level mo props 145 | kwargs = dict(assignment_order=module.params['order']) 146 | kwargs['descr'] = module.params['description'] 147 | if mo.check_prop_match(**kwargs): 148 | # top-level props match, check next level mo/props 149 | if module.params['last_addr'] and module.params['first_addr']: 150 | # mac address block specified, check properties 151 | block_dn = dn + '/block-' + module.params['first_addr'].upper() + '-' + module.params['last_addr'].upper() 152 | mo_1 = ucs.login_handle.query_dn(block_dn) 153 | if mo_1: 154 | props_match = True 155 | else: 156 | # no MAC address block specified, but top-level props matched 157 | props_match = True 158 | 159 | if not props_match: 160 | if not module.check_mode: 161 | # create if mo does not already exist 162 | mo = MacpoolPool( 163 | parent_mo_or_dn=module.params['org_dn'], 164 | name=module.params['name'], 165 | descr=module.params['description'], 166 | assignment_order=module.params['order'], 167 | ) 168 | 169 | if module.params['last_addr'] and module.params['first_addr']: 170 | mo_1 = MacpoolBlock( 171 | parent_mo_or_dn=mo, 172 | to=module.params['last_addr'], 173 | r_from=module.params['first_addr'], 174 | ) 175 | 176 | ucs.login_handle.add_mo(mo, True) 177 | ucs.login_handle.commit() 178 | changed = True 179 | 180 | except Exception as e: 181 | err = True 182 | ucs.result['msg'] = "setup error: %s " % str(e) 183 | 184 | ucs.result['changed'] = changed 185 | if err: 186 | module.fail_json(**ucs.result) 187 | module.exit_json(**ucs.result) 188 | 189 | 190 | if __name__ == '__main__': 191 | main() 192 | -------------------------------------------------------------------------------- /plugins/modules/ucs_ntp_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'certified'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_ntp_server 16 | short_description: Configures NTP server on Cisco UCS Manager 17 | extends_documentation_fragment: cisco.ucs.ucs 18 | description: 19 | - Configures NTP server on Cisco UCS Manager. 20 | options: 21 | state: 22 | description: 23 | - If C(absent), will remove an NTP server. 24 | - If C(present), will add or update an NTP server. 25 | choices: [absent, present] 26 | default: present 27 | type: str 28 | 29 | ntp_server: 30 | description: 31 | - NTP server IP address or hostname. 32 | - Enter up to 63 characters that form a valid hostname. 33 | - Enter a valid IPV4 Address. 34 | aliases: [ name ] 35 | type: str 36 | 37 | description: 38 | description: 39 | - A user-defined description of the NTP server. 40 | - Enter up to 256 characters. 41 | - "You can use any characters or spaces except the following:" 42 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)." 43 | aliases: [ descr ] 44 | type: str 45 | 46 | requirements: 47 | - ucsmsdk 48 | author: 49 | - David Soper (@dsoper2) 50 | - John McDonough (@movinalot) 51 | - CiscoUcs (@CiscoUcs) 52 | ''' 53 | 54 | EXAMPLES = r''' 55 | - name: Configure NTP server 56 | cisco.ucs.ucs_ntp_server: 57 | hostname: 172.16.143.150 58 | username: admin 59 | password: password 60 | ntp_server: 10.10.10.10 61 | description: Internal NTP Server by IP address 62 | state: present 63 | 64 | - name: Configure NTP server 65 | cisco.ucs.ucs_ntp_server: 66 | hostname: 172.16.143.150 67 | username: admin 68 | password: password 69 | ntp_server: pool.ntp.org 70 | description: External NTP Server by hostname 71 | state: present 72 | 73 | - name: Remove NTP server 74 | cisco.ucs.ucs_ntp_server: 75 | hostname: 172.16.143.150 76 | username: admin 77 | password: password 78 | ntp_server: 10.10.10.10 79 | state: absent 80 | 81 | - name: Remove NTP server 82 | cisco.ucs.ucs_ntp_server: 83 | hostname: 172.16.143.150 84 | username: admin 85 | password: password 86 | ntp_server: pool.ntp.org 87 | state: absent 88 | ''' 89 | 90 | RETURN = r''' 91 | # 92 | ''' 93 | 94 | from ansible.module_utils.basic import AnsibleModule 95 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 96 | 97 | 98 | def run_module(): 99 | argument_spec = ucs_argument_spec.copy() 100 | argument_spec.update( 101 | ntp_server=dict(type='str', aliases=['name']), 102 | description=dict(type='str', aliases=['descr']), 103 | state=dict(type='str', default='present', choices=['present', 'absent']), 104 | ) 105 | 106 | module = AnsibleModule( 107 | argument_spec, 108 | supports_check_mode=True, 109 | required_if=[ 110 | ['state', 'present', ['ntp_server']], 111 | ], 112 | ) 113 | # UCSModule verifies ucsmsdk is present and exits on failure. Imports are below ucs object creation. 114 | ucs = UCSModule(module) 115 | 116 | err = False 117 | 118 | from ucsmsdk.mometa.comm.CommNtpProvider import CommNtpProvider 119 | 120 | changed = False 121 | try: 122 | mo_exists = False 123 | props_match = False 124 | 125 | dn = 'sys/svc-ext/datetime-svc/ntp-' + module.params['ntp_server'] 126 | 127 | mo = ucs.login_handle.query_dn(dn) 128 | if mo: 129 | mo_exists = True 130 | 131 | if module.params['state'] == 'absent': 132 | if mo_exists: 133 | if not module.check_mode: 134 | ucs.login_handle.remove_mo(mo) 135 | ucs.login_handle.commit() 136 | changed = True 137 | else: 138 | if mo_exists: 139 | # check top-level mo props 140 | kwargs = dict(descr=module.params['description']) 141 | if mo.check_prop_match(**kwargs): 142 | props_match = True 143 | 144 | if not props_match: 145 | if not module.check_mode: 146 | # update/add mo 147 | mo = CommNtpProvider(parent_mo_or_dn='sys/svc-ext/datetime-svc', 148 | name=module.params['ntp_server'], 149 | descr=module.params['description']) 150 | ucs.login_handle.add_mo(mo, modify_present=True) 151 | ucs.login_handle.commit() 152 | changed = True 153 | 154 | except Exception as e: 155 | err = True 156 | ucs.result['msg'] = "setup error: %s " % str(e) 157 | 158 | ucs.result['changed'] = changed 159 | if err: 160 | module.fail_json(**ucs.result) 161 | module.exit_json(**ucs.result) 162 | 163 | 164 | def main(): 165 | run_module() 166 | 167 | 168 | if __name__ == '__main__': 169 | main() 170 | -------------------------------------------------------------------------------- /plugins/modules/ucs_org.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | ANSIBLE_METADATA = {'metadata_version': '1.1', 11 | 'status': ['preview'], 12 | 'supported_by': 'community'} 13 | 14 | DOCUMENTATION = r''' 15 | --- 16 | module: ucs_org 17 | 18 | short_description: Manages UCS Organizations for UCS Manager 19 | 20 | description: 21 | - Manages UCS Organizations for UCS Manager. 22 | 23 | extends_documentation_fragment: cisco.ucs.ucs 24 | 25 | options: 26 | state: 27 | description: 28 | - If C(absent), will remove organization. 29 | - If C(present), will create or update organization. 30 | choices: [absent, present] 31 | default: present 32 | type: str 33 | 34 | org_name: 35 | description: 36 | - The name of the organization. 37 | - Enter up to 16 characters. 38 | - "You can use any characters or spaces except the following:" 39 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)." 40 | aliases: [ name ] 41 | type: str 42 | 43 | parent_org_path: 44 | description: 45 | - A forward slash / separated hierarchical path from the root organization to the parent of the organization to be added or updated. 46 | - UCS Manager supports a hierarchical structure of organizations up to five levels deep not including the root organization. 47 | - For example the parent_org_path for an organization named level5 could be root/level1/level2/level3/level4 48 | default: root 49 | type: str 50 | 51 | description: 52 | description: 53 | - A user-defined description of the organization. 54 | - Enter up to 256 characters. 55 | - "You can use any characters or spaces except the following:" 56 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)." 57 | aliases: [ descr ] 58 | type: str 59 | 60 | delegate_to: 61 | description: 62 | - Where the module will be run 63 | default: localhost 64 | type: str 65 | 66 | requirements: 67 | - ucsmsdk 68 | 69 | author: 70 | - David Soper (@dsoper2) 71 | - John McDonough (@movinalot) 72 | - CiscoUcs (@CiscoUcs) 73 | ''' 74 | 75 | EXAMPLES = r''' 76 | - name: Add UCS Organization 77 | cisco.ucs.ucs_org: 78 | hostname: "{{ ucs_hostname }}" 79 | username: "{{ ucs_username }}" 80 | password: "{{ ucs_password }}" 81 | org_name: test 82 | description: testing org 83 | state: present 84 | delegate_to: localhost 85 | 86 | - name: Update UCS Organization 87 | cisco.ucs.ucs_org: 88 | hostname: "{{ ucs_hostname }}" 89 | username: "{{ ucs_username }}" 90 | password: "{{ ucs_password }}" 91 | org_name: test 92 | description: Testing org 93 | state: present 94 | delegate_to: localhost 95 | 96 | - name: Add UCS Organization 97 | cisco.ucs.ucs_org: 98 | hostname: "{{ ucs_hostname }}" 99 | username: "{{ ucs_username }}" 100 | password: "{{ ucs_password }}" 101 | org_name: level1 102 | parent_org_path: root 103 | description: level1 org 104 | state: present 105 | delegate_to: localhost 106 | 107 | - name: Add UCS Organization 108 | cisco.ucs.ucs_org: 109 | hostname: "{{ ucs_hostname }}" 110 | username: "{{ ucs_username }}" 111 | password: "{{ ucs_password }}" 112 | org_name: level2 113 | parent_org_path: root/level1 114 | description: level2 org 115 | state: present 116 | 117 | - name: Add UCS Organization 118 | cisco.ucs.ucs_org: 119 | hostname: "{{ ucs_hostname }}" 120 | username: "{{ ucs_username }}" 121 | password: "{{ ucs_password }}" 122 | org_name: level3 123 | parent_org_path: root/level1/level2 124 | description: level3 org 125 | state: present 126 | 127 | - name: Remove UCS Organization 128 | cisco.ucs.ucs_org: 129 | hostname: "{{ ucs_hostname }}" 130 | username: "{{ ucs_username }}" 131 | password: "{{ ucs_password }}" 132 | org_name: level2 133 | parent_org_path: root/level1 134 | state: absent 135 | ''' 136 | 137 | RETURN = r''' 138 | # 139 | ''' 140 | 141 | from ansible.module_utils.basic import AnsibleModule 142 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 143 | 144 | 145 | def main(): 146 | argument_spec = ucs_argument_spec.copy() 147 | argument_spec.update( 148 | org_name=dict(type='str', aliases=['name']), 149 | parent_org_path=dict(type='str', default='root'), 150 | description=dict(type='str', aliases=['descr']), 151 | state=dict(type='str', default='present', choices=['present', 'absent']), 152 | delegate_to=dict(type='str', default='localhost'), 153 | ) 154 | 155 | module = AnsibleModule( 156 | argument_spec, 157 | supports_check_mode=True, 158 | required_if=[ 159 | ['state', 'present', ['org_name']], 160 | ], 161 | ) 162 | 163 | # UCSModule verifies ucsmsdk is present and exits on failure. 164 | # Imports are below for UCS object creation. 165 | ucs = UCSModule(module) 166 | from ucsmsdk.mometa.org.OrgOrg import OrgOrg 167 | 168 | err = False 169 | changed = False 170 | requested_state = module.params['state'] 171 | 172 | kwargs = dict() 173 | 174 | if module.params['description'] is not None: 175 | kwargs['descr'] = module.params['description'] 176 | 177 | try: 178 | parent_org_dn = 'org-' + module.params['parent_org_path'].replace('/', '/org-') 179 | dn = parent_org_dn + '/org-' + module.params['org_name'] 180 | 181 | mo = ucs.login_handle.query_dn(dn) 182 | 183 | # Determine state change 184 | if mo: 185 | # Object exists, if it should exist has anything changed? 186 | if requested_state == 'present': 187 | # Do some or all Object properties not match, that is a change 188 | if not mo.check_prop_match(**kwargs): 189 | changed = True 190 | 191 | # Object does not exist but should, that is a change 192 | else: 193 | if requested_state == 'present': 194 | changed = True 195 | 196 | # Object exists but should not, that is a change 197 | if mo and requested_state == 'absent': 198 | changed = True 199 | 200 | # Apply state if not check_mode 201 | if changed and not module.check_mode: 202 | if requested_state == 'absent': 203 | ucs.login_handle.remove_mo(mo) 204 | else: 205 | kwargs['parent_mo_or_dn'] = parent_org_dn 206 | kwargs['name'] = module.params['org_name'] 207 | if module.params['description'] is not None: 208 | kwargs['descr'] = module.params['description'] 209 | 210 | mo = OrgOrg(**kwargs) 211 | ucs.login_handle.add_mo(mo, modify_present=True) 212 | ucs.login_handle.commit() 213 | 214 | except Exception as e: 215 | err = True 216 | ucs.result['msg'] = "setup error: %s " % str(e) 217 | 218 | ucs.result['changed'] = changed 219 | if err: 220 | module.fail_json(**ucs.result) 221 | 222 | module.exit_json(**ucs.result) 223 | 224 | 225 | if __name__ == '__main__': 226 | main() 227 | -------------------------------------------------------------------------------- /plugins/modules/ucs_query.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_query 16 | 17 | short_description: Queries UCS Manager objects by class or distinguished name 18 | 19 | description: 20 | -Queries UCS Manager objects by class or distinguished name. 21 | 22 | extends_documentation_fragment: cisco.ucs.ucs 23 | 24 | options: 25 | class_ids: 26 | description: 27 | - One or more UCS Manager Class IDs to query. 28 | - As a comma separated list 29 | type: str 30 | 31 | distinguished_names: 32 | description: 33 | - One or more UCS Manager Distinguished Names to query. 34 | - As a comma separated list 35 | type: str 36 | 37 | delegate_to: 38 | description: 39 | - Where the module will be run 40 | default: localhost 41 | type: str 42 | 43 | requirements: 44 | - ucsmsdk 45 | 46 | author: 47 | - John McDonough (@movinalot) 48 | - CiscoUcs (@CiscoUcs) 49 | ''' 50 | 51 | EXAMPLES = r''' 52 | - name: Query UCS Class ID 53 | cisco.ucs.ucs_query: 54 | hostname: "{{ ucs_hostname }}" 55 | username: "{{ ucs_username }}" 56 | password: "{{ ucs_password }}" 57 | class_ids: computeBlade 58 | delegate_to: localhost 59 | 60 | - name: Query UCS Class IDs 61 | cisco.ucs.ucs_query: 62 | hostname: "{{ ucs_hostname }}" 63 | username: "{{ ucs_username }}" 64 | password: "{{ ucs_password }}" 65 | class_ids: computeBlade, fabricVlan 66 | delegate_to: localhost 67 | 68 | - name: Query UCS Distinguished Name 69 | cisco.ucs.ucs_query: 70 | hostname: "{{ ucs_hostname }}" 71 | username: "{{ ucs_username }}" 72 | password: "{{ ucs_password }}" 73 | distinguished_names: org-root 74 | delegate_to: localhost 75 | 76 | - name: Query UCS Distinguished Names 77 | cisco.ucs.ucs_query: 78 | hostname: "{{ ucs_hostname }}" 79 | username: "{{ ucs_username }}" 80 | password: "{{ ucs_password }}" 81 | distinguished_names: org-root, sys/rack-unit-1, sys/chassis-1/blade-2 82 | delegate_to: localhost 83 | ''' 84 | 85 | RETURN = r''' 86 | objects: 87 | description: results JSON encodded 88 | returned: always 89 | type: dict 90 | ''' 91 | 92 | from ansible.module_utils.basic import AnsibleModule 93 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 94 | 95 | 96 | def retrieve_class_id(class_id, ucs): 97 | return ucs.login_handle.query_classid(class_id) 98 | 99 | 100 | def retrieve_distinguished_name(distinguished_name, ucs): 101 | return ucs.login_handle.query_dn(distinguished_name) 102 | 103 | 104 | def make_mo_dict(ucs_mo): 105 | obj_dict = {} 106 | for mo_property in ucs_mo.prop_map.values(): 107 | obj_dict[mo_property] = getattr(ucs_mo, mo_property) 108 | return obj_dict 109 | 110 | 111 | def main(): 112 | argument_spec = ucs_argument_spec.copy() 113 | argument_spec.update( 114 | class_ids=dict(type='str'), 115 | distinguished_names=dict(type='str'), 116 | delegate_to=dict(type='str', default='localhost'), 117 | ) 118 | 119 | module = AnsibleModule( 120 | argument_spec, 121 | supports_check_mode=False, 122 | mutually_exclusive=[ 123 | ['class_ids', 'distinguished_names'], 124 | ], 125 | ) 126 | 127 | # UCSModule verifies ucsmsdk is present and exits on failure. 128 | # Imports are below for UCS object creation. 129 | ucs = UCSModule(module) 130 | err = False 131 | query_result = {} 132 | 133 | try: 134 | if module.params['class_ids']: 135 | class_ids = [ 136 | x.strip() for x in module.params['class_ids'].split(',') 137 | ] 138 | for class_id in class_ids: 139 | query_result[class_id] = [] 140 | ucs_mos = retrieve_class_id(class_id, ucs) 141 | if ucs_mos: 142 | for ucs_mo in ucs_mos: 143 | query_result[class_id].append(make_mo_dict(ucs_mo)) 144 | 145 | ucs.result['objects'] = query_result 146 | 147 | elif module.params['distinguished_names']: 148 | distinguished_names = [ 149 | x.strip() 150 | for x in module.params['distinguished_names'].split(',') 151 | ] 152 | for distinguished_name in distinguished_names: 153 | query_result[distinguished_name] = {} 154 | ucs_mo = retrieve_distinguished_name(distinguished_name, ucs) 155 | 156 | if ucs_mo: 157 | query_result[distinguished_name] = make_mo_dict(ucs_mo) 158 | 159 | ucs.result['objects'] = query_result 160 | 161 | except Exception as e: 162 | err = True 163 | ucs.result['msg'] = "setup error: %s " % str(e) 164 | 165 | if err: 166 | module.fail_json(**ucs.result) 167 | 168 | module.exit_json(**ucs.result) 169 | 170 | 171 | if __name__ == '__main__': 172 | main() 173 | -------------------------------------------------------------------------------- /plugins/modules/ucs_server_maintenance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | ANSIBLE_METADATA = {'metadata_version': '1.1', 11 | 'status': ['preview'], 12 | 'supported_by': 'community'} 13 | 14 | DOCUMENTATION = r''' 15 | --- 16 | module: ucs_server_maintenance 17 | short_description: Creates Server Maintenance Policy on Cisco UCS Manager 18 | description: 19 | - Configures Server Maintenance Policy on Cisco UCS Manager. 20 | extends_documentation_fragment: cisco.ucs.ucs 21 | options: 22 | state: 23 | description: 24 | - If C(present), will verify Server Maintenance Policy is present and will create if needed. 25 | - If C(absent), will verify Server Maintenance Policy is absent and will delete if needed. 26 | choices: [present, absent] 27 | default: present 28 | type: str 29 | name: 30 | description: 31 | - The name assigned to the Server Maintenance Policy. 32 | - The Server Maintenance Policy name is case sensitive. 33 | - This name can be between 1 and 16 alphanumeric characters. 34 | - "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)." 35 | - You cannot change this name after the Server Maintenance Policy is created. 36 | required: yes 37 | type: str 38 | description: 39 | description: 40 | - A description of the Server Maintenance Package Policy. 41 | - Cisco recommends including information about where and when to use the policy. 42 | - Enter up to 256 characters. 43 | - "You can use any characters or spaces except the following:" 44 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)." 45 | aliases: [ descr ] 46 | type: str 47 | trigger_config: 48 | description: 49 | - This option is used in combination with either User Ack (user-ack) or Timer Automatic (timer-automatic). 50 | - When the On Next Boot option is enabled, the host OS reboot, shutdown, or server reset also triggers the associated FSM to apply the changes. 51 | - Note that de-selecting the On Next Boot option disables the Maintenance Policy on the BMC. 52 | choices: [on-next-boot] 53 | type: str 54 | uptime_disr: 55 | description: 56 | - When a Server profile is associated with a Server, or when changes are made to an associated Server profile, you must reboot the Server. 57 | - The Reboot Policy field determines when the reboot occurs for Server associated with any Server profiles that include this maintenance policy. 58 | choices: [immediate, timer-automatic, user-ack] 59 | required: true 60 | type: str 61 | requirements: 62 | - ucsmsdk 63 | author: 64 | - Brett Johnson (@brettjohnson008) 65 | ''' 66 | 67 | EXAMPLES = r''' 68 | - name: Add Server Maintenance Policy 69 | cisco.ucs.ucs_server_maintenance: 70 | hostname: 172.16.143.150 71 | username: admin 72 | password: password 73 | name: user-ack 74 | uptime_disr: user-ack 75 | trigger_config: on-next-boot 76 | ''' 77 | 78 | RETURN = r''' 79 | # 80 | ''' 81 | 82 | from ansible.module_utils.basic import AnsibleModule 83 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 84 | 85 | 86 | def main(): 87 | argument_spec = ucs_argument_spec.copy() 88 | argument_spec.update( 89 | name=dict(type='str', required=True), 90 | description=dict(type='str', aliases=['descr']), 91 | trigger_config=dict(type='str', choices=['on-next-boot']), 92 | uptime_disr=dict(type='str', required=True, choices=['immediate', 'timer-automatic', 'user-ack']), 93 | state=dict(type='str', default='present', choices=['present', 'absent']), 94 | ) 95 | 96 | module = AnsibleModule( 97 | argument_spec, 98 | supports_check_mode=True, 99 | ) 100 | 101 | ucs = UCSModule(module) 102 | 103 | err = False 104 | 105 | # UCSModule creation above verifies ucsmsdk is present and exits on failure, so additional imports are done below. 106 | from ucsmsdk.mometa.lsmaint.LsmaintMaintPolicy import LsmaintMaintPolicy 107 | 108 | changed = False 109 | try: 110 | mo_exists = False 111 | props_match = False 112 | dn_base = 'org-root' 113 | dn = dn_base + '/maint-' + module.params['name'] 114 | 115 | mo = ucs.login_handle.query_dn(dn) 116 | if mo: 117 | mo_exists = True 118 | 119 | if module.params['state'] == 'absent': 120 | # mo must exist but all properties do not have to match 121 | if mo_exists: 122 | if not module.check_mode: 123 | ucs.login_handle.remove_mo(mo) 124 | ucs.login_handle.commit() 125 | changed = True 126 | else: 127 | if mo_exists: 128 | # check top-level mo props 129 | kwargs = dict(name=module.params['name']) 130 | kwargs['descr'] = module.params['description'] 131 | kwargs['trigger_config'] = module.params['trigger_config'] 132 | kwargs['uptime_disr'] = module.params['uptime_disr'] 133 | if mo.check_prop_match(**kwargs): 134 | props_match = True 135 | 136 | if not props_match: 137 | if not module.check_mode: 138 | # create if mo does not already exist 139 | mo = LsmaintMaintPolicy( 140 | parent_mo_or_dn=dn_base, 141 | name=module.params['name'], 142 | descr=module.params['description'], 143 | trigger_config=module.params['trigger_config'], 144 | uptime_disr=module.params['uptime_disr'], 145 | ) 146 | 147 | ucs.login_handle.add_mo(mo, True) 148 | ucs.login_handle.commit() 149 | changed = True 150 | 151 | except Exception as e: 152 | err = True 153 | ucs.result['msg'] = "setup error: %s " % str(e) 154 | 155 | ucs.result['changed'] = changed 156 | if err: 157 | module.fail_json(**ucs.result) 158 | module.exit_json(**ucs.result) 159 | 160 | 161 | if __name__ == '__main__': 162 | main() 163 | -------------------------------------------------------------------------------- /plugins/modules/ucs_service_profile_from_template.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_service_profile_from_template 16 | short_description: Configures Service Profiles from templates on Cisco UCS Manager 17 | description: 18 | - Configures Service Profile created from templates on Cisco UCS Manager. 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | state: 22 | description: 23 | - If C(present), will verify Service Profiles are present and will create if needed. 24 | - If C(absent), will verify Service Profiles are absent and will delete if needed. 25 | choices: [present, absent] 26 | default: present 27 | type: str 28 | name: 29 | description: 30 | - The name of the service profile. 31 | - This name can be between 2 and 32 alphanumeric characters. 32 | - "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)." 33 | - This name must be unique across all service profiles and service profile templates within the same organization. 34 | required: true 35 | type: str 36 | source_template: 37 | description: 38 | - The name of the service profile template used to create this serivce profile. 39 | required: true 40 | type: str 41 | power_state: 42 | description: 43 | - The power state to be applied when this service profile is associated with a server. 44 | - If no value is provided, the power_state for the service profile will not be modified. 45 | choices: [up, down] 46 | type: str 47 | user_label: 48 | description: 49 | - The User Label you want to assign to this service profile. 50 | type: str 51 | org_dn: 52 | description: 53 | - Org dn (distinguished name) 54 | default: org-root 55 | type: str 56 | description: 57 | description: 58 | - Optional 59 | - The Description of the service profile 60 | type: str 61 | requirements: 62 | - ucsmsdk 63 | author: 64 | - David Soper (@dsoper2) 65 | - CiscoUcs (@CiscoUcs) 66 | ''' 67 | 68 | EXAMPLES = r''' 69 | - name: Configure Service Profile from Template 70 | cisco.ucs.ucs_service_profile_from_template: 71 | hostname: 172.16.143.150 72 | username: admin 73 | password: password 74 | name: test-sp-instance1 75 | source_template: test-sp 76 | discription: Created from Ansible 77 | 78 | - name: Remove Service Profile 79 | cisco.ucs.ucs_service_profile_from_template: 80 | hostname: 172.16.143.150 81 | username: admin 82 | password: password 83 | name: test-sp-instance1 84 | state: absent 85 | ''' 86 | 87 | RETURN = r''' 88 | # 89 | ''' 90 | 91 | from ansible.module_utils.basic import AnsibleModule 92 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 93 | 94 | 95 | def main(): 96 | argument_spec = ucs_argument_spec.copy() 97 | argument_spec.update( 98 | org_dn=dict(type='str', default='org-root'), 99 | name=dict(type='str', required=True), 100 | source_template=dict(type='str', required=True), 101 | user_label=dict(type='str'), 102 | power_state=dict(type='str', choices=['up', 'down']), 103 | state=dict(type='str', default='present', choices=['present', 'absent']), 104 | description=dict(type='str'), 105 | ) 106 | 107 | module = AnsibleModule( 108 | argument_spec, 109 | supports_check_mode=True, 110 | ) 111 | ucs = UCSModule(module) 112 | 113 | err = False 114 | 115 | # UCSModule creation above verifies ucsmsdk is present and exits on failure. Additional imports are done below. 116 | from ucsmsdk.mometa.ls.LsServer import LsServer 117 | from ucsmsdk.mometa.ls.LsPower import LsPower 118 | 119 | changed = False 120 | try: 121 | mo_exists = False 122 | props_match = False 123 | dn = module.params['org_dn'] + '/ls-' + module.params['name'] 124 | 125 | mo = ucs.login_handle.query_dn(dn) 126 | if mo: 127 | mo_exists = True 128 | 129 | if module.params['state'] == 'absent': 130 | # mo must exist but all properties do not have to match 131 | if mo_exists: 132 | if not module.check_mode: 133 | ucs.login_handle.remove_mo(mo) 134 | ucs.login_handle.commit() 135 | changed = True 136 | else: 137 | if mo_exists: 138 | # check top-level mo props 139 | kwargs = dict(src_templ_name=module.params['source_template']) 140 | kwargs['usr_lbl'] = module.params['user_label'] 141 | # service profiles are of type 'instance' 142 | kwargs['type'] = 'instance' 143 | 144 | if mo.check_prop_match(**kwargs): 145 | # top-level props match 146 | if module.params.get('power_state'): 147 | child_dn = dn + '/power' 148 | mo_1 = ucs.login_handle.query_dn(child_dn) 149 | if mo_1: 150 | kwargs = dict(state=module.params['power_state']) 151 | if mo_1.check_prop_match(**kwargs): 152 | props_match = True 153 | else: 154 | # no power state provided, use existing state as match 155 | props_match = True 156 | 157 | if not props_match: 158 | if not module.check_mode: 159 | # create if mo does not already exist 160 | mo = LsServer( 161 | parent_mo_or_dn=module.params['org_dn'], 162 | name=module.params['name'], 163 | src_templ_name=module.params['source_template'], 164 | type='instance', 165 | usr_lbl=module.params['user_label'], 166 | descr=module.params['description'], 167 | ) 168 | if module.params.get('power_state'): 169 | admin_state = 'admin-' + module.params['power_state'] 170 | mo_1 = LsPower( 171 | parent_mo_or_dn=mo, 172 | state=admin_state, 173 | ) 174 | 175 | ucs.login_handle.add_mo(mo, True) 176 | ucs.login_handle.commit() 177 | changed = True 178 | 179 | except Exception as e: 180 | err = True 181 | ucs.result['msg'] = "setup error: %s " % str(e) 182 | 183 | ucs.result['changed'] = changed 184 | if err: 185 | module.fail_json(**ucs.result) 186 | module.exit_json(**ucs.result) 187 | 188 | 189 | if __name__ == '__main__': 190 | main() 191 | -------------------------------------------------------------------------------- /plugins/modules/ucs_sp_vnic_order.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | __metaclass__ = type 9 | 10 | ANSIBLE_METADATA = {'metadata_version': '1.0', 11 | 'status': ['preview'], 12 | 'supported_by': 'community'} 13 | 14 | DOCUMENTATION = r''' 15 | --- 16 | module: ucs_sp_vnic_order 17 | 18 | short_description: Configures vNIC order for service profiles and templates on Cisco UCS Manager 19 | 20 | description: 21 | - Configures Configures vNIC order for service profiles and templates on Cisco UCS Manager 22 | 23 | options: 24 | sp_name: 25 | description: DN of the service profile 26 | required: true 27 | type: str 28 | vnics: 29 | description: List of vNIC order properties 30 | type: list 31 | elements: dict 32 | required: true 33 | suboptions: 34 | name: 35 | description: Name of the vNIC 36 | required: true 37 | type: str 38 | admin_vcon: 39 | description: Name of the virtual connection 40 | choices: ["1","2","3","4","any"] 41 | type: str 42 | order: 43 | description: vNIC connection order. Choices are 0-256 or unspecified. 44 | type: str 45 | transport: 46 | description: transport medium 47 | choices: ["ethernet", "fc"] 48 | required: true 49 | type: str 50 | state: 51 | description: Desired state of the vNIC. 52 | choices: [present, absent] 53 | default: present 54 | type: str 55 | org_dn: 56 | description: root org dn 57 | default: org-root 58 | type: str 59 | extends_documentation_fragment: 60 | - cisco.ucs.ucs 61 | requirements: 62 | - ucsmsdk 63 | author: 64 | - Brett Johnson (@sdbrett) 65 | 66 | ''' 67 | 68 | EXAMPLES = r''' 69 | - name: Configure vnic order 70 | cisco.ucs.ucs_sp_vnic_order: 71 | sp_name: my_sp 72 | vnics: 73 | - name: 'my_vnic' 74 | admin_vcon: '1' 75 | order: '1' 76 | transport: 'ethernet' 77 | hostname: 192.168.99.100 78 | username: admin 79 | password: password 80 | - name: Configure vhba order 81 | cisco.ucs.ucs_sp_vnic_order: 82 | sp_name: my_sp 83 | vnics: 84 | - name: 'my_vhba' 85 | admin_vcon: '2' 86 | order: '1' 87 | transport: 'fc' 88 | hostname: 192.168.99.100 89 | username: admin 90 | password: password 91 | - name: Configure vnic and vhba order 92 | cisco.ucs.ucs_sp_vnic_order: 93 | sp_name: my_sp 94 | vnics: 95 | - name: my_vhba 96 | admin_vcon: '2' 97 | order: '1' 98 | transport: fc 99 | - name: my_vnic 100 | admin_vcon: '1' 101 | order: '1' 102 | transport: ethernet 103 | hostname: 192.168.99.100 104 | username: admin 105 | password: password 106 | - name: Remove vnic order configuration from my_vnic 107 | cisco.ucs.ucs_sp_vnic_order: 108 | sp_name: my_sp 109 | vnics: 110 | - name: 'my_vnic' 111 | transport: ethernet 112 | state: absent 113 | hostname: 192.168.99.100 114 | username: admin 115 | password: password 116 | 117 | ''' 118 | 119 | RETURN = r''' 120 | # 121 | ''' 122 | 123 | 124 | from ansible.module_utils.basic import AnsibleModule 125 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 126 | 127 | 128 | def get_service_profile(handle, org_dn, sp_name): 129 | dn = org_dn + "/ls-" + sp_name 130 | sp = handle.query_dn(dn) 131 | return sp 132 | 133 | 134 | def update_vnic_assignment_order(ucs, vnic, sp): 135 | from ucsmsdk.mometa.ls.LsVConAssign import LsVConAssign 136 | 137 | mo = LsVConAssign(parent_mo_or_dn=sp, admin_vcon=vnic['admin_vcon'], 138 | order=vnic['order'], transport=vnic['transport'], 139 | vnic_name=vnic['name']) 140 | ucs.login_handle.add_mo(mo, True) 141 | ucs.login_handle.commit() 142 | 143 | 144 | def remove_vnic_assignment_order(ucs, vnic, sp): 145 | from ucsmsdk.mometa.ls.LsVConAssign import LsVConAssign 146 | 147 | mo = LsVConAssign(parent_mo_or_dn=sp, admin_vcon='any', 148 | order='unspecified', transport=vnic['transport'], 149 | vnic_name=vnic['name']) 150 | ucs.login_handle.add_mo(mo, True) 151 | ucs.login_handle.commit() 152 | 153 | 154 | def get_vnic(ucs, dn): 155 | return ucs.login_handle.query_dn(dn) 156 | 157 | 158 | def get_vnic_dn(sp_dn, transport, name): 159 | if transport == 'ethernet': 160 | return sp_dn + '/ether-' + name 161 | return sp_dn + '/fc-' + name 162 | 163 | 164 | def matches_existing_vnic_order(vnic, vnic_mo): 165 | if vnic['state'] == 'absent': 166 | kwargs = dict(admin_vcon='any') 167 | kwargs['order'] = 'unspecified' 168 | else: 169 | kwargs = dict(admin_vcon=vnic['admin_vcon']) 170 | kwargs['order'] = vnic['order'] 171 | 172 | if vnic['transport'] == 'ethernet': 173 | kwargs['type'] = 'ether' 174 | else: 175 | kwargs['type'] = vnic['transport'] 176 | return vnic_mo.check_prop_match(**kwargs) 177 | 178 | 179 | def main(): 180 | vnic_spec = dict( 181 | name=dict(type='str', required=True), 182 | admin_vcon=dict(type='str', choices=['1', '2', '3', '4', 'any']), 183 | order=dict(type='str'), 184 | transport=dict(type='str', required=True, choices=['ethernet', 'fc']), 185 | state=dict(type='str', default='present', choices=['present', 'absent']), 186 | ) 187 | argument_spec = ucs_argument_spec.copy() 188 | argument_spec.update( 189 | sp_name=dict(required=True, type='str'), 190 | vnics=dict(required=True, type='list', elements='dict', options=vnic_spec), 191 | org_dn=dict(required=False, type='str', default='org-root'), 192 | ) 193 | module = AnsibleModule(argument_spec, 194 | supports_check_mode=True) 195 | ucs = UCSModule(module) 196 | 197 | err = False 198 | changed = False 199 | 200 | try: 201 | sp_dn = dn = module.params['org_dn'] + "/ls-" + module.params['sp_name'] 202 | sp = ucs.login_handle.query_dn(dn) 203 | if not sp: 204 | raise ValueError("SP '%s' does not exist" % sp_dn) 205 | 206 | for vnic in module.params['vnics']: 207 | vnic_mo = get_vnic(ucs, (get_vnic_dn(sp_dn, vnic['transport'], vnic['name']))) 208 | 209 | if vnic['state'] != 'absent' and not vnic_mo: 210 | raise ValueError("vNIC '%s' is not assigned to service profile '%s'" % (vnic['name'], sp_dn)) 211 | 212 | if vnic_mo: 213 | if not matches_existing_vnic_order(vnic, vnic_mo): 214 | changed = True 215 | break 216 | 217 | if changed and not module.check_mode: 218 | for vnic in module.params['vnics']: 219 | vnic_mo = get_vnic(ucs, (get_vnic_dn(sp_dn, vnic['transport'], vnic['name']))) 220 | if vnic['state'] == 'absent' and vnic_mo: 221 | remove_vnic_assignment_order(ucs, vnic, sp) 222 | elif not vnic_mo: 223 | 224 | update_vnic_assignment_order(ucs, vnic, sp) 225 | elif not matches_existing_vnic_order(vnic, vnic_mo): 226 | update_vnic_assignment_order(ucs, vnic, sp) 227 | 228 | except Exception as e: 229 | err = True 230 | ucs.result['msg'] = "setup error: %s " % str(e) 231 | 232 | ucs.result['changed'] = changed 233 | if err: 234 | module.fail_json(**ucs.result) 235 | module.exit_json(**ucs.result) 236 | 237 | 238 | if __name__ == '__main__': 239 | main() 240 | -------------------------------------------------------------------------------- /plugins/modules/ucs_system_qos.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_system_qos 16 | short_description: Configures system QoS settings 17 | description: 18 | - Configures system QoS settings 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | priority: 22 | description: Priority to configure 23 | choices: ["best-effort", "bronze", "fc", "gold","platinum", "silver"] 24 | required: true 25 | type: str 26 | admin_state: 27 | description: Admin state of QoS Policy 28 | choices: ['disabled', 'enabled'] 29 | default: enabled 30 | type: str 31 | cos: 32 | description: CoS setting. Choices are any or 0-6. 33 | required: true 34 | type: str 35 | weight: 36 | description: CoS profile weight. Choices are best-effort, none or 0-10. 37 | required: true 38 | type: str 39 | mtu: 40 | description: MTU size. Choices are fc, normal or 0-4294967295. 41 | default: normal 42 | type: str 43 | multicast_optimize: 44 | description: Set multicast optimization options 45 | choices: ['false', 'no', 'true', 'yes'] 46 | default: 'no' 47 | type: str 48 | drop: 49 | description: Set multicast optimization options 50 | default: 'drop' 51 | choices: ['drop', 'no-drop'] 52 | type: str 53 | requirements: ['ucsmsdk'] 54 | author: "Brett Johnson (@sdbrett)" 55 | ''' 56 | 57 | EXAMPLES = ''' 58 | - name: 59 | cisco.ucs.ucs_system_qos: 60 | priority: platinum 61 | admin_state: enabled 62 | multicast_optimize: no 63 | cos: '5' 64 | weight: '10' 65 | mtu: '9216' 66 | hostname: 192.168.99.100 67 | username: admin 68 | password: password 69 | ''' 70 | 71 | from ansible.module_utils.basic import AnsibleModule 72 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 73 | 74 | 75 | # TODO Add ranges for cos, weight and mtu 76 | def main(): 77 | argument_spec = ucs_argument_spec.copy() 78 | argument_spec.update( 79 | priority=dict(required=True, type='str', choices=["best-effort", "bronze", "fc", "gold", "platinum", "silver"]), 80 | cos=dict(required=True, type='str'), 81 | weight=dict(required=True, type='str'), 82 | admin_state=dict(required=False, type='str', default='enabled', choices=['disabled', 'enabled']), 83 | drop=dict(required=False, type='str', default='drop', choices=['drop', 'no-drop']), 84 | mtu=dict(required=False, type='str', default='normal'), 85 | multicast_optimize=dict(required=False, type='str', default='no', choices=['false', 'no', 'true', 'yes']), 86 | ) 87 | 88 | module = AnsibleModule( 89 | argument_spec, 90 | supports_check_mode=True, 91 | ) 92 | ucs = UCSModule(module) 93 | 94 | err = False 95 | 96 | changed = False 97 | try: 98 | dn = "fabric/lan/classes/class-" + module.params['priority'] 99 | mo = ucs.login_handle.query_dn(dn) 100 | # check top-level mo props 101 | if module.params['priority'] == 'best-effort': 102 | kwargs = dict(weight=module.params['weight']) 103 | kwargs['mtu'] = module.params['mtu'] 104 | kwargs['multicast_optimize'] = module.params['multicast_optimize'] 105 | if not mo.check_prop_match(**kwargs): 106 | if not module.check_mode: 107 | mo.weight = module.params['weight'] 108 | mo.mtu = module.params['mtu'] 109 | mo.multicast_optimize = module.params['multicast_optimize'] 110 | ucs.login_handle.add_mo(mo, True) 111 | ucs.login_handle.commit() 112 | changed = True 113 | elif module.params['priority'] == 'fc': 114 | kwargs = dict(weight=module.params['weight']) 115 | kwargs['cos'] = module.params['cos'] 116 | if not mo.check_prop_match(**kwargs): 117 | if not module.check_mode: 118 | mo.weight = module.params['weight'] 119 | mo.cos = module.params['cos'] 120 | ucs.login_handle.add_mo(mo, True) 121 | ucs.login_handle.commit() 122 | changed = True 123 | 124 | else: 125 | kwargs = dict(weight=module.params['weight']) 126 | kwargs['priority'] = module.params['priority'] 127 | kwargs['mtu'] = module.params['mtu'] 128 | kwargs['cos'] = module.params['cos'] 129 | kwargs['drop'] = module.params['drop'] 130 | kwargs['admin_state'] = module.params['admin_state'] 131 | kwargs['multicast_optimize'] = module.params['multicast_optimize'] 132 | if not mo.check_prop_match(**kwargs): 133 | if not module.check_mode: 134 | mo.weight = module.params['weight'] 135 | mo.mtu = module.params['mtu'] 136 | mo.cos = module.params['cos'] 137 | mo.drop = module.params['drop'] 138 | mo.admin_state = module.params['admin_state'] 139 | mo.multicast_optimize = module.params['multicast_optimize'] 140 | 141 | ucs.login_handle.add_mo(mo, True) 142 | ucs.login_handle.commit() 143 | changed = True 144 | 145 | except Exception as e: 146 | err = True 147 | ucs.result['msg'] = "setup error: %s " % str(e) 148 | 149 | ucs.result['changed'] = changed 150 | if err: 151 | module.fail_json(**ucs.result) 152 | module.exit_json(**ucs.result) 153 | 154 | 155 | if __name__ == '__main__': 156 | main() 157 | -------------------------------------------------------------------------------- /plugins/modules/ucs_timezone.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'certified'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_timezone 16 | short_description: Configures timezone on Cisco UCS Manager 17 | description: 18 | - Configures timezone on Cisco UCS Manager. 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | state: 22 | description: 23 | - If C(absent), will unset timezone. 24 | - If C(present), will set or update timezone. 25 | choices: [absent, present] 26 | default: present 27 | type: str 28 | 29 | admin_state: 30 | description: 31 | - The admin_state setting 32 | - The enabled admin_state indicates the timezone configuration is utilized by UCS Manager. 33 | - The disabled admin_state indicates the timezone configuration is ignored by UCS Manager. 34 | choices: [disabled, enabled] 35 | default: enabled 36 | type: str 37 | 38 | description: 39 | description: 40 | - A user-defined description of the timezone. 41 | - Enter up to 256 characters. 42 | - "You can use any characters or spaces except the following:" 43 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)." 44 | aliases: [ descr ] 45 | type: str 46 | 47 | timezone: 48 | description: 49 | - The timezone name. 50 | - Time zone names are from the L(tz database,https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) 51 | - The timezone name is case sensitive. 52 | - The timezone name can be between 0 and 510 alphanumeric characters. 53 | - You cannot use spaces or any special characters other than 54 | - "\"-\" (hyphen), \"_\" (underscore), \"/\" (backslash)." 55 | type: str 56 | 57 | requirements: 58 | - ucsmsdk 59 | author: 60 | - David Soper (@dsoper2) 61 | - John McDonough (@movinalot) 62 | - CiscoUcs (@CiscoUcs) 63 | ''' 64 | 65 | EXAMPLES = r''' 66 | - name: Configure Time Zone 67 | cisco.ucs.ucs_timezone: 68 | hostname: 172.16.143.150 69 | username: admin 70 | password: password 71 | state: present 72 | admin_state: enabled 73 | timezone: America/Los_Angeles 74 | description: 'Time Zone for Los Angeles' 75 | 76 | - name: Unconfigure Time Zone 77 | cisco.ucs.ucs_timezone: 78 | hostname: 172.16.143.150 79 | username: admin 80 | password: password 81 | state: absent 82 | admin_state: disabled 83 | ''' 84 | 85 | RETURN = r''' 86 | # 87 | ''' 88 | 89 | from ansible.module_utils.basic import AnsibleModule 90 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 91 | 92 | 93 | def run_module(): 94 | argument_spec = ucs_argument_spec.copy() 95 | argument_spec.update( 96 | timezone=dict(type='str'), 97 | description=dict(type='str', aliases=['descr']), 98 | admin_state=dict(type='str', default='enabled', choices=['disabled', 'enabled']), 99 | state=dict(type='str', default='present', choices=['present', 'absent']), 100 | ) 101 | 102 | module = AnsibleModule( 103 | argument_spec, 104 | supports_check_mode=True, 105 | required_if=[ 106 | ['state', 'present', ['timezone']], 107 | ], 108 | ) 109 | ucs = UCSModule(module) 110 | 111 | err = False 112 | 113 | changed = False 114 | try: 115 | mo_exists = False 116 | props_match = False 117 | 118 | dn = 'sys/svc-ext/datetime-svc' 119 | 120 | mo = ucs.login_handle.query_dn(dn) 121 | if mo: 122 | mo_exists = True 123 | 124 | if module.params['state'] == 'absent': 125 | # mo must exist but all properties do not have to match 126 | if mo_exists: 127 | if not module.check_mode: 128 | mo.timezone = "" 129 | mo.descr = "" 130 | ucs.login_handle.add_mo(mo, modify_present=True) 131 | ucs.login_handle.commit() 132 | changed = True 133 | else: 134 | if mo_exists: 135 | # check top-level mo props 136 | kwargs = dict(descr=module.params['description']) 137 | kwargs['timezone'] = module.params['timezone'] 138 | kwargs['admin_state'] = module.params['admin_state'] 139 | if mo.check_prop_match(**kwargs): 140 | props_match = True 141 | 142 | if not props_match: 143 | if not module.check_mode: 144 | # update mo, timezone mo always exists 145 | mo.timezone = module.params['timezone'] 146 | mo.descr = module.params['description'] 147 | mo.admin_state = module.params['admin_state'] 148 | ucs.login_handle.add_mo(mo, modify_present=True) 149 | ucs.login_handle.commit() 150 | changed = True 151 | 152 | except Exception as e: 153 | err = True 154 | ucs.result['msg'] = "setup error: %s " % str(e) 155 | 156 | ucs.result['changed'] = changed 157 | if err: 158 | module.fail_json(**ucs.result) 159 | module.exit_json(**ucs.result) 160 | 161 | 162 | def main(): 163 | run_module() 164 | 165 | 166 | if __name__ == '__main__': 167 | main() 168 | -------------------------------------------------------------------------------- /plugins/modules/ucs_uuid_pool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'certified'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_uuid_pool 16 | short_description: Configures server UUID pools on Cisco UCS Manager 17 | description: 18 | - Configures server UUID pools and UUID blocks on Cisco UCS Manager. 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | state: 22 | description: 23 | - If C(present), will verify UUID pool is present and will create if needed. 24 | - If C(absent), will verify UUID pool is absent and will delete if needed. 25 | choices: [present, absent] 26 | default: present 27 | type: str 28 | name: 29 | description: 30 | - The name of the UUID pool. 31 | - This name can be between 1 and 32 alphanumeric characters. 32 | - "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)." 33 | - You cannot change this name after the UUID pool is created. 34 | required: yes 35 | type: str 36 | description: 37 | description: 38 | - "The user-defined description of the UUID pool." 39 | - Enter up to 256 characters. 40 | - "You can use any characters or spaces except the following:" 41 | - "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)." 42 | aliases: [ descr ] 43 | type: str 44 | prefix: 45 | description: 46 | - UUID prefix used for the range of server UUIDs. 47 | - "If no value is provided, the system derived prefix will be used (equivalent to selecting 'derived' option in UI)." 48 | - "If the user provides a value, the user provided prefix will be used (equivalent to selecting 'other' option in UI)." 49 | - A user provided value should be in the format XXXXXXXX-XXXX-XXXX. 50 | type: str 51 | order: 52 | description: 53 | - The Assignment Order field. 54 | - "This can be one of the following:" 55 | - "default - Cisco UCS Manager selects a random identity from the pool." 56 | - "sequential - Cisco UCS Manager selects the lowest available identity from the pool." 57 | choices: [default, sequential] 58 | default: default 59 | type: str 60 | first_uuid: 61 | description: 62 | - The first UUID in the block of UUIDs. 63 | - This is the From field in the UCS Manager UUID Blocks menu. 64 | type: str 65 | last_uuid: 66 | description: 67 | - The last UUID in the block of UUIDs. 68 | - This is the To field in the UCS Manager Add UUID Blocks menu. 69 | type: str 70 | org_dn: 71 | description: 72 | - The distinguished name (dn) of the organization where the resource is assigned. 73 | default: org-root 74 | type: str 75 | requirements: 76 | - ucsmsdk 77 | author: 78 | - David Soper (@dsoper2) 79 | - CiscoUcs (@CiscoUcs) 80 | ''' 81 | 82 | EXAMPLES = r''' 83 | - name: Configure UUID address pool 84 | cisco.ucs.ucs_uuid_pool: 85 | hostname: 172.16.143.150 86 | username: admin 87 | password: password 88 | name: UUID-Pool 89 | order: sequential 90 | first_uuid: 0000-000000000001 91 | last_uuid: 0000-000000000078 92 | 93 | - name: Remove UUID address pool 94 | cisco.ucs.ucs_uuid_pool: 95 | hostname: 172.16.143.150 96 | username: admin 97 | password: password 98 | name: UUID-Pool 99 | state: absent 100 | ''' 101 | 102 | RETURN = r''' 103 | # 104 | ''' 105 | 106 | from ansible.module_utils.basic import AnsibleModule 107 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 108 | 109 | 110 | def main(): 111 | argument_spec = ucs_argument_spec.copy() 112 | argument_spec.update( 113 | org_dn=dict(type='str', default='org-root'), 114 | name=dict(type='str', required=True), 115 | description=dict(type='str', aliases=['descr']), 116 | order=dict(type='str', default='default', choices=['default', 'sequential']), 117 | prefix=dict(type='str'), 118 | first_uuid=dict(type='str'), 119 | last_uuid=dict(type='str'), 120 | state=dict(default='present', choices=['present', 'absent'], type='str'), 121 | ) 122 | module = AnsibleModule( 123 | argument_spec, 124 | supports_check_mode=True, 125 | ) 126 | # UCSModule verifies ucsmsdk is present and exits on failure. Imports are below ucs object creation. 127 | ucs = UCSModule(module) 128 | 129 | err = False 130 | 131 | from ucsmsdk.mometa.uuidpool.UuidpoolPool import UuidpoolPool 132 | from ucsmsdk.mometa.uuidpool.UuidpoolBlock import UuidpoolBlock 133 | 134 | ucs.result['changed'] = False 135 | try: 136 | mo_exists = False 137 | props_match = False 138 | # dn is /uuid-pool- 139 | dn = module.params['org_dn'] + '/uuid-pool-' + module.params['name'] 140 | mo = ucs.login_handle.query_dn(dn) 141 | if mo: 142 | mo_exists = True 143 | 144 | if module.params['state'] == 'absent': 145 | if mo_exists: 146 | if not module.check_mode: 147 | ucs.login_handle.remove_mo(mo) 148 | ucs.login_handle.commit() 149 | ucs.result['changed'] = True 150 | else: 151 | if mo_exists: 152 | # check top-level mo props 153 | kwargs = dict(assignment_order=module.params['order']) 154 | kwargs['descr'] = module.params['description'] 155 | if module.params['prefix']: 156 | kwargs['prefix'] = module.params['prefix'] 157 | if mo.check_prop_match(**kwargs): 158 | # top-level props match, check next level mo/props 159 | if module.params['last_uuid'] and module.params['first_uuid']: 160 | # uuid address block specified, check properties 161 | block_dn = dn + '/block-from-' + module.params['first_uuid'].upper() + '-to-' + module.params['last_uuid'].upper() 162 | mo_1 = ucs.login_handle.query_dn(block_dn) 163 | if mo_1: 164 | props_match = True 165 | else: 166 | # no UUID address block specified, but top-level props matched 167 | props_match = True 168 | 169 | if not props_match: 170 | if not module.check_mode: 171 | # create if mo does not already exist 172 | if not module.params['prefix']: 173 | module.params['prefix'] = 'derived' 174 | mo = UuidpoolPool( 175 | parent_mo_or_dn=module.params['org_dn'], 176 | name=module.params['name'], 177 | descr=module.params['description'], 178 | assignment_order=module.params['order'], 179 | prefix=module.params['prefix'] 180 | ) 181 | 182 | if module.params['last_uuid'] and module.params['first_uuid']: 183 | mo_1 = UuidpoolBlock( 184 | parent_mo_or_dn=mo, 185 | to=module.params['last_uuid'], 186 | r_from=module.params['first_uuid'], 187 | ) 188 | 189 | ucs.login_handle.add_mo(mo, True) 190 | ucs.login_handle.commit() 191 | ucs.result['changed'] = True 192 | 193 | except Exception as e: 194 | err = True 195 | ucs.result['msg'] = "setup error: %s " % str(e) 196 | 197 | if err: 198 | module.fail_json(**ucs.result) 199 | module.exit_json(**ucs.result) 200 | 201 | 202 | if __name__ == '__main__': 203 | main() 204 | -------------------------------------------------------------------------------- /plugins/modules/ucs_vlan_find.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_vlan_find 16 | short_description: Find VLANs on Cisco UCS Manager 17 | description: 18 | - Find VLANs on Cisco UCS Manager based on different criteria. 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | pattern: 22 | description: 23 | - Regex pattern to find within the name property of the fabricVlan class. 24 | - This is required if C(vlanid) parameter is not supplied. 25 | type: str 26 | fabric: 27 | description: 28 | - "The fabric configuration of the VLAN. This can be one of the following:" 29 | - "common - The VLAN applies to both fabrics and uses the same configuration parameters in both cases." 30 | - "A — The VLAN only applies to fabric A." 31 | - "B — The VLAN only applies to fabric B." 32 | choices: [common, A, B] 33 | default: common 34 | type: str 35 | vlanid: 36 | description: 37 | - The unique string identifier assigned to the VLAN. 38 | - A VLAN ID can be between '1' and '3967', or between '4048' and '4093'. 39 | - This is required if C(pattern) parameter is not supplied. 40 | type: str 41 | requirements: 42 | - ucsmsdk 43 | author: 44 | - David Martinez (@dx0xm) 45 | - David Soper (@dsoper2) 46 | - John McDonough (@movinalot) 47 | - CiscoUcs (@CiscoUcs) 48 | ''' 49 | 50 | EXAMPLES = r''' 51 | - name: Get all vlans in fabric A 52 | cisco.ucs.ucs_vlan_find: 53 | hostname: 172.16.143.150 54 | username: admin 55 | password: password 56 | fabric: 'A' 57 | pattern: '.' 58 | - name: Confirm if vlan 15 is present 59 | cisco.ucs.ucs_vlan_find: 60 | hostname: 172.16.143.150 61 | username: admin 62 | password: password 63 | vlanid: '15' 64 | ''' 65 | 66 | RETURN = r''' 67 | vlan_list: 68 | description: basic details of vlans found 69 | returned: on success 70 | type: list 71 | sample: [ 72 | { 73 | "id": "0", 74 | "name": "vlcloud1" 75 | } 76 | ] 77 | ''' 78 | 79 | 80 | from ansible.module_utils.basic import AnsibleModule 81 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 82 | 83 | 84 | def main(): 85 | argument_spec = ucs_argument_spec.copy() 86 | argument_spec.update( 87 | fabric=dict(type='str', default='common', choices=['common', 'A', 'B']), 88 | pattern=dict(type='str'), 89 | vlanid=dict(type='str') 90 | ) 91 | 92 | module = AnsibleModule( 93 | argument_spec=argument_spec, 94 | supports_check_mode=True, 95 | required_one_of=[['pattern', 'vlanid']] 96 | ) 97 | 98 | ucs = UCSModule(module) 99 | 100 | filtls = ['(cloud,"ethlan")'] 101 | if module.params['fabric'] != 'common': 102 | filtls.append('(switch_id,"' + module.params['fabric'] + '")') 103 | if module.params['vlanid']: 104 | filtls.append('(id,"' + module.params['vlanid'] + '")') 105 | else: 106 | filtls.append('(name,"' + module.params['pattern'] + '")') 107 | 108 | object_dict = ucs.login_handle.query_classid("fabricVlan", filter_str=' and '.join(filtls)) 109 | 110 | if object_dict is None: 111 | module.fail_json(msg="Failed to query vlan objects") 112 | 113 | vlnlist = [] 114 | for ob in object_dict: 115 | vlnlist.append(dict(name=ob.name, id=ob.id)) 116 | 117 | module.exit_json(changed=False, 118 | vlan_list=vlnlist) 119 | 120 | 121 | if __name__ == '__main__': 122 | main() 123 | -------------------------------------------------------------------------------- /plugins/modules/ucs_vlan_to_group.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'community'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_vlan_to_group 16 | short_description: Add VLANs to a VLAN Group. Requires VLAN and VLAN Group to already be created on UCS prior to running module. 17 | description: 18 | - Add VLANs to VLAN Groups on Cisco UCS Manager. 19 | extends_documentation_fragment: ucs 20 | options: 21 | state: 22 | description: 23 | - If C(present), will verify VLANs are present and will create if needed. 24 | - If C(absent), will verify VLANs are absent and will delete if needed. 25 | choices: [present, absent] 26 | default: present 27 | type: str 28 | vlanname: 29 | description: 30 | - The name assigned to the VLAN. 31 | - The VLAN name is case sensitive. 32 | - This name can be between 1 and 32 alphanumeric characters. 33 | - "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)." 34 | required: yes 35 | type: str 36 | vlangroup: 37 | description: 38 | - The name assigned to the VLAN Group. 39 | - The VLAN Group name is case sensitive. 40 | - This name can be between 1 and 32 alphanumeric characters. 41 | - "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)." 42 | required: yes 43 | type: str 44 | requirements: 45 | - ucsmsdk 46 | author: 47 | - Derrick Johnson (@derricktj) 48 | ''' 49 | 50 | EXAMPLES = r''' 51 | - name: Configure VLAN 52 | cisco.ucs.ucs_vlan_to_group: 53 | hostname: 1.1.1.1 54 | username: admin 55 | password: password 56 | vlangroup: VLANGROUP 57 | vlanname: VLANNAME 58 | state: present 59 | - name: Remove VLAN 60 | cisco.ucs.ucs_vlan_to_group: 61 | hostname: 1.1.1.1 62 | username: admin 63 | password: password 64 | vlangroup: VLANGROUP 65 | vlanname: VLANNAME 66 | state: absent 67 | ''' 68 | 69 | RETURN = r''' 70 | # 71 | ''' 72 | 73 | from ansible.module_utils.basic import AnsibleModule 74 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 75 | 76 | 77 | def main(): 78 | argument_spec = ucs_argument_spec.copy() 79 | argument_spec.update( 80 | vlangroup=dict(type='str', required=True), 81 | vlanname=dict(type='str', required=True), 82 | state=dict(default='present', choices=['present', 'absent'], type='str'), 83 | ) 84 | 85 | module = AnsibleModule( 86 | argument_spec, 87 | supports_check_mode=True, 88 | required_if=[ 89 | ['state', 'present', ['vlangroup', 'vlanname']], 90 | ], 91 | ) 92 | ucs = UCSModule(module) 93 | 94 | err = False 95 | 96 | from ucsmsdk.mometa.fabric.FabricNetGroup import FabricNetGroup 97 | from ucsmsdk.mometa.fabric.FabricPooledVlan import FabricPooledVlan 98 | 99 | changed = False 100 | try: 101 | dnpooled1_exists = False 102 | 103 | # dn = fabric/lan/net-group-VLANGROUP 104 | # Check for VLAN Group 105 | dngroup = 'fabric/lan/net-group-' + module.params['vlangroup'] 106 | dngroup1 = ucs.login_handle.query_dn(dngroup) 107 | 108 | # dn = fabric/lan/net-VLANNAME 109 | # Check for VLAN 110 | dnvlan = 'fabric/lan/net-' + module.params['vlanname'] 111 | dnvlan1 = ucs.login_handle.query_dn(dnvlan) 112 | 113 | # dn = fabric/lan/net-group-VLANGROUP/net-VLANNAME 114 | # Check for VLAN within VLAN Group 115 | dnpooled = 'fabric/lan/net-group-' + module.params['vlangroup'] + '/net-' + module.params['vlanname'] 116 | dnpooled1 = ucs.login_handle.query_dn(dnpooled) 117 | 118 | # Configuration MOs. Couldn't really get this to work off the DNs, so I built additional objects. 119 | mo = FabricNetGroup(parent_mo_or_dn="fabric/lan", name=module.params['vlangroup']) 120 | mo_1 = FabricPooledVlan(parent_mo_or_dn=mo, name=module.params['vlanname']) 121 | 122 | if not dngroup1: 123 | # Error out if the VLAN Group is missing 124 | err = True 125 | ucs.result['msg'] = module.params['vlangroup'] + " VLAN Group not configured in UCS" 126 | 127 | if not dnvlan1: 128 | # Error out if VLAN is missing 129 | err = True 130 | ucs.result['msg'] = module.params['vlanname'] + " VLAN not configured in UCS. Use ucs_vlans module to create the VLAN first" 131 | 132 | if dnpooled1: 133 | dnpooled1_exists = True 134 | 135 | if module.params['state'] == 'absent': 136 | if dnpooled1_exists: 137 | if not module.check_mode: 138 | ucs.login_handle.remove_mo(mo_1) 139 | ucs.login_handle.commit() 140 | changed = True 141 | 142 | if module.params['state'] == 'present': 143 | if not dnpooled1_exists: 144 | if not module.check_mode: 145 | ucs.login_handle.add_mo(mo, True) 146 | ucs.login_handle.commit() 147 | changed = True 148 | 149 | except Exception as e: 150 | err = True 151 | ucs.result['msg'] = "setup error: %s " % str(e) 152 | 153 | ucs.result['changed'] = changed 154 | if err: 155 | module.fail_json(**ucs.result) 156 | module.exit_json(**ucs.result) 157 | 158 | 159 | if __name__ == '__main__': 160 | main() 161 | -------------------------------------------------------------------------------- /plugins/modules/ucs_vlans.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'certified'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_vlans 16 | short_description: Configures VLANs on Cisco UCS Manager 17 | description: 18 | - Configures VLANs on Cisco UCS Manager. 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | state: 22 | description: 23 | - If C(present), will verify VLANs are present and will create if needed. 24 | - If C(absent), will verify VLANs are absent and will delete if needed. 25 | choices: [present, absent] 26 | default: present 27 | type: str 28 | name: 29 | description: 30 | - The name assigned to the VLAN. 31 | - The VLAN name is case sensitive. 32 | - This name can be between 1 and 32 alphanumeric characters. 33 | - "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)." 34 | - You cannot change this name after the VLAN is created. 35 | required: yes 36 | type: str 37 | multicast_policy: 38 | description: 39 | - The multicast policy associated with this VLAN. 40 | - This option is only valid if the Sharing Type field is set to None or Primary. 41 | type: str 42 | fabric: 43 | description: 44 | - "The fabric configuration of the VLAN. This can be one of the following:" 45 | - "common - The VLAN applies to both fabrics and uses the same configuration parameters in both cases." 46 | - "A — The VLAN only applies to fabric A." 47 | - "B — The VLAN only applies to fabric B." 48 | - For upstream disjoint L2 networks, Cisco recommends that you choose common to create VLANs that apply to both fabrics. 49 | choices: [common, A, B] 50 | default: common 51 | type: str 52 | id: 53 | description: 54 | - The unique string identifier assigned to the VLAN. 55 | - A VLAN ID can be between '1' and '3967', or between '4048' and '4093'. 56 | - You cannot create VLANs with IDs from 4030 to 4047. This range of VLAN IDs is reserved. 57 | - The VLAN IDs you specify must also be supported on the switch that you are using. 58 | - VLANs in the LAN cloud and FCoE VLANs in the SAN cloud must have different IDs. 59 | - Optional if state is absent. 60 | type: str 61 | sharing: 62 | description: 63 | - The Sharing Type field. 64 | - "Whether this VLAN is subdivided into private or secondary VLANs. This can be one of the following:" 65 | - "none - This VLAN does not have any secondary or private VLANs. This is a regular VLAN." 66 | - "primary - This VLAN can have one or more secondary VLANs, as shown in the Secondary VLANs area. This VLAN is a primary VLAN in the private VLAN domain." 67 | - "isolated - This is a private VLAN associated with a primary VLAN. This VLAN is an Isolated VLAN." 68 | - "community - This VLAN can communicate with other ports on the same community VLAN as well as the promiscuous port. This VLAN is a Community VLAN." 69 | choices: [none, primary, isolated, community] 70 | default: none 71 | type: str 72 | native: 73 | description: 74 | - Designates the VLAN as a native VLAN. 75 | choices: ['yes', 'no'] 76 | default: 'no' 77 | type: str 78 | requirements: 79 | - ucsmsdk 80 | author: 81 | - David Soper (@dsoper2) 82 | - CiscoUcs (@CiscoUcs) 83 | ''' 84 | 85 | EXAMPLES = r''' 86 | - name: Configure VLAN 87 | cisco.ucs.ucs_vlans: 88 | hostname: 172.16.143.150 89 | username: admin 90 | password: password 91 | name: vlan2 92 | id: '2' 93 | native: 'yes' 94 | 95 | - name: Remove VLAN 96 | cisco.ucs.ucs_vlans: 97 | hostname: 172.16.143.150 98 | username: admin 99 | password: password 100 | name: vlan2 101 | state: absent 102 | ''' 103 | 104 | RETURN = r''' 105 | # 106 | ''' 107 | 108 | from ansible.module_utils.basic import AnsibleModule 109 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 110 | 111 | 112 | def main(): 113 | argument_spec = ucs_argument_spec.copy() 114 | argument_spec.update( 115 | name=dict(type='str', required=True), 116 | multicast_policy=dict(type='str'), 117 | fabric=dict(type='str', default='common', choices=['common', 'A', 'B']), 118 | id=dict(type='str'), 119 | sharing=dict(type='str', default='none', choices=['none', 'primary', 'isolated', 'community']), 120 | native=dict(type='str', default='no', choices=['yes', 'no']), 121 | state=dict(type='str', default='present', choices=['present', 'absent']), 122 | ) 123 | 124 | module = AnsibleModule( 125 | argument_spec, 126 | supports_check_mode=True, 127 | required_if=[ 128 | ['state', 'present', ['id']], 129 | ], 130 | ) 131 | ucs = UCSModule(module) 132 | 133 | err = False 134 | 135 | # UCSModule creation above verifies ucsmsdk is present and exits on failure, so additional imports are done below. 136 | from ucsmsdk.mometa.fabric.FabricVlan import FabricVlan 137 | 138 | changed = False 139 | try: 140 | mo_exists = False 141 | props_match = False 142 | # dn is fabric/lan/net- for common vlans or fabric/lan/[A or B]/net- for A or B 143 | dn_base = 'fabric/lan' 144 | if module.params['fabric'] != 'common': 145 | dn_base += '/' + module.params['fabric'] 146 | dn = dn_base + '/net-' + module.params['name'] 147 | 148 | mo = ucs.login_handle.query_dn(dn) 149 | if mo: 150 | mo_exists = True 151 | 152 | if module.params['state'] == 'absent': 153 | # mo must exist but all properties do not have to match 154 | if mo_exists: 155 | if not module.check_mode: 156 | ucs.login_handle.remove_mo(mo) 157 | ucs.login_handle.commit() 158 | changed = True 159 | else: 160 | if mo_exists: 161 | # check top-level mo props 162 | kwargs = dict(id=module.params['id']) 163 | kwargs['default_net'] = module.params['native'] 164 | kwargs['sharing'] = module.params['sharing'] 165 | kwargs['mcast_policy_name'] = module.params['multicast_policy'] 166 | if mo.check_prop_match(**kwargs): 167 | props_match = True 168 | 169 | if not props_match: 170 | if not module.check_mode: 171 | # create if mo does not already exist 172 | mo = FabricVlan( 173 | parent_mo_or_dn=dn_base, 174 | name=module.params['name'], 175 | id=module.params['id'], 176 | default_net=module.params['native'], 177 | sharing=module.params['sharing'], 178 | mcast_policy_name=module.params['multicast_policy'], 179 | ) 180 | 181 | ucs.login_handle.add_mo(mo, True) 182 | ucs.login_handle.commit() 183 | changed = True 184 | 185 | except Exception as e: 186 | err = True 187 | ucs.result['msg'] = "setup error: %s " % str(e) 188 | 189 | ucs.result['changed'] = changed 190 | if err: 191 | module.fail_json(**ucs.result) 192 | module.exit_json(**ucs.result) 193 | 194 | 195 | if __name__ == '__main__': 196 | main() 197 | -------------------------------------------------------------------------------- /plugins/modules/ucs_vsans.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | 6 | from __future__ import absolute_import, division, print_function 7 | __metaclass__ = type 8 | 9 | ANSIBLE_METADATA = {'metadata_version': '1.1', 10 | 'status': ['preview'], 11 | 'supported_by': 'certified'} 12 | 13 | DOCUMENTATION = r''' 14 | --- 15 | module: ucs_vsans 16 | short_description: Configures VSANs on Cisco UCS Manager 17 | description: 18 | - Configures VSANs on Cisco UCS Manager. 19 | extends_documentation_fragment: cisco.ucs.ucs 20 | options: 21 | state: 22 | description: 23 | - If C(present), will verify VSANs are present and will create if needed. 24 | - If C(absent), will verify VSANs are absent and will delete if needed. 25 | choices: [present, absent] 26 | default: present 27 | type: str 28 | name: 29 | description: 30 | - The name assigned to the VSAN. 31 | - This name can be between 1 and 32 alphanumeric characters. 32 | - "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)." 33 | - You cannot change this name after the VSAN is created. 34 | required: yes 35 | type: str 36 | vsan_id: 37 | description: 38 | - The unique identifier assigned to the VSAN. 39 | - The ID can be a string between '1' and '4078', or between '4080' and '4093'. '4079' is a reserved VSAN ID. 40 | - In addition, if you plan to use FC end-host mode, the range between '3840' to '4079' is also a reserved VSAN ID range. 41 | - Optional if state is absent. 42 | type: str 43 | vlan_id: 44 | description: 45 | - The unique string identifier assigned to the VLAN used for Fibre Channel connections. 46 | - Note that Cisco UCS Manager uses VLAN '4048'. See the UCS Manager configuration guide if you want to assign '4048' to a VLAN. 47 | - Optional if state is absent. 48 | type: str 49 | fc_zoning: 50 | description: 51 | - Fibre Channel zoning configuration for the Cisco UCS domain. 52 | - "Fibre Channel zoning can be set to one of the following values:" 53 | - "disabled — The upstream switch handles Fibre Channel zoning, or Fibre Channel zoning is not implemented for the Cisco UCS domain." 54 | - "enabled — Cisco UCS Manager configures and controls Fibre Channel zoning for the Cisco UCS domain." 55 | - If you enable Fibre Channel zoning, do not configure the upstream switch with any VSANs that are being used for Fibre Channel zoning. 56 | choices: [disabled, enabled] 57 | default: disabled 58 | type: str 59 | fabric: 60 | description: 61 | - "The fabric configuration of the VSAN. This can be one of the following:" 62 | - "common - The VSAN maps to the same VSAN ID in all available fabrics." 63 | - "A - The VSAN maps to the a VSAN ID that exists only in fabric A." 64 | - "B - The VSAN maps to the a VSAN ID that exists only in fabric B." 65 | choices: [common, A, B] 66 | default: common 67 | type: str 68 | requirements: 69 | - ucsmsdk 70 | author: 71 | - David Soper (@dsoper2) 72 | - John McDonough (@movinalot) 73 | - CiscoUcs (@CiscoUcs) 74 | ''' 75 | 76 | EXAMPLES = r''' 77 | - name: Configure VSAN 78 | cisco.ucs.ucs_vsans: 79 | hostname: 172.16.143.150 80 | username: admin 81 | password: password 82 | name: vsan110 83 | fabric: common 84 | vsan_id: '110' 85 | vlan_id: '110' 86 | 87 | - name: Remove VSAN 88 | cisco.ucs.ucs_vsans: 89 | hostname: 172.16.143.150 90 | username: admin 91 | password: password 92 | name: vsan110 93 | state: absent 94 | ''' 95 | 96 | RETURN = r''' 97 | # 98 | ''' 99 | 100 | from ansible.module_utils.basic import AnsibleModule 101 | from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec 102 | 103 | 104 | def main(): 105 | argument_spec = ucs_argument_spec.copy() 106 | argument_spec.update( 107 | name=dict(type='str', required=True), 108 | vsan_id=dict(type='str'), 109 | vlan_id=dict(type='str'), 110 | fc_zoning=dict(type='str', default='disabled', choices=['disabled', 'enabled']), 111 | fabric=dict(type='str', default='common', choices=['common', 'A', 'B']), 112 | state=dict(type='str', default='present', choices=['present', 'absent']), 113 | ) 114 | 115 | module = AnsibleModule( 116 | argument_spec, 117 | supports_check_mode=True, 118 | ) 119 | ucs = UCSModule(module) 120 | 121 | err = False 122 | 123 | from ucsmsdk.mometa.fabric.FabricVsan import FabricVsan 124 | 125 | changed = False 126 | try: 127 | # single resource specified, create list from the current params 128 | vsan_list = [module.params] 129 | for vsan in vsan_list: 130 | mo_exists = False 131 | props_match = False 132 | # set default params. Done here to set values for lists which can't be done in the argument_spec 133 | if not vsan.get('fc_zoning'): 134 | vsan['fc_zoning'] = 'disabled' 135 | if not vsan.get('fabric'): 136 | vsan['fabric'] = 'common' 137 | # dn is fabric/san/net- for common vsans or fabric/san/[A or B]/net- for A or B 138 | dn_base = 'fabric/san' 139 | if vsan['fabric'] != 'common': 140 | dn_base += '/' + vsan['fabric'] 141 | dn = dn_base + '/net-' + vsan['name'] 142 | 143 | mo = ucs.login_handle.query_dn(dn) 144 | if mo: 145 | mo_exists = True 146 | 147 | if module.params['state'] == 'absent': 148 | # mo must exist but all properties do not have to match 149 | if mo_exists: 150 | if not module.check_mode: 151 | ucs.login_handle.remove_mo(mo) 152 | ucs.login_handle.commit() 153 | changed = True 154 | else: 155 | if mo_exists: 156 | # check top-level mo props 157 | kwargs = dict(id=vsan['vsan_id']) 158 | kwargs['fcoe_vlan'] = vsan['vlan_id'] 159 | kwargs['zoning_state'] = vsan['fc_zoning'] 160 | if (mo.check_prop_match(**kwargs)): 161 | props_match = True 162 | 163 | if not props_match: 164 | if not module.check_mode: 165 | # create if mo does not already exist 166 | mo = FabricVsan( 167 | parent_mo_or_dn=dn_base, 168 | name=vsan['name'], 169 | id=vsan['vsan_id'], 170 | fcoe_vlan=vsan['vlan_id'], 171 | zoning_state=vsan['fc_zoning'], 172 | ) 173 | 174 | ucs.login_handle.add_mo(mo, True) 175 | ucs.login_handle.commit() 176 | changed = True 177 | 178 | except Exception as e: 179 | err = True 180 | ucs.result['msg'] = "setup error: %s " % str(e) 181 | 182 | ucs.result['changed'] = changed 183 | if err: 184 | module.fail_json(**ucs.result) 185 | module.exit_json(**ucs.result) 186 | 187 | 188 | if __name__ == '__main__': 189 | main() 190 | -------------------------------------------------------------------------------- /releases/README.md: -------------------------------------------------------------------------------- 1 | # Ansible UCS Collection Releases 2 | 3 | This directory contains the UCS Ansible collection releases -------------------------------------------------------------------------------- /releases/cisco-ucs-1.1.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.1.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.10.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.10.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.11.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.11.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.12.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.12.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.14.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.14.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.15.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.15.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.16.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.16.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.2.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.2.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.3.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.3.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.4.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.4.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.5.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.5.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.6.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.6.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.7.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.7.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.8.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.8.0.tar.gz -------------------------------------------------------------------------------- /releases/cisco-ucs-1.9.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CiscoDevNet/ansible-ucs/c95cefe33999d09f367deec62eda3f954011a2a3/releases/cisco-ucs-1.9.0.tar.gz -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ucsmsdk 2 | -------------------------------------------------------------------------------- /tests/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Intersight collection ansible-test configuration file. 3 | # Support for this feature was first added in ansible-core 2.12. 4 | 5 | modules: 6 | # Configuration for modules/module_utils. 7 | # These settings do not apply to other content in the collection. 8 | 9 | python_requires: '>=3.7' 10 | # Python versions supported by modules/module_utils. 11 | # This setting is required. 12 | # 13 | # Possible values: 14 | # 15 | # - 'default' - All Python versions supported by Ansible. 16 | # This is the default value if no configuration is provided. 17 | # - 'controller' - All Python versions supported by the Ansible controller. 18 | # This indicates the modules/module_utils can only run on the controller. 19 | # Intended for use only with modules/module_utils that depend on ansible-connection, which only runs on the controller. 20 | # Unit tests for modules/module_utils will be permitted to import any Ansible code, instead of only module_utils. 21 | # - SpecifierSet - A PEP 440 specifier set indicating the supported Python versions. 22 | # This is only needed when modules/module_utils do not support all Python versions supported by Ansible. 23 | # It is not necessary to exclude versions which Ansible does not support, as this will be done automatically. 24 | # 25 | # What does this affect? 26 | # 27 | # - Unit tests will be skipped on any unsupported Python version. 28 | # - Sanity tests that are Python version specific will be skipped on any unsupported Python version that is not supported by the controller. 29 | # 30 | # Sanity tests that are Python version specific will always be executed for Python versions supported by the controller, regardless of this setting. 31 | # Reasons for this restriction include, but are not limited to: 32 | # 33 | # - AnsiballZ must be able to AST parse modules/module_utils on the controller, even though they may execute on a managed node. 34 | # - ansible-doc must be able to AST parse modules/module_utils on the controller to display documentation. 35 | # - ansible-test must be able to AST parse modules/module_utils to perform static analysis on them. 36 | # - ansible-test must be able to execute portions of modules/module_utils to validate their argument specs. 37 | # 38 | # These settings only apply to modules/module_utils. 39 | # It is not possible to declare supported Python versions for controller-only code. 40 | # All Python versions supported by the controller must be supported by controller-only code. 41 | --------------------------------------------------------------------------------