def update_configuration(self, update=None, body=None, attempt_recovery=True): """Update audit-log configuration.""" if update is None or body is None: update, body = self.build_configuration() if update and not self.check_mode: try: if self.proxy_used: rc, result = request(self.url + "storage-systems/audit-log/config", timeout=300, data=json.dumps(body), method='POST', headers=self.HEADERS, ignore_errors=True, **self.creds) else: rc, result = request(self.url + "storage-systems/%s/audit-log/config" % self.ssid, timeout=300, data=json.dumps(body), method='POST', headers=self.HEADERS, ignore_errors=True, **self.creds) if rc == 422: if self.force and attempt_recovery: self.delete_log_messages() update = self.update_configuration(update, body, False) else: self.module.fail_json(msg="Failed to update audit-log configuration! Array Id [%s]. Error [%s]." % (self.ssid, to_native(rc, result))) except Exception as error: self.module.fail_json(msg="Failed to update audit-log configuration! Array Id [%s]. Error [%s]." % (self.ssid, to_native(error))) return update
def apply_target_changes(self): update = False target = self.target body = dict() if self.ping != target['ping']: update = True body['icmpPingResponseEnabled'] = self.ping if self.unnamed_discovery != target['unnamed_discovery']: update = True body['unnamedDiscoverySessionsEnabled'] = self.unnamed_discovery self._logger.info(pformat(body)) if update and not self.check_mode: try: request(self.url + 'storage-systems/%s/iscsi/entity' % self.ssid, method='POST', data=json.dumps(body), timeout=60, headers=HEADERS, **self.creds) except Exception as err: self.module.fail_json( msg= "Failed to update the iSCSI target settings. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) return update
def target(self): """Provide information on the iSCSI Target configuration Sample: { 'alias': 'myCustomName', 'ping': True, 'unnamed_discovery': True, 'chap': False, 'iqn': 'iqn.1992-08.com.netapp:2800.000a132000b006d2000000005a0e8f45', } """ target = dict() try: (rc, data) = request( self.url + 'storage-systems/%s/graph/xpath-filter?query=/storagePoolBundle/target' % self.ssid, headers=HEADERS, **self.creds) # This likely isn't an iSCSI-enabled system if not data: self.module.fail_json( msg= "This storage-system doesn't appear to have iSCSI interfaces. Array Id [%s]." % (self.ssid)) data = data[0] chap = any([ auth for auth in data['configuredAuthMethods']['authMethodData'] if auth['authMethod'] == 'chap' ]) target.update( dict(alias=data['alias']['iscsiAlias'], iqn=data['nodeName']['iscsiNodeName'], chap=chap)) (rc, data) = request( self.url + 'storage-systems/%s/graph/xpath-filter?query=/sa/iscsiEntityData' % self.ssid, headers=HEADERS, **self.creds) data = data[0] target.update( dict( ping=data['icmpPingResponseEnabled'], unnamed_discovery=data['unnamedDiscoverySessionsEnabled'])) except Exception as err: self.module.fail_json( msg= "Failed to retrieve the iSCSI target information. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) return target
def update(self): """Execute the changes the require changes on the storage array.""" target_match, lun_reference, lun = self.get_lun_mapping() update = (self.state and not target_match) or (not self.state and target_match) if update and not self.check_mode: try: if self.state: body = dict() target = None if not self.target else self.mapping_info[ "target_by_name"][self.target] if target: body.update(dict(targetId=target)) if self.lun is not None: body.update(dict(lun=self.lun)) if lun_reference: rc, response = request( self.url + "storage-systems/%s/volume-mappings/%s/move" % (self.ssid, lun_reference), method="POST", data=json.dumps(body), headers=HEADERS, **self.creds) else: body.update( dict(mappableObjectId=self. mapping_info["volume_by_name"][self.volume])) rc, response = request( self.url + "storage-systems/%s/volume-mappings" % self.ssid, method="POST", data=json.dumps(body), headers=HEADERS, **self.creds) else: # Remove existing lun mapping for volume and target rc, response = request( self.url + "storage-systems/%s/volume-mappings/%s" % (self.ssid, lun_reference), method="DELETE", headers=HEADERS, **self.creds) except Exception as error: self.module.fail_json( msg= "Failed to update storage array lun mapping. Id [%s]. Error [%s]" % (self.ssid, to_native(error))) self.module.exit_json(msg="Lun mapping is complete.", changed=update)
def delete_log_messages(self): """Delete all audit-log messages.""" self._logger.info("Deleting audit-log messages...") try: if self.proxy_used: rc, result = request(self.url + "audit-log?clearAll=True", timeout=300, method="DELETE", headers=self.HEADERS, **self.creds) else: rc, result = request(self.url + "storage-systems/%s/audit-log?clearAll=True" % self.ssid, timeout=300, method="DELETE", headers=self.HEADERS, **self.creds) except Exception as err: self.module.fail_json(msg="Failed to delete audit-log messages! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
def update_configuration(self): # Define a new domain based on the user input domain = self.make_configuration() # This is the current list of configurations current = self.get_configuration(self.identifier) update = current != domain msg = "No changes were necessary for [%s]." % self.identifier self._logger.info("Is updated: %s", update) if update and not self.check_mode: msg = "The configuration changes were made for [%s]." % self.identifier try: if current is None: api = self.base_path + 'addDomain' else: api = self.base_path + '%s' % (domain['id']) (rc, result) = request(self.url + api, method='POST', data=json.dumps(domain), **self.creds) except Exception as err: self._logger.exception( "Failed to modify the LDAP configuration.") self.module.fail_json( msg= "Failed to modify LDAP configuration! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) return msg, update
def get_configuration(self): """Retrieve the existing audit-log configurations. :returns: dictionary containing current audit-log configuration """ try: if self.proxy_used: rc, data = request(self.url + "audit-log/config", timeout=300, headers=self.HEADERS, **self.creds) else: rc, data = request(self.url + "storage-systems/%s/audit-log/config" % self.ssid, timeout=300, headers=self.HEADERS, **self.creds) return data except Exception as err: self.module.fail_json(msg="Failed to retrieve the audit-log configuration! " "Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
def clear_configuration(self): configuration = self.get_full_configuration() updated = False msg = self.NO_CHANGE_MSG if configuration['ldapDomains']: updated = True msg = "The LDAP configuration for all domains was cleared." if not self.check_mode: try: (rc, result) = request(self.url + self.base_path, method='DELETE', ignore_errors=True, **self.creds) # Older versions of NetApp E-Series restAPI does not possess an API to remove all existing configs if rc == 405: for config in configuration['ldapDomains']: self.clear_single_configuration(config['id']) except Exception as err: self.module.fail_json( msg= "Failed to clear LDAP configuration! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) return msg, updated
def get_controllers(self): """Retrieve a mapping of controller labels to their references { 'A': '070000000000000000000001', 'B': '070000000000000000000002', } :return: the controllers defined on the system """ controllers = list() try: (rc, controllers) = request( self.url + 'storage-systems/%s/graph/xpath-filter?query=/controller/id' % self.ssid, headers=HEADERS, **self.creds) except Exception as err: self.module.fail_json( msg= "Failed to retrieve controller list! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) controllers.sort() controllers_dict = {} i = ord('A') for controller in controllers: label = chr(i) controllers_dict[label] = controller i += 1 return controllers_dict
def host_exists(self): """Determine if the requested host exists As a side effect, set the full list of defined hosts in 'all_hosts', and the target host in 'host_obj'. """ match = False all_hosts = list() try: (rc, all_hosts) = request(self.url + 'storage-systems/%s/hosts' % self.ssid, url_password=self.pwd, url_username=self.user, validate_certs=self.certs, headers=HEADERS) except Exception as err: self.module.fail_json( msg="Failed to determine host existence. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) # Augment the host objects for host in all_hosts: for port in host['hostSidePorts']: port['type'] = port['type'].lower() port['address'] = port['address'].lower() port['label'] = port['label'].lower() # Augment hostSidePorts with their ID (this is an omission in the API) ports = dict((port['label'], port['id']) for port in host['ports']) ports.update((port['label'], port['id']) for port in host['initiators']) for host_side_port in host['hostSidePorts']: if host_side_port['label'] in ports: host_side_port['id'] = ports[host_side_port['label']] if host['label'] == self.name: self.host_obj = host match = True self.all_hosts = all_hosts return match
def controllers(self): """Retrieve a mapping of controller labels to their references { 'A': '070000000000000000000001', 'B': '070000000000000000000002', } :return: the controllers defined on the system """ try: (rc, controllers) = request( self.url + 'storage-systems/%s/controllers' % self.ssid, headers=HEADERS, **self.creds) except Exception as err: controllers = list() self.module.fail_json( msg= "Failed to retrieve the controller settings. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) controllers.sort(key=lambda c: c['physicalLocation']['slot']) controllers_dict = dict() i = ord('A') for controller in controllers: label = chr(i) settings = dict( controllerSlot=controller['physicalLocation']['slot'], controllerRef=controller['controllerRef'], ssh=controller['networkSettings']['remoteAccessEnabled']) controllers_dict[label] = settings i += 1 return controllers_dict
def update_host(self): self._logger.info("Beginning the update for host=%s.", self.name) if self.ports: # Remove ports that need reassigning from their current host. self.assigned_host_ports(apply_unassigning=True) self.post_body["portsToUpdate"] = self.portsForUpdate self.post_body["ports"] = self.newPorts self._logger.info("Requested ports: %s", pformat(self.ports)) else: self._logger.info("No host ports were defined.") if self.group: self.post_body['groupId'] = self.group_id() self.post_body['hostType'] = dict(index=self.host_type_index) api = self.url + 'storage-systems/%s/hosts/%s' % (self.ssid, self.host_obj['id']) self._logger.info("POST => url=%s, body=%s.", api, pformat(self.post_body)) if not self.check_mode: try: (rc, self.host_obj) = request(api, url_username=self.user, url_password=self.pwd, headers=HEADERS, validate_certs=self.certs, method='POST', data=json.dumps(self.post_body)) except Exception as err: self.module.fail_json( msg="Failed to update host. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) payload = self.build_success_payload(self.host_obj) self.module.exit_json(changed=True, **payload)
def update_async(module, ssid, api_url, pwd, user, body, new_name, async_id): endpoint = 'storage-systems/%s/async-mirrors/%s' % (ssid, async_id) url = api_url + endpoint compare_keys = [ 'syncIntervalMinutes', 'syncWarnThresholdMinutes', 'recoveryWarnThresholdMinutes', 'repoUtilizationWarnThreshold' ] desired_state = dict((x, (body.get(x))) for x in compare_keys) if new_name: desired_state['new_name'] = new_name post_data = json.dumps(desired_state) try: rc, data = request(url, data=post_data, method='POST', headers=HEADERS, url_username=user, url_password=pwd) except Exception as e: module.exit_json( msg="Exception while updating async mirror group. Message: %s" % to_native(e), exception=traceback.format_exc()) return data
def create_host(self): self._logger.info("Creating host definition.") # Remove ports that need reassigning from their current host. self.assigned_host_ports(apply_unassigning=True) # needs_reassignment = False post_body = dict( name=self.name, hostType=dict(index=self.host_type_index), groupId=self.group_id(), ) if self.ports: post_body.update(ports=self.ports) api = self.url + "storage-systems/%s/hosts" % self.ssid self._logger.info('POST => url=%s, body=%s', api, pformat(post_body)) if not self.check_mode: if not self.host_exists(): try: (rc, self.host_obj) = request(api, method='POST', url_username=self.user, url_password=self.pwd, validate_certs=self.certs, data=json.dumps(post_body), headers=HEADERS) except Exception as err: self.module.fail_json( msg="Failed to create host. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) else: payload = self.build_success_payload(self.host_obj) self.module.exit_json(changed=False, msg="Host already exists. Id [%s]. Host [%s]." % (self.ssid, self.name), **payload) payload = self.build_success_payload(self.host_obj) self.module.exit_json(changed=True, msg='Host created.', **payload)
def send_test_email(self): """Send a test email to verify that the provided configuration is valid and functional.""" if not self.check_mode: try: (rc, result) = request( self.url + 'storage-systems/%s/device-alerts/alert-email-test' % self.ssid, timeout=300, method='POST', headers=HEADERS, **self.creds) if result['response'] != 'emailSentOK': self.module.fail_json( msg= "The test email failed with status=[%s]! Array Id [%s]." % (result['response'], self.ssid)) # This is going to catch cases like a connection failure except Exception as err: self.module.fail_json( msg= "We failed to send the test email! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
def assigned_host_ports(self, apply_unassigning=False): """Determine if the hostPorts requested have already been assigned and return list of required used ports.""" used_host_ports = {} for host in self.all_hosts: if host['label'] != self.name: for host_port in host['hostSidePorts']: for port in self.ports: if port['port'] == host_port["address"] or port['label'] == host_port['label']: if not self.force_port: self.module.fail_json(msg="There are no host ports available OR there are not enough" " unassigned host ports") else: # Determine port reference port_ref = [port["hostPortRef"] for port in host["ports"] if port["hostPortName"] == host_port["address"]] port_ref.extend([port["initiatorRef"] for port in host["initiators"] if port["nodeName"]["iscsiNodeName"] == host_port["address"]]) # Create dictionary of hosts containing list of port references if host["hostRef"] not in used_host_ports.keys(): used_host_ports.update({host["hostRef"]: port_ref}) else: used_host_ports[host["hostRef"]].extend(port_ref) else: for host_port in host['hostSidePorts']: for port in self.ports: if ((host_port['label'] == port['label'] and host_port['address'] != port['port']) or (host_port['label'] != port['label'] and host_port['address'] == port['port'])): if not self.force_port: self.module.fail_json(msg="There are no host ports available OR there are not enough" " unassigned host ports") else: # Determine port reference port_ref = [port["hostPortRef"] for port in host["ports"] if port["hostPortName"] == host_port["address"]] port_ref.extend([port["initiatorRef"] for port in host["initiators"] if port["nodeName"]["iscsiNodeName"] == host_port["address"]]) # Create dictionary of hosts containing list of port references if host["hostRef"] not in used_host_ports.keys(): used_host_ports.update({host["hostRef"]: port_ref}) else: used_host_ports[host["hostRef"]].extend(port_ref) # Unassign assigned ports if apply_unassigning: for host_ref in used_host_ports.keys(): try: rc, resp = request(self.url + 'storage-systems/%s/hosts/%s' % (self.ssid, host_ref), url_username=self.user, url_password=self.pwd, headers=HEADERS, validate_certs=self.certs, method='POST', data=json.dumps({"portsToRemove": used_host_ports[host_ref]})) except Exception as err: self.module.fail_json(msg="Failed to unassign host port. Host Id [%s]. Array Id [%s]. Ports [%s]." " Error [%s]." % (self.host_obj['id'], self.ssid, used_host_ports[host_ref], to_native(err))) return used_host_ports
def remove_host(self): try: (rc, resp) = request(self.url + "storage-systems/%s/hosts/%s" % (self.ssid, self.host_obj['id']), method='DELETE', url_username=self.user, url_password=self.pwd, validate_certs=self.certs) except Exception as err: self.module.fail_json( msg="Failed to remove host. Host[%s]. Array Id [%s]. Error [%s]." % (self.host_obj['id'], self.ssid, to_native(err)))
def get_configuration(self): try: (rc, result) = request(self.url + 'device-asup', headers=HEADERS, **self.creds) if not (result['asupCapable'] and result['onDemandCapable']): self.module.fail_json(msg="ASUP is not supported on this device. Array Id [%s]." % (self.ssid)) return result except Exception as err: self.module.fail_json(msg="Failed to retrieve ASUP configuration! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
def get_full_configuration(self): try: (rc, result) = request(self.url + self.base_path, **self.creds) return result except Exception as err: self._logger.exception( "Failed to retrieve the LDAP configuration.") self.module.fail_json( msg= "Failed to retrieve LDAP configuration! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
def update_configuration(self): config = self.get_configuration() update = False body = dict() if self.alerts: body = dict(alertingEnabled=True) if not config['alertingEnabled']: update = True body.update(emailServerAddress=self.server) if config['emailServerAddress'] != self.server: update = True body.update(additionalContactInformation=self.contact, sendAdditionalContactInformation=True) if self.contact and ( self.contact != config['additionalContactInformation'] or not config['sendAdditionalContactInformation']): update = True body.update(emailSenderAddress=self.sender) if config['emailSenderAddress'] != self.sender: update = True self.recipients.sort() if config['recipientEmailAddresses']: config['recipientEmailAddresses'].sort() body.update(recipientEmailAddresses=self.recipients) if config['recipientEmailAddresses'] != self.recipients: update = True elif config['alertingEnabled']: body = dict(alertingEnabled=False) update = True self._logger.debug(pformat(body)) if update and not self.check_mode: try: (rc, result) = request( self.url + 'storage-systems/%s/device-alerts' % self.ssid, method='POST', data=json.dumps(body), headers=HEADERS, **self.creds) # This is going to catch cases like a connection failure except Exception as err: self.module.fail_json( msg= "We failed to set the storage-system name! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) return update
def update_api_address_interface_match(self, body): """Change network interface address which matches the api_address""" try: try: (rc, data) = request( self.url + 'storage-systems/%s/configuration/ethernet-interfaces' % self.ssid, use_proxy=False, force=True, ignore_errors=True, method='POST', data=json.dumps(body), headers=HEADERS, timeout=10, **self.creds) except Exception: url_parts = list(urlparse.urlparse(self.url)) domain = url_parts[1].split(":") domain[0] = self.address url_parts[1] = ":".join(domain) expected_url = urlparse.urlunparse(url_parts) self._logger.info(pformat(expected_url)) (rc, data) = request( expected_url + 'storage-systems/%s/configuration/ethernet-interfaces' % self.ssid, headers=HEADERS, timeout=300, **self.creds) return except Exception as err: self._logger.info(type(err)) self.module.fail_json( msg= "Connection failure: we failed to modify the network settings! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
def get_configuration(self): try: (rc, result) = request( self.url + 'storage-systems/%s/device-alerts' % self.ssid, headers=HEADERS, **self.creds) self._logger.info("Current config: %s", pformat(result)) return result except Exception as err: self.module.fail_json( msg= "Failed to retrieve the alerts configuration! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
def update(self): self.controllers = self.get_controllers() if self.controller not in self.controllers: self.module.fail_json( msg= "The provided controller name is invalid. Valid controllers: %s." % ", ".join(self.controllers.keys())) iface_before = self.fetch_target_interface() update_required, body = self.make_update_body(iface_before) if update_required and not self.check_mode: try: url = ( self.url + 'storage-systems/%s/symbol/setIscsiInterfaceProperties' % self.ssid) (rc, result) = request(url, method='POST', data=json.dumps(body), headers=HEADERS, timeout=300, ignore_errors=True, **self.creds) # We could potentially retry this a few times, but it's probably a rare enough case (unless a playbook # is cancelled mid-flight), that it isn't worth the complexity. if rc == 422 and result['retcode'] in ['busy', '3']: self.module.fail_json( msg= "The interface is currently busy (probably processing a previously requested modification" " request). This operation cannot currently be completed. Array Id [%s]. Error [%s]." % (self.ssid, result)) # Handle authentication issues, etc. elif rc != 200: self.module.fail_json( msg= "Failed to modify the interface! Array Id [%s]. Error [%s]." % (self.ssid, to_native(result))) self._logger.debug("Update request completed successfully.") # This is going to catch cases like a connection failure except Exception as err: self.module.fail_json( msg= "Connection failure: we failed to modify the interface! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) iface_after = self.fetch_target_interface() self.module.exit_json(msg="The interface settings have been updated.", changed=update_required, enabled=iface_after['ipv4Enabled'])
def valid_host_type(self): host_types = None try: (rc, host_types) = request(self.url + 'storage-systems/%s/host-types' % self.ssid, url_password=self.pwd, url_username=self.user, validate_certs=self.certs, headers=HEADERS) except Exception as err: self.module.fail_json( msg="Failed to get host types. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) try: match = list(filter(lambda host_type: host_type['index'] == self.host_type_index, host_types))[0] return True except IndexError: self.module.fail_json(msg="There is no host type with index %s" % self.host_type_index)
def apply_iscsi_settings(self): """Update the iSCSI target alias and CHAP settings""" update = False target = self.target body = dict() if self.name is not None and self.name != target['alias']: update = True body['alias'] = self.name # If the CHAP secret was provided, we trigger an update. if self.chap_secret: update = True body.update( dict(enableChapAuthentication=True, chapSecret=self.chap_secret)) # If no secret was provided, then we disable chap elif target['chap']: update = True body.update(dict(enableChapAuthentication=False)) if update and not self.check_mode: try: request(self.url + 'storage-systems/%s/iscsi/target-settings' % self.ssid, method='POST', data=json.dumps(body), headers=HEADERS, **self.creds) except Exception as err: self.module.fail_json( msg= "Failed to update the iSCSI target settings. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) return update
def is_proxy(self): """Determine whether the API is embedded or proxy.""" try: # replace http url path with devmgr/utils/about about_url = list(urlparse(self.url)) about_url[2] = "devmgr/utils/about" about_url = urlunparse(about_url) rc, data = request(about_url, timeout=300, headers=self.HEADERS, **self.creds) return data["runningAsProxy"] except Exception as err: self.module.fail_json(msg="Failed to retrieve the webservices about information! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))
def remove_amg(module, ssid, api_url, pwd, user, async_id): endpoint = 'storage-systems/%s/async-mirrors/%s' % (ssid, async_id) url = api_url + endpoint try: rc, data = request(url, method='DELETE', url_username=user, url_password=pwd, headers=HEADERS) except Exception as e: module.exit_json( msg="Exception while removing async mirror group. Message: %s" % to_native(e), exception=traceback.format_exc()) return
def find_volume_copy_pair_id_by_volume_copy_pair_id(params): get_status = 'storage-systems/%s/volume-copy-jobs/%s?retainRepositories=false' % ( params['ssid'], params['volume_copy_pair_id']) url = params['api_url'] + get_status (rc, resp) = request(url, ignore_errors=True, method='DELETE', url_username=params['api_username'], url_password=params['api_password'], headers=HEADERS, validate_certs=params['validate_certs']) if rc != 200: return False, (rc, resp) else: return True, (rc, resp)
def create_async(module, ssid, api_url, api_pwd, api_usr, body): endpoint = 'storage-systems/%s/async-mirrors' % ssid url = api_url + endpoint post_data = json.dumps(body) try: rc, data = request(url, data=post_data, method='POST', url_username=api_usr, url_password=api_pwd, headers=HEADERS) except Exception as e: module.exit_json( msg="Exception while creating aysnc mirror group. Message: %s" % to_native(e), exception=traceback.format_exc()) return data
def update_configuration(self): config = self.get_configuration() update = False body = dict() if self.asup: body = dict(asupEnabled=True) if not config['asupEnabled']: update = True if (config['onDemandEnabled'] and config['remoteDiagsEnabled']) != self.active: update = True body.update(dict(onDemandEnabled=self.active, remoteDiagsEnabled=self.active)) self.days.sort() config['schedule']['daysOfWeek'].sort() body['schedule'] = dict(daysOfWeek=self.days, dailyMinTime=self.start, dailyMaxTime=self.end, weeklyMinTime=self.start, weeklyMaxTime=self.end) if self.days != config['schedule']['daysOfWeek']: update = True if self.start != config['schedule']['dailyMinTime'] or self.start != config['schedule']['weeklyMinTime']: update = True elif self.end != config['schedule']['dailyMaxTime'] or self.end != config['schedule']['weeklyMaxTime']: update = True elif config['asupEnabled']: body = dict(asupEnabled=False) update = True self._logger.info(pformat(body)) if update and not self.check_mode: try: (rc, result) = request(self.url + 'device-asup', method='POST', data=json.dumps(body), headers=HEADERS, **self.creds) # This is going to catch cases like a connection failure except Exception as err: self.module.fail_json(msg="We failed to set the storage-system name! Array Id [%s]. Error [%s]." % (self.ssid, to_native(err))) return update