diff options
Diffstat (limited to 'lib/ansible/modules/storage/netapp/na_ontap_firmware_upgrade.py')
-rw-r--r-- | lib/ansible/modules/storage/netapp/na_ontap_firmware_upgrade.py | 461 |
1 files changed, 0 insertions, 461 deletions
diff --git a/lib/ansible/modules/storage/netapp/na_ontap_firmware_upgrade.py b/lib/ansible/modules/storage/netapp/na_ontap_firmware_upgrade.py deleted file mode 100644 index dd50060c54..0000000000 --- a/lib/ansible/modules/storage/netapp/na_ontap_firmware_upgrade.py +++ /dev/null @@ -1,461 +0,0 @@ -#!/usr/bin/python - -# (c) 2019, NetApp, Inc -# 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 = ''' -author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com> -description: - - Update ONTAP service-prosessor firmware -extends_documentation_fragment: - - netapp.na_ontap -module: na_ontap_firmware_upgrade -options: - state: - description: - - Whether the specified ONTAP firmware should be upgraded or not. - default: present - type: str - node: - description: - - Node on which the device is located. - type: str - required: true - clear_logs: - description: - - Clear logs on the device after update. Default value is true - type: bool - default: true - package: - description: - - Name of the package file containing the firmware to be installed. Not required when -baseline is true. - type: str - shelf_module_fw: - description: - - Shelf module firmware to be updated to. - type: str - disk_fw: - description: - - disk firmware to be updated to. - type: str - update_type: - description: - - Type of firmware update to be performed. Options include serial_full, serial_differential, network_full. - type: str - install_baseline_image: - description: - - Install the version packaged with ONTAP if this parameter is set to true. Otherwise, package must be used to specify the package to install. - type: bool - default: false - firmware_type: - description: - - Type of firmware to be upgraded. Options include shelf, ACP, service-processor, and disk. - - For shelf firmware upgrade the operation is asynchronous, and therefore returns no errors that might occur during the download process. - - Shelf firmware upgrade is idempotent if shelf_module_fw is provided . - - disk firmware upgrade is idempotent if disk_fw is provided . - - With check mode, SP, ACP, disk, and shelf firmware upgrade is not idempotent. - - This operation will only update firmware on shelves/disk that do not have the latest firmware-revision. - choices: ['service-processor', 'shelf', 'acp', 'disk'] - type: str -short_description: NetApp ONTAP firmware upgrade for SP, shelf, ACP, and disk. -version_added: "2.9" -''' - -EXAMPLES = """ - - - name: SP firmware upgrade - na_ontap_firmware_upgrade: - state: present - node: vsim1 - package: "{{ file name }}" - clear_logs: True - install_baseline_image: False - update_type: serial_full - firmware_type: service-processor - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - - name: ACP firmware upgrade - na_ontap_firmware_upgrade: - state: present - node: vsim1 - firmware_type: acp - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - - name: shelf firmware upgrade - na_ontap_firmware_upgrade: - state: present - firmware_type: shelf - shelf_module_fw: 1221 - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - - name: disk firmware upgrade - na_ontap_firmware_upgrade: - state: present - firmware_type: disk - disk_fw: NA02 - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" -""" - -RETURN = """ -""" - -import traceback -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible.module_utils.netapp as netapp_utils -from ansible.module_utils.netapp_module import NetAppModule -import time - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppONTAPFirmwareUpgrade(object): - """ - Class with ONTAP firmware upgrade methods - """ - - def __init__(self): - self.argument_spec = netapp_utils.na_ontap_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=False, type='str', default='present'), - node=dict(required=False, type='str'), - firmware_type=dict(required=True, type='str', choices=['service-processor', 'shelf', 'acp', 'disk']), - clear_logs=dict(required=False, type='bool', default=True), - package=dict(required=False, type='str'), - install_baseline_image=dict(required=False, type='bool', default=False), - update_type=dict(required=False, type='str'), - shelf_module_fw=dict(required=False, type='str'), - disk_fw=dict(required=False, type='str') - - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('firmware_type', 'acp', ['node']), - ('firmware_type', 'disk', ['node']), - ('firmware_type', 'service-processor', ['node', 'update_type']), - ], - supports_check_mode=True - ) - - self.na_helper = NetAppModule() - self.parameters = self.na_helper.set_parameters(self.module.params) - if self.parameters.get('firmware_type') == 'service-processor': - if self.parameters.get('install_baseline_image') and self.parameters.get('package') is not None: - self.module.fail_json(msg='Do not specify both package and install_baseline_image: true') - if not self.parameters.get('package') and self.parameters.get('install_baseline_image') == 'False': - self.module.fail_json(msg='Specify at least one of package or install_baseline_image') - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_na_ontap_zapi(module=self.module) - - def firmware_image_get_iter(self): - """ - Compose NaElement object to query current firmware version - :return: NaElement object for firmware_image_get_iter with query - """ - firmware_image_get = netapp_utils.zapi.NaElement('service-processor-get-iter') - query = netapp_utils.zapi.NaElement('query') - firmware_image_info = netapp_utils.zapi.NaElement('service-processor-info') - firmware_image_info.add_new_child('node', self.parameters['node']) - query.add_child_elem(firmware_image_info) - firmware_image_get.add_child_elem(query) - return firmware_image_get - - def firmware_image_get(self, node_name): - """ - Get current firmware image info - :return: True if query successful, else return None - """ - firmware_image_get_iter = self.firmware_image_get_iter() - try: - result = self.server.invoke_successfully(firmware_image_get_iter, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as error: - self.module.fail_json(msg='Error fetching firmware image details: %s: %s' - % (self.parameters['node'], to_native(error)), - exception=traceback.format_exc()) - # return firmware image details - if result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) > 0: - sp_info = result.get_child_by_name('attributes-list').get_child_by_name('service-processor-info') - firmware_version = sp_info.get_child_content('firmware-version') - return firmware_version - return None - - def acp_firmware_required_get(self): - """ - where acp firmware upgrade is required - :return: True is firmware upgrade is required else return None - """ - acp_firmware_get_iter = netapp_utils.zapi.NaElement('storage-shelf-acp-module-get-iter') - query = netapp_utils.zapi.NaElement('query') - acp_info = netapp_utils.zapi.NaElement('storage-shelf-acp-module') - query.add_child_elem(acp_info) - acp_firmware_get_iter.add_child_elem(query) - try: - result = self.server.invoke_successfully(acp_firmware_get_iter, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as error: - self.module.fail_json(msg='Error fetching acp firmware details details: %s' - % (to_native(error)), exception=traceback.format_exc()) - if result.get_child_by_name('attributes-list').get_child_by_name('storage-shelf-acp-module'): - acp_module_info = result.get_child_by_name('attributes-list').get_child_by_name( - 'storage-shelf-acp-module') - state = acp_module_info.get_child_content('state') - if state == 'firmware_update_required': - # acp firmware version upgrade required - return True - return False - - def sp_firmware_image_update_progress_get(self, node_name): - """ - Get current firmware image update progress info - :return: Dictionary of firmware image update progress if query successful, else return None - """ - firmware_update_progress_get = netapp_utils.zapi.NaElement('service-processor-image-update-progress-get') - firmware_update_progress_get.add_new_child('node', self.parameters['node']) - - firmware_update_progress_info = dict() - try: - result = self.server.invoke_successfully(firmware_update_progress_get, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as error: - self.module.fail_json(msg='Error fetching firmware image upgrade progress details: %s' - % (to_native(error)), exception=traceback.format_exc()) - # return firmware image update progress details - if result.get_child_by_name('attributes').get_child_by_name('service-processor-image-update-progress-info'): - update_progress_info = result.get_child_by_name('attributes').get_child_by_name('service-processor-image-update-progress-info') - firmware_update_progress_info['is-in-progress'] = update_progress_info.get_child_content('is-in-progress') - firmware_update_progress_info['node'] = update_progress_info.get_child_content('node') - return firmware_update_progress_info - - def shelf_firmware_info_get(self): - """ - Get the current firmware of shelf module - :return:dict with module id and firmware info - """ - shelf_id_fw_info = dict() - shelf_firmware_info_get = netapp_utils.zapi.NaElement('storage-shelf-info-get-iter') - desired_attributes = netapp_utils.zapi.NaElement('desired-attributes') - storage_shelf_info = netapp_utils.zapi.NaElement('storage-shelf-info') - shelf_module = netapp_utils.zapi.NaElement('shelf-modules') - shelf_module_info = netapp_utils.zapi.NaElement('storage-shelf-module-info') - shelf_module.add_child_elem(shelf_module_info) - storage_shelf_info.add_child_elem(shelf_module) - desired_attributes.add_child_elem(storage_shelf_info) - shelf_firmware_info_get.add_child_elem(desired_attributes) - - try: - result = self.server.invoke_successfully(shelf_firmware_info_get, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as error: - self.module.fail_json(msg='Error fetching shelf module firmware details: %s' - % (to_native(error)), exception=traceback.format_exc()) - if result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) > 0: - shelf_info = result.get_child_by_name('attributes-list').get_child_by_name('storage-shelf-info') - if (shelf_info.get_child_by_name('shelf-modules') and - shelf_info.get_child_by_name('shelf-modules').get_child_by_name('storage-shelf-module-info')): - shelves = shelf_info['shelf-modules'].get_children() - for shelf in shelves: - shelf_id_fw_info[shelf.get_child_content('module-id')] = shelf.get_child_content('module-fw-revision') - return shelf_id_fw_info - - def disk_firmware_info_get(self): - """ - Get the current firmware of disks module - :return: - """ - disk_id_fw_info = dict() - disk_firmware_info_get = netapp_utils.zapi.NaElement('storage-disk-get-iter') - desired_attributes = netapp_utils.zapi.NaElement('desired-attributes') - storage_disk_info = netapp_utils.zapi.NaElement('storage-disk-info') - disk_inv = netapp_utils.zapi.NaElement('disk-inventory-info') - storage_disk_info.add_child_elem(disk_inv) - desired_attributes.add_child_elem(storage_disk_info) - disk_firmware_info_get.add_child_elem(desired_attributes) - try: - result = self.server.invoke_successfully(disk_firmware_info_get, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as error: - self.module.fail_json(msg='Error fetching disk module firmware details: %s' - % (to_native(error)), exception=traceback.format_exc()) - if result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) > 0: - disk_info = result.get_child_by_name('attributes-list') - disks = disk_info.get_children() - for disk in disks: - disk_id_fw_info[disk.get_child_content('disk-uid')] = disk.get_child_by_name('disk-inventory-info').get_child_content('firmware-revision') - return disk_id_fw_info - - def disk_firmware_required_get(self): - """ - Check weather disk firmware upgrade is required or not - :return: True if the firmware upgrade is required - """ - disk_firmware_info = self.disk_firmware_info_get() - for disk in disk_firmware_info: - if (disk_firmware_info[disk]) != self.parameters['disk_fw']: - return True - return False - - def shelf_firmware_required_get(self): - """ - Check weather shelf firmware upgrade is required or not - :return: True if the firmware upgrade is required - """ - shelf_firmware_info = self.shelf_firmware_info_get() - for module in shelf_firmware_info: - if (shelf_firmware_info[module]) != self.parameters['shelf_module_fw']: - return True - return False - - def sp_firmware_image_update(self): - """ - Update current firmware image - """ - firmware_update_info = netapp_utils.zapi.NaElement('service-processor-image-update') - if self.parameters.get('package') is not None: - firmware_update_info.add_new_child('package', self.parameters['package']) - if self.parameters.get('clear_logs') is not None: - firmware_update_info.add_new_child('clear-logs', str(self.parameters['clear_logs'])) - if self.parameters.get('install_baseline_image') is not None: - firmware_update_info.add_new_child('install-baseline-image', str(self.parameters['install_baseline_image'])) - firmware_update_info.add_new_child('node', self.parameters['node']) - firmware_update_info.add_new_child('update-type', self.parameters['update_type']) - - try: - self.server.invoke_successfully(firmware_update_info, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as error: - # Current firmware version matches the version to be installed - if to_native(error.code) == '13001' and (error.message.startswith('Service Processor update skipped')): - return False - self.module.fail_json(msg='Error updating firmware image for %s: %s' - % (self.parameters['node'], to_native(error)), - exception=traceback.format_exc()) - return True - - def shelf_firmware_upgrade(self): - """ - Upgrade shelf firmware image - """ - shelf_firmware_update_info = netapp_utils.zapi.NaElement('storage-shelf-firmware-update') - try: - self.server.invoke_successfully(shelf_firmware_update_info, enable_tunneling=True) - return True - except netapp_utils.zapi.NaApiError as error: - self.module.fail_json(msg='Error updating shelf firmware image : %s' - % (to_native(error)), exception=traceback.format_exc()) - - def acp_firmware_upgrade(self): - - """ - Upgrade shelf firmware image - """ - acp_firmware_update_info = netapp_utils.zapi.NaElement('storage-shelf-acp-firmware-update') - acp_firmware_update_info.add_new_child('node-name', self.parameters['node']) - try: - self.server.invoke_successfully(acp_firmware_update_info, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as error: - self.module.fail_json(msg='Error updating acp firmware image : %s' - % (to_native(error)), exception=traceback.format_exc()) - - def disk_firmware_upgrade(self): - - """ - Upgrade disk firmware - """ - disk_firmware_update_info = netapp_utils.zapi.NaElement('disk-update-disk-fw') - disk_firmware_update_info.add_new_child('node-name', self.parameters['node']) - try: - self.server.invoke_successfully(disk_firmware_update_info, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as error: - self.module.fail_json(msg='Error updating disk firmware image : %s' - % (to_native(error)), exception=traceback.format_exc()) - return True - - def autosupport_log(self): - """ - Autosupport log for software_update - :return: - """ - results = netapp_utils.get_cserver(self.server) - cserver = netapp_utils.setup_na_ontap_zapi(module=self.module, vserver=results) - netapp_utils.ems_log_event("na_ontap_firmware_upgrade", cserver) - - def apply(self): - """ - Apply action to upgrade firmware - """ - changed = False - self.autosupport_log() - firmware_update_progress = dict() - if self.parameters.get('firmware_type') == 'service-processor': - # service-processor firmware upgrade - current = self.firmware_image_get(self.parameters['node']) - - if self.parameters.get('state') == 'present' and current: - if not self.module.check_mode: - if self.sp_firmware_image_update(): - changed = True - firmware_update_progress = self.sp_firmware_image_update_progress_get(self.parameters['node']) - while firmware_update_progress.get('is-in-progress') == 'true': - time.sleep(25) - firmware_update_progress = self.sp_firmware_image_update_progress_get(self.parameters['node']) - else: - # we don't know until we try the upgrade - changed = True - - elif self.parameters.get('firmware_type') == 'shelf': - # shelf firmware upgrade - if self.parameters.get('shelf_module_fw'): - if self.shelf_firmware_required_get(): - if not self.module.check_mode: - changed = self.shelf_firmware_upgrade() - else: - changed = True - else: - if not self.module.check_mode: - changed = self.shelf_firmware_upgrade() - else: - # we don't know until we try the upgrade -- assuming the worst - changed = True - elif self.parameters.get('firmware_type') == 'acp': - # acp firmware upgrade - if self.acp_firmware_required_get(): - if not self.module.check_mode: - self.acp_firmware_upgrade() - changed = True - elif self.parameters.get('firmware_type') == 'disk': - # Disk firmware upgrade - if self.parameters.get('disk_fw'): - if self.disk_firmware_required_get(): - if not self.module.check_mode: - changed = self.disk_firmware_upgrade() - else: - changed = True - else: - if not self.module.check_mode: - changed = self.disk_firmware_upgrade() - else: - # we don't know until we try the upgrade -- assuming the worst - changed = True - - self.module.exit_json(changed=changed) - - -def main(): - """Execute action""" - community_obj = NetAppONTAPFirmwareUpgrade() - community_obj.apply() - - -if __name__ == '__main__': - main() |