summaryrefslogtreecommitdiffstats
path: root/collections-debian-merged/ansible_collections/cisco/ucs/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'collections-debian-merged/ansible_collections/cisco/ucs/plugins')
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/README.md31
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/doc_fragments/ucs.py72
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/module_utils/ucs.py97
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_disk_group_policy.py428
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_dns_server.py165
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_graphics_card_policy.py261
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_ip_pool.py452
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_lan_connectivity.py355
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_mac_pool.py185
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_managed_objects.py256
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_ntp_server.py169
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_org.py227
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_query.py172
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_san_connectivity.py248
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_scrub_policy.py320
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_serial_over_lan_policy.py271
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_server_maintenance.py158
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_association.py252
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_from_template.py177
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_template.py523
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_sp_vnic_order.py230
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_storage_profile.py254
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_system_qos.py152
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_timezone.py165
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_uuid_pool.py196
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vhba_template.py274
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlan_find.py123
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlan_to_group.py158
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlans.py192
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vnic_template.py377
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vsans.py204
-rw-r--r--collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_wwn_pool.py239
32 files changed, 7383 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/README.md b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/README.md
new file mode 100644
index 00000000..6541cf7c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/README.md
@@ -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). \ No newline at end of file
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/doc_fragments/ucs.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/doc_fragments/ucs.py
new file mode 100644
index 00000000..5e03a772
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/doc_fragments/ucs.py
@@ -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
+'''
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/module_utils/ucs.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/module_utils/ucs.py
new file mode 100644
index 00000000..bbb0a407
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/module_utils/ucs.py
@@ -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
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_disk_group_policy.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_disk_group_policy.py
new file mode 100644
index 00000000..86d7eaca
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_disk_group_policy.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_dns_server.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_dns_server.py
new file mode 100644
index 00000000..5271cacc
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_dns_server.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_graphics_card_policy.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_graphics_card_policy.py
new file mode 100644
index 00000000..ccc8c583
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_graphics_card_policy.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_ip_pool.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_ip_pool.py
new file mode 100644
index 00000000..308ffd4b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_ip_pool.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_lan_connectivity.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_lan_connectivity.py
new file mode 100644
index 00000000..7638091f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_lan_connectivity.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_mac_pool.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_mac_pool.py
new file mode 100644
index 00000000..35bdbfa5
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_mac_pool.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_managed_objects.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_managed_objects.py
new file mode 100644
index 00000000..7e679e12
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_managed_objects.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_ntp_server.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_ntp_server.py
new file mode 100644
index 00000000..a917ed60
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_ntp_server.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_org.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_org.py
new file mode 100644
index 00000000..51237ca6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_org.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_query.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_query.py
new file mode 100644
index 00000000..f9a7a1a0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_query.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_san_connectivity.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_san_connectivity.py
new file mode 100644
index 00000000..7e9c1054
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_san_connectivity.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_scrub_policy.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_scrub_policy.py
new file mode 100644
index 00000000..f6c262e6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_scrub_policy.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_serial_over_lan_policy.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_serial_over_lan_policy.py
new file mode 100644
index 00000000..0dd9ba57
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_serial_over_lan_policy.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_server_maintenance.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_server_maintenance.py
new file mode 100644
index 00000000..a8aca943
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_server_maintenance.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_association.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_association.py
new file mode 100644
index 00000000..81d9aa4b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_association.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_from_template.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_from_template.py
new file mode 100644
index 00000000..0c1bc60d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_from_template.py
@@ -0,0 +1,177 @@
+#!/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
+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
+
+- 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']),
+ )
+
+ 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'],
+ )
+ 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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_template.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_template.py
new file mode 100644
index 00000000..0c6f2e71
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_service_profile_template.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_sp_vnic_order.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_sp_vnic_order.py
new file mode 100644
index 00000000..6498323c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_sp_vnic_order.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_storage_profile.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_storage_profile.py
new file mode 100644
index 00000000..9ca825a8
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_storage_profile.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_system_qos.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_system_qos.py
new file mode 100644
index 00000000..6dcf7aac
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_system_qos.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_timezone.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_timezone.py
new file mode 100644
index 00000000..d7a22e78
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_timezone.py
@@ -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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_uuid_pool.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_uuid_pool.py
new file mode 100644
index 00000000..d314a9ba
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_uuid_pool.py
@@ -0,0 +1,196 @@
+#!/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_uuid_pool
+short_description: Configures server UUID pools on Cisco UCS Manager
+description:
+- Configures server UUID pools and UUID blocks on Cisco UCS Manager.
+extends_documentation_fragment: cisco.ucs.ucs
+options:
+ state:
+ description:
+ - If C(present), will verify UUID pool is present and will create if needed.
+ - If C(absent), will verify UUID pool is absent and will delete if needed.
+ choices: [present, absent]
+ default: present
+ name:
+ description:
+ - The name of the UUID 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 UUID pool is created.
+ required: yes
+ description:
+ description:
+ - "The user-defined description of the UUID 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 ]
+ prefix:
+ description:
+ - UUID prefix used for the range of server UUIDs.
+ - "If no value is provided, the system derived prefix will be used (equivalent to selecting 'derived' option in UI)."
+ - "If the user provides a value, the user provided prefix will be used (equivalent to selecting 'other' option in UI)."
+ - A user provided value should be in the format XXXXXXXX-XXXX-XXXX.
+ 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_uuid:
+ description:
+ - The first UUID in the block of UUIDs.
+ - This is the From field in the UCS Manager UUID Blocks menu.
+ last_uuid:
+ description:
+ - The last UUID in the block of UUIDs.
+ - This is the To field in the UCS Manager Add UUID 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.7'
+'''
+
+EXAMPLES = r'''
+- name: Configure UUID address pool
+ cisco.ucs.ucs_uuid_pool:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: UUID-Pool
+ order: sequential
+ first_uuid: 0000-000000000001
+ last_uuid: 0000-000000000078
+
+- name: Remove UUID address pool
+ cisco.ucs.ucs_uuid_pool:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: UUID-Pool
+ 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),
+ description=dict(type='str', aliases=['descr'], default=''),
+ order=dict(type='str', default='default', choices=['default', 'sequential']),
+ prefix=dict(type='str', default=''),
+ first_uuid=dict(type='str'),
+ last_uuid=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.uuidpool.UuidpoolPool import UuidpoolPool
+ from ucsmsdk.mometa.uuidpool.UuidpoolBlock import UuidpoolBlock
+
+ ucs.result['changed'] = False
+ try:
+ mo_exists = False
+ props_match = False
+ # dn is <org_dn>/uuid-pool-<name>
+ dn = module.params['org_dn'] + '/uuid-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()
+ ucs.result['changed'] = True
+ else:
+ if mo_exists:
+ # check top-level mo props
+ kwargs = dict(assignment_order=module.params['order'])
+ kwargs['descr'] = module.params['description']
+ if module.params['prefix']:
+ kwargs['prefix'] = module.params['prefix']
+ if mo.check_prop_match(**kwargs):
+ # top-level props match, check next level mo/props
+ if module.params['last_uuid'] and module.params['first_uuid']:
+ # uuid address block specified, check properties
+ block_dn = dn + '/block-from-' + module.params['first_uuid'].upper() + '-to-' + module.params['last_uuid'].upper()
+ mo_1 = ucs.login_handle.query_dn(block_dn)
+ if mo_1:
+ props_match = True
+ else:
+ # no UUID 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
+ if not module.params['prefix']:
+ module.params['prefix'] = 'derived'
+ mo = UuidpoolPool(
+ parent_mo_or_dn=module.params['org_dn'],
+ name=module.params['name'],
+ descr=module.params['description'],
+ assignment_order=module.params['order'],
+ prefix=module.params['prefix']
+ )
+
+ if module.params['last_uuid'] and module.params['first_uuid']:
+ mo_1 = UuidpoolBlock(
+ parent_mo_or_dn=mo,
+ to=module.params['last_uuid'],
+ r_from=module.params['first_uuid'],
+ )
+
+ 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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vhba_template.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vhba_template.py
new file mode 100644
index 00000000..597e8c91
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vhba_template.py
@@ -0,0 +1,274 @@
+#!/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_vhba_template
+short_description: Configures vHBA templates on Cisco UCS Manager
+description:
+- Configures vHBA templates on Cisco UCS Manager.
+extends_documentation_fragment: cisco.ucs.ucs
+options:
+ state:
+ description:
+ - If C(present), will verify vHBA templates are present and will create if needed.
+ - If C(absent), will verify vHBA templates are absent and will delete if needed.
+ choices: [present, absent]
+ default: present
+ name:
+ description:
+ - The name of the virtual HBA template.
+ - 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 template is created.
+ required: yes
+ description:
+ description:
+ - A user-defined description of the 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 ]
+ fabric:
+ description:
+ - The Fabric ID field.
+ - The name of the fabric interconnect that vHBAs created with this template are associated with.
+ choices: [A, B]
+ default: A
+ redundancy_type:
+ description:
+ - The Redundancy Type used for template pairing from the Primary or Secondary redundancy template.
+ - "primary — Creates configurations that can be shared with the Secondary template."
+ - Any other shared changes on the Primary template are automatically synchronized to the Secondary template.
+ - "secondary — All shared configurations are inherited from the Primary template."
+ - "none - Legacy vHBA template behavior. Select this option if you do not want to use redundancy."
+ choices: [none, primary, secondary]
+ default: none
+ vsan:
+ description:
+ - The VSAN to associate with vHBAs created from this template.
+ default: default
+ template_type:
+ description:
+ - The Template Type field.
+ - "This can be one of the following:"
+ - "initial-template — vHBAs created from this template are not updated if the template changes."
+ - "updating-template - vHBAs created from this template are updated if the template changes."
+ choices: [initial-template, updating-template]
+ default: initial-template
+ max_data:
+ description:
+ - The Max Data Field Size field.
+ - The maximum size of the Fibre Channel frame payload bytes that the vHBA supports.
+ - Enter an string between '256' and '2112'.
+ default: '2048'
+ wwpn_pool:
+ description:
+ - The WWPN pool that a vHBA created from this template uses to derive its WWPN address.
+ default: default
+ qos_policy:
+ description:
+ - The QoS policy that is associated with vHBAs created from this template.
+ pin_group:
+ description:
+ - The SAN pin group that is associated with vHBAs created from this template.
+ stats_policy:
+ description:
+ - The statistics collection policy that is associated with vHBAs created from this template.
+ default: default
+ 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 vHBA template
+ cisco.ucs.ucs_vhba_template:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vHBA-A
+ fabric: A
+ vsan: VSAN-A
+ wwpn_pool: WWPN-Pool-A
+
+- name: Remote vHBA template
+ cisco.ucs.ucs_vhba_template:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vHBA-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'),
+ descr=dict(type='str'),
+ fabric=dict(type='str', default='A', choices=['A', 'B']),
+ redundancy_type=dict(type='str', default='none', choices=['none', 'primary', 'secondary']),
+ vsan=dict(type='str', default='default'),
+ template_type=dict(type='str', default='initial-template', choices=['initial-template', 'updating-template']),
+ max_data=dict(type='str', default='2048'),
+ wwpn_pool=dict(type='str', default='default'),
+ qos_policy=dict(type='str'),
+ pin_group=dict(type='str'),
+ stats_policy=dict(type='str', default='default'),
+ state=dict(type='str', default='present', choices=['present', 'absent']),
+ vhba_template_list=dict(type='list'),
+ )
+
+ # Note that use of vhba_template_list is an experimental feature which allows multiple resource updates with a single UCSM connection.
+ # Support for vhba_template_list may change or be removed once persistent UCS connections are supported.
+ # Either vhba_template_list or name is required (user can specify either a list of single resource).
+
+ module = AnsibleModule(
+ argument_spec,
+ supports_check_mode=True,
+ required_one_of=[
+ ['vhba_template_list', 'name']
+ ],
+ mutually_exclusive=[
+ ['vhba_template_list', 'name']
+ ],
+ )
+ ucs = UCSModule(module)
+
+ err = False
+
+ from ucsmsdk.mometa.vnic.VnicSanConnTempl import VnicSanConnTempl
+ 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 vhba_template_list below.
+
+ if module.params['vhba_template_list']:
+ # directly use the list (single resource and list are mutually exclusive
+ vhba_template_list = module.params['vhba_template_list']
+ else:
+ # single resource specified, create list from the current params
+ vhba_template_list = [module.params]
+ for vhba_template in vhba_template_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 vhba_template.get('descr'):
+ vhba_template['descr'] = ''
+ if not vhba_template.get('fabric'):
+ vhba_template['fabric'] = 'A'
+ if not vhba_template.get('redundancy_type'):
+ vhba_template['redundancy_type'] = 'none'
+ if not vhba_template.get('vsan'):
+ vhba_template['vsan'] = 'default'
+ if not vhba_template.get('template_type'):
+ vhba_template['template_type'] = 'initial-template'
+ if not vhba_template.get('max_data'):
+ vhba_template['max_data'] = '2048'
+ if not vhba_template.get('wwpn_pool'):
+ vhba_template['wwpn_pool'] = 'default'
+ if not vhba_template.get('qos_policy'):
+ vhba_template['qos_policy'] = ''
+ if not vhba_template.get('pin_group'):
+ vhba_template['pin_group'] = ''
+ if not vhba_template.get('stats_policy'):
+ vhba_template['stats_policy'] = 'default'
+ # dn is <org_dn>/san-conn-templ-<name>
+ dn = module.params['org_dn'] + '/san-conn-templ-' + vhba_template['name']
+
+ mo = ucs.login_handle.query_dn(dn)
+ if mo:
+ mo_exists = True
+ # check top-level mo props
+ kwargs = dict(descr=vhba_template['descr'])
+ kwargs['switch_id'] = vhba_template['fabric']
+ kwargs['redundancy_pair_type'] = vhba_template['redundancy_type']
+ kwargs['templ_type'] = vhba_template['template_type']
+ kwargs['max_data_field_size'] = vhba_template['max_data']
+ kwargs['ident_pool_name'] = vhba_template['wwpn_pool']
+ kwargs['qos_policy_name'] = vhba_template['qos_policy']
+ kwargs['pin_to_group_name'] = vhba_template['pin_group']
+ kwargs['stats_policy_name'] = vhba_template['stats_policy']
+ if (mo.check_prop_match(**kwargs)):
+ # top-level props match, check next level mo/props
+ child_dn = dn + '/if-default'
+ mo_1 = ucs.login_handle.query_dn(child_dn)
+ if mo_1:
+ kwargs = dict(name=vhba_template['vsan'])
+ if (mo_1.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 = VnicSanConnTempl(
+ parent_mo_or_dn=module.params['org_dn'],
+ name=vhba_template['name'],
+ descr=vhba_template['descr'],
+ switch_id=vhba_template['fabric'],
+ redundancy_pair_type=vhba_template['redundancy_type'],
+ templ_type=vhba_template['template_type'],
+ max_data_field_size=vhba_template['max_data'],
+ ident_pool_name=vhba_template['wwpn_pool'],
+ qos_policy_name=vhba_template['qos_policy'],
+ pin_to_group_name=vhba_template['pin_group'],
+ stats_policy_name=vhba_template['stats_policy'],
+ )
+
+ mo_1 = VnicFcIf(
+ parent_mo_or_dn=mo,
+ name=vhba_template['vsan'],
+ )
+
+ 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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlan_find.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlan_find.py
new file mode 100644
index 00000000..595fb596
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlan_find.py
@@ -0,0 +1,123 @@
+#!/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_vlan_find
+short_description: Find VLANs on Cisco UCS Manager
+description:
+- Find VLANs on Cisco UCS Manager based on different criteria.
+extends_documentation_fragment: cisco.ucs.ucs
+options:
+ pattern:
+ description:
+ - Regex pattern to find within the name property of the fabricVlan class.
+ - This is required if C(vlanid) parameter is not supplied.
+ type: str
+ fabric:
+ description:
+ - "The fabric configuration of the VLAN. This can be one of the following:"
+ - "common - The VLAN applies to both fabrics and uses the same configuration parameters in both cases."
+ - "A — The VLAN only applies to fabric A."
+ - "B — The VLAN only applies to fabric B."
+ choices: [common, A, B]
+ default: common
+ type: str
+ vlanid:
+ description:
+ - The unique string identifier assigned to the VLAN.
+ - A VLAN ID can be between '1' and '3967', or between '4048' and '4093'.
+ - This is required if C(pattern) parameter is not supplied.
+ type: str
+requirements:
+- ucsmsdk
+author:
+- David Martinez (@dx0xm)
+- David Soper (@dsoper2)
+- John McDonough (@movinalot)
+- CiscoUcs (@CiscoUcs)
+version_added: '2.9'
+'''
+
+EXAMPLES = r'''
+- name: Get all vlans in fabric A
+ cisco.ucs.ucs_vlan_find:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ fabric: 'A'
+ pattern: '.'
+- name: Confirm if vlan 15 is present
+ cisco.ucs.ucs_vlan_find:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ vlanid: '15'
+'''
+
+RETURN = r'''
+vlan_list:
+ description: basic details of vlans found
+ returned: on success
+ type: list
+ sample: [
+ {
+ "id": "0",
+ "name": "vlcloud1"
+ }
+ ]
+'''
+
+
+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(
+ fabric=dict(type='str', default='common', choices=['common', 'A', 'B']),
+ pattern=dict(type='str'),
+ vlanid=dict(type='str')
+ )
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=True,
+ required_one_of=[['pattern', 'vlanid']]
+ )
+
+ ucs = UCSModule(module)
+
+ filtls = ['(cloud,"ethlan")']
+ if module.params['fabric'] != 'common':
+ filtls.append('(switch_id,"' + module.params['fabric'] + '")')
+ if module.params['vlanid']:
+ filtls.append('(id,"' + module.params['vlanid'] + '")')
+ else:
+ filtls.append('(name,"' + module.params['pattern'] + '")')
+
+ object_dict = ucs.login_handle.query_classid("fabricVlan", filter_str=' and '.join(filtls))
+
+ if object_dict is None:
+ module.fail_json(msg="Failed to query vlan objects")
+
+ vlnlist = []
+ for ob in object_dict:
+ vlnlist.append(dict(name=ob.name, id=ob.id))
+
+ module.exit_json(changed=False,
+ vlan_list=vlnlist)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlan_to_group.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlan_to_group.py
new file mode 100644
index 00000000..c7b6e81c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlan_to_group.py
@@ -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_vlan_to_group
+short_description: Add VLANs to a VLAN Group. Requires VLAN and VLAN Group to already be created on UCS prior to running module.
+description:
+- Add VLANs to VLAN Groups on Cisco UCS Manager.
+extends_documentation_fragment: ucs
+options:
+ state:
+ description:
+ - If C(present), will verify VLANs are present and will create if needed.
+ - If C(absent), will verify VLANs are absent and will delete if needed.
+ choices: [present, absent]
+ default: present
+ vlanname:
+ description:
+ - The name assigned to the VLAN.
+ - The VLAN name is case sensitive.
+ - 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)."
+ required: yes
+ vlangroup:
+ description:
+ - The name assigned to the VLAN Group.
+ - The VLAN Group name is case sensitive.
+ - 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)."
+ required: yes
+requirements:
+- ucsmsdk
+author:
+- Derrick Johnson @derricktj
+version_added: '2.10'
+'''
+
+EXAMPLES = r'''
+- name: Configure VLAN
+ cisco.ucs.ucs_vlan_to_group:
+ hostname: 1.1.1.1
+ username: admin
+ password: password
+ vlangroup: VLANGROUP
+ vlanname: VLANNAME
+ state: present
+- name: Remove VLAN
+ cisco.ucs.ucs_vlan_to_group:
+ hostname: 1.1.1.1
+ username: admin
+ password: password
+ vlangroup: VLANGROUP
+ vlanname: VLANNAME
+ 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(
+ vlangroup=dict(type='str', required=True),
+ vlanname=dict(type='str', required=True),
+ state=dict(default='present', choices=['present', 'absent'], type='str'),
+ )
+
+ module = AnsibleModule(
+ argument_spec,
+ supports_check_mode=True,
+ required_if=[
+ ['state', 'present', ['vlangroup', 'vlanname']],
+ ],
+ )
+ ucs = UCSModule(module)
+
+ err = False
+
+ from ucsmsdk.mometa.fabric.FabricNetGroup import FabricNetGroup
+ from ucsmsdk.mometa.fabric.FabricPooledVlan import FabricPooledVlan
+
+ changed = False
+ try:
+ dnpooled1_exists = False
+
+ # dn = fabric/lan/net-group-VLANGROUP
+ # Check for VLAN Group
+ dngroup = 'fabric/lan/net-group-' + module.params['vlangroup']
+ dngroup1 = ucs.login_handle.query_dn(dngroup)
+
+ # dn = fabric/lan/net-VLANNAME
+ # Check for VLAN
+ dnvlan = 'fabric/lan/net-' + module.params['vlanname']
+ dnvlan1 = ucs.login_handle.query_dn(dnvlan)
+
+ # dn = fabric/lan/net-group-VLANGROUP/net-VLANNAME
+ # Check for VLAN within VLAN Group
+ dnpooled = 'fabric/lan/net-group-' + module.params['vlangroup'] + '/net-' + module.params['vlanname']
+ dnpooled1 = ucs.login_handle.query_dn(dnpooled)
+
+ # Configuration MOs. Couldn't really get this to work off the DNs, so I built additional objects.
+ mo = FabricNetGroup(parent_mo_or_dn="fabric/lan", name=module.params['vlangroup'])
+ mo_1 = FabricPooledVlan(parent_mo_or_dn=mo, name=module.params['vlanname'])
+
+ if not dngroup1:
+ # Error out if the VLAN Group is missing
+ err = True
+ ucs.result['msg'] = module.params['vlangroup'] + " VLAN Group not configured in UCS"
+
+ if not dnvlan1:
+ # Error out if VLAN is missing
+ err = True
+ ucs.result['msg'] = module.params['vlanname'] + " VLAN not configured in UCS. Use ucs_vlans module to create the VLAN first"
+
+ if dnpooled1:
+ dnpooled1_exists = True
+
+ if module.params['state'] == 'absent':
+ if dnpooled1_exists:
+ if not module.check_mode:
+ ucs.login_handle.remove_mo(mo_1)
+ ucs.login_handle.commit()
+ changed = True
+
+ if module.params['state'] == 'present':
+ if not dnpooled1_exists:
+ if not module.check_mode:
+ 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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlans.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlans.py
new file mode 100644
index 00000000..a0376f9b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vlans.py
@@ -0,0 +1,192 @@
+#!/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_vlans
+short_description: Configures VLANs on Cisco UCS Manager
+description:
+- Configures VLANs on Cisco UCS Manager.
+extends_documentation_fragment: cisco.ucs.ucs
+options:
+ state:
+ description:
+ - If C(present), will verify VLANs are present and will create if needed.
+ - If C(absent), will verify VLANs are absent and will delete if needed.
+ choices: [present, absent]
+ default: present
+ name:
+ description:
+ - The name assigned to the VLAN.
+ - The VLAN name is case sensitive.
+ - 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 VLAN is created.
+ required: yes
+ multicast_policy:
+ description:
+ - The multicast policy associated with this VLAN.
+ - This option is only valid if the Sharing Type field is set to None or Primary.
+ default: ''
+ fabric:
+ description:
+ - "The fabric configuration of the VLAN. This can be one of the following:"
+ - "common - The VLAN applies to both fabrics and uses the same configuration parameters in both cases."
+ - "A — The VLAN only applies to fabric A."
+ - "B — The VLAN only applies to fabric B."
+ - For upstream disjoint L2 networks, Cisco recommends that you choose common to create VLANs that apply to both fabrics.
+ choices: [common, A, B]
+ default: common
+ id:
+ description:
+ - The unique string identifier assigned to the VLAN.
+ - A VLAN ID can be between '1' and '3967', or between '4048' and '4093'.
+ - You cannot create VLANs with IDs from 4030 to 4047. This range of VLAN IDs is reserved.
+ - The VLAN IDs you specify must also be supported on the switch that you are using.
+ - VLANs in the LAN cloud and FCoE VLANs in the SAN cloud must have different IDs.
+ - Optional if state is absent.
+ required: yes
+ sharing:
+ description:
+ - The Sharing Type field.
+ - "Whether this VLAN is subdivided into private or secondary VLANs. This can be one of the following:"
+ - "none - This VLAN does not have any secondary or private VLANs. This is a regular VLAN."
+ - "primary - This VLAN can have one or more secondary VLANs, as shown in the Secondary VLANs area. This VLAN is a primary VLAN in the private VLAN domain."
+ - "isolated - This is a private VLAN associated with a primary VLAN. This VLAN is an Isolated VLAN."
+ - "community - This VLAN can communicate with other ports on the same community VLAN as well as the promiscuous port. This VLAN is a Community VLAN."
+ choices: [none, primary, isolated, community]
+ default: none
+ native:
+ description:
+ - Designates the VLAN as a native VLAN.
+ choices: ['yes', 'no']
+ default: 'no'
+requirements:
+- ucsmsdk
+author:
+- David Soper (@dsoper2)
+- CiscoUcs (@CiscoUcs)
+version_added: '2.5'
+'''
+
+EXAMPLES = r'''
+- name: Configure VLAN
+ cisco.ucs.ucs_vlans:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vlan2
+ id: '2'
+ native: 'yes'
+
+- name: Remove VLAN
+ cisco.ucs.ucs_vlans:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vlan2
+ 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(
+ name=dict(type='str', required=True),
+ multicast_policy=dict(type='str', default=''),
+ fabric=dict(type='str', default='common', choices=['common', 'A', 'B']),
+ id=dict(type='str'),
+ sharing=dict(type='str', default='none', choices=['none', 'primary', 'isolated', 'community']),
+ native=dict(type='str', default='no', choices=['yes', 'no']),
+ state=dict(type='str', default='present', choices=['present', 'absent']),
+ )
+
+ module = AnsibleModule(
+ argument_spec,
+ supports_check_mode=True,
+ required_if=[
+ ['state', 'present', ['id']],
+ ],
+ )
+ 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.fabric.FabricVlan import FabricVlan
+
+ changed = False
+ try:
+ mo_exists = False
+ props_match = False
+ # dn is fabric/lan/net-<name> for common vlans or fabric/lan/[A or B]/net-<name> for A or B
+ dn_base = 'fabric/lan'
+ if module.params['fabric'] != 'common':
+ dn_base += '/' + module.params['fabric']
+ dn = dn_base + '/net-' + 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(id=module.params['id'])
+ kwargs['default_net'] = module.params['native']
+ kwargs['sharing'] = module.params['sharing']
+ kwargs['mcast_policy_name'] = module.params['multicast_policy']
+ 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 = FabricVlan(
+ parent_mo_or_dn=dn_base,
+ name=module.params['name'],
+ id=module.params['id'],
+ default_net=module.params['native'],
+ sharing=module.params['sharing'],
+ mcast_policy_name=module.params['multicast_policy'],
+ )
+
+ 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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vnic_template.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vnic_template.py
new file mode 100644
index 00000000..544af9a0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vnic_template.py
@@ -0,0 +1,377 @@
+#!/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_vnic_template
+short_description: Configures vNIC templates on Cisco UCS Manager
+description:
+- Configures vNIC templates on Cisco UCS Manager.
+extends_documentation_fragment: cisco.ucs.ucs
+options:
+ state:
+ description:
+ - If C(present), will verify vNIC templates are present and will create if needed.
+ - If C(absent), will verify vNIC templates are absent and will delete if needed.
+ choices: [present, absent]
+ default: present
+ name:
+ description:
+ - The name of the vNIC template.
+ - 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 template is created.
+ required: yes
+ description:
+ description:
+ - A user-defined description of the vNIC 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 ]
+ fabric:
+ description:
+ - The Fabric ID field specifying the fabric interconnect associated with vNICs created from this template.
+ - If you want fabric failover enabled on vNICs created from this template, use of of the following:"
+ - "A-B to use Fabric A by default with failover enabled."
+ - "B-A to use Fabric B by default with failover enabled."
+ - "Do not enable vNIC fabric failover under the following circumstances:"
+ - "- If the Cisco UCS domain is running in Ethernet switch mode. vNIC fabric failover is not supported in that mode."
+ - "- If you plan to associate one or more vNICs created from this template to a server with an adapter that does not support fabric failover."
+ choices: [A, B, A-B, B-A]
+ default: A
+ redundancy_type:
+ description:
+ - The Redundancy Type used for vNIC redundancy pairs during fabric failover.
+ - "This can be one of the following:"
+ - "primary — Creates configurations that can be shared with the Secondary template."
+ - "secondary — All shared configurations are inherited from the Primary template."
+ - "none - Legacy vNIC template behavior. Select this option if you do not want to use redundancy."
+ choices: [none, primary, secondary]
+ default: none
+ peer_redundancy_template:
+ description:
+ - The Peer Redundancy Template.
+ - The name of the vNIC template sharing a configuration with this template.
+ - If the redundancy_type is primary, the name of the secondary template should be provided.
+ - If the redundancy_type is secondary, the name of the primary template should be provided.
+ - Secondary templates can only configure non-shared properties (name, description, and mac_pool).
+ aliases: [ peer_redundancy_templ ]
+ target:
+ description:
+ - The possible target for vNICs created from this template.
+ - The target determines whether or not Cisco UCS Manager automatically creates a VM-FEX port profile with the appropriate settings for the vNIC template.
+ - "This can be one of the following:"
+ - "adapter — The vNICs apply to all adapters. No VM-FEX port profile is created if you choose this option."
+ - "vm - The vNICs apply to all virtual machines. A VM-FEX port profile is created if you choose this option."
+ default: adapter
+ template_type:
+ description:
+ - The Template Type field.
+ - "This can be one of the following:"
+ - "initial-template — vNICs created from this template are not updated if the template changes."
+ - "updating-template - vNICs created from this template are updated if the template changes."
+ choices: [initial-template, updating-template]
+ default: initial-template
+ vlans_list:
+ description:
+ - List of VLANs used by the vNIC template.
+ - "Each list element has the following suboptions:"
+ - "= name"
+ - " The name of the VLAN (required)."
+ - "- native"
+ - " Designates the VLAN as a native VLAN. Only one VLAN in the list can be a native VLAN."
+ - " [choices: 'no', 'yes']"
+ - " [Default: 'no']"
+ - "- state"
+ - " If present, will verify VLAN is present on template."
+ - " If absent, will verify VLAN is absent on template."
+ - " choices: [present, absent]"
+ - " default: present"
+ cdn_source:
+ description:
+ - CDN Source field.
+ - "This can be one of the following options:"
+ - "vnic-name - Uses the vNIC template name of the vNIC instance as the CDN name. This is the default option."
+ - "user-defined - Uses a user-defined CDN name for the vNIC template. If this option is chosen, cdn_name must also be provided."
+ choices: [vnic-name, user-defined]
+ default: vnic-name
+ cdn_name:
+ description:
+ - CDN Name used when cdn_source is set to user-defined.
+ mtu:
+ description:
+ - The MTU field.
+ - The maximum transmission unit, or packet size, that vNICs created from this vNIC template should use.
+ - Enter a string between '1500' and '9000'.
+ - If the vNIC template has an associated QoS policy, the MTU specified here must be equal to or less than the MTU specified in the QoS system class.
+ default: '1500'
+ mac_pool:
+ description:
+ - The MAC address pool that vNICs created from this vNIC template should use.
+ qos_policy:
+ description:
+ - The quality of service (QoS) policy that vNICs created from this vNIC template should use.
+ network_control_policy:
+ description:
+ - The network control policy that vNICs created from this vNIC template should use.
+ pin_group:
+ description:
+ - The LAN pin group that vNICs created from this vNIC template should use.
+ stats_policy:
+ description:
+ - The statistics collection policy that vNICs created from this vNIC template should use.
+ default: default
+ 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 vNIC template
+ cisco.ucs.ucs_vnic_template:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vNIC-A
+ fabric: A
+ vlans_list:
+ - name: default
+ native: 'yes'
+
+- name: Configure vNIC template with failover
+ cisco.ucs.ucs_vnic_template:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vNIC-A-B
+ fabric: A-B
+ vlans_list:
+ - name: default
+ native: 'yes'
+ state: present
+
+- name: Remove vNIC template
+ cisco.ucs.ucs_vnic_template:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vNIC-A
+ state: absent
+
+- name: Remove another vNIC template
+ cisco.ucs.ucs_vnic_template:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vNIC-A-B
+ state: absent
+
+- name: Remove VLAN from template
+ cisco.ucs.ucs_vnic_template:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vNIC-A-B
+ fabric: A-B
+ vlans_list:
+ - name: default
+ native: 'yes'
+ 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),
+ description=dict(type='str', aliases=['descr'], default=''),
+ fabric=dict(type='str', default='A', choices=['A', 'B', 'A-B', 'B-A']),
+ redundancy_type=dict(type='str', default='none', choices=['none', 'primary', 'secondary']),
+ peer_redundancy_template=dict(type='str', aliases=['peer_redundancy_templ'], default=''),
+ target=dict(type='str', default='adapter', choices=['adapter', 'vm']),
+ template_type=dict(type='str', default='initial-template', choices=['initial-template', 'updating-template']),
+ vlans_list=dict(type='list'),
+ cdn_source=dict(type='str', default='vnic-name', choices=['vnic-name', 'user-defined']),
+ cdn_name=dict(type='str', default=''),
+ mtu=dict(type='str', default='1500'),
+ mac_pool=dict(type='str', default=''),
+ qos_policy=dict(type='str', default=''),
+ network_control_policy=dict(type='str', default=''),
+ pin_group=dict(type='str', default=''),
+ stats_policy=dict(type='str', default='default'),
+ state=dict(type='str', default='present', choices=['present', 'absent']),
+ )
+
+ module = AnsibleModule(
+ argument_spec,
+ supports_check_mode=True,
+ required_if=[
+ ['cdn_source', 'user-defined', ['cdn_name']],
+ ],
+ )
+ ucs = UCSModule(module)
+
+ err = False
+
+ # UCSModule creation above verifies ucsmsdk is present and exits on failure. Additional imports are done below.
+ from ucsmsdk.mometa.vnic.VnicLanConnTempl import VnicLanConnTempl
+ from ucsmsdk.mometa.vnic.VnicEtherIf import VnicEtherIf
+
+ changed = False
+ try:
+ mo_exists = False
+ props_match = False
+ # dn is <org_dn>/lan-conn-templ-<name>
+ dn = module.params['org_dn'] + '/lan-conn-templ-' + 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:
+ # set default params for lists which can't be done in the argument_spec
+ if module.params.get('vlans_list'):
+ for vlan in module.params['vlans_list']:
+ if not vlan.get('native'):
+ vlan['native'] = 'no'
+ if not vlan.get('state'):
+ vlan['state'] = 'present'
+ # for target 'adapter', change to internal UCS Manager spelling 'adaptor'
+ if module.params['target'] == 'adapter':
+ module.params['target'] = 'adaptor'
+ if mo_exists:
+ # check top-level mo props
+ kwargs = dict(descr=module.params['description'])
+ kwargs['switch_id'] = module.params['fabric']
+ kwargs['redundancy_pair_type'] = module.params['redundancy_type']
+ kwargs['peer_redundancy_templ_name'] = module.params['peer_redundancy_template']
+ kwargs['ident_pool_name'] = module.params['mac_pool']
+ # do not check shared props if this is a secondary template
+ if module.params['redundancy_type'] != 'secondary':
+ kwargs['target'] = module.params['target']
+ kwargs['templ_type'] = module.params['template_type']
+ kwargs['cdn_source'] = module.params['cdn_source']
+ kwargs['admin_cdn_name'] = module.params['cdn_name']
+ kwargs['mtu'] = module.params['mtu']
+ kwargs['qos_policy_name'] = module.params['qos_policy']
+ kwargs['nw_ctrl_policy_name'] = module.params['network_control_policy']
+ kwargs['pin_to_group_name'] = module.params['pin_group']
+ kwargs['stats_policy_name'] = module.params['stats_policy']
+ if mo.check_prop_match(**kwargs):
+ # top-level props match, check next level mo/props
+ if not module.params.get('vlans_list'):
+ props_match = True
+ else:
+ # check vlan props
+ for vlan in module.params['vlans_list']:
+ child_dn = dn + '/if-' + str(vlan['name'])
+ mo_1 = ucs.login_handle.query_dn(child_dn)
+ if vlan['state'] == 'absent':
+ if mo_1:
+ props_match = False
+ break
+ else:
+ if mo_1:
+ kwargs = dict(default_net=vlan['native'])
+ 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
+ # secondary template only sets non shared props
+ if module.params['redundancy_type'] == 'secondary':
+ mo = VnicLanConnTempl(
+ parent_mo_or_dn=module.params['org_dn'],
+ name=module.params['name'],
+ descr=module.params['description'],
+ switch_id=module.params['fabric'],
+ redundancy_pair_type=module.params['redundancy_type'],
+ peer_redundancy_templ_name=module.params['peer_redundancy_template'],
+ ident_pool_name=module.params['mac_pool'],
+ )
+ else:
+ mo = VnicLanConnTempl(
+ parent_mo_or_dn=module.params['org_dn'],
+ name=module.params['name'],
+ descr=module.params['description'],
+ switch_id=module.params['fabric'],
+ redundancy_pair_type=module.params['redundancy_type'],
+ peer_redundancy_templ_name=module.params['peer_redundancy_template'],
+ target=module.params['target'],
+ templ_type=module.params['template_type'],
+ cdn_source=module.params['cdn_source'],
+ admin_cdn_name=module.params['cdn_name'],
+ mtu=module.params['mtu'],
+ ident_pool_name=module.params['mac_pool'],
+ qos_policy_name=module.params['qos_policy'],
+ nw_ctrl_policy_name=module.params['network_control_policy'],
+ pin_to_group_name=module.params['pin_group'],
+ stats_policy_name=module.params['stats_policy'],
+ )
+
+ if module.params.get('vlans_list'):
+ for vlan in module.params['vlans_list']:
+ if vlan['state'] == 'absent':
+ child_dn = dn + '/if-' + str(vlan['name'])
+ mo_1 = ucs.login_handle.query_dn(child_dn)
+ ucs.login_handle.remove_mo(mo_1)
+ else:
+ mo_1 = VnicEtherIf(
+ parent_mo_or_dn=mo,
+ name=str(vlan['name']),
+ default_net=vlan['native'],
+ )
+
+ 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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vsans.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vsans.py
new file mode 100644
index 00000000..cf4c656e
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_vsans.py
@@ -0,0 +1,204 @@
+#!/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_vsans
+short_description: Configures VSANs on Cisco UCS Manager
+description:
+- Configures VSANs on Cisco UCS Manager.
+extends_documentation_fragment: cisco.ucs.ucs
+options:
+ state:
+ description:
+ - If C(present), will verify VSANs are present and will create if needed.
+ - If C(absent), will verify VSANs are absent and will delete if needed.
+ choices: [present, absent]
+ default: present
+ name:
+ description:
+ - The name assigned to the VSAN.
+ - 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 VSAN is created.
+ required: yes
+ vsan_id:
+ description:
+ - The unique identifier assigned to the VSAN.
+ - The ID can be a string between '1' and '4078', or between '4080' and '4093'. '4079' is a reserved VSAN ID.
+ - In addition, if you plan to use FC end-host mode, the range between '3840' to '4079' is also a reserved VSAN ID range.
+ - Optional if state is absent.
+ required: yes
+ vlan_id:
+ description:
+ - The unique string identifier assigned to the VLAN used for Fibre Channel connections.
+ - Note that Cisco UCS Manager uses VLAN '4048'. See the UCS Manager configuration guide if you want to assign '4048' to a VLAN.
+ - Optional if state is absent.
+ required: yes
+ fc_zoning:
+ description:
+ - Fibre Channel zoning configuration for the Cisco UCS domain.
+ - "Fibre Channel zoning can be set to one of the following values:"
+ - "disabled — The upstream switch handles Fibre Channel zoning, or Fibre Channel zoning is not implemented for the Cisco UCS domain."
+ - "enabled — Cisco UCS Manager configures and controls Fibre Channel zoning for the Cisco UCS domain."
+ - If you enable Fibre Channel zoning, do not configure the upstream switch with any VSANs that are being used for Fibre Channel zoning.
+ choices: [disabled, enabled]
+ default: disabled
+ fabric:
+ description:
+ - "The fabric configuration of the VSAN. This can be one of the following:"
+ - "common - The VSAN maps to the same VSAN ID in all available fabrics."
+ - "A - The VSAN maps to the a VSAN ID that exists only in fabric A."
+ - "B - The VSAN maps to the a VSAN ID that exists only in fabric B."
+ choices: [common, A, B]
+ default: common
+requirements:
+- ucsmsdk
+author:
+- David Soper (@dsoper2)
+- John McDonough (@movinalot)
+- CiscoUcs (@CiscoUcs)
+version_added: '2.5'
+'''
+
+EXAMPLES = r'''
+- name: Configure VSAN
+ cisco.ucs.ucs_vsans:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vsan110
+ fabric: common
+ vsan_id: '110'
+ vlan_id: '110'
+
+- name: Remove VSAN
+ cisco.ucs.ucs_vsans:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: vsan110
+ 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(
+ name=dict(type='str'),
+ vsan_id=dict(type='str'),
+ vlan_id=dict(type='str'),
+ fc_zoning=dict(type='str', default='disabled', choices=['disabled', 'enabled']),
+ fabric=dict(type='str', default='common', choices=['common', 'A', 'B']),
+ state=dict(type='str', default='present', choices=['present', 'absent']),
+ vsan_list=dict(type='list'),
+ )
+
+ # Note that use of vsan_list is an experimental feature which allows multiple resource updates with a single UCSM connection.
+ # Support for vsan_list may change or be removed once persistent UCS connections are supported.
+ # Either vsan_list or name/vsan_id/vlan_id is required (user can specify either a list or single resource).
+
+ module = AnsibleModule(
+ argument_spec,
+ supports_check_mode=True,
+ required_one_of=[
+ ['vsan_list', 'name']
+ ],
+ mutually_exclusive=[
+ ['vsan_list', 'name']
+ ],
+ )
+ ucs = UCSModule(module)
+
+ err = False
+
+ from ucsmsdk.mometa.fabric.FabricVsan import FabricVsan
+
+ 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 vsan_list below.
+
+ if module.params['vsan_list']:
+ # directly use the list (single resource and list are mutually exclusive
+ vsan_list = module.params['vsan_list']
+ else:
+ # single resource specified, create list from the current params
+ vsan_list = [module.params]
+ for vsan in vsan_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 vsan.get('fc_zoning'):
+ vsan['fc_zoning'] = 'disabled'
+ if not vsan.get('fabric'):
+ vsan['fabric'] = 'common'
+ # dn is fabric/san/net-<name> for common vsans or fabric/san/[A or B]/net-<name> for A or B
+ dn_base = 'fabric/san'
+ if vsan['fabric'] != 'common':
+ dn_base += '/' + vsan['fabric']
+ dn = dn_base + '/net-' + vsan['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(id=vsan['vsan_id'])
+ kwargs['fcoe_vlan'] = vsan['vlan_id']
+ kwargs['zoning_state'] = vsan['fc_zoning']
+ 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 = FabricVsan(
+ parent_mo_or_dn=dn_base,
+ name=vsan['name'],
+ id=vsan['vsan_id'],
+ fcoe_vlan=vsan['vlan_id'],
+ zoning_state=vsan['fc_zoning'],
+ )
+
+ 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()
diff --git a/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_wwn_pool.py b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_wwn_pool.py
new file mode 100644
index 00000000..9751ebcb
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/ucs/plugins/modules/ucs_wwn_pool.py
@@ -0,0 +1,239 @@
+#!/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_wwn_pool
+short_description: Configures WWNN or WWPN pools on Cisco UCS Manager
+description:
+- Configures WWNNs or WWPN pools on Cisco UCS Manager.
+extends_documentation_fragment: cisco.ucs.ucs
+options:
+ state:
+ description:
+ - If C(present), will verify WWNNs/WWPNs are present and will create if needed.
+ - If C(absent), will verify WWNNs/WWPNs are absent and will delete if needed.
+ choices: [present, absent]
+ default: present
+ name:
+ description:
+ - The name of the World Wide Node Name (WWNN) or World Wide Port Name (WWPN) 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 WWNN or WWPN pool is created.
+ required: yes
+ purpose:
+ description:
+ - Specify whether this is a node (WWNN) or port (WWPN) pool.
+ - Optional if state is absent.
+ choices: [node, port]
+ required: yes
+ description:
+ description:
+ - A description of the WWNN or WWPN 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 initiator in the World Wide Name (WWN) block.
+ - This is the From field in the UCS Manager Add WWN Blocks menu.
+ last_addr:
+ description:
+ - The last initiator in the World Wide Name (WWN) block.
+ - This is the To field in the UCS Manager Add WWN Blocks menu.
+ - For WWxN pools, the pool size must be a multiple of ports-per-node + 1.
+ - For example, if there are 7 ports per node, the pool size must be a multiple of 8.
+ - If there are 63 ports per node, the pool size must be a multiple of 64.
+ 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 WWNN/WWPN pools
+ cisco.ucs.ucs_wwn_pool:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: WWNN-Pool
+ purpose: node
+ first_addr: 20:00:00:25:B5:48:00:00
+ last_addr: 20:00:00:25:B5:48:00:0F
+- cisco.ucs.ucs_wwn_pool:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: WWPN-Pool-A
+ 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: Remove WWNN/WWPN pools
+ cisco.ucs.ucs_wwn_pool:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: WWNN-Pool
+ state: absent
+- cisco.ucs.ucs_wwn_pool:
+ hostname: 172.16.143.150
+ username: admin
+ password: password
+ name: WWPN-Pool-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'),
+ purpose=dict(type='str', choices=['node', 'port']),
+ descr=dict(type='str'),
+ order=dict(type='str', default='default', choices=['default', 'sequential']),
+ first_addr=dict(type='str'),
+ last_addr=dict(type='str'),
+ state=dict(type='str', default='present', choices=['present', 'absent']),
+ wwn_list=dict(type='list'),
+ )
+
+ # Note that use of wwn_list is an experimental feature which allows multiple resource updates with a single UCSM connection.
+ # Support for wwn_list may change or be removed once persistent UCS connections are supported.
+ # Either wwn_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=[
+ ['wwn_list', 'name']
+ ],
+ mutually_exclusive=[
+ ['wwn_list', 'name']
+ ],
+ )
+ ucs = UCSModule(module)
+
+ err = False
+
+ from ucsmsdk.mometa.fcpool.FcpoolInitiators import FcpoolInitiators
+ from ucsmsdk.mometa.fcpool.FcpoolBlock import FcpoolBlock
+
+ 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 wwn_list below.
+
+ if module.params['wwn_list']:
+ # directly use the list (single resource and list are mutually exclusive
+ wwn_list = module.params['wwn_list']
+ else:
+ # single resource specified, create list from the current params
+ wwn_list = [module.params]
+ for wwn in wwn_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 wwn.get('descr'):
+ wwn['descr'] = ''
+ if not wwn.get('order'):
+ wwn['order'] = 'default'
+ # dn is <org_dn>/wwn-pool-<name> for WWNN or WWPN
+ dn = module.params['org_dn'] + '/wwn-pool-' + wwn['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:
+ # append purpose param with suffix used by UCSM
+ purpose_param = wwn['purpose'] + '-wwn-assignment'
+ if mo_exists:
+ # check top-level mo props
+ kwargs = dict(assignment_order=wwn['order'])
+ kwargs['descr'] = wwn['descr']
+ kwargs['purpose'] = purpose_param
+ if (mo.check_prop_match(**kwargs)):
+ # top-level props match, check next level mo/props
+ if 'last_addr' in wwn and 'first_addr' in wwn:
+ block_dn = dn + '/block-' + wwn['first_addr'].upper() + '-' + wwn['last_addr'].upper()
+ mo_1 = ucs.login_handle.query_dn(block_dn)
+ if mo_1:
+ props_match = True
+ else:
+ props_match = True
+
+ if not props_match:
+ if not module.check_mode:
+ # create if mo does not already exist
+ mo = FcpoolInitiators(
+ parent_mo_or_dn=module.params['org_dn'],
+ name=wwn['name'],
+ descr=wwn['descr'],
+ assignment_order=wwn['order'],
+ purpose=purpose_param,
+ )
+ if 'last_addr' in wwn and 'first_addr' in wwn:
+ mo_1 = FcpoolBlock(
+ parent_mo_or_dn=mo,
+ to=wwn['last_addr'],
+ r_from=wwn['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()