Init: mediaserver

This commit is contained in:
2023-02-08 12:13:28 +01:00
parent 848bc9739c
commit f7c23d4ba9
31914 changed files with 6175775 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
# cisco.ucs Collection Development Notes
### Current Development Status
These object specific modules cover a very small set of UCS Manager managed objects. For UCS objects that do not
have a specific module below use `ucs_managed_objects`. This module accepts either JSON or YAML
when used as a task in a playbook. Review `playbooks/ucs_managed_objects` playbook for examples.
| Configuration Category | Configuration Task | Module Name |
| ---------------------- | ------------------ | ----------- |
| Objects | | |
| | Any UCS Object | cisco.ucs.ucs_managed_objects |
| Query | | |
| | Query Classes or DNs | cisco.ucs.ucs_query |
| | VLAN Find | cisco.ucs.ucs_vlan_find
| Organizations | | |
| | Organizations | cisco.ucs.ucs_org |
| Servers | | |
| | Graphics Card Policy | cisco.ucs.ucs_graphics_card_policy |
| | Scrub Policy | cisco.ucs.ucs_scrub_policy |
| | Serial Over Lan Policy | cisco.ucs.ucs_serial_over_lan_policy |
| | Service Profile Template | cisco.ucs.ucs_service_profile_template |
| | Service Profile from Template | cisco.ucs.ucs_service_profile_from_template |
| | UUID Suffix Pool | cisco.ucs.ucs_uuid_pool |
| LAN | | |
| | IP Addresses for KVM Access | cisco.ucs.ucs_ip_pool |
| | LAN Connectivity Policy | cisco.ucs.ucs_lan_connectivity |
| | MAC Address Pools | cisco.ucs.ucs_mac_pool |
| | System QOS | cisco.ucs.ucs_system_qos |
| | vNIC Template | cisco.ucs.ucs_vnic_template |
| | VLANs | cisco.ucs.ucs_vlans |
| SAN | | |
| | SAN Connectivity Policy | cisco.ucs.ucs_san_connectivity |
| | vHBA Template | cisco.ucs.ucs_vhba_template |
| | VSANs | cisco.ucs.ucs_vsans |
| | WWN Pool | cisco.ucs.ucs_wwn_pool |
| Storage | | |
| | Disk Group Policy | cisco.ucs.ucs_disk_group_policy |
| | Storage Profile | cisco.ucs.ucs_storage_profile |
| Admin | | |
| | DNS Server | cisco.ucs.ucs_dns_server |
| | NTP Server | cisco.ucs.ucs_ntp_server |
| | Time Zone | cisco.ucs.ucs_timezone |
### Ansible Development Notes
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.
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:
```
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 <module_name>.py
pycodestyle --max-line-length 160 --config /dev/null --ignore E402 <module_name>.py
ansible-doc <module_name>
```
# Community:
* We are on Slack (https://ciscoucs.slack.com/) - Slack requires registration, but the ucspython team is open invitation to
anyone. Click [here](https://ucspython.herokuapp.com) to register

View File

@@ -0,0 +1,670 @@
{
"files": [
{
"name": ".",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "misc",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "misc/README.md",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "e61dd07deb821f7d7de15f2667c7b8c0a636efab8ad63484badfeb37ad6d7796",
"format": 1
},
{
"name": "misc/Impact DNW07 UCS Ansible Collection Lab Guide.pdf",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "8cce3d380ece9706c078a39e2ab729a555d585e546c12acd4d247d78ff3dfb7f",
"format": 1
},
{
"name": "requirements.txt",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "aa3e8ff6c09414944bff4bf66cd0d1b885333c1ea305c1aa7b4dde48a1abee1e",
"format": 1
},
{
"name": "plugins",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "plugins/doc_fragments",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "plugins/doc_fragments/ucs.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "9a91b29311e81b8c9db22d6fa74e6aebea262e57ec4b3e8912103e5efbe90328",
"format": 1
},
{
"name": "plugins/README.md",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "c82ee692702ec1dd604cdbc38ff252114e5204e1b0627045a66c9451e7a918ac",
"format": 1
},
{
"name": "plugins/module_utils",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "plugins/module_utils/ucs.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "1c2bb177e2a14aada0ef9921533ed78813e7969b77b5e5aa25f383e21e94f5e1",
"format": 1
},
{
"name": "plugins/modules",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "plugins/modules/ucs_vsans.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "8919b0519d1083b08e27d8df96f3823612359c9bb059547794b38272962ba242",
"format": 1
},
{
"name": "plugins/modules/ucs_lan_connectivity.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "fbdbaf175df169e342ce705a9bb681341a65e7bff4bb56b9c4d33d5203f1252c",
"format": 1
},
{
"name": "plugins/modules/ucs_system_qos.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "80b949ac3deb50592098a49ce517b962a3972c85f9732961431e5c667440d366",
"format": 1
},
{
"name": "plugins/modules/ucs_managed_objects.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "b60efa21bcd6162f8f2b30e21e8456e1babfa40d9d22e90c4a5737c7be5d71d0",
"format": 1
},
{
"name": "plugins/modules/ucs_san_connectivity.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "1a33a74d1ab46735686d97ab5abfdac74965f9dcf3f442a7a222e1519a6a2b64",
"format": 1
},
{
"name": "plugins/modules/ucs_serial_over_lan_policy.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "2fc8fca5ddd9a070486e6507a26e6fb3286de264cc1ffcf9548637109da23e77",
"format": 1
},
{
"name": "plugins/modules/ucs_wwn_pool.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "64fd4588ad5f970d9ebb7326d0cbde40c38a7dc243252e0fd55a8118e162f670",
"format": 1
},
{
"name": "plugins/modules/ucs_vhba_template.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "2f49fb8de46c89971bf97d201a790f63c3e90e962f05260b65b4e05d76013f33",
"format": 1
},
{
"name": "plugins/modules/ucs_vlans.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "44833390c6dca5c4d84ea741b011ebdd8048a8d3ae08f56b092f94f407a2819d",
"format": 1
},
{
"name": "plugins/modules/ucs_sp_vnic_order.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "3b1f5b666900e81ed47c0fc49c864d9ca3e325ae83e123110f1f95a34b0d110e",
"format": 1
},
{
"name": "plugins/modules/ucs_disk_group_policy.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "b2079621e3ec6b509006acd22ac9a422191926cfd34315ca8c0af843cdb96870",
"format": 1
},
{
"name": "plugins/modules/ucs_ntp_server.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "c87d20311dc4520fef184a523657bddecc1659912bcba747da49551c77c64dba",
"format": 1
},
{
"name": "plugins/modules/ucs_scrub_policy.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "efc721b747f2955a998ea67c595286a94ef983b71cced9eb10ca16378a488099",
"format": 1
},
{
"name": "plugins/modules/ucs_uuid_pool.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "937ed44aca4af4f9cc3795850d0b6faa283d0f511461e7a9842b1b08d1723e0e",
"format": 1
},
{
"name": "plugins/modules/ucs_dns_server.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "737d20161c466848d0d4fef11cf989a70c37a8b1255c76ed77f74cdc56748458",
"format": 1
},
{
"name": "plugins/modules/ucs_vlan_find.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "efcc0bd315ecfc7404b4f50bfa8416d7e8bc2329278b5e5343dc63c71c5af760",
"format": 1
},
{
"name": "plugins/modules/ucs_graphics_card_policy.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "a635e301c5a42ab7d3b93d107638bdfa13256926f7507a4386ba5afee2a569e3",
"format": 1
},
{
"name": "plugins/modules/ucs_org.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "8b50c9af02932abe59b7dc3044a8146ea2393de435932ba83450ca4174608b58",
"format": 1
},
{
"name": "plugins/modules/ucs_vnic_template.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "da4b4e7c608e690d4b53f6e1972c3b3bbd3782245b303a847dee6db8ce8ecd71",
"format": 1
},
{
"name": "plugins/modules/ucs_storage_profile.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "60ed97f411860171f579fe1b1d31716db66cce08a69e9e9752fb3484bd97990f",
"format": 1
},
{
"name": "plugins/modules/ucs_service_profile_association.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "cb306f31e4e0f23519d6af4de72a1eda5382c6d5bc79b697c4c140978a7635dc",
"format": 1
},
{
"name": "plugins/modules/ucs_vlan_to_group.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "e34928b3c067dae6da852ec16183db1f4464f4ec4c6ebf06e6e2f5c7607777ef",
"format": 1
},
{
"name": "plugins/modules/ucs_timezone.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "ac8518370ee6f0f6d768f9464e13011269d55d4032a9b767228b0d27a7f0fb03",
"format": 1
},
{
"name": "plugins/modules/ucs_ip_pool.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "9990d779de27b83f6449e06d933d7d9a2d0344ad0b871ee83f01cdc71f7cb1cb",
"format": 1
},
{
"name": "plugins/modules/ucs_service_profile_from_template.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "2c15389a8e9aa4fb284e328a49e0b311eb5d13670bbd82322aca19ef4c2c16a1",
"format": 1
},
{
"name": "plugins/modules/ucs_query.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "c41609719a3501d378dee7c3d64ac436c5b7b58459ec4151820b9b6e9f0c640b",
"format": 1
},
{
"name": "plugins/modules/ucs_server_maintenance.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "7909713ae7541e07c14a47fdeef30741b35424a49be8688a582aee60d80e2c07",
"format": 1
},
{
"name": "plugins/modules/ucs_service_profile_template.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "945abd9f0855f640afccdba195a9b0e8ad15f75adf7e8c8ebfda15adbb87d4c0",
"format": 1
},
{
"name": "plugins/modules/ucs_mac_pool.py",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "13a00a3f340c16e71a3f907f499db455b9c10e12034db6dc8536203898f99afd",
"format": 1
},
{
"name": "meta",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "aa2e34142e05cac25ebdf95790050adccca8011fdeb0aec65425c2547fd80f39",
"format": 1
},
{
"name": "roles",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/ucs_storage_profile.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "3777b58c91917d04a3ec4dc9d279489dd865c2fcb269aa43ceb23bea968937c8",
"format": 1
},
{
"name": "playbooks/ucs_wwn_pool.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "191db96eb7a6adb4a2bc82c95aaff7cd20fdba0a532d1dd1e2e50dc97f65feb2",
"format": 1
},
{
"name": "playbooks/ucs_serial_over_lan_policy.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "6dcfa1cbcb46ca123dd97ef08c5c434753da47c7ed685991b77ea6464f743370",
"format": 1
},
{
"name": "playbooks/ucs_vhba_template.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "00cda823af22cc1603f448616cac0c76fbb6ca2bde70a2ffbb4b69a346c4d43b",
"format": 1
},
{
"name": "playbooks/ucs_lan_connectivity.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "859208b19078ba8862402da21e574e7878b03a0ad941110962e153472a19ca25",
"format": 1
},
{
"name": "playbooks/ucs_mac_pool.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "1b08ecac7d4b2391bc679199a2048ef21e4c530bde0657540c30c18c69f2b6cf",
"format": 1
},
{
"name": "playbooks/ucs_vsans.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "79074b78bc316bae4834d7bf6e24e6483cb7d5cb1008f4989ef2cbcb37b30280",
"format": 1
},
{
"name": "playbooks/ucs_system_qos.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "d4d6c5b5c72bcd66ad8dcba66c8453b395fb3bfa9fe0fc72a6bc3b0251c46dfa",
"format": 1
},
{
"name": "playbooks/ucs_ntp_server.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "77299c4830b65606abc39d720469981362df6dd498e88baee7cc989616982317",
"format": 1
},
{
"name": "playbooks/ucs_service_profile_from_template.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "9e7cf62de403f1ca24e6048ecab5a4de7f9fbcc366a65e457e85b6f530b23937",
"format": 1
},
{
"name": "playbooks/ucs_vlan_find.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "4314b028607d257cd71018545d70198f0514ed237f6338b9c66ee8363691629b",
"format": 1
},
{
"name": "playbooks/ucs_vlan_to_group.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "96d7f24656cbd38da33aef2570ae605a64340152396bfa63cd09d43faf3b3c59",
"format": 1
},
{
"name": "playbooks/ucs_uuid_pool.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "7241264e900011016678b997bbf831f1d6bc779108e67634f3b51e2e368d2556",
"format": 1
},
{
"name": "playbooks/ucs_service_profile_association.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "14dac7f4aaacfafe69fda6574416fa6fd37ca2d84df4880b8b9f2cca85513c82",
"format": 1
},
{
"name": "playbooks/example_playbook.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "7510073bfa856bd46084f6f64817f4a4dc918eb41b06305cf6441697be4700ae",
"format": 1
},
{
"name": "playbooks/roles",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/roles/servers",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/roles/servers/service_profile_templates",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/roles/servers/service_profile_templates/tasks",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/roles/servers/service_profile_templates/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "76a596b849386fd161f9a0404954c6a84ce372e13ffbbc9cd8184a8f4c844599",
"format": 1
},
{
"name": "playbooks/roles/servers/service_profiles",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/roles/servers/service_profiles/tasks",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/roles/servers/service_profiles/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "b03e8aa16fddd905499d0bb4fcbe84f95dfadf9cce767d321f33205b64419645",
"format": 1
},
{
"name": "playbooks/roles/servers/defaults",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/roles/servers/defaults/tasks",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "playbooks/roles/servers/defaults/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "bbe7b86819348adaf8076cc9633535a80b858b957860d97cddc71acf0018e7c3",
"format": 1
},
{
"name": "playbooks/ucs_managed_objects.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "3c6b7a20e2c330a5cade1a53f67534296714456abd99f1371aac62fad178219e",
"format": 1
},
{
"name": "playbooks/ucs_vnic_template.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "cbc6add894923e8a6246a94f1f2381de211b1483f733c5a7c881f52ad859197e",
"format": 1
},
{
"name": "playbooks/ucs_scrub_policy.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "3e03124d0180685b351cc39dbcb4d2c7070204ce812753150ccfd49c7bf5ed8e",
"format": 1
},
{
"name": "playbooks/ucs_san_connectivity.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "bea00638d91b6ed884bad08f631643894a6336dd85c9ea594d089c52017fd60c",
"format": 1
},
{
"name": "playbooks/ucs_server_maintenance.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "f66d3bafb2811978d47b31d9148ace000c70045809e6ba70c1882cc587677f42",
"format": 1
},
{
"name": "playbooks/fw_download_config_hfp.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "17cd79e71470587a70d01b6f3d80afc8d3e4fe51daa4dd1f72b2bc2f9e8ee6c2",
"format": 1
},
{
"name": "playbooks/ucs_vlans.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "0525339a713095f1cd72688203c1bf7e09af518ff34449f9dfa6c150d0754155",
"format": 1
},
{
"name": "playbooks/ucs_timezone.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "e9ae6a7429ee3030b96caee58a8e417a23b919023d892ad00143dc5206d0ff87",
"format": 1
},
{
"name": "playbooks/inventory",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "fb8cee99e65566c3554036f8954a343bbeb1028c0400fb39f13d446745eb15f3",
"format": 1
},
{
"name": "playbooks/ucs_service_profile_template.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "a6fea5f68845578d69aaf34883be9d6f5bd846f0f22815bdbbd9b39e91c40d48",
"format": 1
},
{
"name": "playbooks/ucs_query.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "f67b361a468838e509c252e739b37c85978821ce4dafef6fb5a0645321bf769e",
"format": 1
},
{
"name": "playbooks/ucs_ip_pool.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "705bff291c1ef759c19110c2c941269470a0e40b1e8ea0831a15dcc7611c37b3",
"format": 1
},
{
"name": "playbooks/ucs_graphics_card_policy.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "65ef05804963545ee353e13395751b63177949b6713003f4124502a40109e9a4",
"format": 1
},
{
"name": "playbooks/ucs_sp_vnic_order.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "4732febd59e04f510c13372427c2351dc7d681cc4ea9281d17efa1311d6f47c3",
"format": 1
},
{
"name": "playbooks/ucs_org.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "8d66cd58db0b4ad70f2ff4ba8e0dd33061b2d78ad7830a680d917e309cefc892",
"format": 1
},
{
"name": "playbooks/sandbox_inventory",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "f39d48e2ce1d77a8a2c7c48580e474470793757faa3f6b49adc5382277ba1182",
"format": 1
},
{
"name": "playbooks/ucs_dns_server.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "1d6622fbe1de63bc74e280c556ea2c1047b8dcb76f3fc2c3e808647f142c4c2d",
"format": 1
},
{
"name": "playbooks/ucs_disk_group_policy.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "ae1f622dfcb5d1c1a31244432ea35b1b1fbba0da585ad19d2ba7321a52168c75",
"format": 1
},
{
"name": "playbooks/server_deploy.yml",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "087cece69b2bd12dcbe7d4b98b5783a94bd440c24ba88e9dcfe01fdd8b4790d5",
"format": 1
},
{
"name": "docs",
"ftype": "dir",
"chksum_type": null,
"chksum_sha256": null,
"format": 1
},
{
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "eebb8fd73b6f1040b24bb9176c6c28484dab8833149bff13abb25455419eb01f",
"format": 1
},
{
"name": ".gitignore",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "fbbde23b486e876ee1aab3a0053c76df8b996c6e0f15502013fff9c8ecdb4fcc",
"format": 1
},
{
"name": "LICENSE.txt",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "1babfc8408a4d1d6f39b9c01c763e313b3e0f764bf90a11fc9151a2ae556b12d",
"format": 1
},
{
"name": "Development.md",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "9877e1ab8e3670990bf466609609750a6f38c54f8e5ddb9761fe5f7966bfd93d",
"format": 1
}
],
"format": 1
}

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Cisco Systems, Inc. and/or its affiliates
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,34 @@
{
"collection_info": {
"namespace": "cisco",
"name": "ucs",
"version": "1.8.0",
"authors": [
"David Soper (@dsoper2)",
"John McDonough (@movinalot)"
],
"readme": "README.md",
"tags": [
"cisco",
"ucs"
],
"description": "modules for Cisco UCS Manager",
"license": [
"GPL-3.0-or-later"
],
"license_file": null,
"dependencies": {},
"repository": "https://github.com/CiscoDevNet/ansible-ucs",
"documentation": "https://developer.cisco.com/site/ucs-dev-center",
"homepage": "https://github.com/CiscoDevNet/ansible-ucs",
"issues": "https://github.com/CiscoDevNet/ansible-ucs"
},
"file_manifest_file": {
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
"chksum_sha256": "aa96b36e3d9e7dde362cd2a55ef8ed616efc0a72203cd68c86281fc5042732ae",
"format": 1
},
"format": 1
}

View File

@@ -0,0 +1,101 @@
# Ansible Collection - cisco.ucs
Ansible collection for managing and automing Cisco UCS Manager envrionments. Modules and roles are provided for common Cisco UCS Manager tasks.
* Note: This collection is not compatible with versions of Ansible before v2.8.
## Requirements
- Ansible v2.8 or newer
- UCSM Python SDK (ucsmsdk)
## Install
- ansible must be installed
```
sudo pip install ansible
```
- ucsmsdk must be installed
```
sudo pip install ucsmsdk
```
We recommend verifying the ucsmsdk can connect to the domains you want to manage with Ansible. Here is an example connection test using python:
```
# python
Python 2.7.14 (default, Apr 27 2018, 14:31:56)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ucsmsdk import ucshandle
>>> handle = ucshandle.UcsHandle(ip='172.22.250.236', username='admin', password='password')
>>> handle.login()
True
```
## Usage
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:
```
# ansible-doc cisco.ucs.ucs_vlans
<snip>
EXAMPLES:
- name: Configure VLAN
cisco.ucs.ucs_vlans:
hostname: 172.16.143.150
username: admin
password: password
name: vlan2
id: '2'
native: 'yes'
```
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:
```
# vi inventory
[ucs]
13.58.22.56
[ucs:vars]
username=admin
password=password
```
An example_playbook.yml playbook is included to test VLAN configuration on the UCSM domain given in the inventory file:
```
# vi example_playbook.yml
---
# Example Playbook: VLAN configuration using the [ucs] hosts group
- hosts: ucs
connection: local
collections:
- cisco.ucs
gather_facts: false
tasks:
- name: Configure VLAN
ucs_vlans:
hostname: "{{ inventory_hostname }}"
username: "{{ username | default(omit) }}"
password: "{{ password }}"
state: "{{ state | default(omit) }}"
name: vlan2
id: '2'
native: 'no'
delegate_to: localhost
```
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.
The ansible-playbook command can be used to run the above playbook and inventory file:
```
# ansible-playbook -i inventory example_playbook.yml
PLAY [ucs] *********************************************************************
TASK [Configure VLAN] **********************************************************
ok: [13.58.22.56 -> localhost]
PLAY RECAP *********************************************************************
13.58.22.56 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
```
A more detailed configuration example is provided in the server_deploy.yml playbook.
# Community:
* We are on Slack (https://ciscoucs.slack.com/) - Slack requires registration, but the ucspython team is open invitation to
anyone. Click [here](https://ucspython.herokuapp.com) to register.

View File

@@ -0,0 +1 @@
requires_ansible: ">=2.9"

View File

@@ -0,0 +1,3 @@
# Miscellaneous Items
This folder contains miscellaneous items related to the collection. Trainings, DevNet Workshop giudes, etc.

View File

@@ -0,0 +1,18 @@
---
# Example Playbook: VLAN configuration using the [ucs] hosts group
- hosts: ucs
connection: local
collections:
- cisco.ucs
gather_facts: false
tasks:
- name: Configure VLAN
ucs_vlans:
hostname: "{{ inventory_hostname }}"
username: "{{ username | default(omit) }}"
password: "{{ password }}"
state: "{{ state | default(omit) }}"
name: vlan2
id: '2'
native: 'no'
delegate_to: localhost

View File

@@ -0,0 +1,83 @@
---
#
# Download firmware to the FI and configure Host Firmware Packages (HFP).
# Uses remote fileshare and scp for FW download (server, remote_path, etc. provided through variables):
# Example vars:
# [ucs:vars]
# remote_ip_address=172.28.224.77
# remote_fw_path=/mnt/SHARE/ISOS/UCS_Code/4.1
# remote_username=...
#
# The fw_bundles variable is a list that can be passed on the command line.
# Example:
# ansible-playbook ... -e '{"fw_bundles": ["ucs-k9-bundle-b-series.4.1.2b.B.bin"]}'
#
- hosts: ucs
connection: local
gather_facts: false
vars:
login_info: &login_info
hostname: "{{ inventory_hostname }}"
username: "{{ username | default(omit) }}"
password: "{{ password }}"
tasks:
- name: Download FW to FI
ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.firmware.FirmwareCatalogue
class: FirmwareCatalogue
properties:
parent_mo_or_dn: sys
children:
- module: ucsmsdk.mometa.firmware.FirmwareDownloader
class: FirmwareDownloader
properties:
protocol: scp
server: "{{ remote_ip_address }}"
remote_path: "{{ remote_fw_path }}"
file_name: "{{ item }}"
user: "{{ remote_username }}"
pwd: "{{ remote_password }}"
loop: "{{ fw_bundles }}"
delegate_to: localhost
register: download_result
- name: Query and wait for download if needed
cisco.ucs.ucs_query:
<<: *login_info
distinguished_names: "{{ fw_download_dn }}"
loop: "{{ fw_bundles }}"
vars:
fw_download_dn: "sys/fw-catalogue/dnld-{{ item }}"
delegate_to: localhost
register: query_response
# works with warnings:
# until: query_response['objects']["{{ fw_download_dn }}"]['transfer_state'] == 'downloaded'
until: query_response.objects is search('downloaded')
# retry every 60 seconds for 20 minutes
delay: 60
retries: 20
# regular escapes in a set variable
- set_fact:
match_str: 'ucs-.*?\.(?P<rel>\d\.\d)\.(?P<patch>.*)\.'
# escape the escapes when used directly in strings
- set_fact:
blade_version: "{{ item | regex_replace(match_str + 'B\\.bin', '\\g<rel>(\\g<patch>)B') }}"
loop: "{{ fw_bundles }}"
when: item | regex_search(match_str + 'B\\.bin')
- set_fact:
rack_version: "{{ item | regex_replace(match_str + 'C\\.bin', '\\g<rel>(\\g<patch>)C') }}"
loop: "{{ fw_bundles }}"
when: item | regex_search(match_str + 'C\\.bin')
- name: Config Host FW Package
ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.firmware.FirmwareComputeHostPack
class: FirmwareComputeHostPack
properties:
parent_mo_or_dn: org-root
name: ansible-latest
blade_bundle_version: "{{ blade_version | default(omit) }}"
rack_bundle_version: "{{ rack_version | default(omit) }}"
delegate_to: localhost

View File

@@ -0,0 +1,6 @@
[ucs]
13.58.22.56
[ucs:vars]
username=admin
password=password

View File

@@ -0,0 +1,136 @@
---
- name: "Configure default IP Pool"
vars:
# Create an anchor for login_info that can be used throughout the file
login_info: &login_info
hostname: "{{ hostname }}"
username: "{{ username | default(omit) }}"
password: "{{ password | default('password') }}"
state: "{{ state | default(omit) }}"
cisco.ucs.ucs_ip_pool:
<<: *login_info
name: ext-mgmt
ipv4_blocks:
- first_addr: 198.18.0.20
last_addr: 198.18.0.40
subnet_mask: 255.255.255.0
default_gw: 198.18.0.1
tags: ip_pool
- name: "Configure default MAC Pool"
cisco.ucs.ucs_mac_pool:
<<: *login_info
name: default
first_addr: 00:25:B5:DE:30:00
last_addr: 00:25:B5:DE:32:FF
tags: mac_pool
- name: "Configure default UUID Pool"
cisco.ucs.ucs_uuid_pool:
<<: *login_info
name: default
first_uuid: 0000-000000000001
last_uuid: 0000-000000000078
tags: uuid_pool
- name: "Configure default Virtual Media Policy"
cisco.ucs.ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.cimcvmedia.CimcvmediaMountConfigPolicy
class: CimcvmediaMountConfigPolicy
properties:
parent_mo_or_dn: org-root
name: "{{ vmedia_policy }}"
children:
- module: ucsmsdk.mometa.cimcvmedia.CimcvmediaConfigMountEntry
class: CimcvmediaConfigMountEntry
properties:
device_type: cdd
image_file_name: "{{ image_file_name | default('centos7.2-boot-ks.iso') }}"
image_path: "{{ image_path | default('/home/public') }}"
mapping_name: cdd-nfs
mount_protocol: nfs
remote_ip_address: "{{ remote_ip_address | default('198.18.134.242') }}"
tags: virtual_media
- name: "Configure default Boot Order Policy"
cisco.ucs.ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.lsboot.LsbootPolicy
class: LsbootPolicy
properties:
parent_mo_or_dn: org-root
boot_mode: legacy
enforce_vnic_name: 'yes'
name: vmedia-local
reboot_on_update: 'no'
children:
- module: ucsmsdk.mometa.lsboot.LsbootVirtualMedia
class: LsbootVirtualMedia
properties:
access: read-only-remote-cimc
lun_id: '0'
order: '1'
- module: ucsmsdk.mometa.lsboot.LsbootStorage
class: LsbootStorage
properties:
order: '2'
children:
- module: ucsmsdk.mometa.lsboot.LsbootLocalStorage
class: LsbootLocalStorage
properties: {}
children:
- module: ucsmsdk.mometa.lsboot.LsbootDefaultLocalImage
class: LsbootDefaultLocalImage
properties:
order: '2'
tags: boot_order
- name: "Configure default Server Pool"
cisco.ucs.ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.compute.ComputePool
class: ComputePool
properties:
parent_mo_or_dn: org-root
name: default
children:
- module: ucsmsdk.mometa.compute.ComputePooledSlot
class: ComputePooledSlot
properties:
chassis_id: '1'
slot_id: '1'
- module: ucsmsdk.mometa.compute.ComputePooledSlot
class: ComputePooledSlot
properties:
chassis_id: '1'
slot_id: '2'
- module: ucsmsdk.mometa.compute.ComputePooledSlot
class: ComputePooledSlot
properties:
chassis_id: '1'
slot_id: '3'
- module: ucsmsdk.mometa.compute.ComputePooledSlot
class: ComputePooledSlot
properties:
chassis_id: '1'
slot_id: '4'
- module: ucsmsdk.mometa.compute.ComputePooledSlot
class: ComputePooledSlot
properties:
chassis_id: '1'
slot_id: '5'
- module: ucsmsdk.mometa.compute.ComputePooledSlot
class: ComputePooledSlot
properties:
chassis_id: '1'
slot_id: '6'
- module: ucsmsdk.mometa.compute.ComputePooledSlot
class: ComputePooledSlot
properties:
chassis_id: '1'
slot_id: '7'
- module: ucsmsdk.mometa.compute.ComputePooledSlot
class: ComputePooledSlot
properties:
chassis_id: '1'
slot_id: '8'
tags: server_pool

View File

@@ -0,0 +1,18 @@
---
- name: "Configure {{ template_name }} Service Profile Template"
vars:
# Create an anchor for login_info that can be used throughout the file
login_info: &login_info
hostname: "{{ hostname }}"
username: "{{ username | default(omit) }}"
password: "{{ password | default('password') }}"
state: "{{ state | default(omit) }}"
cisco.ucs.ucs_service_profile_template:
<<: *login_info
name: "{{ template_name }}"
template_type: "{{ template_type }}"
host_firmware_package: "{{ host_firmware_package }}"
server_pool: default
vmedia_policy: "{{ vmedia_policy }}"
boot_policy: vmedia-local
maintenance_policy: "{{ maintenance_policy }}"

View File

@@ -0,0 +1,14 @@
---
- name: "Configure {{ profile_name }} Service Profiles from template {{ template_name }}"
vars:
# Create an anchor for login_info that can be used throughout the file
login_info: &login_info
hostname: "{{ hostname }}"
username: "{{ username | default(omit) }}"
password: "{{ password | default('password') }}"
state: "{{ state | default(omit) }}"
cisco.ucs.ucs_service_profile_from_template:
<<: *login_info
name: "{{ profile_name }}-{{ '%d' | format(item) }}"
source_template: "{{ template_name }}"
loop: "{{ range(1, num_profiles|int + 1) | list }}"

View File

@@ -0,0 +1,6 @@
[ucs]
ucs1 ucs_hostname=sandbox-ucsm1.cisco.com
[ucs:vars]
ucs_username=admin
ucs_password=C1sco12345

View File

@@ -0,0 +1,39 @@
---
#
# Configure UCS, Associate Service Profiles, and Install OS
#
# The hosts group used is provided by the group variable or defaulted to 'ucs'.
# You can specify a specific host (or host group) on the command line:
# ansible-playbook ... -e group=<your host group>
# e.g., ansible-playbook server_profiles.yml -e group=TME_Demo
#
- hosts: "{{ group | default('ucs') }}"
connection: local
gather_facts: false
vars:
# The UCS domain hostname can be set in the inventory or on the command line as needed
hostname: "{{ inventory_hostname }}"
# Names for Service Profiles, Policies, and number of Profiles
template_name: auto-template
template_type: updating-template
host_firmware_package: ansible-latest
maintenance_policy: user-ack
vmedia_policy: cdd-nfs
profile_name: auto-profile
num_profiles: 2
tasks:
- block:
# Configure default pools and other settings
- import_role:
name: servers/defaults
tags: defaults
# Configure Service Profile Template with default settings
- import_role:
name: servers/service_profile_templates
tags: templates
# Create Service Profiles from template and associate
- import_role:
name: servers/service_profiles
tags: profiles
# Use the localhost's environment and Python
delegate_to: localhost

View File

@@ -0,0 +1,74 @@
---
# Example Playbook: cisco.ucs.ucs_disk_group_policy
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure Disk Group Policy
cisco.ucs.ucs_disk_group_policy:
<<: *login_info
name: DEE-DG
raid_level: mirror
configuration_mode: manual
manual_disks:
- slot_num: '1'
role: normal
- slot_num: '2'
role: normal
org_dn: org-root/org-level1
- name: Remove Disk from Policy
cisco.ucs.ucs_disk_group_policy:
<<: *login_info
name: DEE-DG
description: Testing Ansible
raid_level: stripe
configuration_mode: manual
manual_disks:
- slot_num: '1'
role: normal
- slot_num: '2'
role: normal
state: absent
virtual_drive:
access_policy: platform-default
io_policy: direct
strip_size: 64KB
org_dn: org-root/org-level1
- name: Remove Disk Group Policy
cisco.ucs.ucs_disk_group_policy:
<<: *login_info
name: DEE-DG
state: absent
org_dn: org-root/org-level1
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,33 @@
---
# Example Playbook: cisco.ucs.ucs_dns_server
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Configure DNS server
cisco.ucs.ucs_dns_server:
<<: *login_info
dns_server: 10.10.10.10
description: DNS Server IP address
state: present
delegate_to: localhost
- name: Remove DNS server
cisco.ucs.ucs_dns_server:
<<: *login_info
dns_server: 10.10.10.10
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,105 @@
---
# Example Playbook: cisco.ucs_graphics_card_policy
- hosts: ucs
connection: local
gather_facts: false
vars:
org: AnsibleOrg
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: "{{ org }}"
parent_org_path: root
description: "Org {{ org }}"
state: present
delegate_to: localhost
- name: Add Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
description: Any Graphics Mode Policy
name: prod_graphics
graphics_card_mode: any-configuration
delegate_to: localhost
- name: Check Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
description: Any Graphics Mode Policy
name: prod_graphics
graphics_card_mode: any-configuration
delegate_to: localhost
check_mode: True
- name: Add Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
<<: *login_info
state: present
description: Any Graphics Mode Policy
name: any_graphics
graphics_card_mode: any-configuration
delegate_to: localhost
- name: Idempotent Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
<<: *login_info
state: present
description: Any Graphics Mode Policy
name: any_graphics
graphics_card_mode: any-configuration
delegate_to: localhost
- name: Check Create/Update Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
description: Compute Graphics Mode Policy
name: prod_graphics
graphics_card_mode: compute
delegate_to: localhost
check_mode: true
- name: Create/Update Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
description: Compute Graphics Mode Policy
name: prod_graphics
graphics_card_mode: compute
delegate_to: localhost
- name: Delete Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
<<: *login_info
state: absent
name: any_graphics
delegate_to: localhost
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: "{{ org }}"
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,78 @@
---
# Example Playbook: cisco.ucs.ucs_ip_pool
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure IPv4 and IPv6 address pool
cisco.ucs.ucs_ip_pool:
<<: *login_info
name: ip-pool-01
org_dn: org-root/org-level1
ipv4_blocks:
- first_addr: 192.168.10.1
last_addr: 192.168.10.20
subnet_mask: 255.255.255.128
default_gw: 192.168.10.2
- first_addr: 192.168.11.1
last_addr: 192.168.11.20
subnet_mask: 255.255.255.128
default_gw: 192.168.11.2
ipv6_blocks:
- ipv6_first_addr: fe80::1cae:7992:d7a1:ed07
ipv6_last_addr: fe80::1cae:7992:d7a1:edfe
ipv6_default_gw: fe80::1cae:7992:d7a1:ecff
- ipv6_first_addr: fe80::1cae:7992:d7a1:ec07
ipv6_last_addr: fe80::1cae:7992:d7a1:ecfe
ipv6_default_gw: fe80::1cae:7992:d7a1:ecff
- name: Remove IPv4 and IPv6 address pool blocks
cisco.ucs.ucs_ip_pool:
<<: *login_info
name: ip-pool-01
org_dn: org-root/org-level1
ipv4_blocks:
- first_addr: 192.168.10.1
last_addr: 192.168.10.20
state: absent
ipv6_blocks:
- ipv6_first_addr: fe80::1cae:7992:d7a1:ec07
ipv6_last_addr: fe80::1cae:7992:d7a1:ecfe
state: absent
- name: Remove IPv4 and IPv6 address pool
cisco.ucs.ucs_ip_pool:
<<: *login_info
name: ip-pool-01
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,67 @@
---
# Example Playbook: cisco.ucs.ucs_lan_connectivity
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure LAN Connectivity Policy
cisco.ucs.ucs_lan_connectivity:
<<: *login_info
name: Cntr-FC-Boot
org_dn: org-root/org-level1
vnic_list:
- name: eno1
vnic_template: Cntr-Template
adapter_policy: Linux
- name: eno2
vnic_template: Container-NFS-A
adapter_policy: Linux
- name: eno3
vnic_template: Container-NFS-B
adapter_policy: Linux
iscsi_vnic_list:
- name: iSCSIa
overlay_vnic: eno1
iscsi_adapter_policy: default
vlan_name: Container-MGMT-VLAN
- name: iSCSIb
overlay_vnic: eno3
iscsi_adapter_policy: default
vlan_name: Container-TNT-A-NFS
- name: Remove LAN Connectivity Policy
cisco.ucs.ucs_lan_connectivity:
<<: *login_info
name: Cntr-FC-Boot
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,51 @@
---
# Example Playbook: cisco.ucs.ucs_mac_pool
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure MAC address pool
cisco.ucs.ucs_mac_pool:
<<: *login_info
name: mac-A
org_dn: org-root/org-level1
first_addr: 00:25:B5:00:66:00
last_addr: 00:25:B5:00:67:F3
order: sequential
- name: Remove MAC address pool
cisco.ucs.ucs_mac_pool:
<<: *login_info
name: mac-A
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,124 @@
---
# Example Playbook: cisco.ucs.ucs_managed_objects
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure Network Control Policy
cisco.ucs.ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.nwctrl.NwctrlDefinition
class: NwctrlDefinition
properties:
parent_mo_or_dn: org-root/org-level1
cdp: enabled
descr: ''
lldp_receive: enabled
lldp_transmit: enabled
name: Enable-CDP-LLDP
- name: Remove Network Control Policy
cisco.ucs.ucs_managed_objects:
<<: *login_info
objects:
- module: ucsmsdk.mometa.nwctrl.NwctrlDefinition
class: NwctrlDefinition
properties:
parent_mo_or_dn: org-root/org-level1
name: Enable-CDP-LLDP
state: absent
- name: Configure Boot Policy Using JSON objects list with children
cisco.ucs.ucs_managed_objects:
<<: *login_info
objects:
- {
"module": "ucsmsdk.mometa.lsboot.LsbootPolicy",
"class": "LsbootPolicy",
"properties": {
"parent_mo_or_dn": "org-root/org-level1",
"name": "Python_SDS",
"enforce_vnic_name": "yes",
"boot_mode": "legacy",
"reboot_on_update": "no"
},
"children": [
{
"module": "ucsmsdk.mometa.lsboot.LsbootVirtualMedia",
"class": "LsbootVirtualMedia",
"properties": {
"access": "read-only-local",
"lun_id": "0",
"order": "2"
}
},
{
"module": "ucsmsdk.mometa.lsboot.LsbootStorage",
"class": "LsbootStorage",
"properties": {
"order": "1"
},
"children": [
{
"module": "ucsmsdk.mometa.lsboot.LsbootLocalStorage",
"class": "LsbootLocalStorage",
"properties": {},
"children": [
{
"module": "ucsmsdk.mometa.lsboot.LsbootDefaultLocalImage",
"class": "LsbootDefaultLocalImage",
"properties": {
"order": "1"
}
}
]
}
]
}
]
}
- name: Remove Boot Policy Using JSON objects list
cisco.ucs.ucs_managed_objects:
<<: *login_info
objects:
- {
"module": "ucsmsdk.mometa.lsboot.LsbootPolicy",
"class": "LsbootPolicy",
"properties": {
"parent_mo_or_dn": "org-root/org-level1",
"name": "Python_SDS"
}
}
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,44 @@
---
# Example Playbook: cisco.ucs.ucs_dns_server
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Configure NTP server
cisco.ucs.ucs_ntp_server:
<<: *login_info
ntp_server: 10.10.10.10
description: Internal NTP Server by IP address
state: present
- name: Configure NTP server
cisco.ucs.ucs_ntp_server:
<<: *login_info
ntp_server: pool.ntp.org
description: External NTP Server by hostname
state: present
- name: Remove NTP server
cisco.ucs.ucs_ntp_server:
<<: *login_info
ntp_server: 10.10.10.10
state: absent
- name: Remove NTP server
cisco.ucs.ucs_ntp_server:
<<: *login_info
ntp_server: pool.ntp.org
state: absent

View File

@@ -0,0 +1,73 @@
---
# Example Playbook: cisco.ucs.ucs_org
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: test
description: testing org
state: present
delegate_to: localhost
- name: Update UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: test
description: Testing org
state: present
delegate_to: localhost
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: test
state: absent
delegate_to: localhost
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level2
parent_org_path: root/level1
description: level2 org
state: present
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level3
parent_org_path: root/level1/level2
description: level3 org
state: present
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level2
parent_org_path: root/level1
state: absent

View File

@@ -0,0 +1,62 @@
---
# Example Playbook: cisco.ucs.ucs_query
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Query UCS Class ID
cisco.ucs.ucs_query:
<<: *login_info
class_ids: computeBlade
delegate_to: localhost
register: response
- name: show response
debug:
msg: "{{ response }}"
- name: Query UCS Class IDs
cisco.ucs.ucs_query:
<<: *login_info
class_ids: computeBlade, fabricVlan
delegate_to: localhost
register: response
- name: show response
debug:
msg: "{{ response }}"
- name: Query UCS Distinguished Name
cisco.ucs.ucs_query:
<<: *login_info
distinguished_names: org-root
delegate_to: localhost
register: response
- name: show response
debug:
msg: "{{ response }}"
- name: Query UCS Distinguished Names
cisco.ucs.ucs_query:
<<: *login_info
distinguished_names: org-root, sys/rack-unit-1, sys/chassis-1/blade-2
delegate_to: localhost
register: response
- name: show response
debug:
msg: "{{ response }}"

View File

@@ -0,0 +1,56 @@
---
# Example Playbook: cisco.ucs.ucs_san_connectivity
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure SAN Connectivity Policy
cisco.ucs.ucs_san_connectivity:
<<: *login_info
name: Cntr-FC-Boot
org_dn: org-root/org-level1
wwnn_pool: WWNN-Pool
vhba_list:
- name: Fabric-A
vhba_template: vHBA-Template-A
adapter_policy: Linux
- name: Fabric-B
vhba_template: vHBA-Template-B
adapter_policy: Linux
- name: Remove SAN Connectivity Policy
cisco.ucs.ucs_san_connectivity:
<<: *login_info
name: Cntr-FC-Boot
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,123 @@
---
# Example Playbook: cisco.ucs.ucs_scrub_policy
- hosts: ucs
connection: local
gather_facts: false
vars:
org: AnsibleOrg
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: "{{ org }}"
parent_org_path: root
description: "Org {{ org }}"
state: present
delegate_to: localhost
- name: Add Scrub Policy
cisco.ucs.ucs_scrub_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
description: Scrub All Policy
name: all_scrub
bios_settings_scrub: "yes"
disk_scrub: "yes"
flex_flash_scrub: "yes"
persistent_memory_scrub: "yes"
delegate_to: localhost
- name: Check Scrub Policy
cisco.ucs.ucs_scrub_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
description: Scrub All Policy
name: all_scrub
bios_settings_scrub: "yes"
disk_scrub: "yes"
flex_flash_scrub: "yes"
persistent_memory_scrub: "yes"
delegate_to: localhost
check_mode: True
- name: Add Scrub Policy
cisco.ucs.ucs_scrub_policy:
<<: *login_info
state: present
description: Scrub All Policy
name: all_scrub
bios_settings_scrub: "yes"
disk_scrub: "yes"
flex_flash_scrub: "yes"
persistent_memory_scrub: "yes"
delegate_to: localhost
- name: Idempotent Scrub Policy
cisco.ucs.ucs_scrub_policy:
<<: *login_info
state: present
description: Scrub All Policy
name: all_scrub
bios_settings_scrub: "yes"
disk_scrub: "yes"
flex_flash_scrub: "yes"
persistent_memory_scrub: "yes"
delegate_to: localhost
- name: Check Create/Update Scrub Policy
cisco.ucs.ucs_scrub_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
name: BD_scrub
description: Scrub BIOS and Disk Policy
bios_settings_scrub: "yes"
disk_scrub: "yes"
flex_flash_scrub: "no"
persistent_memory_scrub: "no"
delegate_to: localhost
check_mode: true
- name: Create/Update Scrub Policy
cisco.ucs.ucs_scrub_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
name: BD_scrub
description: Scrub BIOS and Disk Policy
bios_settings_scrub: "yes"
disk_scrub: "yes"
flex_flash_scrub: "no"
persistent_memory_scrub: "no"
delegate_to: localhost
- name: Delete Scrub Policy
cisco.ucs.ucs_scrub_policy:
<<: *login_info
state: absent
name: all_scrub
delegate_to: localhost
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: "{{ org }}"
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,109 @@
---
# Example Playbook: cisco.ucs.ucs_serial_over_lan_policy
- hosts: ucs
connection: local
gather_facts: false
vars:
org: AnsibleOrg
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: "{{ org }}"
parent_org_path: root
description: "Org {{ org }}"
state: present
delegate_to: localhost
- name: Add UCS Serial Over Lan Policy
cisco.ucs.ucs_serial_over_lan_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
name: sol_pol
description: "Serial Over Lan for Org {{ org }} servers"
admin_state: enable
speed: "38400"
delegate_to: localhost
- name: Check Serial Over Lan
cisco.ucs.ucs_serial_over_lan_policy:
<<: *login_info
state: present
org_dn: "org-root/org-{{ org }}"
name: sol_pol
description: "Serial Over Lan for Org {{ org }} servers"
admin_state: enable
speed: "38400"
delegate_to: localhost
check_mode: True
- name: Add Serial Over Lan
cisco.ucs.ucs_serial_over_lan_policy:
<<: *login_info
state: present
name: sol_pol
description: Serial Over Lan for Org Root servers
admin_state: enable
speed: "57600"
delegate_to: localhost
- name: Idempotent Serial Over Lan
cisco.ucs.ucs_serial_over_lan_policy:
<<: *login_info
state: present
name: sol_pol
description: Serial Over Lan for Org Root servers
admin_state: enable
speed: "57600"
delegate_to: localhost
- name: Check Update Serial Over Lan
cisco.ucs.ucs_serial_over_lan_policy:
<<: *login_info
state: present
name: sol_pol
description: Serial Over Lan for Org Root servers
admin_state: enable
speed: "57600"
delegate_to: localhost
check_mode: true
- name: Update Serial Over Lan
cisco.ucs.ucs_serial_over_lan_policy:
<<: *login_info
state: present
name: sol_pol
description: Serial Over Lan for Org Root servers
admin_state: enable
speed: "57600"
delegate_to: localhost
- name: Delete Serial Over Lan
cisco.ucs.ucs_serial_over_lan_policy:
<<: *login_info
state: absent
name: sol_pol
delegate_to: localhost
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: "{{ org }}"
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,43 @@
---
# Example Playbook: cisco.ucs.ucs_server_maintenance
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add Server Maintenance Policy (check_mode)
cisco.ucs.ucs_server_maintenance:
<<: *login_info
name: user-ack
uptime_disr: user-ack
trigger_config: on-next-boot
delegate_to: localhost
check_mode: true
- name: Add Server Maintenance Policy
cisco.ucs.ucs_server_maintenance:
<<: *login_info
name: user-ack
uptime_disr: user-ack
trigger_config: on-next-boot
delegate_to: localhost
- name: Idempotent Add Server Maintenance Policy
cisco.ucs.ucs_server_maintenance:
<<: *login_info
name: user-ack
uptime_disr: user-ack
trigger_config: on-next-boot
delegate_to: localhost

View File

@@ -0,0 +1,53 @@
---
# Example Playbook: cisco.ucs.ucs_ucs_service_profile_association
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Change Service Profile Association to Existing Server
cisco.ucs.ucs_service_profile_association:
<<: *login_info
service_profile_name: auto-profile-2
server_assignment: server
server_dn: sys/chassis-6/blade-1
delegate_to: localhost
register: result
until: result.assign_state == 'assigned' and result.assoc_state == 'associated'
retries: 10
delay: 60
- name: Change Service Profile Association to Pool
cisco.ucs.ucs_service_profile_association:
<<: *login_info
service_profile_name: auto-profile-2
server_assignment: pool
server_pool_name: default
delegate_to: localhost
register: result
until: result.assign_state == 'assigned' and result.assoc_state == 'associated'
retries: 10
delay: 60
- name: Disassociate Service Profile
cisco.ucs.ucs_service_profile_association:
<<: *login_info
service_profile_name: auto-profile-2
state: absent
delegate_to: localhost
register: result
until: result.assign_state == 'unassigned' and result.assoc_state == 'unassociated'
retries: 10
delay: 60

View File

@@ -0,0 +1,68 @@
---
# Example Playbook: cisco.ucs.ucs_service_profile_from_template
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure Service Profile Template with LAN/SAN Connectivity and all other options defaulted
cisco.ucs.ucs_service_profile_template:
<<: *login_info
name: sp-template
org_dn: org-root/org-level1
template_type: updating-template
uuid_pool: UUID-Pool
storage_profile: DEE-StgProf
lan_connectivity_policy: Cntr-FC-Boot
iqn_pool: iSCSI-Boot-A
san_connectivity_policy: Cntr-FC-Boot
boot_policy: DEE-vMedia
maintenance_policy: default
server_pool: Container-Pool
host_firmware_package: 3.1.2b
bios_policy: Docker
- name: Configure Service Profile from Template
cisco.ucs.ucs_service_profile_from_template:
<<: *login_info
name: sp-instance-1
org_dn: org-root/org-level1
user_label: SP Instance
power_state: down
source_template: sp-template
- name: Remove Service Profile Template
cisco.ucs.ucs_service_profile_template:
<<: *login_info
name: sp-template
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,59 @@
---
# Example Playbook: cisco.ucs.ucs_service_profile_template
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure Service Profile Template with LAN/SAN Connectivity and all other options defaulted
cisco.ucs.ucs_service_profile_template:
<<: *login_info
name: sp-template
org_dn: org-root/org-level1
template_type: updating-template
uuid_pool: UUID-Pool
storage_profile: DEE-StgProf
lan_connectivity_policy: Cntr-FC-Boot
iqn_pool: iSCSI-Boot-A
san_connectivity_policy: Cntr-FC-Boot
boot_policy: DEE-vMedia
maintenance_policy: default
server_pool: Container-Pool
host_firmware_package: 3.1.2b
bios_policy: Docker
- name: Remove Service Profile Template
cisco.ucs.ucs_service_profile_template:
<<: *login_info
name: sp-template
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,29 @@
---
# Example Playbook: cisco.ucs.ucs_sp_vnic_order
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Configure vnic order
cisco.ucs.ucs_sp_vnic_order:
<<: *login_info
sp_name: DEE-Ctrl-02
vnics:
- name: eno1
admin_vcon: '1'
order: '1'
transport: ethernet
delegate_to: localhost

View File

@@ -0,0 +1,64 @@
---
# Example Playbook: cisco.ucs.ucs_storage_profile
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure Storage Profile
cisco.ucs.ucs_storage_profile:
<<: *login_info
name: DEE-StgProf
org_dn: org-root/org-level1
local_luns:
- name: Boot-LUN
size: '60'
disk_policy_name: DEE-DG
- name: Data-LUN
size: '200'
disk_policy_name: DEE-DG
- name: Remove Local LUN from Storage Profile
cisco.ucs.ucs_storage_profile:
<<: *login_info
name: DEE-StgProf
org_dn: org-root/org-level1
local_luns:
- name: Data-LUN
state: absent
- name: Remove Storage Profile
cisco.ucs.ucs_storage_profile:
<<: *login_info
name: DEE-StgProf
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,71 @@
---
# Example Playbook: cisco.ucs.ucs_system_qos
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Check QoS System Class
cisco.ucs.ucs_system_qos:
<<: *login_info
priority: platinum
cos: '5'
weight: '10'
delegate_to: localhost
check_mode: true
- name: Add QoS System Class
cisco.ucs.ucs_system_qos:
<<: *login_info
priority: platinum
cos: '5'
weight: '10'
delegate_to: localhost
- name: Idempotent Add QoS System Class
cisco.ucs.ucs_system_qos:
<<: *login_info
priority: platinum
cos: '5'
weight: '10'
delegate_to: localhost
- name: Check Update QoS System Class
cisco.ucs.ucs_system_qos:
<<: *login_info
priority: platinum
cos: '5'
weight: '10'
mtu: '9216'
delegate_to: localhost
check_mode: true
- name: Update QoS System Class
cisco.ucs.ucs_system_qos:
<<: *login_info
priority: platinum
cos: '5'
weight: '10'
mtu: '9216'
delegate_to: localhost
- name: Idempotent Update QoS System Class
cisco.ucs.ucs_system_qos:
<<: *login_info
priority: platinum
cos: '5'
weight: '10'
mtu: '9216'
delegate_to: localhost

View File

@@ -0,0 +1,31 @@
---
# Example Playbook: cisco.ucs.ucs_timezone
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Configure Time Zone
cisco.ucs.ucs_timezone:
<<: *login_info
state: present
admin_state: enabled
timezone: America/Phoenix
- name: Unconfigure Time Zone
cisco.ucs.ucs_timezone:
<<: *login_info
state: absent
admin_state: disabled

View File

@@ -0,0 +1,51 @@
---
# Example Playbook: cisco.ucs.ucs_uuid_pool
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure UUID address pool
cisco.ucs.ucs_uuid_pool:
<<: *login_info
name: UUID-Pool
org_dn: org-root/org-level1
order: sequential
first_uuid: 0000-000000000001
last_uuid: 0000-000000000078
- name: Remove UUID address pool
cisco.ucs.ucs_uuid_pool:
<<: *login_info
name: UUID-Pool
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,51 @@
---
# Example Playbook: cisco.ucs.ucs_vhba_template
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure vHBA template
cisco.ucs.ucs_vhba_template:
<<: *login_info
name: vHBA-A
org_dn: org-root/org-level1
fabric: A
vsan: VSAN-A
wwpn_pool: WWPN-Pool-A
- name: Remote vHBA template
cisco.ucs.ucs_vhba_template:
<<: *login_info
name: vHBA-A
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,39 @@
---
# Example Playbook: cisco.ucs.ucs_vlan_find
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Get all vlans in fabric A
cisco.ucs.ucs_vlan_find:
<<: *login_info
fabric: 'common'
pattern: '.'
register: response
- name: show response
debug:
msg: "{{ response }}"
- name: Confirm if vlan 15 is present
cisco.ucs.ucs_vlan_find:
<<: *login_info
vlanid: '200'
register: response
- name: show response
debug:
msg: "{{ response }}"

View File

@@ -0,0 +1,25 @@
---
# Example Playbook: cisco.ucs.ucs_vlan_to_group
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add VLAN to existing VLAN group
cisco.ucs.ucs_vlan_to_group:
<<: *login_info
vlangroup: inband
vlanname: vlan244
delegate_to: localhost

View File

@@ -0,0 +1,31 @@
---
# Example Playbook: cisco.ucs.ucs_vlans
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Configure VLAN
cisco.ucs.ucs_vlans:
<<: *login_info
name: vlan300
id: '300'
native: 'no'
- name: Remove VLAN
cisco.ucs.ucs_vlans:
<<: *login_info
name: vlan300
state: absent

View File

@@ -0,0 +1,98 @@
---
# Example Playbook: cisco.ucs.ucs_vnic_template
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure vNIC template
cisco.ucs.ucs_vnic_template:
<<: *login_info
name: vNIC-A
org_dn: org-root/org-level1
fabric: A
vlans_list:
- name: default
native: 'yes'
- name: vlan200
native: 'no'
- name: Remove VLAN from template
cisco.ucs.ucs_vnic_template:
<<: *login_info
name: vNIC-A
org_dn: org-root/org-level1
fabric: A
vlans_list:
- name: vlan200
state: absent
- name: Configure vNIC template for failover
cisco.ucs.ucs_vnic_template:
<<: *login_info
name: vNIC-A-B
org_dn: org-root/org-level1
fabric: A-B
redundancy_type: primary
vlans_list:
- name: default
native: 'yes'
- name: vlan200
native: 'no'
- name: Configure vNIC template for failover
cisco.ucs.ucs_vnic_template:
<<: *login_info
name: vNIC-B-A
org_dn: org-root/org-level1
fabric: B-A
redundancy_type: secondary
vlans_list:
- name: default
native: 'yes'
- name: vlan200
native: 'no'
- name: Remove vNIC template
cisco.ucs.ucs_vnic_template:
<<: *login_info
name: vNIC-A-B
org_dn: org-root/org-level1
# state: absent
- name: Remove vNIC template
cisco.ucs.ucs_vnic_template:
<<: *login_info
name: vNIC-B-A
org_dn: org-root/org-level1
# state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
# state: absent
delegate_to: localhost

View File

@@ -0,0 +1,32 @@
---
# Example Playbook: cisco.ucs.ucs_vsans
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Configure VSAN
cisco.ucs.ucs_vsans:
<<: *login_info
name: vsan110
fabric: common
vsan_id: '110'
vlan_id: '110'
- name: Remove VSAN
cisco.ucs.ucs_vsans:
<<: *login_info
name: vsan110
state: absent

View File

@@ -0,0 +1,85 @@
---
# Example Playbook: cisco.ucs.ucs_wwn_pool
- hosts: ucs
connection: local
gather_facts: false
tasks:
- name: Test that we have a UCS hostname, UCS username, and UCS password
fail:
msg: 'Please define the following variables: ucs_hostname, ucs_username and ucs_password.'
when: ucs_hostname is not defined or ucs_username is not defined or ucs_password is not defined
vars:
# use "<<: *login_info" to substite the information below in each task
# this is not required, however it makes the playbook shorter.
login_info: &login_info
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
- name: Add UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Configure WWNN pool
cisco.ucs.ucs_wwn_pool:
<<: *login_info
name: WWNN-Pool
org_dn: org-root/org-level1
purpose: node
first_addr: 20:00:00:25:B5:48:00:00
last_addr: 20:00:00:25:B5:48:00:0F
- name: Configure WWPN A pool
cisco.ucs.ucs_wwn_pool:
<<: *login_info
name: WWPN-Pool-A
org_dn: org-root/org-level1
purpose: port
order: sequential
first_addr: 20:00:00:25:B5:48:0A:00
last_addr: 20:00:00:25:B5:48:0A:0F
- name: Configure WWPN Bpool
cisco.ucs.ucs_wwn_pool:
<<: *login_info
name: WWPN-Pool-B
org_dn: org-root/org-level1
purpose: port
order: sequential
first_addr: 20:00:00:25:B5:48:0B:00
last_addr: 20:00:00:25:B5:48:0B:0F
- name: Remove WWNN pool
cisco.ucs.ucs_wwn_pool:
<<: *login_info
org_dn: org-root/org-level1
name: WWNN-Pool
state: absent
- name: Remove WWPN pool
cisco.ucs.ucs_wwn_pool:
<<: *login_info
name: WWPN-Pool-A
org_dn: org-root/org-level1
state: absent
- name: Remove WWPN pool
cisco.ucs.ucs_wwn_pool:
<<: *login_info
name: WWPN-Pool-B
org_dn: org-root/org-level1
state: absent
- name: Remove UCS Organization
cisco.ucs.ucs_org:
<<: *login_info
org_name: level1
parent_org_path: root
state: absent
delegate_to: localhost

View File

@@ -0,0 +1,31 @@
# Collections Plugins Directory
This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that
is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that
would contain module utils and modules respectively.
Here is an example directory of the majority of plugins currently supported by Ansible:
```
└── plugins
├── action
├── become
├── cache
├── callback
├── cliconf
├── connection
├── filter
├── httpapi
├── inventory
├── lookup
├── module_utils
├── modules
├── netconf
├── shell
├── strategy
├── terminal
├── test
└── vars
```
A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible/2.9/plugins/plugins.html).

View File

@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
# This code is part of Ansible, but is an independent component.
# This particular file snippet, and this file snippet only, is BSD licensed.
# Modules you write using this snippet, which is embedded dynamically by Ansible
# still belong to the author of the module, and may assign their own license
# to the complete work.
#
# (c) 2016 Red Hat Inc.
# (c) 2017 Cisco Systems Inc.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
class ModuleDocFragment(object):
# Cisco UCS doc fragment
DOCUMENTATION = '''
options:
hostname:
description:
- IP address or hostname of Cisco UCS Manager.
- Modules can be used with the UCS Platform Emulator U(https://cs.co/ucspe)
type: str
required: yes
username:
description:
- Username for Cisco UCS Manager authentication.
type: str
default: admin
password:
description:
- Password for Cisco UCS Manager authentication.
type: str
required: yes
port:
description:
- Port number to be used during connection (by default uses 443 for https and 80 for http connection).
type: int
use_ssl:
description:
- If C(no), an HTTP connection will be used instead of the default HTTPS connection.
type: bool
default: yes
use_proxy:
description:
- If C(no), will not use the proxy as defined by system environment variable.
type: bool
default: yes
proxy:
description:
- If use_proxy is no, specfies proxy to be used for connection.
e.g. 'http://proxy.xy.z:8080'
type: str
'''

View File

@@ -0,0 +1,97 @@
# This code is part of Ansible, but is an independent component.
# This particular file snippet, and this file snippet only, is BSD licensed.
# Modules you write using this snippet, which is embedded dynamically by Ansible
# still belong to the author of the module, and may assign their own license
# to the complete work.
#
# (c) 2016 Red Hat Inc.
# (c) 2019 Cisco Systems Inc.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import traceback
from ansible.module_utils.basic import missing_required_lib
UCSMSDK_IMP_ERR = None
try:
import ucsmsdk
HAS_UCSMSDK = True
except Exception:
UCSMSDK_IMP_ERR = traceback.format_exc()
HAS_UCSMSDK = False
ucs_argument_spec = dict(
hostname=dict(type='str', required=True),
username=dict(type='str', default='admin'),
password=dict(type='str', required=True, no_log=True),
port=dict(type='int', default=None),
use_ssl=dict(type='bool', default=True),
use_proxy=dict(type='bool', default=True),
proxy=dict(type='str', default=None),
)
class UCSModule():
def __init__(self, module):
self.module = module
self.result = {}
if not HAS_UCSMSDK:
self.module.fail_json(msg=missing_required_lib('ucsmsdk'), exception=UCSMSDK_IMP_ERR)
self.login()
def __del__(self):
self.logout()
def login(self):
from ucsmsdk.ucshandle import UcsHandle
# use_proxy=yes (default) and proxy=None (default) should be using the system defined proxy
# use_proxy=yes (default) and proxy=value should use the provided proxy
# use_proxy=no (user) should not be using a proxy
if self.module.params['use_proxy']:
proxy = self.module.params['proxy']
else:
# force no proxy to be used. Note that proxy=None in UcsHandle will
# use the system proxy so we must set to something else
proxy = {}
try:
handle = UcsHandle(
ip=self.module.params['hostname'],
username=self.module.params['username'],
password=self.module.params['password'],
port=self.module.params['port'],
secure=self.module.params['use_ssl'],
proxy=proxy
)
handle.login()
except Exception as e:
self.result['msg'] = str(e)
self.module.fail_json(**self.result)
self.login_handle = handle
def logout(self):
if hasattr(self, 'login_handle'):
self.login_handle.logout()
return True
return False

View File

@@ -0,0 +1,428 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_disk_group_policy
short_description: Configures disk group policies on Cisco UCS Manager
description:
- Configures disk group policies on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- Desired state of the disk group policy.
- If C(present), will verify that the disk group policy is present and will create if needed.
- If C(absent), will verify that the disk group policy is absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name of the disk group policy.
- This name can be between 1 and 16 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- You cannot change this name after the policy is created.
required: yes
description:
description:
- The user-defined description of the storage profile.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
raid_level:
description:
- "The RAID level for the disk group policy. This can be one of the following:"
- "stripe - UCS Manager shows RAID 0 Striped"
- "mirror - RAID 1 Mirrored"
- "mirror-stripe - RAID 10 Mirrored and Striped"
- "stripe-parity - RAID 5 Striped Parity"
- "stripe-dual-parity - RAID 6 Striped Dual Parity"
- "stripe-parity-stripe - RAID 50 Striped Parity and Striped"
- "stripe-dual-parity-stripe - RAID 60 Striped Dual Parity and Striped"
choices: [stripe, mirror, mirror-stripe, stripe-parity, stripe-dual-parity, stripe-parity-stripe, stripe-dual-parity-stripe]
default: stripe
configuration_mode:
description:
- "Disk group configuration mode. Choose one of the following:"
- "automatic - Automatically configures the disks in the disk group."
- "manual - Enables you to manually configure the disks in the disk group."
choices: [automatic, manual]
default: automatic
num_drives:
description:
- Specify the number of drives for the disk group.
- This can be from 0 to 24.
- Option only applies when configuration mode is automatic.
default: 1
drive_type:
description:
- Specify the drive type to use in the drive group.
- "This can be one of the following:"
- "unspecified — Selects the first available drive type, and applies that to all drives in the group."
- "HDD — Hard disk drive"
- "SSD — Solid state drive"
- Option only applies when configuration mode is automatic.
choices: [unspecified, HDD, SSD]
default: unspecified
num_ded_hot_spares:
description:
- Specify the number of hot spares for the disk group.
- This can be from 0 to 24.
- Option only applies when configuration mode is automatic.
default: unspecified
num_glob_hot_spares:
description:
- Specify the number of global hot spares for the disk group.
- This can be from 0 to 24.
- Option only applies when configuration mode is automatic.
default: unspecified
min_drive_size:
description:
- Specify the minimum drive size or unspecified to allow all drive sizes.
- This can be from 0 to 10240 GB.
- Option only applies when configuration mode is automatic.
default: 'unspecified'
use_remaining_disks:
description:
- Specifies whether you can use all the remaining disks in the disk group or not.
- Option only applies when configuration mode is automatic.
choices: ['yes', 'no']
default: 'no'
manual_disks:
description:
- List of manually configured disks.
- Options are only used when you choose manual configuration_mode.
suboptions:
name:
description:
- The name of the local LUN.
required: yes
slot_num:
description:
- The slot number of the specific disk.
role:
description:
- "The role of the disk. This can be one of the following:"
- "normal - Normal"
- "ded-hot-spare - Dedicated Hot Spare"
- "glob-hot-spare - Glob Hot Spare"
span_id:
description:
- The Span ID of the specific disk.
default: 'unspecified'
state:
description:
- If C(present), will verify disk slot is configured within policy.
If C(absent), will verify disk slot is absent from policy.
choices: [ present, absent ]
default: present
virtual_drive:
description:
- Configuration of virtual drive options.
suboptions:
access_policy:
description:
- Configure access policy to virtual drive.
choices: [blocked, hidden, platform-default, read-only, read-write, transport-ready]
default: platform-default
drive_cache:
description:
- Configure drive caching.
choices: [disable, enable, no-change, platform-default]
default: platform-default
io_policy:
description:
- Direct or Cached IO path.
choices: [cached, direct, platform-default]
default: platform-default
read_policy:
description:
- Read access policy to virtual drive.
choices: [normal, platform-default, read-ahead]
default: platform-default
strip_size:
description:
- Virtual drive strip size.
choices: [ present, absent ]
default: platform-default
write_cache_policy:
description:
- Write back cache policy.
choices: [always-write-back, platform-default, write-back-good-bbu, write-through]
default: platform-default
org_dn:
description:
- The distinguished name (dn) of the organization where the resource is assigned.
default: org-root
requirements:
- ucsmsdk
author:
- Sindhu Sudhir (@sisudhir)
- David Soper (@dsoper2)
- CiscoUcs (@CiscoUcs)
- Brett Johnson (@sdbrett)
- John McDonough (@movinalot)
version_added: '2.8'
'''
EXAMPLES = r'''
- name: Configure Disk Group Policy
cisco.ucs.ucs_disk_group_policy:
hostname: 172.16.143.150
username: admin
password: password
name: DEE-DG
raid_level: mirror
configuration_mode: manual
manual_disks:
- slot_num: '1'
role: normal
- slot_num: '2'
role: normal
- name: Remove Disk Group Policy
cisco.ucs.ucs_disk_group_policy:
name: DEE-DG
hostname: 172.16.143.150
username: admin
password: password
state: absent
- name: Remove Disk from Policy
cisco.ucs.ucs_disk_group_policy:
hostname: 172.16.143.150
username: admin
password: password
name: DEE-DG
description: Testing Ansible
raid_level: stripe
configuration_mode: manual
manual_disks:
- slot_num: '1'
role: normal
- slot_num: '2'
role: normal
state: absent
virtual_drive:
access_policy: platform-default
io_policy: direct
strip_size: 64KB
'''
RETURN = r'''
#
'''
from ucsmsdk.mometa.lstorage.LstorageDiskGroupConfigPolicy import LstorageDiskGroupConfigPolicy
from ucsmsdk.mometa.lstorage.LstorageDiskGroupQualifier import LstorageDiskGroupQualifier
from ucsmsdk.mometa.lstorage.LstorageLocalDiskConfigRef import LstorageLocalDiskConfigRef
from ucsmsdk.mometa.lstorage.LstorageVirtualDriveDef import LstorageVirtualDriveDef
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def configure_disk_policy(ucs, module, dn):
# from ucsmsdk.mometa.lstorage.LstorageDiskGroupConfigPolicy import LstorageDiskGroupConfigPolicy
# from ucsmsdk.mometa.lstorage.LstorageDiskGroupQualifier import LstorageDiskGroupQualifier
# from ucsmsdk.mometa.lstorage.LstorageLocalDiskConfigRef import LstorageLocalDiskConfigRef
if not module.check_mode:
try:
# create if mo does not already exist
mo = LstorageDiskGroupConfigPolicy(
parent_mo_or_dn=module.params['org_dn'],
name=module.params['name'],
descr=module.params['description'],
raid_level=module.params['raid_level'],
)
if module.params['configuration_mode'] == 'automatic':
LstorageDiskGroupQualifier(
parent_mo_or_dn=mo,
num_drives=module.params['num_drives'],
drive_type=module.params['drive_type'],
use_remaining_disks=module.params['use_remaining_disks'],
num_ded_hot_spares=module.params['num_ded_hot_spares'],
num_glob_hot_spares=module.params['num_glob_hot_spares'],
min_drive_size=module.params['min_drive_size'],
)
else: # configuration_mode == 'manual'
for disk in module.params['manual_disks']:
if disk['state'] == 'absent':
child_dn = dn + '/slot-' + disk['slot_num']
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
ucs.login_handle.remove_mo(mo_1)
else: # state == 'present'
LstorageLocalDiskConfigRef(
parent_mo_or_dn=mo,
slot_num=disk['slot_num'],
role=disk['role'],
span_id=disk['span_id'],
)
if module.params['virtual_drive']:
_configure_virtual_drive(module, mo)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
except Exception as e: # generic Exception handling because SDK can throw a variety
ucs.result['msg'] = "setup error: %s " % str(e)
module.fail_json(**ucs.result)
ucs.result['changed'] = True
def check_disk_policy_props(ucs, module, mo, dn):
props_match = True
# check top-level mo props
kwargs = dict(descr=module.params['description'])
kwargs['raid_level'] = module.params['raid_level']
if mo.check_prop_match(**kwargs):
# top-level props match, check next level mo/props
if module.params['configuration_mode'] == 'automatic':
child_dn = dn + '/disk-group-qual'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(num_drives=module.params['num_drives'])
kwargs['drive_type'] = module.params['drive_type']
kwargs['use_remaining_disks'] = module.params['use_remaining_disks']
kwargs['num_ded_hot_spares'] = module.params['num_ded_hot_spares']
kwargs['num_glob_hot_spares'] = module.params['num_glob_hot_spares']
kwargs['min_drive_size'] = module.params['min_drive_size']
props_match = mo_1.check_prop_match(**kwargs)
else: # configuration_mode == 'manual'
for disk in module.params['manual_disks']:
child_dn = dn + '/slot-' + disk['slot_num']
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
if disk['state'] == 'absent':
props_match = False
else: # state == 'present'
kwargs = dict(slot_num=disk['slot_num'])
kwargs['role'] = disk['role']
kwargs['span_id'] = disk['span_id']
if not mo_1.check_prop_match(**kwargs):
props_match = False
break
if props_match:
if module.params['virtual_drive']:
props_match = check_virtual_drive_props(ucs, module, dn)
else:
props_match = False
return props_match
def check_virtual_drive_props(ucs, module, dn):
child_dn = dn + '/virtual-drive-def'
mo_1 = ucs.login_handle.query_dn(child_dn)
return mo_1.check_prop_match(**module.params['virtual_drive'])
def _configure_virtual_drive(module, mo):
# from ucsmsdk.mometa.lstorage.LstorageVirtualDriveDef import LstorageVirtualDriveDef
LstorageVirtualDriveDef(parent_mo_or_dn=mo, **module.params['virtual_drive'])
def _virtual_drive_argument_spec():
return dict(
access_policy=dict(type='str', default='platform-default',
choices=["blocked", "hidden", "platform-default", "read-only", "read-write",
"transport-ready"]),
drive_cache=dict(type='str', default='platform-default',
choices=["disable", "enable", "no-change", "platform-default"]),
io_policy=dict(type='str', default='platform-default',
choices=["cached", "direct", "platform-default"]),
read_policy=dict(type='str', default='platform-default',
choices=["normal", "platform-default", "read-ahead"]),
strip_size=dict(type='str', default='platform-default',
choices=["1024KB", "128KB", "16KB", "256KB", "32KB", "512KB", "64KB", "8KB",
"platform-default"]),
write_cache_policy=dict(type='str', default='platform-default',
choices=["always-write-back", "platform-default", "write-back-good-bbu",
"write-through"]),
)
def main():
manual_disk = dict(
slot_num=dict(type='str', required=True),
role=dict(type='str', default='normal', choices=['normal', 'ded-hot-spare', 'glob-hot-spare']),
span_id=dict(type='str', default='unspecified'),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(type='str', required=True),
description=dict(type='str', aliases=['descr'], default=''),
raid_level=dict(
type='str',
default='stripe',
choices=[
'stripe',
'mirror',
'mirror-stripe',
'stripe-parity',
'stripe-dual-parity',
'stripe-parity-stripe',
'stripe-dual-parity-stripe',
],
),
num_drives=dict(type='str', default='1'),
configuration_mode=dict(type='str', default='automatic', choices=['automatic', 'manual']),
num_ded_hot_spares=dict(type='str', default='unspecified'),
num_glob_hot_spares=dict(type='str', default='unspecified'),
drive_type=dict(type='str', default='unspecified', choices=['unspecified', 'HDD', 'SSD']),
use_remaining_disks=dict(type='str', default='no', choices=['yes', 'no']),
min_drive_size=dict(type='str', default='unspecified'),
manual_disks=dict(type='list', elements='dict', options=manual_disk),
state=dict(type='str', default='present', choices=['present', 'absent']),
virtual_drive=dict(type='dict', options=_virtual_drive_argument_spec()),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
ucs = UCSModule(module)
# UCSModule creation above verifies ucsmsdk is present and exits on failure.
# Additional imports are done below or in called functions.
ucs.result['changed'] = False
props_match = False
# dn is <org_dn>/disk-group-config-<name>
dn = module.params['org_dn'] + '/disk-group-config-' + module.params['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
ucs.result['changed'] = True
else: # state == 'present'
props_match = check_disk_policy_props(ucs, module, mo, dn)
if module.params['state'] == 'present' and not props_match:
configure_disk_policy(ucs, module, dn)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,165 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_dns_server
short_description: Configure DNS servers on Cisco UCS Manager
description:
- Configure DNS servers on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(absent), will remove a DNS server.
- If C(present), will add or update a DNS server.
choices: [absent, present]
default: present
type: str
dns_server:
description:
- DNS server IP address.
- Enter a valid IPV4 Address.
- UCS Manager supports up to 4 DNS Servers
aliases: [ name ]
type: str
description:
description:
- A user-defined description of the DNS server.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
type: str
delegate_to:
description:
- Where the module will be run
default: localhost
type: str
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: "2.8"
'''
EXAMPLES = r'''
- name: Configure DNS server
cisco.ucs.ucs_dns_server:
hostname: 172.16.143.150
username: admin
password: password
dns_server: 10.10.10.10
description: DNS Server IP address
state: present
delegate_to: localhost
- name: Remove DNS server
cisco.ucs.ucs_dns_server:
hostname: 172.16.143.150
username: admin
password: password
dns_server: 10.10.10.10
state: absent
delegate_to: localhost
'''
RETURN = r'''
#
'''
from ucsmsdk.mometa.comm.CommDnsProvider import CommDnsProvider
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def run_module():
argument_spec = ucs_argument_spec
argument_spec.update(
dns_server=dict(type='str', aliases=['name']),
description=dict(type='str', aliases=['descr'], default=''),
state=dict(type='str', default='present', choices=['present', 'absent']),
delegate_to=dict(type='str', default='localhost'),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_if=[
['state', 'present', ['dns_server']],
],
)
# UCSModule verifies ucsmsdk is present and exits on failure.
# Imports are below for UCS object creation.
ucs = UCSModule(module)
# from ucsmsdk.mometa.comm.CommDnsProvider import CommDnsProvider
err = False
changed = False
try:
mo_exists = False
props_match = False
dn = 'sys/svc-ext/dns-svc/dns-' + module.params['dns_server']
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
if module.params['state'] == 'absent':
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
changed = True
else:
if mo_exists:
# check top-level mo props
kwargs = dict(descr=module.params['description'])
if mo.check_prop_match(**kwargs):
props_match = True
if not props_match:
if not module.check_mode:
# update/add mo
mo = CommDnsProvider(parent_mo_or_dn='sys/svc-ext/dns-svc',
name=module.params['dns_server'],
descr=module.params['description'])
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
def main():
run_module()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,261 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_graphics_card_policy
short_description: Manages UCS Graphics Card Policies on UCS Manager
description:
- Manages UCS Graphics Card Policies on UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(absent), will remove organization.
- If C(present), will create or update organization.
choices: [absent, present]
default: present
type: str
name:
description:
- The name of the organization.
- Enter up to 16 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote)"
- "= (equal sign), > (greater than), < (less than), ' (single quote)."
required: true
type: str
description:
description:
- A user-defined description of the organization.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote)"
- "= (equal sign), > (greater than), < (less than), ' (single quote)."
aliases: [ descr ]
type: str
graphics_card_mode:
description:
- Set the Graphics Card Mode.
choices: [any-configuration, compute, graphics]
type: str
org_dn:
description:
- Org dn (distinguished name)
default: org-root
type: str
requirements:
- ucsmsdk
author:
- John McDonough (@movinalot)
version_added: "2.9"
'''
EXAMPLES = r'''
- name: Add UCS Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
description: Any Graphics Mode Policy
name: any_graphics
graphics_card_mode: any-configuration
delegate_to: localhost
- name: Add UCS Graphics Card Policy in an Organization
cisco.ucs.ucs_graphics_card_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
description: Any Graphics Mode Policy
name: prod_graphics
graphics_card_mode: any-configuration
delegate_to: localhost
- name: Update UCS Graphics Card Policy in an Organization
cisco.ucs.ucs_graphics_card_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
description: Graphics Mode Policy
name: prod_graphics
graphics_card_mode: graphics
delegate_to: localhost
- name: Update UCS Graphics Card Policy in an Organization
cisco.ucs.ucs_graphics_card_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
description: Compute Mode Policy
name: prod_graphics
graphics_card_mode: compute
delegate_to: localhost
- name: Delete UCS Graphics Card Policy in an Organization
cisco.ucs.ucs_graphics_card_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: absent
org_dn: org-root/org-prod
name: prod_graphics
delegate_to: localhost
- name: Delete UCS Graphics Card Policy
cisco.ucs.ucs_graphics_card_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: absent
name: any_graphics
delegate_to: localhost
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import (
UCSModule,
ucs_argument_spec
)
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(required=True, type='str'),
descr=dict(type='str'),
description=dict(type='str', aliases=['descr']),
graphics_card_mode=dict(type='str', choices=[
'any-configuration',
'compute',
'graphics'
]),
state=dict(
type='str', default='present',
choices=['present', 'absent']
),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_if=[
['state', 'present', ['name']],
],
)
# UCSModule verifies ucsmsdk is present and exits on failure.
# Imports are below for UCS object creation.
ucs = UCSModule(module)
from importlib import import_module
from ucsmsdk.ucscoreutils import get_meta_info
# The Class(es) this module is managing
module_file = 'ucsmsdk.mometa.compute.ComputeGraphicsCardPolicy'
module_class = 'ComputeGraphicsCardPolicy'
mo_module = import_module(module_file)
mo_class = getattr(mo_module, module_class)
META = get_meta_info(class_id=module_class)
err = False
changed = False
requested_state = module.params['state']
kwargs = dict()
# Manage Aliased Attributes
for attribute in ['descr:description']:
attribute_alias = attribute.split(':')
if module.params[attribute_alias[1]] is not None:
kwargs[attribute_alias[0]] = module.params[attribute_alias[1]]
# Manage Attributes
for attribute in [
'graphics_card_mode', 'descr']:
if module.params[attribute] is not None:
kwargs[attribute] = module.params[attribute]
try:
dn = (
module.params['org_dn'] + '/' +
META.rn[0:META.rn.rindex('-') + 1] +
module.params['name']
)
mo = ucs.login_handle.query_dn(dn)
# Determine state change
if mo:
# Object exists, if it should exist has anything changed?
if requested_state == 'present':
# Do some or all Object properties not match, that is a change
if not mo.check_prop_match(**kwargs):
changed = True
# Object does not exist but should, that is a change
else:
if requested_state == 'present':
changed = True
# Object exists but should not, that is a change
if mo and requested_state == 'absent':
changed = True
# Apply state if not check_mode
if changed and not module.check_mode:
if requested_state == 'absent':
ucs.login_handle.remove_mo(mo)
else:
kwargs['parent_mo_or_dn'] = module.params['org_dn']
kwargs['name'] = module.params['name']
mo = mo_class(**kwargs)
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.login_handle.commit()
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,452 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_ip_pool
short_description: Configures IP address pools on Cisco UCS Manager
description:
- Configures IP address pools and blocks of IP addresses on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify IP pool is present and will create if needed.
- If C(absent), will verify IP pool is absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name of the IP address pool.
- This name can be between 1 and 32 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- You cannot change this name after the IP address pool is created.
required: yes
description:
description:
- The user-defined description of the IP address pool.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
order:
description:
- The Assignment Order field.
- "This can be one of the following:"
- "default - Cisco UCS Manager selects a random identity from the pool."
- "sequential - Cisco UCS Manager selects the lowest available identity from the pool."
choices: [default, sequential]
default: default
ip_blocks:
description:
- List of IPv4 blocks used by the IP Pool.
suboptions:
first_addr:
description:
- The first IPv4 address in the IPv4 addresses block.
- This is the From field in the UCS Manager Add IPv4 Blocks menu.
last_addr:
description:
- The last IPv4 address in the IPv4 addresses block.
- This is the To field in the UCS Manager Add IPv4 Blocks menu.
subnet_mask:
description:
- The subnet mask associated with the IPv4 addresses in the block.
default: 255.255.255.0
default_gw:
description:
- The default gateway associated with the IPv4 addresses in the block.
default: 0.0.0.0
primary_dns:
description:
- The primary DNS server that this block of IPv4 addresses should access.
default: 0.0.0.0
secondary_dns:
description:
- The secondary DNS server that this block of IPv4 addresses should access.
default: 0.0.0.0
ipv6_blocks:
description:
- List of IPv6 blocks used by the IP Pool.
suboptions:
ipv6_first_addr:
description:
- The first IPv6 address in the IPv6 addresses block.
- This is the From field in the UCS Manager Add IPv6 Blocks menu.
ipv6_last_addr:
description:
- The last IPv6 address in the IPv6 addresses block.
- This is the To field in the UCS Manager Add IPv6 Blocks menu.
ipv6_prefix:
description:
- The network address prefix associated with the IPv6 addresses in the block.
default: '64'
ipv6_default_gw:
description:
- The default gateway associated with the IPv6 addresses in the block.
default: '::'
ipv6_primary_dns:
description:
- The primary DNS server that this block of IPv6 addresses should access.
default: '::'
ipv6_secondary_dns:
description:
- The secondary DNS server that this block of IPv6 addresses should access.
default: '::'
org_dn:
description:
- Org dn (distinguished name)
default: org-root
requirements:
- ucsmsdk
author:
- Brett Johnson (@sdbrett)
- David Soper (@dsoper2)
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: '2.5'
'''
EXAMPLES = r'''
- name: Configure IPv4 and IPv6 address pool
cisco.ucs.ucs_ip_pool:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
name: ip-pool-01
org_dn: org-root/org-level1
ipv4_blocks:
- first_addr: 192.168.10.1
last_addr: 192.168.10.20
subnet_mask: 255.255.255.128
default_gw: 192.168.10.2
- first_addr: 192.168.11.1
last_addr: 192.168.11.20
subnet_mask: 255.255.255.128
default_gw: 192.168.11.2
ipv6_blocks:
- ipv6_first_addr: fe80::1cae:7992:d7a1:ed07
ipv6_last_addr: fe80::1cae:7992:d7a1:edfe
ipv6_default_gw: fe80::1cae:7992:d7a1:ecff
- ipv6_first_addr: fe80::1cae:7992:d7a1:ec07
ipv6_last_addr: fe80::1cae:7992:d7a1:ecfe
ipv6_default_gw: fe80::1cae:7992:d7a1:ecff
- name: Delete IPv4 and IPv6 address pool blocks
cisco.ucs.ucs_ip_pool:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
name: ip-pool-01
org_dn: org-root/org-level1
ipv4_blocks:
- first_addr: 192.168.10.1
last_addr: 192.168.10.20
state: absent
ipv6_blocks:
- ipv6_first_addr: fe80::1cae:7992:d7a1:ec07
ipv6_last_addr: fe80::1cae:7992:d7a1:ecfe
state: absent
- name: Remove IPv4 and IPv6 address pool
cisco.ucs.ucs_ip_pool:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
name: ip-pool-01
state: absent
'''
RETURN = r'''
#
'''
def update_ip_pool(ucs, module):
from ucsmsdk.mometa.ippool.IppoolPool import IppoolPool
mo = IppoolPool(
parent_mo_or_dn=module.params['org_dn'],
name=module.params['name'],
descr=module.params['descr'],
assignment_order=module.params['order'],
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
return mo
def match_existing_ipv4_block(ucs, dn, ipv4_block):
# ipv4 block specified, check properties
mo_1 = get_ip_block(ucs, dn, ipv4_block['first_addr'], ipv4_block['last_addr'], 'v4')
if not mo_1:
if ipv4_block['state'] == 'absent':
return True
return False
else:
if ipv4_block['state'] == 'absent':
return False
kwargs = dict(subnet=ipv4_block['subnet_mask'])
kwargs['def_gw'] = ipv4_block['default_gw']
kwargs['prim_dns'] = ipv4_block['primary_dns']
kwargs['sec_dns'] = ipv4_block['secondary_dns']
return mo_1.check_prop_match(**kwargs)
def match_existing_ipv6_block(ucs, dn, ipv6_block):
# ipv6 block specified, check properties
mo_1 = get_ip_block(ucs, dn, ipv6_block['ipv6_first_addr'], ipv6_block['ipv6_last_addr'], 'v6')
if not mo_1:
if ipv6_block['state'] == 'absent':
return True
return False
else:
if ipv6_block['state'] == 'absent':
return False
kwargs = dict(prefix=ipv6_block['ipv6_prefix'])
kwargs['def_gw'] = ipv6_block['ipv6_default_gw']
kwargs['prim_dns'] = ipv6_block['ipv6_primary_dns']
kwargs['sec_dns'] = ipv6_block['ipv6_secondary_dns']
return mo_1.check_prop_match(**kwargs)
def remove_ip_block(ucs, dn, ip_block, ip_version):
if ip_version == 'v6':
first_addr = ip_block['ipv6_first_addr']
last_addr = ip_block['ipv6_last_addr']
else:
first_addr = ip_block['first_addr']
last_addr = ip_block['last_addr']
mo_1 = get_ip_block(ucs, dn, first_addr, last_addr, ip_version)
if mo_1:
ucs.login_handle.remove_mo(mo_1)
ucs.login_handle.commit()
def update_ip_block(ucs, mo, ip_block, ip_version):
remove_ip_block(ucs, mo.dn, ip_block, ip_version)
if not ip_block['state'] == 'absent':
if ip_version == 'v6':
from ucsmsdk.mometa.ippool.IppoolIpV6Block import IppoolIpV6Block
IppoolIpV6Block(
parent_mo_or_dn=mo,
to=ip_block['ipv6_last_addr'],
r_from=ip_block['ipv6_first_addr'],
prefix=ip_block['ipv6_prefix'],
def_gw=ip_block['ipv6_default_gw'],
prim_dns=ip_block['ipv6_primary_dns'],
sec_dns=ip_block['ipv6_secondary_dns']
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
else:
from ucsmsdk.mometa.ippool.IppoolBlock import IppoolBlock
IppoolBlock(
parent_mo_or_dn=mo,
to=ip_block['last_addr'],
r_from=ip_block['first_addr'],
subnet=ip_block['subnet_mask'],
def_gw=ip_block['default_gw'],
prim_dns=ip_block['primary_dns'],
sec_dns=ip_block['secondary_dns']
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
def get_ip_block(ucs, pool_dn, first_addr, last_addr, ip_version):
if ip_version == 'v6':
dn_type = '/v6block-'
else:
dn_type = '/block-'
block_dn = pool_dn + dn_type + first_addr + '-' + last_addr
return ucs.login_handle.query_dn(block_dn)
def main():
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
ipv4_configuration_spec = dict(
first_addr=dict(type='str'),
last_addr=dict(type='str'),
subnet_mask=dict(type='str', default='255.255.255.0'),
default_gw=dict(type='str', default='0.0.0.0'),
primary_dns=dict(type='str', default='0.0.0.0'),
secondary_dns=dict(type='str', default='0.0.0.0'),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
ipv6_configuration_spec = dict(
ipv6_first_addr=dict(type='str'),
ipv6_last_addr=dict(type='str'),
ipv6_prefix=dict(type='str', default='64'),
ipv6_default_gw=dict(type='str', default='::'),
ipv6_primary_dns=dict(type='str', default='::'),
ipv6_secondary_dns=dict(type='str', default='::'),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(type='str', required=True),
descr=dict(type='str', default='', aliases=['description']),
order=dict(type='str', default='default', choices=['default', 'sequential']),
first_addr=dict(type='str'),
last_addr=dict(type='str'),
subnet_mask=dict(type='str', default='255.255.255.0'),
default_gw=dict(type='str', default='0.0.0.0'),
primary_dns=dict(type='str', default='0.0.0.0'),
secondary_dns=dict(type='str', default='0.0.0.0'),
ipv6_first_addr=dict(type='str'),
ipv6_last_addr=dict(type='str'),
ipv6_prefix=dict(type='str', default='64'),
ipv6_default_gw=dict(type='str', default='::'),
ipv6_primary_dns=dict(type='str', default='::'),
ipv6_secondary_dns=dict(type='str', default='::'),
state=dict(type='str', default='present', choices=['present', 'absent']),
ipv4_blocks=dict(type='list', default=None, elements='dict', options=ipv4_configuration_spec),
ipv6_blocks=dict(type='list', default=None, elements='dict', options=ipv6_configuration_spec),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
# UCSModule verifies ucsmsdk is present and exits on failure. Imports are below ucs object creation.
ucs = UCSModule(module)
err = False
from ucsmsdk.mometa.ippool.IppoolBlock import IppoolBlock
from ucsmsdk.mometa.ippool.IppoolIpV6Block import IppoolIpV6Block
changed = False
try:
mo_exists = False
ipv4_props_match = True
ipv6_props_match = True
# dn is <org_dn>/ip-pool-<name>
dn = module.params['org_dn'] + '/ip-pool-' + module.params['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
if module.params['state'] == 'absent':
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
changed = True
else:
if not mo_exists:
if not module.check_mode:
mo = update_ip_pool(ucs, module)
changed = True
if mo_exists:
# check top-level mo props
kwargs = dict(assignment_order=module.params['order'])
kwargs['descr'] = module.params['descr']
if not mo.check_prop_match(**kwargs):
if not module.check_mode:
mo = update_ip_pool(ucs, module)
changed = True
# top-level props match, check next level mo/props
if module.params['ipv4_blocks']:
for ipv4_block in module.params['ipv4_blocks']:
if not match_existing_ipv4_block(ucs, dn, ipv4_block):
if not module.check_mode:
update_ip_block(ucs, mo, ipv4_block, 'v4')
changed = True
elif module.params['last_addr'] and module.params['first_addr']:
# ipv4 block specified, check properties
mo_1 = get_ip_block(ucs, dn, module.params['first_addr'], module.params['last_addr'], 'v4')
if mo_1:
kwargs = dict(subnet=module.params['subnet_mask'])
kwargs['def_gw'] = module.params['default_gw']
kwargs['prim_dns'] = module.params['primary_dns']
kwargs['sec_dns'] = module.params['secondary_dns']
if not mo_1.check_prop_match(**kwargs):
# ipv4 block exists and properties match
ipv4_props_match = False
else:
ipv4_props_match = False
# only check ipv6 props if the top-level and ipv4 props matched
if module.params['ipv6_blocks']:
for ipv6_block in module.params['ipv6_blocks']:
if not match_existing_ipv6_block(ucs, dn, ipv6_block):
if not module.check_mode:
update_ip_block(ucs, mo, ipv6_block, 'v6')
changed = True
elif module.params['ipv6_last_addr'] and module.params['ipv6_first_addr']:
# ipv6 block specified, check properties
block_dn = dn + '/v6block-' + module.params['ipv6_first_addr'].lower() + '-' + module.params[
'ipv6_last_addr'].lower()
mo_1 = ucs.login_handle.query_dn(block_dn)
if mo_1:
kwargs = dict(prefix=module.params['ipv6_prefix'])
kwargs['def_gw'] = module.params['ipv6_default_gw']
kwargs['prim_dns'] = module.params['ipv6_primary_dns']
kwargs['sec_dns'] = module.params['ipv6_secondary_dns']
if not mo_1.check_prop_match(**kwargs):
# ipv6 block exists and properties match
ipv6_props_match = False
else:
ipv6_props_match = False
if not ipv4_props_match or not ipv6_props_match:
if not module.check_mode:
if module.params['last_addr'] and module.params['first_addr']:
IppoolBlock(
parent_mo_or_dn=mo,
to=module.params['last_addr'],
r_from=module.params['first_addr'],
subnet=module.params['subnet_mask'],
def_gw=module.params['default_gw'],
prim_dns=module.params['primary_dns'],
sec_dns=module.params['secondary_dns'],
)
if module.params['ipv6_last_addr'] and module.params['ipv6_first_addr']:
IppoolIpV6Block(
parent_mo_or_dn=mo,
to=module.params['ipv6_last_addr'],
r_from=module.params['ipv6_first_addr'],
prefix=module.params['ipv6_prefix'],
def_gw=module.params['ipv6_default_gw'],
prim_dns=module.params['ipv6_primary_dns'],
sec_dns=module.params['ipv6_secondary_dns'],
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,355 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'certified'}
DOCUMENTATION = r'''
---
module: ucs_lan_connectivity
short_description: Configures LAN Connectivity Policies on Cisco UCS Manager
description:
- Configures LAN Connectivity Policies on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify LAN Connectivity Policies are present and will create if needed.
- If C(absent), will verify LAN Connectivity Policies are absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name of the LAN Connectivity Policy.
- This name can be between 1 and 16 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- You cannot change this name after the policy is created.
required: yes
description:
description:
- A description of the LAN Connectivity Policy.
- Cisco recommends including information about where and when to use the policy.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
vnic_list:
description:
- List of vNICs used by the LAN Connectivity Policy.
- vNICs used by the LAN Connectivity Policy must be created from a vNIC template.
suboptions:
name:
description:
- The name of the vNIC.
required: yes
vnic_template:
description:
- The name of the vNIC template.
required: yes
adapter_policy:
description:
- The name of the Ethernet adapter policy.
- A user defined policy can be used, or one of the system defined policies.
order:
description:
- String specifying the vNIC assignment order (e.g., '1', '2').
default: 'unspecified'
state:
description:
- If C(present), will verify vnic is configured within policy.
If C(absent), will verify vnic is absent from policy.
choices: [ present, absent ]
default: present
version_added: '2.8'
iscsi_vnic_list:
description:
- List of iSCSI vNICs used by the LAN Connectivity Policy.
suboptions:
name:
description:
- The name of the iSCSI vNIC.
required: yes
overlay_vnic:
description:
- The LAN vNIC associated with this iSCSI vNIC.
iscsi_adapter_policy:
description:
- The iSCSI adapter policy associated with this iSCSI vNIC.
mac_address:
description:
- The MAC address associated with this iSCSI vNIC.
- If the MAC address is not set, Cisco UCS Manager uses a derived MAC address.
default: derived
vlan_name:
description:
- The VLAN used for the iSCSI vNIC.
default: default
state:
description:
- If C(present), will verify iscsi vnic is configured within policy.
If C(absent), will verify iscsi vnic is absent from policy.
choices: [ present, absent ]
default: present
version_added: '2.8'
org_dn:
description:
- Org dn (distinguished name)
default: org-root
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: '2.5'
'''
EXAMPLES = r'''
- name: Configure LAN Connectivity Policy
cisco.ucs.ucs_lan_connectivity:
hostname: 172.16.143.150
username: admin
password: password
name: Cntr-FC-Boot
vnic_list:
- name: eno1
vnic_template: Cntr-Template
adapter_policy: Linux
- name: eno2
vnic_template: Container-NFS-A
adapter_policy: Linux
- name: eno3
vnic_template: Container-NFS-B
adapter_policy: Linux
iscsi_vnic_list:
- name: iSCSIa
overlay_vnic: eno1
iscsi_adapter_policy: default
vlan_name: Container-MGMT-VLAN
- name: iSCSIb
overlay_vnic: eno3
iscsi_adapter_policy: default
vlan_name: Container-TNT-A-NFS
- name: Remove LAN Connectivity Policy
cisco.ucs.ucs_lan_connectivity:
hostname: 172.16.143.150
username: admin
password: password
name: Cntr-FC-Boot
state: absent
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def configure_lan_connectivity(ucs, module, dn):
from ucsmsdk.mometa.vnic.VnicLanConnPolicy import VnicLanConnPolicy
from ucsmsdk.mometa.vnic.VnicEther import VnicEther
from ucsmsdk.mometa.vnic.VnicIScsiLCP import VnicIScsiLCP
from ucsmsdk.mometa.vnic.VnicVlan import VnicVlan
if not module.check_mode:
try:
# create if mo does not already exist
mo = VnicLanConnPolicy(
parent_mo_or_dn=module.params['org_dn'],
name=module.params['name'],
descr=module.params['description'],
)
if module.params.get('vnic_list'):
for vnic in module.params['vnic_list']:
if vnic['state'] == 'absent':
child_dn = dn + '/ether-' + vnic['name']
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
ucs.login_handle.remove_mo(mo_1)
else: # state == 'present'
mo_1 = VnicEther(
addr='derived',
parent_mo_or_dn=mo,
name=vnic['name'],
adaptor_profile_name=vnic['adapter_policy'],
nw_templ_name=vnic['vnic_template'],
order=vnic['order'],
)
if module.params.get('iscsi_vnic_list'):
for iscsi_vnic in module.params['iscsi_vnic_list']:
if iscsi_vnic['state'] == 'absent':
child_dn = dn + '/iscsi-' + iscsi_vnic['name']
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
ucs.login_handle.remove_mo(mo_1)
else: # state == 'present'
mo_1 = VnicIScsiLCP(
parent_mo_or_dn=mo,
name=iscsi_vnic['name'],
adaptor_profile_name=iscsi_vnic['iscsi_adapter_policy'],
vnic_name=iscsi_vnic['overlay_vnic'],
addr=iscsi_vnic['mac_address'],
)
VnicVlan(
parent_mo_or_dn=mo_1,
vlan_name=iscsi_vnic['vlan_name'],
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
except Exception as e: # generic Exception handling because SDK can throw a variety of exceptions
ucs.result['msg'] = "setup error: %s " % str(e)
module.fail_json(**ucs.result)
ucs.result['changed'] = True
def check_vnic_props(ucs, module, dn):
props_match = True
if module.params.get('vnic_list'):
# check vnicEther props
for vnic in module.params['vnic_list']:
child_dn = dn + '/ether-' + vnic['name']
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
if vnic['state'] == 'absent':
props_match = False
break
else: # state == 'present'
kwargs = dict(adaptor_profile_name=vnic['adapter_policy'])
kwargs['order'] = vnic['order']
kwargs['nw_templ_name'] = vnic['vnic_template']
if not (mo_1.check_prop_match(**kwargs)):
props_match = False
break
else: # mo_1 did not exist
if vnic['state'] == 'present':
props_match = False
break
return props_match
def check_iscsi_vnic_props(ucs, module, dn):
props_match = True
if module.params.get('iscsi_vnic_list'):
# check vnicIScsiLCP props
for iscsi_vnic in module.params['iscsi_vnic_list']:
child_dn = dn + '/iscsi-' + iscsi_vnic['name']
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
if iscsi_vnic['state'] == 'absent':
props_match = False
break
else: # state == 'present'
kwargs = dict(vnic_name=iscsi_vnic['overlay_vnic'])
kwargs['adaptor_profile_name'] = iscsi_vnic['iscsi_adapter_policy']
kwargs['addr'] = iscsi_vnic['mac_address']
if (mo_1.check_prop_match(**kwargs)):
# check vlan
child_dn = child_dn + '/vlan'
mo_2 = ucs.login_handle.query_dn(child_dn)
if mo_2:
kwargs = dict(vlan_name=iscsi_vnic['vlan_name'])
if not (mo_2.check_prop_match(**kwargs)):
props_match = False
break
else: # mo_1 props did not match
props_match = False
break
else: # mo_1 did not exist
if iscsi_vnic['state'] == 'present':
props_match = False
break
return props_match
def check_lan_connecivity_props(ucs, module, mo, dn):
props_match = False
# check top-level mo props
kwargs = dict(descr=module.params['description'])
if (mo.check_prop_match(**kwargs)):
# top-level props match, check next level mo/props
# check vnic 1st
props_match = check_vnic_props(ucs, module, dn)
if props_match:
props_match = check_iscsi_vnic_props(ucs, module, dn)
return props_match
def main():
vnic = dict(
name=dict(type='str', required=True),
vnic_template=dict(type='str', required=True),
adapter_policy=dict(type='str', default=''),
order=dict(type='str', default='unspecified'),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
iscsi_vnic = dict(
name=dict(type='str', required=True),
overlay_vnic=dict(type='str', default=''),
iscsi_adapter_policy=dict(type='str', default=''),
mac_address=dict(type='str', default='derived'),
vlan_name=dict(type='str', default='default'),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(type='str', required=True),
description=dict(type='str', aliases=['descr'], default=''),
vnic_list=dict(type='list', elements='dict', options=vnic),
iscsi_vnic_list=dict(type='list', elements='dict', options=iscsi_vnic),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
ucs = UCSModule(module)
# UCSModule creation above verifies ucsmsdk is present and exits on failure.
# Additional imports are done below or in called functions.
ucs.result['changed'] = False
props_match = False
# dn is <org_dn>/lan-conn-pol-<name>
dn = module.params['org_dn'] + '/lan-conn-pol-' + module.params['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
ucs.result['changed'] = True
else: # state == 'present'
props_match = check_lan_connecivity_props(ucs, module, mo, dn)
if module.params['state'] == 'present' and not props_match:
configure_lan_connectivity(ucs, module, dn)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,185 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'certified'}
DOCUMENTATION = r'''
---
module: ucs_mac_pool
short_description: Configures MAC address pools on Cisco UCS Manager
description:
- Configures MAC address pools and MAC address blocks on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify MAC pool is present and will create if needed.
- If C(absent), will verify MAC pool is absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name of the MAC pool.
- This name can be between 1 and 32 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- You cannot change this name after the MAC pool is created.
required: yes
description:
description:
- A description of the MAC pool.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
order:
description:
- The Assignment Order field.
- "This can be one of the following:"
- "default - Cisco UCS Manager selects a random identity from the pool."
- "sequential - Cisco UCS Manager selects the lowest available identity from the pool."
choices: [default, sequential]
default: default
first_addr:
description:
- The first MAC address in the block of addresses.
- This is the From field in the UCS Manager MAC Blocks menu.
last_addr:
description:
- The last MAC address in the block of addresses.
- This is the To field in the UCS Manager Add MAC Blocks menu.
org_dn:
description:
- The distinguished name (dn) of the organization where the resource is assigned.
default: org-root
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- CiscoUcs (@CiscoUcs)
version_added: '2.5'
'''
EXAMPLES = r'''
- name: Configure MAC address pool
cisco.ucs.ucs_mac_pool:
hostname: 172.16.143.150
username: admin
password: password
name: mac-A
first_addr: 00:25:B5:00:66:00
last_addr: 00:25:B5:00:67:F3
order: sequential
- name: Remove MAC address pool
cisco.ucs.ucs_mac_pool:
hostname: 172.16.143.150
username: admin
password: password
name: mac-A
state: absent
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(type='str', required=True),
descr=dict(type='str', default='', aliases=['description']),
order=dict(type='str', default='default', choices=['default', 'sequential']),
first_addr=dict(type='str'),
last_addr=dict(type='str'),
state=dict(default='present', choices=['present', 'absent'], type='str'),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
# UCSModule verifies ucsmsdk is present and exits on failure. Imports are below ucs object creation.
ucs = UCSModule(module)
err = False
from ucsmsdk.mometa.macpool.MacpoolPool import MacpoolPool
from ucsmsdk.mometa.macpool.MacpoolBlock import MacpoolBlock
changed = False
try:
mo_exists = False
props_match = False
# dn is <org_dn>/mac-pool-<name>
dn = module.params['org_dn'] + '/mac-pool-' + module.params['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
if module.params['state'] == 'absent':
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
changed = True
else:
if mo_exists:
# check top-level mo props
kwargs = dict(assignment_order=module.params['order'])
kwargs['descr'] = module.params['descr']
if mo.check_prop_match(**kwargs):
# top-level props match, check next level mo/props
if module.params['last_addr'] and module.params['first_addr']:
# mac address block specified, check properties
block_dn = dn + '/block-' + module.params['first_addr'].upper() + '-' + module.params['last_addr'].upper()
mo_1 = ucs.login_handle.query_dn(block_dn)
if mo_1:
props_match = True
else:
# no MAC address block specified, but top-level props matched
props_match = True
if not props_match:
if not module.check_mode:
# create if mo does not already exist
mo = MacpoolPool(
parent_mo_or_dn=module.params['org_dn'],
name=module.params['name'],
descr=module.params['descr'],
assignment_order=module.params['order'],
)
if module.params['last_addr'] and module.params['first_addr']:
mo_1 = MacpoolBlock(
parent_mo_or_dn=mo,
to=module.params['last_addr'],
r_from=module.params['first_addr'],
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,256 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_managed_objects
short_description: Configures Managed Objects on Cisco UCS Manager
description:
- Configures Managed Objects on Cisco UCS Manager.
- The Python SDK module, Python class within the module (UCSM Class), and all properties must be directly specified.
- More information on the UCSM Python SDK and how to directly configure Managed Objects is available at L(UCSM Python SDK,http://ucsmsdk.readthedocs.io/).
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify that the Managed Objects are present and will create if needed.
- If C(absent), will verify that the Managed Objects are absent and will delete if needed.
choices: [ absent, present ]
default: present
objects:
description:
- List of managed objects to configure. Each managed object has suboptions the specify the Python SDK module, class, and properties to configure.
suboptions:
module:
description:
- Name of the Python SDK module implementing the required class.
required: yes
class_name:
description:
- Name of the Python class that will be used to configure the Managed Object.
required: yes
properties:
description:
- List of properties to configure on the Managed Object. See the UCSM Python SDK for information on properties for each class.
required: yes
children:
description:
- Optional list of child objects. Each child has its own module, class, and properties suboptions.
- The parent_mo_or_dn property for child objects is automatically set as the list of children is configured.
required: yes
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- CiscoUcs (@CiscoUcs)
version_added: '2.8'
'''
EXAMPLES = r'''
- name: Configure Network Control Policy
cisco.ucs.ucs_managed_objects:
hostname: 172.16.143.150
username: admin
password: password
objects:
- module: ucsmsdk.mometa.nwctrl.NwctrlDefinition
class: NwctrlDefinition
properties:
parent_mo_or_dn: org-root
cdp: enabled
descr: ''
lldp_receive: enabled
lldp_transmit: enabled
name: Enable-CDP-LLDP
- name: Remove Network Control Policy
cisco.ucs.ucs_managed_objects:
hostname: 172.16.143.150
username: admin
password: password
objects:
- module: ucsmsdk.mometa.nwctrl.NwctrlDefinition
class: NwctrlDefinition
properties:
parent_mo_or_dn: org-root
name: Enable-CDP-LLDP
state: absent
- name: Configure Boot Policy Using JSON objects list with children
cisco.ucs.ucs_managed_objects:
hostname: 172.16.143.150
username: admin
password: password
objects:
- {
"module": "ucsmsdk.mometa.lsboot.LsbootPolicy",
"class": "LsbootPolicy",
"properties": {
"parent_mo_or_dn": "org-root",
"name": "Python_SDS",
"enforce_vnic_name": "yes",
"boot_mode": "legacy",
"reboot_on_update": "no"
},
"children": [
{
"module": "ucsmsdk.mometa.lsboot.LsbootVirtualMedia",
"class": "LsbootVirtualMedia",
"properties": {
"access": "read-only-local",
"lun_id": "0",
"order": "2"
}
},
{
"module": "ucsmsdk.mometa.lsboot.LsbootStorage",
"class": "LsbootStorage",
"properties": {
"order": "1"
},
"children": [
{
"module": "ucsmsdk.mometa.lsboot.LsbootLocalStorage",
"class": "LsbootLocalStorage",
"properties": {},
"children": [
{
"module": "ucsmsdk.mometa.lsboot.LsbootDefaultLocalImage",
"class": "LsbootDefaultLocalImage",
"properties": {
"order": "1"
}
}
]
}
]
}
]
}
- name: Remove Boot Policy Using JSON objects list
cisco.ucs.ucs_managed_objects:
hostname: 172.16.143.150
username: admin
password: password
objects:
- {
"module": "ucsmsdk.mometa.lsboot.LsbootPolicy",
"class": "LsbootPolicy",
"properties": {
"parent_mo_or_dn": "org-root",
"name": "Python_SDS"
}
}
state: absent
'''
RETURN = r'''
#
'''
try:
from importlib import import_module
HAS_IMPORT_MODULE = True
except ImportError:
HAS_IMPORT_MODULE = False
from copy import deepcopy
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def traverse_objects(module, ucs, managed_object, mo=''):
props_match = False
mo_module = import_module(managed_object['module'])
mo_class = getattr(mo_module, managed_object['class'])
if not managed_object['properties'].get('parent_mo_or_dn'):
managed_object['properties']['parent_mo_or_dn'] = mo
mo = mo_class(**managed_object['properties'])
existing_mo = ucs.login_handle.query_dn(mo.dn)
if module.params['state'] == 'absent':
# mo must exist, but all properties do not have to match
if existing_mo:
if not module.check_mode:
ucs.login_handle.remove_mo(existing_mo)
ucs.result['changed'] = True
else:
if existing_mo:
# check mo props
kwargs = dict(managed_object['properties'])
# remove parent info and passwords because those aren't presented in the actual props
kwargs.pop('parent_mo_or_dn', None)
kwargs.pop('pwd', None)
kwargs.pop('password', None)
if existing_mo.check_prop_match(**kwargs):
props_match = True
if not props_match:
if not module.check_mode:
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.result['changed'] = True
if managed_object.get('children'):
for child in managed_object['children']:
# explicit deep copy of child object since traverse_objects may modify parent mo information
copy_of_child = deepcopy(child)
traverse_objects(module, ucs, copy_of_child, mo)
def main():
object_dict = dict(
module=dict(type='str', required=True),
class_name=dict(type='str', aliases=['class'], required=True),
properties=dict(type='dict', required=True),
children=dict(type='list'),
)
argument_spec = ucs_argument_spec
argument_spec.update(
objects=dict(type='list', elements='dict', options=object_dict, required=True),
state=dict(type='str', choices=['present', 'absent'], default='present'),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
if not HAS_IMPORT_MODULE:
module.fail_json(msg='import_module is required for this module')
ucs = UCSModule(module)
# note that all objects specified in the object list report a single result (including a single changed).
ucs.result['changed'] = False
for managed_object in module.params['objects']:
traverse_objects(module, ucs, managed_object)
# single commit for object and any children
if not module.check_mode and ucs.result['changed']:
try:
ucs.login_handle.commit()
except Exception as e:
# generic Exception because UCSM can throw a variety of exceptions
ucs.result['msg'] = "setup error: %s " % str(e)
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,169 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'certified'}
DOCUMENTATION = r'''
---
module: ucs_ntp_server
short_description: Configures NTP server on Cisco UCS Manager
extends_documentation_fragment: cisco.ucs.ucs
description:
- Configures NTP server on Cisco UCS Manager.
options:
state:
description:
- If C(absent), will remove an NTP server.
- If C(present), will add or update an NTP server.
choices: [absent, present]
default: present
ntp_server:
description:
- NTP server IP address or hostname.
- Enter up to 63 characters that form a valid hostname.
- Enter a valid IPV4 Address.
aliases: [ name ]
default: ""
description:
description:
- A user-defined description of the NTP server.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
default: ""
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: "2.7"
'''
EXAMPLES = r'''
- name: Configure NTP server
cisco.ucs.ucs_ntp_server:
hostname: 172.16.143.150
username: admin
password: password
ntp_server: 10.10.10.10
description: Internal NTP Server by IP address
state: present
- name: Configure NTP server
cisco.ucs.ucs_ntp_server:
hostname: 172.16.143.150
username: admin
password: password
ntp_server: pool.ntp.org
description: External NTP Server by hostname
state: present
- name: Remove NTP server
cisco.ucs.ucs_ntp_server:
hostname: 172.16.143.150
username: admin
password: password
ntp_server: 10.10.10.10
state: absent
- name: Remove NTP server
cisco.ucs.ucs_ntp_server:
hostname: 172.16.143.150
username: admin
password: password
ntp_server: pool.ntp.org
state: absent
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def run_module():
argument_spec = ucs_argument_spec
argument_spec.update(
ntp_server=dict(type='str', aliases=['name']),
description=dict(type='str', aliases=['descr'], default=''),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_if=[
['state', 'present', ['ntp_server']],
],
)
# UCSModule verifies ucsmsdk is present and exits on failure. Imports are below ucs object creation.
ucs = UCSModule(module)
err = False
from ucsmsdk.mometa.comm.CommNtpProvider import CommNtpProvider
changed = False
try:
mo_exists = False
props_match = False
dn = 'sys/svc-ext/datetime-svc/ntp-' + module.params['ntp_server']
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
if module.params['state'] == 'absent':
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
changed = True
else:
if mo_exists:
# check top-level mo props
kwargs = dict(descr=module.params['description'])
if mo.check_prop_match(**kwargs):
props_match = True
if not props_match:
if not module.check_mode:
# update/add mo
mo = CommNtpProvider(parent_mo_or_dn='sys/svc-ext/datetime-svc',
name=module.params['ntp_server'],
descr=module.params['description'])
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
def main():
run_module()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,227 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_org
short_description: Manages UCS Organizations for UCS Manager
description:
- Manages UCS Organizations for UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(absent), will remove organization.
- If C(present), will create or update organization.
choices: [absent, present]
default: present
type: str
org_name:
description:
- The name of the organization.
- Enter up to 16 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ name ]
type: str
parent_org_path:
description:
- A forward slash / separated hierarchical path from the root organization to the parent of the organization to be added or updated.
- UCS Manager supports a hierarchical structure of organizations up to five levels deep not including the root organization.
- For example the parent_org_path for an organization named level5 could be root/level1/level2/level3/level4
default: root
type: str
description:
description:
- A user-defined description of the organization.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
type: str
delegate_to:
description:
- Where the module will be run
default: localhost
type: str
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: "2.8"
'''
EXAMPLES = r'''
- name: Add UCS Organization
cisco.ucs.ucs_org:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
org_name: test
description: testing org
state: present
delegate_to: localhost
- name: Update UCS Organization
cisco.ucs.ucs_org:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
org_name: test
description: Testing org
state: present
delegate_to: localhost
- name: Add UCS Organization
cisco.ucs.ucs_org:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
org_name: level1
parent_org_path: root
description: level1 org
state: present
delegate_to: localhost
- name: Add UCS Organization
cisco.ucs.ucs_org:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
org_name: level2
parent_org_path: root/level1
description: level2 org
state: present
- name: Add UCS Organization
cisco.ucs.ucs_org:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
org_name: level3
parent_org_path: root/level1/level2
description: level3 org
state: present
- name: Remove UCS Organization
cisco.ucs.ucs_org:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
org_name: level2
parent_org_path: root/level1
state: absent
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_name=dict(type='str', aliases=['name']),
parent_org_path=dict(type='str', default='root'),
description=dict(type='str', aliases=['descr']),
state=dict(type='str', default='present', choices=['present', 'absent']),
delegate_to=dict(type='str', default='localhost'),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_if=[
['state', 'present', ['org_name']],
],
)
# UCSModule verifies ucsmsdk is present and exits on failure.
# Imports are below for UCS object creation.
ucs = UCSModule(module)
from ucsmsdk.mometa.org.OrgOrg import OrgOrg
err = False
changed = False
requested_state = module.params['state']
kwargs = dict()
if module.params['description'] is not None:
kwargs['descr'] = module.params['description']
try:
parent_org_dn = 'org-' + module.params['parent_org_path'].replace('/', '/org-')
dn = parent_org_dn + '/org-' + module.params['org_name']
mo = ucs.login_handle.query_dn(dn)
# Determine state change
if mo:
# Object exists, if it should exist has anything changed?
if requested_state == 'present':
# Do some or all Object properties not match, that is a change
if not mo.check_prop_match(**kwargs):
changed = True
# Object does not exist but should, that is a change
else:
if requested_state == 'present':
changed = True
# Object exists but should not, that is a change
if mo and requested_state == 'absent':
changed = True
# Apply state if not check_mode
if changed and not module.check_mode:
if requested_state == 'absent':
ucs.login_handle.remove_mo(mo)
else:
kwargs['parent_mo_or_dn'] = parent_org_dn
kwargs['name'] = module.params['org_name']
if module.params['description'] is not None:
kwargs['descr'] = module.params['description']
mo = OrgOrg(**kwargs)
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.login_handle.commit()
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,172 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_query
short_description: Queries UCS Manager objects by class or distinguished name
description:
-Queries UCS Manager objects by class or distinguished name.
extends_documentation_fragment: cisco.ucs.ucs
options:
class_ids:
description:
- One or more UCS Manager Class IDs to query.
- As a comma separated list
type: str
distinguished_names:
description:
- One or more UCS Manager Distinguished Names to query.
- As a comma separated list
type: str
delegate_to:
description:
- Where the module will be run
default: localhost
type: str
requirements:
- ucsmsdk
author:
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: "2.8"
'''
EXAMPLES = r'''
- name: Query UCS Class ID
cisco.ucs.ucs_query:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
class_ids: computeBlade
delegate_to: localhost
- name: Query UCS Class IDs
cisco.ucs.ucs_query:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
class_ids: computeBlade, fabricVlan
delegate_to: localhost
- name: Query UCS Distinguished Name
cisco.ucs.ucs_query:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
distinguished_names: org-root
delegate_to: localhost
- name: Query UCS Distinguished Names
cisco.ucs.ucs_query:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
distinguished_names: org-root, sys/rack-unit-1, sys/chassis-1/blade-2
delegate_to: localhost
'''
RETURN = '''
objects:
description: results JSON encodded
type: dict
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def retrieve_class_id(class_id, ucs):
return ucs.login_handle.query_classid(class_id)
def retrieve_distinguished_name(distinguished_name, ucs):
return ucs.login_handle.query_dn(distinguished_name)
def make_mo_dict(ucs_mo):
obj_dict = {}
for mo_property in ucs_mo.prop_map.values():
obj_dict[mo_property] = getattr(ucs_mo, mo_property)
return obj_dict
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
class_ids=dict(type='str'),
distinguished_names=dict(type='str'),
delegate_to=dict(type='str', default='localhost'),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=False,
mutually_exclusive=[
['class_ids', 'distinguished_names'],
],
)
# UCSModule verifies ucsmsdk is present and exits on failure.
# Imports are below for UCS object creation.
ucs = UCSModule(module)
err = False
query_result = {}
try:
if module.params['class_ids']:
class_ids = [
x.strip() for x in module.params['class_ids'].split(',')
]
for class_id in class_ids:
query_result[class_id] = []
ucs_mos = retrieve_class_id(class_id, ucs)
if ucs_mos:
for ucs_mo in ucs_mos:
query_result[class_id].append(make_mo_dict(ucs_mo))
ucs.result['objects'] = query_result
elif module.params['distinguished_names']:
distinguished_names = [
x.strip()
for x in module.params['distinguished_names'].split(',')
]
for distinguished_name in distinguished_names:
query_result[distinguished_name] = {}
ucs_mo = retrieve_distinguished_name(distinguished_name, ucs)
if ucs_mo:
query_result[distinguished_name] = make_mo_dict(ucs_mo)
ucs.result['objects'] = query_result
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,248 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'certified'}
DOCUMENTATION = r'''
---
module: ucs_san_connectivity
short_description: Configures SAN Connectivity Policies on Cisco UCS Manager
description:
- Configures SAN Connectivity Policies on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify SAN Connectivity Policies are present and will create if needed.
- If C(absent), will verify SAN Connectivity Policies are absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name of the SAN Connectivity Policy.
- This name can be between 1 and 16 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- You cannot change this name after the policy is created.
required: yes
description:
description:
- A description of the policy.
- Cisco recommends including information about where and when to use the policy.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
wwnn_pool:
description:
- Name of the WWNN pool to use for WWNN assignment.
default: default
vhba_list:
description:
- List of vHBAs used by the SAN Connectivity Policy.
- vHBAs used by the SAN Connectivity Policy must be created from a vHBA template.
- "Each list element has the following suboptions:"
- "= name"
- " The name of the virtual HBA (required)."
- "= vhba_template"
- " The name of the virtual HBA template (required)."
- "- adapter_policy"
- " The name of the Fibre Channel adapter policy."
- " A user defined policy can be used, or one of the system defined policies (default, Linux, Solaris, VMware, Windows, WindowsBoot)"
- " [Default: default]"
- "- order"
- " String specifying the vHBA assignment order (e.g., '1', '2')."
- " [Default: unspecified]"
org_dn:
description:
- Org dn (distinguished name)
default: org-root
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: '2.5'
'''
EXAMPLES = r'''
- name: Configure SAN Connectivity Policy
cisco.ucs.ucs_san_connectivity:
hostname: 172.16.143.150
username: admin
password: password
name: Cntr-FC-Boot
wwnn_pool: WWNN-Pool
vhba_list:
- name: Fabric-A
vhba_template: vHBA-Template-A
adapter_policy: Linux
- name: Fabric-B
vhba_template: vHBA-Template-B
adapter_policy: Linux
- name: Remove SAN Connectivity Policy
cisco.ucs.ucs_san_connectivity:
hostname: 172.16.143.150
username: admin
password: password
name: Cntr-FC-Boot
state: absent
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(type='str'),
descr=dict(type='str'),
wwnn_pool=dict(type='str', default='default'),
vhba_list=dict(type='list'),
state=dict(type='str', default='present', choices=['present', 'absent']),
san_connectivity_list=dict(type='list'),
)
# Note that use of san_connectivity_list is an experimental feature which allows multiple resource updates with a single UCSM connection.
# Support for san_connectivity_list may change or be removed once persistent UCS connections are supported.
# Either san_connectivity_list or name is required (user can specify either a list or single resource).
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_one_of=[
['san_connectivity_list', 'name'],
],
mutually_exclusive=[
['san_connectivity_list', 'name'],
],
)
ucs = UCSModule(module)
err = False
from ucsmsdk.mometa.vnic.VnicSanConnPolicy import VnicSanConnPolicy
from ucsmsdk.mometa.vnic.VnicFcNode import VnicFcNode
from ucsmsdk.mometa.vnic.VnicFc import VnicFc
from ucsmsdk.mometa.vnic.VnicFcIf import VnicFcIf
changed = False
try:
# Only documented use is a single resource, but to also support experimental
# feature allowing multiple updates all params are converted to a san_connectivity_list below.
if module.params['san_connectivity_list']:
# directly use the list (single resource and list are mutually exclusive
san_connectivity_list = module.params['san_connectivity_list']
else:
# single resource specified, create list from the current params
san_connectivity_list = [module.params]
for san_connectivity in san_connectivity_list:
mo_exists = False
props_match = False
# set default params. Done here to set values for lists which can't be done in the argument_spec
if not san_connectivity.get('descr'):
san_connectivity['descr'] = ''
if not san_connectivity.get('wwnn_pool'):
san_connectivity['wwnn_pool'] = 'default'
if san_connectivity.get('vhba_list'):
for vhba in san_connectivity['vhba_list']:
if not vhba.get('adapter_policy'):
vhba['adapter_policy'] = ''
if not vhba.get('order'):
vhba['order'] = 'unspecified'
# dn is <org_dn>/san-conn-pol-<name>
dn = module.params['org_dn'] + '/san-conn-pol-' + san_connectivity['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
# check top-level mo props
kwargs = dict(descr=san_connectivity['descr'])
if (mo.check_prop_match(**kwargs)):
# top-level props match, check next level mo/props
# vnicFcNode object
child_dn = dn + '/fc-node'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(ident_pool_name=san_connectivity['wwnn_pool'])
if (mo_1.check_prop_match(**kwargs)):
if not san_connectivity.get('vhba_list'):
props_match = True
else:
# check vnicFc props
for vhba in san_connectivity['vhba_list']:
child_dn = dn + '/fc-' + vhba['name']
mo_2 = ucs.login_handle.query_dn(child_dn)
kwargs = {}
kwargs['adaptor_profile_name'] = vhba['adapter_policy']
kwargs['order'] = vhba['order']
kwargs['nw_templ_name'] = vhba['vhba_template']
if (mo_2.check_prop_match(**kwargs)):
props_match = True
if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
changed = True
else:
if not props_match:
if not module.check_mode:
# create if mo does not already exist
mo = VnicSanConnPolicy(
parent_mo_or_dn=module.params['org_dn'],
name=san_connectivity['name'],
descr=san_connectivity['descr'],
)
mo_1 = VnicFcNode(
parent_mo_or_dn=mo,
ident_pool_name=san_connectivity['wwnn_pool'],
addr='pool-derived',
)
if san_connectivity.get('vhba_list'):
for vhba in san_connectivity['vhba_list']:
mo_2 = VnicFc(
parent_mo_or_dn=mo,
name=vhba['name'],
adaptor_profile_name=vhba['adapter_policy'],
nw_templ_name=vhba['vhba_template'],
order=vhba['order'],
)
mo_2_1 = VnicFcIf(
parent_mo_or_dn=mo_2,
name='default',
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,320 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_scrub_policy
short_description: Manages UCS Scrub Policies on UCS Manager
description:
- Manages UCS Scrub Policies on UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(absent), will remove organization.
- If C(present), will create or update organization.
choices: [absent, present]
default: present
type: str
name:
description:
- The name of the organization.
- Enter up to 16 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote)"
- "= (equal sign), > (greater than), < (less than), ' (single quote)."
required: true
type: str
description:
description:
- A user-defined description of the organization.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote)"
- "= (equal sign), > (greater than), < (less than), ' (single quote)."
aliases: [ descr ]
type: str
bios_settings_scrub:
description:
- Scrub the BIOS settings.
- If the field is set to Yes, when a service profile containing this
- scrub policy is disassociated from a server, the BIOS settings for
- that server are erased and reset to the defaults for that server
- type and vendor. If this field is set to No, the BIOS settings are
- preserved.
- yes scrub the BIOS settings.
- no do not scrub the BIOS settings.
choices: [yes, no]
type: str
disk_scrub:
description:
- Scrub the BIOS settings.
- If this field is set to Yes, when a service profile containing this
- scrub policy is disassociated from a server, all data on the server
- local drives is completely erased. If this field is set to No, the
- data on the local drives is preserved, including all local storage
- configuration.
- yes scrub the server disks.
- no do not scrub the server disks.
choices: [yes, no]
type: str
flex_flash_scrub:
description:
- Scrub the BIOS settings.
- If the field is set to Yes, the HV partition on the SD card is
- formatted using the PNUOS formatting utility when the server is
- reacknowledged. If this field is set to No, the SD card is preserved.
- yes scrub the flex flash.
- no do not scrub the flex flash.
choices: [yes, no]
type: str
persistent_memory_scrub:
description:
- Scrub the BIOS settings.
- If the field is set to Yes, when a service profile containing this
- scrub policy is disassociated from a server, all persistent memory
- modules for that server are erased and reset to the defaults for that
- server type and vendor. If this field is set to No, the persistent
- memory modules are preserved.
- yes scrub the persistent memory.
- no do not scrub the persistent memory.
choices: [yes, no]
type: str
org_dn:
description:
- Org dn (distinguished name)
default: org-root
type: str
requirements:
- ucsmsdk
author:
- John McDonough (@movinalot)
version_added: "2.9"
'''
EXAMPLES = r'''
- name: Add UCS Scrub Policy
cisco.ucs.ucs_scrub_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
description: Scrub All Policy
name: all_scrub
bios_settings_scrub: yes
disk_scrub: yes
flex_flash_scrub: yes
persistent_memory_scrub: yes
delegate_to: localhost
- name: Add UCS Scrub Policy in an Organization
cisco.ucs.ucs_scrub_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
name: all_scrub
description: Scrub All Policy Org Prod servers
bios_settings_scrub: yes
disk_scrub: yes
flex_flash_scrub: yes
persistent_memory_scrub: yes
delegate_to: localhost
- name: Update UCS Scrub Policy
cisco.ucs.ucs_scrub_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
name: BD_scrub
description: Scrub BIOS and Disk Policy Org Prod servers
bios_settings_scrub: yes
disk_scrub: yes
flex_flash_scrub: no
persistent_memory_scrub: no
delegate_to: localhost
- name: Update UCS Scrub Policy
cisco.ucs.ucs_scrub_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
name: BD_scrub
description: Scrub BIOS and Disk Policy Org Prod servers
bios_settings_scrub: yes
disk_scrub: yes
flex_flash_scrub: yes
delegate_to: localhost
- name: Delete UCS Scrub Policy
cisco.ucs.ucs_scrub_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: absent
org_dn: org-root/org-prod
name: BD_scrub
delegate_to: localhost
- name: Delete UCS Scrub Policy
cisco.ucs.ucs_scrub_policy:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: absent
name: BD_scrub
delegate_to: localhost
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import (
UCSModule,
ucs_argument_spec
)
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(required=True, type='str'),
descr=dict(type='str'),
description=dict(type='str', aliases=['descr']),
bios_settings_scrub=dict(type='str', choices=['yes', 'no']),
disk_scrub=dict(type='str', choices=['yes', 'no']),
flex_flash_scrub=dict(type='str', choices=['yes', 'no']),
persistent_memory_scrub=dict(type='str', choices=['yes', 'no']),
state=dict(
type='str', default='present',
choices=['present', 'absent']
),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_if=[
['state', 'present', ['name']],
],
)
# UCSModule verifies ucsmsdk is present and exits on failure.
# Imports are below for UCS object creation.
ucs = UCSModule(module)
from importlib import import_module
from ucsmsdk.ucscoreutils import get_meta_info
# The Class(es) this module is managing
module_file = 'ucsmsdk.mometa.compute.ComputeScrubPolicy'
module_class = 'ComputeScrubPolicy'
mo_module = import_module(module_file)
mo_class = getattr(mo_module, module_class)
META = get_meta_info(class_id=module_class)
err = False
changed = False
requested_state = module.params['state']
kwargs = dict()
# Manage Aliased Attributes
for attribute in ['descr:description']:
attribute_alias = attribute.split(':')
if module.params[attribute_alias[1]] is not None:
kwargs[attribute_alias[0]] = module.params[attribute_alias[1]]
# Manage Attributes
for attribute in [
'bios_settings_scrub',
'descr',
'disk_scrub',
'flex_flash_scrub',
'persistent_memory_scrub'
]:
if module.params[attribute] is not None:
kwargs[attribute] = module.params[attribute]
try:
dn = (
module.params['org_dn'] + '/' +
META.rn[0:META.rn.index('-') + 1] +
module.params['name']
)
mo = ucs.login_handle.query_dn(dn)
# Determine state change
if mo:
# Object exists, if it should exist has anything changed?
if requested_state == 'present':
# Do some or all Object properties not match, that is a change
if not mo.check_prop_match(**kwargs):
changed = True
# Object does not exist but should, that is a change
else:
if requested_state == 'present':
changed = True
# Object exists but should not, that is a change
if mo and requested_state == 'absent':
changed = True
# Apply state if not check_mode
if changed and not module.check_mode:
if requested_state == 'absent':
ucs.login_handle.remove_mo(mo)
else:
kwargs['parent_mo_or_dn'] = module.params['org_dn']
kwargs['name'] = module.params['name']
mo = mo_class(**kwargs)
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.login_handle.commit()
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,271 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_serial_over_lan_policy
short_description: Manages UCS Serial Over Lan Policies on UCS Manager
description:
- Manages UCS Serial Over Lan Policies on UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(absent), will remove Serial Over Lan Policy.
- If C(present), will create or update Serial Over Lan Policy.
choices: [absent, present]
default: present
type: str
name:
description:
- The name of the serial over lan policy.
- Enter up to 16 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote)"
- "= (equal sign), > (greater than), < (less than), ' (single quote)."
required: true
type: str
description:
description:
- A user-defined description of the serial over lan policy.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote)"
- "= (equal sign), > (greater than), < (less than), ' (single quote)."
aliases: [ descr ]
type: str
admin_state:
description:
- The administrative state of the serial over lan policy.
- disable Serial over LAN access is blocked.
- enable Serial over LAN access is permitted.
choices: [disable, enable]
type: str
speed:
description:
- The transmission speed of the serial over lan policy.
choices: [9600, 19200, 38400, 57600, 115200]
type: str
org_dn:
description:
- Org dn (distinguished name) of the serial over lan policy.
default: org-root
type: str
requirements:
- ucsmsdk
author:
- John McDonough (@movinalot)
version_added: "2.9"
'''
EXAMPLES = r'''
- name: Add UCS Serial Over Lan Policy
cisco.ucs.ucs_serial_over_lan:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
name: sol_org_root
description: Serial Over Lan for Org root servers
admin_state: enable
speed: 115200
delegate_to: localhost
- name: Add UCS Serial Over Lan Policy in Organization
cisco.ucs.ucs_serial_over_lan:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
name: sol_org_prod
description: Serial Over Lan for Org Prod servers
admin_state: enable
speed: 115200
delegate_to: localhost
- name: Update UCS Serial Over Lan Policy in Organization
cisco.ucs.ucs_serial_over_lan:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
name: sol_org_prod
description: Serial Over Lan for Org Prod servers
admin_state: enable
speed: 38400
delegate_to: localhost
- name: Update UCS Serial Over Lan Policy in Organization
cisco.ucs.ucs_serial_over_lan:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: present
org_dn: org-root/org-prod
name: sol_org_prod
descr: Serial Over Lan for Org Prod servers
admin_state: enable
speed: 57600
delegate_to: localhost
- name: Delete UCS Serial Over Lan Policy in Organization
cisco.ucs.ucs_serial_over_lan:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: absent
org_dn: org-root/org-prod
name: sol_org_prod
delegate_to: localhost
- name: Delete UCS Serial Over Lan Policy
cisco.ucs.ucs_serial_over_lan:
hostname: "{{ ucs_hostname }}"
username: "{{ ucs_username }}"
password: "{{ ucs_password }}"
state: absent
name: sol_org_root
delegate_to: localhost
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import (
UCSModule,
ucs_argument_spec
)
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(required=True, type='str'),
descr=dict(type='str'),
description=dict(type='str', aliases=['descr']),
admin_state=dict(type='str', choices=['enable', 'disable']),
speed=dict(type='str', choices=[
'9600', '19200', '38400', '57600', '115200'
]),
state=dict(
type='str', default='present',
choices=['present', 'absent']
),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_if=[
['state', 'present', ['name']],
],
)
# UCSModule verifies ucsmsdk is present and exits on failure.
# Imports are below for UCS object creation.
ucs = UCSModule(module)
from importlib import import_module
from ucsmsdk.ucscoreutils import get_meta_info
# The Class(es) this module is managing
module_file = 'ucsmsdk.mometa.sol.SolPolicy'
module_class = 'SolPolicy'
mo_module = import_module(module_file)
mo_class = getattr(mo_module, module_class)
META = get_meta_info(class_id=module_class)
err = False
changed = False
requested_state = module.params['state']
kwargs = dict()
# Manage Aliased Attributes
for attribute in ['descr:description']:
attribute_alias = attribute.split(':')
if module.params[attribute_alias[1]] is not None:
kwargs[attribute_alias[0]] = module.params[attribute_alias[1]]
# Manage Attributes
for attribute in ['admin_state', 'descr', 'speed']:
if module.params[attribute] is not None:
kwargs[attribute] = module.params[attribute]
try:
dn = (
module.params['org_dn'] + '/' +
META.rn[0:META.rn.index('-') + 1] +
module.params['name']
)
mo = ucs.login_handle.query_dn(dn)
# Determine state change
if mo:
# Object exists, if it should exist has anything changed?
if requested_state == 'present':
# Do some or all Object properties not match, that is a change
if not mo.check_prop_match(**kwargs):
changed = True
# Object does not exist but should, that is a change
else:
if requested_state == 'present':
changed = True
# Object exists but should not, that is a change
if mo and requested_state == 'absent':
changed = True
# Apply state if not check_mode
if changed and not module.check_mode:
if requested_state == 'absent':
ucs.login_handle.remove_mo(mo)
else:
kwargs['parent_mo_or_dn'] = module.params['org_dn']
kwargs['name'] = module.params['name']
mo = mo_class(**kwargs)
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.login_handle.commit()
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,158 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_server_maintenance
short_description: Creates Server Maintenance Policy on Cisco UCS Manager
version_added: 2.10
description:
- Configures Server Maintenance Policy on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify Server Maintenance Policy is present and will create if needed.
- If C(absent), will verify Server Maintenance Policy is absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name assigned to the Server Maintenance Policy.
- The Server Maintenance Policy name is case sensitive.
- This name can be between 1 and 16 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- You cannot change this name after the Server Maintenance Policy is created.
required: yes
description:
description:
- A description of the Server Maintenance Package Policy.
- Cisco recommends including information about where and when to use the policy.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
trigger_config:
description:
- This option is used in combination with either User Ack (user-ack) or Timer Automatic (timer-automatic).
- 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.
- Note that de-selecting the On Next Boot option disables the Maintenance Policy on the BMC.
choices: [on-next-boot]
uptime_disr:
description:
- When a Server profile is associated with a Server, or when changes are made to a Server profile that is already associated with a Server, you must reboot the Server to complete the process.
- The Reboot Policy field determines when the reboot occurs for Server associated with any Server profiles that include this maintenance policy.
choices: [immediate, timer-automatic, user-ack]
required: true
requirements:
- ucsmsdk
author:
- Brett Johnson (@brettjohnson008)
'''
EXAMPLES = r'''
- name: Add Server Maintenance Policy
cisco.ucs.ucs_server_maintenance:
hostname: 172.16.143.150
username: admin
password: password
name: user-ack
uptime_disr: user-ack
trigger_config: on-next-boot
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
name=dict(type='str', required=True),
description=dict(type='str', default=''),
trigger_config=dict(type='str', default='', choices=['on-next-boot']),
uptime_disr=dict(type='str', required=True, choices=['immediate', 'timer-automatic', 'user-ack']),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
ucs = UCSModule(module)
err = False
# UCSModule creation above verifies ucsmsdk is present and exits on failure, so additional imports are done below.
from ucsmsdk.mometa.lsmaint.LsmaintMaintPolicy import LsmaintMaintPolicy
changed = False
try:
mo_exists = False
props_match = False
dn_base = 'org-root'
dn = dn_base + '/maint-' + module.params['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
changed = True
else:
if mo_exists:
# check top-level mo props
kwargs = dict(name=module.params['name'])
kwargs['descr'] = module.params['description']
kwargs['trigger_config'] = module.params['trigger_config']
kwargs['uptime_disr'] = module.params['uptime_disr']
if mo.check_prop_match(**kwargs):
props_match = True
if not props_match:
if not module.check_mode:
# create if mo does not already exist
mo = LsmaintMaintPolicy(
parent_mo_or_dn=dn_base,
name=module.params['name'],
descr=module.params['description'],
trigger_config=module.params['trigger_config'],
uptime_disr=module.params['uptime_disr'],
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,252 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_service_profile_association
short_description: Configures Service Profile Association on Cisco UCS Manager
description:
- Configures Service Profile Association (change association or disassociate) on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify service profile association and associate with specified server or server pool if needed.
- If C(absent), will verify service profile is not associated and will disassociate if needed. This is the same as specifying Assign Later in the webUI.
choices: [present, absent]
default: present
service_profile_name:
description:
- The name of the Service Profile being associated or disassociated.
required: yes
server_assignment:
description:
- "Specifies how to associate servers with this service profile using the following choices:"
- "server - Use to pre-provision a slot or select an existing server. Slot or server is specified by the server_dn option."
- "pool - Use to select from a server pool. The server_pool option specifies the name of the server pool to use."
- Option is not valid if the service profile is bound to a template.
- Optional if the state is absent.
choices: [server, pool]
required: yes
server_dn:
description:
- The Distinguished Name (dn) of the server object used for pre-provisioning or selecting an existing server.
- Required if the server_assignment option is server.
- Optional if the state is absent.
server_pool_name:
description:
- Name of the server pool used for server pool based assignment.
- Required if the server_assignment option is pool.
- Optional if the state is absent.
restrict_migration:
description:
- Restricts the migration of the service profile after it has been associated with a server.
- If set to no, Cisco UCS Manager does not perform any compatibility checks on the new server before migrating the existing service profile.
- If set to no and the hardware of both servers used in migration are not similar, the association might fail.
choices: ['yes', 'no']
default: 'no'
org_dn:
description:
- The distinguished name (dn) of the organization where the resource is assigned.
default: org-root
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- CiscoUcs (@CiscoUcs)
version_added: 2.10
'''
EXAMPLES = r'''
- name: Change Service Profile Association to server pool Container-Pool and restrict migration
cisco.ucs.ucs_service_profile_association:
hostname: 172.16.143.150
username: admin
password: password
service_profile_name: test-sp
server_assignment: pool
server_pool_name: Container-Pool
restrict_migration: 'yes'
- name: Attempt to change association once a minute for up to 10 minutes
cisco.ucs.ucs_service_profile_association:
hostname: 172.16.143.150
username: admin
password: password
service_profile_name: test-sp
server_assignment: server
server_dn: sys/chassis-2/blade-1
register: result
until: result.assign_state == 'assigned' and result.assoc_state == 'associated'
retries: 10
delay: 60
- name: Disassociate Service Profile
cisco.ucs.ucs_service_profile_association:
hostname: 172.16.143.150
username: admin
password: password
service_profile_name: test-sp
state: absent
'''
RETURN = r'''
assign_state:
description: The logical server Assigned State (assigned, unassigned, or failed).
returned: success
type: string
sample: assigned
assoc_state:
description: The logical server Association State (associated or unassociated).
returned: success
type: string
sample: associated
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
service_profile_name=dict(type='str', required=True),
server_assignment=dict(type='str', choices=['server', 'pool']),
server_dn=dict(type='str'),
server_pool_name=dict(type='str'),
restrict_migration=dict(type='str', default='no', choices=['yes', 'no']),
state=dict(default='present', choices=['present', 'absent'], type='str'),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_if=[
['state', 'present', ['server_assignment']],
['server_assignment', 'server', ['server_dn']],
['server_assignment', 'pool', ['server_pool_name']],
],
mutually_exclusive=[
['server_dn', 'server_pool_name'],
],
)
# UCSModule verifies ucsmsdk is present and exits on failure. Imports are below ucs object creation.
ucs = UCSModule(module)
err = False
from ucsmsdk.mometa.ls.LsRequirement import LsRequirement
from ucsmsdk.mometa.ls.LsBinding import LsBinding
from ucsmsdk.mometa.ls.LsServer import LsServer
changed = False
ucs.result['assign_state'] = 'unassigned'
ucs.result['assoc_state'] = 'unassociated'
try:
ls_mo_exists = False
pn_mo_exists = False
pn_req_mo_exists = False
props_match = False
# logical server distinguished name is <org>/ls-<name> and physical node dn appends 'pn' or 'pn-req'
ls_dn = module.params['org_dn'] + '/ls-' + module.params['service_profile_name']
ls_mo = ucs.login_handle.query_dn(ls_dn)
if ls_mo:
ls_mo_exists = True
pn_dn = ls_dn + '/pn'
pn_mo = ucs.login_handle.query_dn(pn_dn)
if pn_mo:
pn_mo_exists = True
pn_req_dn = ls_dn + '/pn-req'
pn_req_mo = ucs.login_handle.query_dn(pn_req_dn)
if pn_req_mo:
pn_req_mo_exists = True
if module.params['state'] == 'absent':
if ls_mo_exists and ls_mo.assign_state != 'unassigned':
if pn_mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(pn_mo)
ucs.login_handle.commit()
changed = True
elif pn_req_mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(pn_req_mo)
ucs.login_handle.commit()
changed = True
elif ls_mo_exists:
# check if logical server is assigned and associated
ucs.result['assign_state'] = ls_mo.assign_state
ucs.result['assoc_state'] = ls_mo.assoc_state
if module.params['server_assignment'] == 'pool' and pn_req_mo_exists:
# check the current pool
kwargs = dict(name=module.params['server_pool_name'])
kwargs['restrict_migration'] = module.params['restrict_migration']
if pn_req_mo.check_prop_match(**kwargs):
props_match = True
elif pn_mo_exists:
kwargs = dict(pn_dn=module.params['server_dn'])
kwargs['restrict_migration'] = module.params['restrict_migration']
if pn_mo.check_prop_match(**kwargs):
props_match = True
if not props_match:
if not module.check_mode:
# create if mo does not already exist in desired state
mo = LsServer(
parent_mo_or_dn=module.params['org_dn'],
name=module.params['service_profile_name'],
)
if module.params['server_assignment'] == 'pool':
if pn_mo_exists:
ucs.login_handle.remove_mo(pn_mo)
mo_1 = LsRequirement(
parent_mo_or_dn=mo,
name=module.params['server_pool_name'],
restrict_migration=module.params['restrict_migration'],
)
else:
mo_1 = LsBinding(
parent_mo_or_dn=mo,
pn_dn=module.params['server_dn'],
restrict_migration=module.params['restrict_migration'],
)
ucs.login_handle.add_mo(mo_1, True)
ucs.login_handle.commit()
pn_req_mo = ucs.login_handle.query_dn(pn_req_dn)
if pn_req_mo:
# profiles from templates will add a server pool, so remove and add the server again
ucs.login_handle.remove_mo(pn_req_mo)
ucs.login_handle.add_mo(mo_1, True)
ucs.login_handle.commit()
ls_mo = ucs.login_handle.query_dn(ls_dn)
if ls_mo:
ucs.result['assign_state'] = ls_mo.assign_state
ucs.result['assoc_state'] = ls_mo.assoc_state
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,184 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_service_profile_from_template
short_description: Configures Service Profiles from templates on Cisco UCS Manager
description:
- Configures Service Profile created from templates on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify Service Profiles are present and will create if needed.
- If C(absent), will verify Service Profiles are absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name of the service profile.
- This name can be between 2 and 32 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- This name must be unique across all service profiles and service profile templates within the same organization.
required: yes
source_template:
description:
- The name of the service profile template used to create this serivce profile.
required: yes
power_state:
description:
- The power state to be applied when this service profile is associated with a server.
- If no value is provided, the power_state for the service profile will not be modified.
choices: [up, down]
user_label:
description:
- The User Label you want to assign to this service profile.
org_dn:
description:
- Org dn (distinguished name)
default: org-root
description:
description:
- Optional
- The Description of the service profile
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- CiscoUcs (@CiscoUcs)
version_added: '2.5'
'''
EXAMPLES = r'''
- name: Configure Service Profile from Template
cisco.ucs.ucs_service_profile_from_template:
hostname: 172.16.143.150
username: admin
password: password
name: test-sp-instance1
source_template: test-sp
discription: Created from Ansible
- name: Remove Service Profile
cisco.ucs.ucs_service_profile_from_template:
hostname: 172.16.143.150
username: admin
password: password
name: test-sp-instance1
state: absent
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(type='str', required=True),
source_template=dict(type='str', required=True),
user_label=dict(type='str', default=''),
power_state=dict(type='str', choices=['up', 'down']),
state=dict(type='str', default='present', choices=['present', 'absent']),
description=dict(type='str', default=''),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
ucs = UCSModule(module)
err = False
# UCSModule creation above verifies ucsmsdk is present and exits on failure. Additional imports are done below.
from ucsmsdk.mometa.ls.LsServer import LsServer
from ucsmsdk.mometa.ls.LsPower import LsPower
changed = False
try:
mo_exists = False
props_match = False
dn = module.params['org_dn'] + '/ls-' + module.params['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
changed = True
else:
if mo_exists:
# check top-level mo props
kwargs = dict(src_templ_name=module.params['source_template'])
kwargs['usr_lbl'] = module.params['user_label']
# service profiles are of type 'instance'
kwargs['type'] = 'instance'
if mo.check_prop_match(**kwargs):
# top-level props match
if module.params.get('power_state'):
child_dn = dn + '/power'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(state=module.params['power_state'])
if mo_1.check_prop_match(**kwargs):
props_match = True
else:
# no power state provided, use existing state as match
props_match = True
if not props_match:
if not module.check_mode:
# create if mo does not already exist
mo = LsServer(
parent_mo_or_dn=module.params['org_dn'],
name=module.params['name'],
src_templ_name=module.params['source_template'],
type='instance',
usr_lbl=module.params['user_label'],
descr=module.params['description'],
)
if module.params.get('power_state'):
admin_state = 'admin-' + module.params['power_state']
mo_1 = LsPower(
parent_mo_or_dn=mo,
state=admin_state,
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,523 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_service_profile_template
short_description: Configures Service Profile Templates on Cisco UCS Manager
description:
- Configures Service Profile Templates on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify Service Profile Templates are present and will create if needed.
- If C(absent), will verify Service Profile Templates are absent and will delete if needed.
choices: [present, absent]
default: present
name:
description:
- The name of the service profile template.
- This name can be between 2 and 32 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- This name must be unique across all service profiles and service profile templates within the same organization.
required: yes
template_type:
description:
- "The template type field which can be one of the following:"
- "initial-template — Any service profiles created from this template are not updated if the template changes."
- "updating-template — Any service profiles created from this template are updated if the template changes."
choices: [initial-template, updating-template]
default: initial-template
uuid_pool:
description:
- Specifies how the UUID will be set on a server associated with a service profile created from this template.
- "The uuid_pool option can be the name of the UUID pool to use or '' (the empty string)."
- An empty string will use the UUID assigned to the server by the manufacturer, and the
- UUID remains unassigned until a service profile created from this template is associated with a server. At that point,
- the UUID is set to the UUID value assigned to the server by the manufacturer. If the service profile is later moved to
- a different server, the UUID is changed to match the new server."
default: default
description:
description:
- A user-defined description of the service profile template.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
storage_profile:
description:
- The name of the storage profile you want to associate with service profiles created from this template
local_disk_policy:
description:
- The name of the local disk policy you want to associate with service profiles created from this template.
lan_connectivity_policy:
description:
- The name of the LAN connectivity policy you want to associate with service profiles created from this template.
iqn_pool:
description:
- The name of the IQN pool (initiator) you want to apply to all iSCSI vNICs for service profiles created from this template.
san_connectivity_policy:
description:
- The name of the SAN connectivity policy you want to associate with service profiles created from this template.
vmedia_policy:
description:
- The name of the vMedia policy you want to associate with service profiles created from this template.
boot_policy:
description:
- The name of the boot order policy you want to associate with service profiles created from this template.
default: default
maintenance_policy:
description:
- The name of the maintenance policy you want to associate with service profiles created from this template.
server_pool:
description:
- The name of the server pool you want to associate with this service profile template.
server_pool_qualification:
description:
- The name of the server pool policy qualificaiton you want to use for this service profile template.
power_state:
description:
- The power state to be applied when a service profile created from this template is associated with a server.
choices: [up, down]
default: up
host_firmware_package:
description:
- The name of the host firmware package you want to associate with service profiles created from this template.
bios_policy:
description:
- The name of the BIOS policy you want to associate with service profiles created from this template.
ipmi_access_profile:
description:
- The name of the IPMI access profile you want to associate with service profiles created from this template.
sol_policy:
description:
- The name of the Serial over LAN (SoL) policy you want to associate with service profiles created from this template.
mgmt_ip_state:
description:
- The state for the Outband Management IP pool you want to use with service profiles created from this template.
choices: [none, pooled]
default: pooled
mgmt_ip_pool:
description:
- The name of the Outband Management IP pool you want to use with service profiles created from this template.
default: ext-mgmt
power_control_policy:
description:
- The name of the power control policy you want to associate with service profiles created from this template.
default: default
power_sync_policy:
description:
- The name of the power sync policy you want to associate with service profiles created from this template.
scrub_policy:
description:
- The name of the scrub policy you want to associate with service profiles created from this template.
kvm_mgmt_policy:
description:
- The name of the KVM management policy you want to associate with service profiles created from this template.
graphics_card_policy:
description:
- The name of the graphics card policy you want to associate with service profiles created from this template.
threshold_policy:
description:
- The name of the threshold policy you want to associate with service profiles created from this template.
default: default
user_label:
description:
- The User Label you want to assign to service profiles created from this template.
mgmt_interface_mode:
description:
- The Management Interface you want to assign to service profiles created from this template.
choices: ['', in-band]
mgmt_vnet_name:
description:
- A VLAN selected from the associated VLAN group.
mgmt_inband_pool_name:
description:
- How the inband management IPv4 address is derived for the server associated with this service profile.
org_dn:
description:
- Org dn (distinguished name)
default: org-root
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- CiscoUcs (@CiscoUcs)
version_added: '2.8'
'''
EXAMPLES = r'''
- name: Configure Service Profile Template with LAN/SAN Connectivity and all other options defaulted
cisco.ucs.ucs_service_profile_template:
hostname: 172.16.143.150
username: admin
password: password
name: DEE-Ctrl
template_type: updating-template
uuid_pool: UUID-Pool
storage_profile: DEE-StgProf
lan_connectivity_policy: Cntr-FC-Boot
iqn_pool: iSCSI-Boot-A
san_connectivity_policy: Cntr-FC-Boot
boot_policy: DEE-vMedia
maintenance_policy: default
server_pool: Container-Pool
host_firmware_package: 3.1.2b
bios_policy: Docker
- name: Remove Service Profile Template
cisco.ucs.ucs_service_profile_template:
hostname: 172.16.143.150
username: admin
password: password
name: DEE-Ctrl
state: absent
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def configure_service_profile_template(ucs, module):
from ucsmsdk.mometa.ls.LsServer import LsServer
from ucsmsdk.mometa.vnic.VnicConnDef import VnicConnDef
from ucsmsdk.mometa.vnic.VnicIScsiNode import VnicIScsiNode
from ucsmsdk.mometa.ls.LsRequirement import LsRequirement
from ucsmsdk.mometa.ls.LsPower import LsPower
from ucsmsdk.mometa.lstorage.LstorageProfileBinding import LstorageProfileBinding
from ucsmsdk.mometa.mgmt.MgmtInterface import MgmtInterface
from ucsmsdk.mometa.mgmt.MgmtVnet import MgmtVnet
from ucsmsdk.mometa.vnic.VnicIpV4MgmtPooledAddr import VnicIpV4MgmtPooledAddr
if not module.check_mode:
try:
# create if mo does not already exist
mo = LsServer(
parent_mo_or_dn=module.params['org_dn'],
bios_profile_name=module.params['bios_policy'],
boot_policy_name=module.params['boot_policy'],
descr=module.params['description'],
ext_ip_state=module.params['mgmt_ip_state'],
ext_ip_pool_name=module.params['mgmt_ip_pool'],
# graphics_card_policy_name=module.params['graphics_card_policy'],
host_fw_policy_name=module.params['host_firmware_package'],
ident_pool_name=module.params['uuid_pool'],
kvm_mgmt_policy_name=module.params['kvm_mgmt_policy'],
local_disk_policy_name=module.params['local_disk_policy'],
maint_policy_name=module.params['maintenance_policy'],
mgmt_access_policy_name=module.params['ipmi_access_profile'],
name=module.params['name'],
power_policy_name=module.params['power_control_policy'],
power_sync_policy_name=module.params['power_sync_policy'],
scrub_policy_name=module.params['scrub_policy'],
sol_policy_name=module.params['sol_policy'],
stats_policy_name=module.params['threshold_policy'],
type=module.params['template_type'],
usr_lbl=module.params['user_label'],
vmedia_policy_name=module.params['vmedia_policy'],
)
if module.params['storage_profile']:
# Storage profile
mo_1 = LstorageProfileBinding(
parent_mo_or_dn=mo,
storage_profile_name=module.params['storage_profile'],
)
if module.params['mgmt_interface_mode']:
# Management Interface
mo_1 = MgmtInterface(
parent_mo_or_dn=mo,
mode=module.params['mgmt_interface_mode'],
ip_v4_state='pooled',
)
mo_2 = MgmtVnet(
parent_mo_or_dn=mo_1,
id='1',
name=module.params['mgmt_vnet_name'],
)
VnicIpV4MgmtPooledAddr(
parent_mo_or_dn=mo_2,
name=module.params['mgmt_inband_pool_name'],
)
# LAN/SAN connectivity policy
mo_1 = VnicConnDef(
parent_mo_or_dn=mo,
lan_conn_policy_name=module.params['lan_connectivity_policy'],
san_conn_policy_name=module.params['san_connectivity_policy'],
)
if module.params['iqn_pool']:
# IQN pool
mo_1 = VnicIScsiNode(
parent_mo_or_dn=mo,
iqn_ident_pool_name=module.params['iqn_pool']
)
# power state
admin_state = 'admin-' + module.params['power_state']
mo_1 = LsPower(
parent_mo_or_dn=mo,
state=admin_state,
)
if module.params['server_pool']:
# server pool
mo_1 = LsRequirement(
parent_mo_or_dn=mo,
name=module.params['server_pool'],
qualifier=module.params['server_pool_qualification'],
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
except Exception as e: # generic Exception handling because SDK can throw a variety of exceptions
ucs.result['msg'] = "setup error: %s " % str(e)
module.fail_json(**ucs.result)
ucs.result['changed'] = True
def check_storage_profile_props(ucs, module, dn):
props_match = False
child_dn = dn + '/profile-binding'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(storage_profile_name=module.params['storage_profile'])
if mo_1.check_prop_match(**kwargs):
props_match = True
elif not module.params['storage_profile']:
# no stroage profile mo or desired state
props_match = True
return props_match
def check_connectivity_policy_props(ucs, module, dn):
props_match = False
child_dn = dn + '/conn-def'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(lan_conn_policy_name=module.params['lan_connectivity_policy'])
kwargs['san_conn_policy_name'] = module.params['san_connectivity_policy']
if mo_1.check_prop_match(**kwargs):
props_match = True
elif not module.params['lan_connectivity_policy'] and not module.params['san_connectivity_policy']:
# no mo and no desired state
props_match = True
return props_match
def check_iqn_pool_props(ucs, module, dn):
props_match = False
child_dn = dn + '/iscsi-node'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(iqn_ident_pool_name=module.params['iqn_pool'])
if mo_1.check_prop_match(**kwargs):
props_match = True
elif not module.params['iqn_pool']:
# no mo and no desired state
props_match = True
return props_match
def check_inband_management_props(ucs, module, dn):
props_match = False
child_dn = dn + '/iface-in-band'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(mode=module.params['mgmt_interface_mode'])
if mo_1.check_prop_match(**kwargs):
child_dn = child_dn + '/network'
mo_2 = ucs.login_handle.query_dn(child_dn)
if mo_2:
kwargs = dict(name=module.params['mgmt_vnet_name'])
if mo_2.check_prop_match(**kwargs):
child_dn = child_dn + '/ipv4-pooled-addr'
mo_3 = ucs.login_handle.query_dn(child_dn)
if mo_3:
kwargs = dict(name=module.params['mgmt_inband_pool_name'])
if mo_3.check_prop_match(**kwargs):
props_match = True
elif not module.params['mgmt_interface_mode']:
# no mo and no desired state
props_match = True
return props_match
def check_power_props(ucs, module, dn):
props_match = False
child_dn = dn + '/power'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(state=module.params['power_state'])
if mo_1.check_prop_match(**kwargs):
props_match = True
elif not module.params['power_state']:
# no mo and no desired state
props_match = True
return props_match
def check_server_pool(ucs, module, dn):
props_match = False
child_dn = dn + '/pn-req'
mo_1 = ucs.login_handle.query_dn(child_dn)
if mo_1:
kwargs = dict(name=module.params['server_pool'])
kwargs['qualifier'] = module.params['server_pool_qualification']
if mo_1.check_prop_match(**kwargs):
props_match = True
elif not module.params['server_pool']:
# no pn-req object and no server pool name provided
props_match = True
return props_match
def check_serivce_profile_templates_props(ucs, module, mo, dn):
props_match = False
# check top-level mo props
kwargs = dict(bios_profile_name=module.params['bios_policy'])
kwargs['boot_policy_name'] = module.params['boot_policy']
kwargs['descr'] = module.params['description']
kwargs['ext_ip_state'] = module.params['mgmt_ip_state']
kwargs['ext_ip_pool_name'] = module.params['mgmt_ip_pool']
# kwargs['graphics_card_policy_name'] = module.params['graphics_card_policy']
kwargs['host_fw_policy_name'] = module.params['host_firmware_package']
kwargs['ident_pool_name'] = module.params['uuid_pool']
kwargs['kvm_mgmt_policy_name'] = module.params['kvm_mgmt_policy']
kwargs['local_disk_policy_name'] = module.params['local_disk_policy']
kwargs['maint_policy_name'] = module.params['maintenance_policy']
kwargs['mgmt_access_policy_name'] = module.params['ipmi_access_profile']
kwargs['power_policy_name'] = module.params['power_control_policy']
kwargs['power_sync_policy_name'] = module.params['power_sync_policy']
kwargs['scrub_policy_name'] = module.params['scrub_policy']
kwargs['sol_policy_name'] = module.params['sol_policy']
kwargs['stats_policy_name'] = module.params['threshold_policy']
kwargs['type'] = module.params['template_type']
kwargs['usr_lbl'] = module.params['user_label']
kwargs['vmedia_policy_name'] = module.params['vmedia_policy']
if mo.check_prop_match(**kwargs):
# top-level props match, check next level mo/props
# code below should discontinue checks once any mismatch is found
# check storage profile 1st
props_match = check_storage_profile_props(ucs, module, dn)
if props_match:
props_match = check_connectivity_policy_props(ucs, module, dn)
if props_match:
props_match = check_iqn_pool_props(ucs, module, dn)
if props_match:
props_match = check_inband_management_props(ucs, module, dn)
if props_match:
props_match = check_power_props(ucs, module, dn)
if props_match:
props_match = check_server_pool(ucs, module, dn)
return props_match
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(type='str', required=True),
bios_policy=dict(type='str', default=''),
boot_policy=dict(type='str', default='default'),
description=dict(type='str', aliases=['descr'], default=''),
mgmt_ip_state=dict(type='str', default='pooled'),
mgmt_ip_pool=dict(type='str', default='ext-mgmt'),
graphics_card_policy=dict(type='str', default=''),
host_firmware_package=dict(type='str', default=''),
uuid_pool=dict(type='str', default='default'),
kvm_mgmt_policy=dict(type='str', default=''),
local_disk_policy=dict(type='str', default=''),
maintenance_policy=dict(type='str', default=''),
ipmi_access_profile=dict(type='str', default=''),
power_control_policy=dict(type='str', default='default'),
power_sync_policy=dict(type='str', default=''),
scrub_policy=dict(type='str', default=''),
sol_policy=dict(type='str', default=''),
threshold_policy=dict(type='str', default='default'),
template_type=dict(type='str', default='initial-template', choices=['initial-template', 'updating-template']),
user_label=dict(type='str', default=''),
vmedia_policy=dict(type='str', default=''),
storage_profile=dict(type='str', default=''),
lan_connectivity_policy=dict(type='str', default=''),
iqn_pool=dict(type='str', default=''),
san_connectivity_policy=dict(type='str', default=''),
server_pool=dict(type='str', default=''),
server_pool_qualification=dict(type='str', default=''),
power_state=dict(type='str', default='up', choices=['up', 'down']),
mgmt_interface_mode=dict(type='str', default='', choices=['', 'in-band']),
mgmt_vnet_name=dict(type='str', default=''),
mgmt_inband_pool_name=dict(type='str', default=''),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
ucs = UCSModule(module)
# UCSModule creation above verifies ucsmsdk is present and exits on failure.
# Additional imports are done below or in called functions.
ucs.result['changed'] = False
props_match = False
# dn is <org_dn>/ls-<name>
dn = module.params['org_dn'] + '/ls-' + module.params['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
ucs.result['changed'] = True
else: # state == 'present'
props_match = check_serivce_profile_templates_props(ucs, module, mo, dn)
if module.params['state'] == 'present' and not props_match:
configure_service_profile_template(ucs, module)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,230 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.0',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_sp_vnic_order
short_description: Configures vNIC order for service profiles and templates on Cisco UCS Manager
version_added: 2.10
description:
- Configures Configures vNIC order for service profiles and templates on Cisco UCS Manager
options:
sp_name:
description: DN of the service profile
vnics:
description: List of vNIC order properties
suboptions:
name:
description: Name of the vNIC
required: true
admin_vcon:
description: Name of the virtual connection
choices: ["1","2","3","4","any"]
order:
description: vNIC connection order
choices: ["unspecified", "0-256"]
transport:
description: transport medium
choices: ["ethernet", "fc"]
required: true
state:
description: Desired state of the vNIC.
choices: [present, absent]
default: present
org_dn:
description: root org dn
extends_documentation_fragment:
- cisco.ucs.ucs
requirements:
- ucsmsdk
author:
- Brett Johnson (@sdbrett)
'''
EXAMPLES = r'''
- name: Configure vnic order
cisco.ucs.ucs_sp_vnic_order:
sp_name: my_sp
vnics:
- name: 'my_vnic'
admin_vcon: '1'
order: '1'
transport: 'ethernet'
hostname: 192.168.99.100
username: admin
password: password
- name: Configure vhba order
cisco.ucs.ucs_sp_vnic_order:
sp_name: my_sp
vnics:
- name: 'my_vhba'
admin_vcon: '2'
order: '1'
transport: 'fc'
hostname: 192.168.99.100
username: admin
password: password
- name: Configure vnic and vhba order
cisco.ucs.ucs_sp_vnic_order:
sp_name: my_sp
vnics:
- name: my_vhba
admin_vcon: '2'
order: '1'
transport: fc
- name: my_vnic
admin_vcon: '1'
order: '1'
transport: ethernet
hostname: 192.168.99.100
username: admin
password: password
- name: Remove vnic order configuration from my_vnic
cisco.ucs.ucs_sp_vnic_order:
sp_name: my_sp
vnics:
- name: 'my_vnic'
transport: ethernet
state: absent
hostname: 192.168.99.100
username: admin
password: password
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def get_service_profile(handle, org_dn, sp_name):
dn = org_dn + "/ls-" + sp_name
sp = handle.query_dn(dn)
return sp
def update_vnic_assignment_order(ucs, vnic, sp):
from ucsmsdk.mometa.ls.LsVConAssign import LsVConAssign
mo = LsVConAssign(parent_mo_or_dn=sp, admin_vcon=vnic['admin_vcon'],
order=vnic['order'], transport=vnic['transport'],
vnic_name=vnic['name'])
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
def remove_vnic_assignment_order(ucs, vnic, sp):
from ucsmsdk.mometa.ls.LsVConAssign import LsVConAssign
mo = LsVConAssign(parent_mo_or_dn=sp, admin_vcon='any',
order='unspecified', transport=vnic['transport'],
vnic_name=vnic['name'])
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
def get_vnic(ucs, dn):
return ucs.login_handle.query_dn(dn)
def get_vnic_dn(sp_dn, transport, name):
if transport == 'ethernet':
return sp_dn + '/ether-' + name
return sp_dn + '/fc-' + name
def matches_existing_vnic_order(vnic, vnic_mo):
if vnic['state'] == 'absent':
kwargs = dict(admin_vcon='any')
kwargs['order'] = 'unspecified'
else:
kwargs = dict(admin_vcon=vnic['admin_vcon'])
kwargs['order'] = vnic['order']
if vnic['transport'] == 'ethernet':
kwargs['type'] = 'ether'
else:
kwargs['type'] = vnic['transport']
return vnic_mo.check_prop_match(**kwargs)
def main():
vnic_spec = dict(
name=dict(type='str', required=True),
admin_vcon=dict(type='str', choices=['1', '2', '3', '4', 'any']),
order=dict(type='str'),
transport=dict(type='str', required=True, choices=['ethernet', 'fc']),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
argument_spec = ucs_argument_spec
argument_spec.update(
sp_name=dict(required=True, type='str'),
vnics=dict(required=True, type='list', elements='dict', options=vnic_spec),
org_dn=dict(required=False, type='str', default='org-root'),
)
module = AnsibleModule(argument_spec,
supports_check_mode=True)
ucs = UCSModule(module)
err = False
changed = False
try:
sp_dn = dn = module.params['org_dn'] + "/ls-" + module.params['sp_name']
sp = ucs.login_handle.query_dn(dn)
if not sp:
raise ValueError("SP '%s' does not exist" % sp_dn)
for vnic in module.params['vnics']:
vnic_mo = get_vnic(ucs, (get_vnic_dn(sp_dn, vnic['transport'], vnic['name'])))
if vnic['state'] != 'absent' and not vnic_mo:
raise ValueError("vNIC '%s' is not assigned to service profile '%s'" % (vnic['name'], sp_dn))
if vnic_mo:
if not matches_existing_vnic_order(vnic, vnic_mo):
changed = True
break
if changed and not module.check_mode:
for vnic in module.params['vnics']:
vnic_mo = get_vnic(ucs, (get_vnic_dn(sp_dn, vnic['transport'], vnic['name'])))
if vnic['state'] == 'absent' and vnic_mo:
remove_vnic_assignment_order(ucs, vnic, sp)
elif not vnic_mo:
update_vnic_assignment_order(ucs, vnic, sp)
elif not matches_existing_vnic_order(vnic, vnic_mo):
update_vnic_assignment_order(ucs, vnic, sp)
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,254 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'certified'}
DOCUMENTATION = r'''
---
module: ucs_storage_profile
short_description: Configures storage profiles on Cisco UCS Manager
description:
- Configures storage profiles on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(present), will verify that the storage profile is present and will create if needed.
- If C(absent), will verify that the storage profile is absent and will delete if needed.
choices: [ absent, present ]
default: present
name:
description:
- The name of the storage profile.
- This name can be between 1 and 16 alphanumeric characters.
- "You cannot use spaces or any special characters other than - (hyphen), \"_\" (underscore), : (colon), and . (period)."
- You cannot change this name after profile is created.
required: yes
description:
description:
- The user-defined description of the storage profile.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
local_luns:
description:
- List of Local LUNs used by the storage profile.
suboptions:
name:
description:
- The name of the local LUN.
required: yes
size:
description:
- Size of this LUN in GB.
- The size can range from 1 to 10240 GB.
default: '1'
auto_deploy:
description:
- Whether the local LUN should be automatically deployed or not.
choices: [ auto-deploy, no-auto-deploy ]
default: auto-deploy
expand_to_avail:
description:
- Specifies that this LUN can be expanded to use the entire available disk group.
- For each service profile, only one LUN can use this option.
- Expand To Available option is not supported for already deployed LUN.
type: bool
default: 'no'
fractional_size:
description:
- Fractional size of this LUN in MB.
default: '0'
disk_policy_name:
description:
- The disk group configuration policy to be applied to this local LUN.
state:
description:
- If C(present), will verify local LUN is present on profile.
If C(absent), will verify local LUN is absent on profile.
choices: [ absent, present ]
default: present
org_dn:
description:
- The distinguished name (dn) of the organization where the resource is assigned.
default: org-root
requirements:
- ucsmsdk
author:
- Sindhu Sudhir (@sisudhir)
- David Soper (@dsoper2)
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: '2.7'
'''
EXAMPLES = r'''
- name: Configure Storage Profile
cisco.ucs.ucs_storage_profile:
hostname: 172.16.143.150
username: admin
password: password
name: DEE-StgProf
local_luns:
- name: Boot-LUN
size: '60'
disk_policy_name: DEE-DG
- name: Data-LUN
size: '200'
disk_policy_name: DEE-DG
- name: Remove Storage Profile
cisco.ucs.ucs_storage_profile:
hostname: 172.16.143.150
username: admin
password: password
name: DEE-StgProf
state: absent
- name: Remove Local LUN from Storage Profile
cisco.ucs.ucs_storage_profile:
hostname: 172.16.143.150
username: admin
password: password
name: DEE-StgProf
local_luns:
- name: Data-LUN
state: absent
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def main():
local_lun = dict(
name=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['present', 'absent']),
size=dict(type='str', default='1'),
auto_deploy=dict(type='str', default='auto-deploy', choices=['auto-deploy', 'no-auto-deploy']),
expand_to_avail=dict(type='str', default='no', choices=['no', 'yes']),
fractional_size=dict(type='str', default='0'),
disk_policy_name=dict(type='str', default=''),
)
argument_spec = ucs_argument_spec
argument_spec.update(
org_dn=dict(type='str', default='org-root'),
name=dict(type='str', required=True),
description=dict(type='str', aliases=['descr'], default=''),
local_luns=dict(type='list', elements='dict', options=local_lun),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
ucs = UCSModule(module)
err = False
# UCSModule creation above verifies ucsmsdk is present and exits on failure. Additional imports are done below.
from ucsmsdk.mometa.lstorage.LstorageProfile import LstorageProfile
from ucsmsdk.mometa.lstorage.LstorageDasScsiLun import LstorageDasScsiLun
ucs.result['changed'] = False
try:
mo_exists = False
props_match = False
# dn is <org_dn>/profile-<name>
dn = module.params['org_dn'] + '/profile-' + module.params['name']
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if mo_exists:
if not module.check_mode:
ucs.login_handle.remove_mo(mo)
ucs.login_handle.commit()
ucs.result['changed'] = True
else:
if mo_exists:
# check top-level mo props
kwargs = dict(descr=module.params['description'])
if mo.check_prop_match(**kwargs):
# top-level props match, check next level mo/props
if not module.params.get('local_luns'):
props_match = True
else:
# check local lun props
for lun in module.params['local_luns']:
child_dn = dn + '/das-scsi-lun-' + lun['name']
mo_1 = ucs.login_handle.query_dn(child_dn)
if lun['state'] == 'absent':
if mo_1:
props_match = False
break
else:
if mo_1:
kwargs = dict(size=str(lun['size']))
kwargs['auto_deploy'] = lun['auto_deploy']
kwargs['expand_to_avail'] = lun['expand_to_avail']
kwargs['fractional_size'] = str(lun['fractional_size'])
kwargs['local_disk_policy_name'] = lun['disk_policy_name']
if mo_1.check_prop_match(**kwargs):
props_match = True
else:
props_match = False
break
if not props_match:
if not module.check_mode:
# create if mo does not already exist
mo = LstorageProfile(
parent_mo_or_dn=module.params['org_dn'],
name=module.params['name'],
descr=module.params['description'],
)
if module.params.get('local_luns'):
for lun in module.params['local_luns']:
if lun['state'] == 'absent':
child_dn = dn + '/das-scsi-lun-' + lun['name']
mo_1 = ucs.login_handle.query_dn(child_dn)
ucs.login_handle.remove_mo(mo_1)
else:
mo_1 = LstorageDasScsiLun(
parent_mo_or_dn=mo,
name=lun['name'],
size=str(lun['size']),
auto_deploy=lun['auto_deploy'],
expand_to_avail=lun['expand_to_avail'],
fractional_size=str(lun['fractional_size']),
local_disk_policy_name=lun['disk_policy_name'],
)
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
ucs.result['changed'] = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,152 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: ucs_system_qos
short_description: Configures system QoS settings
version_added: 2.10
description:
- Configures system QoS settings
extends_documentation_fragment: cisco.ucs.ucs
options:
priority:
description: Priority to configure
choices: ["best-effort", "bronze", "fc", "gold","platinum", "silver"]
required: true
admin_state:
description: Admin state of QoS Policy
choices: ['disabled', 'enabled']
default: enabled
cos:
description: CoS setting
choices: ['any', '0-6']
required: true
weight:
description: CoS profile weight
choices: ['best-effort', 'none', '0-10']
required: true
mtu:
description: MTU size
choices: ['fc', 'normal', '0-4294967295']
default: normal
multicast_optimize:
description: Set multicast optimization options
choices: ['false', 'no', 'true', 'yes']
drop:
description: Set multicast optimization options
default: 'drop'
choices: ['drop', 'no-drop']
requirements: ['ucsmsdk']
author: "Brett Johnson (@sdbrett)"
'''
EXAMPLES = '''
- name:
cisco.ucs.ucs_system_qos:
priority: platinum
admin_state: enabled
multicast_optimize: no
cos: '5'
weight: '10'
mtu: '9216'
hostname: 192.168.99.100
username: admin
password: password
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
# TODO Add ranges for cos, weight and mtu
def main():
argument_spec = ucs_argument_spec
argument_spec.update(
priority=dict(required=True, type='str', choices=["best-effort", "bronze", "fc", "gold", "platinum", "silver"]),
cos=dict(required=True, type='str'),
weight=dict(required=True, type='str'),
admin_state=dict(required=False, type='str', default='enabled', choices=['disabled', 'enabled']),
drop=dict(required=False, type='str', default='drop', choices=['drop', 'no-drop']),
mtu=dict(required=False, type='str', default='normal'),
multicast_optimize=dict(required=False, type='str', default='no', choices=['false', 'no', 'true', 'yes']),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
)
ucs = UCSModule(module)
err = False
changed = False
try:
dn = "fabric/lan/classes/class-" + module.params['priority']
mo = ucs.login_handle.query_dn(dn)
# check top-level mo props
if module.params['priority'] == 'best-effort':
kwargs = dict(weight=module.params['weight'])
kwargs['mtu'] = module.params['mtu']
kwargs['multicast_optimize'] = module.params['multicast_optimize']
if not mo.check_prop_match(**kwargs):
if not module.check_mode:
mo.weight = module.params['weight']
mo.mtu = module.params['mtu']
mo.multicast_optimize = module.params['multicast_optimize']
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True
elif module.params['priority'] == 'fc':
kwargs = dict(weight=module.params['weight'])
kwargs['cos'] = module.params['cos']
if not mo.check_prop_match(**kwargs):
if not module.check_mode:
mo.weight = module.params['weight']
mo.cos = module.params['cos']
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True
else:
kwargs = dict(weight=module.params['weight'])
kwargs['priority'] = module.params['priority']
kwargs['mtu'] = module.params['mtu']
kwargs['cos'] = module.params['cos']
kwargs['drop'] = module.params['drop']
kwargs['admin_state'] = module.params['admin_state']
kwargs['multicast_optimize'] = module.params['multicast_optimize']
if not mo.check_prop_match(**kwargs):
if not module.check_mode:
mo.weight = module.params['weight']
mo.mtu = module.params['mtu']
mo.cos = module.params['cos']
mo.drop = module.params['drop']
mo.admin_state = module.params['admin_state']
mo.multicast_optimize = module.params['multicast_optimize']
ucs.login_handle.add_mo(mo, True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,165 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'certified'}
DOCUMENTATION = r'''
---
module: ucs_timezone
short_description: Configures timezone on Cisco UCS Manager
description:
- Configures timezone on Cisco UCS Manager.
extends_documentation_fragment: cisco.ucs.ucs
options:
state:
description:
- If C(absent), will unset timezone.
- If C(present), will set or update timezone.
choices: [absent, present]
default: present
admin_state:
description:
- The admin_state setting
- The enabled admin_state indicates the timezone configuration is utilized by UCS Manager.
- The disabled admin_state indicates the timezone configuration is ignored by UCS Manager.
choices: [disabled, enabled]
default: enabled
description:
description:
- A user-defined description of the timezone.
- Enter up to 256 characters.
- "You can use any characters or spaces except the following:"
- "` (accent mark), \ (backslash), ^ (carat), \" (double quote), = (equal sign), > (greater than), < (less than), or ' (single quote)."
aliases: [ descr ]
default: ""
timezone:
description:
- The timezone name.
- Time zone names are from the L(tz database,https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
- The timezone name is case sensitive.
- The timezone name can be between 0 and 510 alphanumeric characters.
- You cannot use spaces or any special characters other than
- "\"-\" (hyphen), \"_\" (underscore), \"/\" (backslash)."
requirements:
- ucsmsdk
author:
- David Soper (@dsoper2)
- John McDonough (@movinalot)
- CiscoUcs (@CiscoUcs)
version_added: '2.7'
'''
EXAMPLES = r'''
- name: Configure Time Zone
cisco.ucs.ucs_timezone:
hostname: 172.16.143.150
username: admin
password: password
state: present
admin_state: enabled
timezone: America/Los_Angeles
description: 'Time Zone for Los Angeles'
- name: Unconfigure Time Zone
cisco.ucs.ucs_timezone:
hostname: 172.16.143.150
username: admin
password: password
state: absent
admin_state: disabled
'''
RETURN = r'''
#
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.cisco.ucs.plugins.module_utils.ucs import UCSModule, ucs_argument_spec
def run_module():
argument_spec = ucs_argument_spec
argument_spec.update(
timezone=dict(type='str'),
description=dict(type='str', aliases=['descr'], default=''),
admin_state=dict(type='str', default='enabled', choices=['disabled', 'enabled']),
state=dict(type='str', default='present', choices=['present', 'absent']),
)
module = AnsibleModule(
argument_spec,
supports_check_mode=True,
required_if=[
['state', 'present', ['timezone']],
],
)
ucs = UCSModule(module)
err = False
changed = False
try:
mo_exists = False
props_match = False
dn = 'sys/svc-ext/datetime-svc'
mo = ucs.login_handle.query_dn(dn)
if mo:
mo_exists = True
if module.params['state'] == 'absent':
# mo must exist but all properties do not have to match
if mo_exists:
if not module.check_mode:
mo.timezone = ""
mo.descr = ""
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.login_handle.commit()
changed = True
else:
if mo_exists:
# check top-level mo props
kwargs = dict(descr=module.params['description'])
kwargs['timezone'] = module.params['timezone']
kwargs['admin_state'] = module.params['admin_state']
if mo.check_prop_match(**kwargs):
props_match = True
if not props_match:
if not module.check_mode:
# update mo, timezone mo always exists
mo.timezone = module.params['timezone']
mo.descr = module.params['description']
mo.admin_state = module.params['admin_state']
ucs.login_handle.add_mo(mo, modify_present=True)
ucs.login_handle.commit()
changed = True
except Exception as e:
err = True
ucs.result['msg'] = "setup error: %s " % str(e)
ucs.result['changed'] = changed
if err:
module.fail_json(**ucs.result)
module.exit_json(**ucs.result)
def main():
run_module()
if __name__ == '__main__':
main()

Some files were not shown because too many files have changed in this diff Show More