예제 #1
0
    def get_volume(self, volume_name):
        self.debug('fetching volumes')
        # fetch the list of volume objects and look for one with a matching name (we'll need to merge volumes and thin-volumes)
        try:
            (rc, volumes) = request(self.api_url + "/storage-systems/%s/volumes" % (self.ssid),
                                    headers=dict(Accept="application/json"), url_username=self.api_usr,
                                    url_password=self.api_pwd, validate_certs=self.validate_certs)
        except Exception as err:
            self.module.fail_json(
                msg="Failed to obtain list of standard/thick volumes.  Array Id [%s]. Error[%s]." % (self.ssid,
                                                                                                     to_native(err)))

        try:
            self.debug('fetching thin-volumes')
            (rc, thinvols) = request(self.api_url + "/storage-systems/%s/thin-volumes" % (self.ssid),
                                     headers=dict(Accept="application/json"), url_username=self.api_usr,
                                     url_password=self.api_pwd, validate_certs=self.validate_certs)
        except Exception as err:
            self.module.fail_json(
                msg="Failed to obtain list of thin volumes.  Array Id [%s]. Error[%s]." % (self.ssid, to_native(err)))

        volumes.extend(thinvols)

        self.debug("searching for volume '%s'", volume_name)
        volume_detail = next(ifilter(lambda a: a['name'] == volume_name, volumes), None)

        if volume_detail:
            self.debug('found')
        else:
            self.debug('not found')

        return volume_detail
예제 #2
0
def get_host_and_group_map(module, ssid, api_url, user, pwd, validate_certs):
    mapping = dict(host=dict(), group=dict())

    hostgroups = 'storage-systems/%s/host-groups' % ssid
    groups_url = api_url + hostgroups
    try:
        hg_rc, hg_data = request(groups_url, headers=HEADERS, url_username=user, url_password=pwd,
                                 validate_certs=validate_certs)
    except Exception as err:
        module.fail_json(msg="Failed to get host groups. Id [%s]. Error [%s]" % (ssid, to_native(err)))

    for group in hg_data:
        mapping['group'][group['name']] = group['id']

    hosts = 'storage-systems/%s/hosts' % ssid
    hosts_url = api_url + hosts
    try:
        h_rc, h_data = request(hosts_url, headers=HEADERS, url_username=user, url_password=pwd,
                               validate_certs=validate_certs)
    except Exception as err:
        module.fail_json(msg="Failed to get hosts. Id [%s]. Error [%s]" % (ssid, to_native(err)))

    for host in h_data:
        mapping['host'][host['name']] = host['id']

    return mapping
    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)
예제 #4
0
    def create_storage_pool(self):
        self.debug("creating storage pool...")

        sp_add_req = dict(raidLevel=self.raid_level,
                          diskDriveIds=self.disk_ids,
                          name=self.name)

        if self.erase_secured_drives:
            sp_add_req['eraseSecuredDrives'] = self.erase_secured_drives

        try:
            (rc,
             resp) = request(self.api_url +
                             "/storage-systems/%s/storage-pools" % (self.ssid),
                             data=json.dumps(sp_add_req),
                             headers=self.post_headers,
                             method='POST',
                             url_username=self.api_usr,
                             url_password=self.api_pwd,
                             validate_certs=self.validate_certs,
                             timeout=120)
        except:
            err = get_exception()
            pool_id = self.pool_detail['id']
            self.module.exit_json(
                msg=
                "Failed to create storage pool. Pool id [%s]. Array id [%s].  Error[%s]."
                % (pool_id, self.ssid, str(err)))

        self.pool_detail = self.get_storage_pool(self.name)

        if self.secure_pool:
            secure_pool_data = dict(securePool=True)
            try:
                (retc, r) = request(self.api_url +
                                    "/storage-systems/%s/storage-pools/%s" %
                                    (self.ssid, self.pool_detail['id']),
                                    data=json.dumps(secure_pool_data),
                                    headers=self.post_headers,
                                    method='POST',
                                    url_username=self.api_usr,
                                    url_password=self.api_pwd,
                                    validate_certs=self.validate_certs,
                                    timeout=120,
                                    ignore_errors=True)
            except:
                err = get_exception()
                pool_id = self.pool_detail['id']
                self.module.exit_json(
                    msg=
                    "Failed to update storage pool. Pool id [%s]. Array id [%s].  Error[%s]."
                    % (pool_id, self.ssid, str(err)))
예제 #5
0
 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)))
예제 #6
0
def find_valid_copy_pair_targets_and_sources(params):
    get_status = 'storage-systems/%s/volumes' % params['ssid']
    url = params['api_url'] + get_status

    (response_code, response_data) = request(url, ignore_errors=True, method='GET',
                                             url_username=params['api_username'], url_password=params['api_password'],
                                             headers=HEADERS,
                                             validate_certs=params['validate_certs'])

    if response_code == 200:
        source_capacity = None
        candidates = []
        for volume in response_data:
            if volume['id'] == params['search_volume_id']:
                source_capacity = volume['capacity']
            else:
                candidates.append(volume)

        potential_sources = []
        potential_targets = []

        for volume in candidates:
            if volume['capacity'] > source_capacity:
                if volume['volumeCopyTarget'] is False:
                    if volume['volumeCopySource'] is False:
                        potential_targets.append(volume['id'])
            else:
                if volume['volumeCopyTarget'] is False:
                    if volume['volumeCopySource'] is False:
                        potential_sources.append(volume['id'])

        return potential_targets, potential_sources

    else:
        raise Exception("Response [%s]" % response_code)
    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)))
예제 #8
0
    def reassign_ports(self, apply=True):
        post_body = dict(
            portsToUpdate=dict()
        )

        for port in self.ports:
            if self.port_on_diff_host(port):
                host_port = self.get_port(port['label'], port['port'])
                post_body['portsToUpdate'].update(dict(
                    portRef=host_port['id'],
                    hostRef=self.host_obj['id'],
                    label=port['label']
                    # Doesn't yet address port identifier or chap secret
                ))

        self._logger.info("reassign_ports: %s", pformat(post_body))

        if apply:
            try:
                (rc, self.host_obj) = request(
                    self.url + 'storage-systems/%s/hosts/%s' % (self.ssid, self.host_obj['id']),
                    url_username=self.user, url_password=self.pwd, headers=HEADERS,
                    validate_certs=self.certs, method='POST', data=json.dumps(post_body))
            except Exception as err:
                self.module.fail_json(
                    msg="Failed to reassign host port. Host Id [%s]. Array Id [%s]. Error [%s]." % (
                        self.host_obj['id'], self.ssid, to_native(err)))

        return post_body
예제 #9
0
    def hostports_available(self):
        used_ids = list()
        try:
            (rc, self.available_ports) = request(self.url + 'storage-systems/%s/unassociated-host-ports' % 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 unassociated host ports. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))

        if len(self.available_ports) > 0 and len(self.ports) <= len(self.available_ports):
            for port in self.ports:
                for free_port in self.available_ports:
                    # Desired Type matches but also make sure we haven't already used the ID
                    if not free_port['id'] in used_ids:
                        # update the port arg to have an id attribute
                        used_ids.append(free_port['id'])
                        break

            if len(used_ids) != len(self.ports) and not self.force_port:
                self.module.fail_json(
                    msg="There are not enough free host ports with the specified port types to proceed")
            else:
                return True

        else:
            self.module.fail_json(msg="There are no host ports available OR there are not enough unassigned host ports")
    def reassign_ports(self, apply=True):
        if not self.post_body:
            self.post_body = dict(
                portsToUpdate=dict()
            )

        for port in self.ports:
            if self.port_on_diff_host(port):
                self.post_body['portsToUpdate'].update(dict(
                    portRef=self.other_host['hostPortRef'],
                    hostRef=self.host_obj['id'],
                    # Doesn't yet address port identifier or chap secret
                ))

        if apply:
            try:
                (rc, self.host_obj) = request(
                    self.url + 'storage-systems/%s/hosts/%s' % (self.ssid, self.host_obj['id']),
                    url_username=self.user, url_password=self.pwd, headers=HEADERS,
                    validate_certs=self.certs, method='POST', data=json.dumps(self.post_body))
            except:
                err = get_exception()
                self.module.fail_json(
                    msg="Failed to reassign host port. Host Id [%s]. Array Id [%s]. Error [%s]." % (
                        self.host_obj['id'], self.ssid, str(err)))
예제 #11
0
    def create_host(self):
        post_body = dict(
            name=self.name,
            host_type=dict(index=self.host_type_index),
            groupId=self.group_id,
            ports=self.ports
        )
        if self.ports:
            # Check that all supplied port args are valid
            if self.hostports_available:
                post_body.update(ports=self.ports)
            elif not self.force_port:
                self.module.fail_json(
                    msg="You supplied ports that are already in use. Supply force_port to True if you wish to reassign the ports")

        if not self.host_exists:
            try:
                (rc, create_resp) = request(self.url + "storage-systems/%s/hosts" % self.ssid, 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:
            self.module.exit_json(changed=False,
                                  msg="Host already exists. Id [%s]. Host [%s]." % (self.ssid, self.name))

        self.host_obj = create_resp

        if self.ports and self.force_port:
            self.reassign_ports()

        self.module.exit_json(changed=True, **self.host_obj)
예제 #12
0
    def create_volume(self, pool_id, name, size_unit, size, segment_size_kb,
                      data_assurance_enabled):
        volume_add_req = dict(
            name=name,
            poolId=pool_id,
            sizeUnit=size_unit,
            size=size,
            segSize=segment_size_kb,
            dataAssuranceEnabled=data_assurance_enabled,
        )

        self.debug("creating volume '%s'", name)
        try:
            (rc, resp) = request(self.api_url + "/storage-systems/%s/volumes" %
                                 (self.ssid),
                                 data=json.dumps(volume_add_req),
                                 headers=HEADERS,
                                 method='POST',
                                 url_username=self.api_usr,
                                 url_password=self.api_pwd,
                                 validate_certs=self.validate_certs,
                                 timeout=120)
        except Exception as err:
            self.module.fail_json(
                msg=
                "Failed to create volume.  Volume [%s].  Array Id [%s]. Error[%s]."
                % (self.name, self.ssid, to_native(err)))
예제 #13
0
    def create_host(self):
        post_body = dict(
            name=self.name,
            hostType=dict(index=self.host_type_index),
            groupId=self.group_id,
            ports=self.ports
        )
        if self.ports:
            # Check that all supplied port args are valid
            if self.hostports_available:
                post_body.update(ports=self.ports)
            elif not self.force_port:
                self.module.fail_json(
                    msg="You supplied ports that are already in use. Supply force_port to True if you wish to reassign the ports")

        if not self.host_exists:
            try:
                (rc, create_resp) = request(self.url + "storage-systems/%s/hosts" % self.ssid, 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:
            self.module.exit_json(changed=False,
                                  msg="Host already exists. Id [%s]. Host [%s]." % (self.ssid, self.name))

        self.host_obj = create_resp

        if self.ports and self.force_port:
            self.reassign_ports()

        self.module.exit_json(changed=True, **self.host_obj)
예제 #14
0
    def create_thin_volume(self, pool_id, name, size_unit, size, thin_volume_repo_size,
                           thin_volume_max_repo_size, data_assurance_enabled):
        thin_volume_add_req = dict(
            name=name,
            poolId=pool_id,
            sizeUnit=size_unit,
            virtualSize=size,
            repositorySize=thin_volume_repo_size,
            maximumRepositorySize=thin_volume_max_repo_size,
            dataAssuranceEnabled=data_assurance_enabled,
        )

        self.debug("creating thin-volume '%s'", name)
        try:
            (rc, resp) = request(self.api_url + "/storage-systems/%s/thin-volumes" % (self.ssid),
                                 data=json.dumps(thin_volume_add_req), headers=HEADERS, method='POST',
                                 url_username=self.api_usr, url_password=self.api_pwd,
                                 validate_certs=self.validate_certs,
                                 timeout=120)
        except Exception:
            err = get_exception()
            self.module.fail_json(
                msg="Failed to create thin volume.  Volume [%s].  Array Id [%s]. Error[%s]." % (self.name,
                                                                                                self.ssid,
                                                                                                str(err)))
예제 #15
0
    def hostports_available(self):
        used_ids = list()
        try:
            (rc, self.available_ports) = request(self.url + 'storage-systems/%s/unassociated-host-ports' % 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 unassociated host ports. Array Id [%s]. Error [%s]." % (self.ssid, to_native(err)))

        if len(self.available_ports) > 0 and len(self.ports) <= len(self.available_ports):
            for port in self.ports:
                for free_port in self.available_ports:
                    # Desired Type matches but also make sure we haven't already used the ID
                    if not free_port['id'] in used_ids:
                        # update the port arg to have an id attribute
                        used_ids.append(free_port['id'])
                        break

            if len(used_ids) != len(self.ports) and not self.force_port:
                self.module.fail_json(
                    msg="There are not enough free host ports with the specified port types to proceed")
            else:
                return True

        else:
            self.module.fail_json(msg="There are no host ports available OR there are not enough unassigned host ports")
예제 #16
0
    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
예제 #17
0
def create_mapping(module, ssid, lun_map, vol_name, api_url, user, pwd, validate_certs):
    mappings = 'storage-systems/%s/volume-mappings' % ssid
    url = api_url + mappings

    if lun_map is not None:
        post_body = json.dumps(dict(
            mappableObjectId=lun_map['volumeRef'],
            targetId=lun_map['mapRef'],
            lun=lun_map['lun']
        ))
    else:
        post_body = json.dumps(dict(
            mappableObjectId=lun_map['volumeRef'],
            targetId=lun_map['mapRef'],
        ))

    rc, data = request(url, data=post_body, method='POST', url_username=user, url_password=pwd, headers=HEADERS,
                       ignore_errors=True, validate_certs=validate_certs)

    if rc == 422 and lun_map['lun'] is not None:
        data = move_lun(module, ssid, lun_map, vol_name, api_url, user, pwd, validate_certs)
        # module.fail_json(msg="The volume you specified '%s' is already "
        #                      "part of a different LUN mapping. If you "
        #                      "want to move it to a different host or "
        #                      "hostgroup, then please use the "
        #                      "netapp_e_move_lun module" % vol_name)
    return data
예제 #18
0
    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'.
        """
        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)))

        self.all_hosts = all_hosts

        # Augment the host objects
        for host in all_hosts:
            # Augment hostSidePorts with their ID (this is an omission in the API)
            host_side_ports = host['hostSidePorts']
            initiators = dict((port['label'], port['id']) for port in host['initiators'])
            ports = dict((port['label'], port['id']) for port in host['ports'])
            ports.update(initiators)
            for port in host_side_ports:
                if port['label'] in ports:
                    port['id'] = ports[port['label']]

        try:  # Try to grab the host object
            self.host_obj = list(filter(lambda host: host['label'] == self.name, all_hosts))[0]
            return True
        except IndexError:
            # Host with the name passed in does not exist
            return False
예제 #19
0
    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)))
예제 #20
0
def create_mapping(module, ssid, lun_map, vol_name, api_url, user, pwd,
                   validate_certs):
    mappings = 'storage-systems/%s/volume-mappings' % ssid
    url = api_url + mappings

    if lun_map is not None:
        post_body = json.dumps(
            dict(mappableObjectId=lun_map['volumeRef'],
                 targetId=lun_map['mapRef'],
                 lun=lun_map['lun']))
    else:
        post_body = json.dumps(
            dict(
                mappableObjectId=lun_map['volumeRef'],
                targetId=lun_map['mapRef'],
            ))

    rc, data = request(url,
                       data=post_body,
                       method='POST',
                       url_username=user,
                       url_password=pwd,
                       headers=HEADERS,
                       ignore_errors=True,
                       validate_certs=validate_certs)

    if rc == 422 and lun_map['lun'] is not None:
        data = move_lun(module, ssid, lun_map, vol_name, api_url, user, pwd,
                        validate_certs)
        # module.fail_json(msg="The volume you specified '%s' is already "
        #                      "part of a different LUN mapping. If you "
        #                      "want to move it to a different host or "
        #                      "hostgroup, then please use the "
        #                      "netapp_e_move_lun module" % vol_name)
    return data
예제 #21
0
def has_match(module, ssid, api_url, api_pwd, api_usr, body):
    compare_keys = ['syncIntervalMinutes', 'syncWarnThresholdMinutes',
                    'recoveryWarnThresholdMinutes', 'repoUtilizationWarnThreshold']
    desired_state = dict((x, (body.get(x))) for x in compare_keys)
    label_exists = False
    matches_spec = False
    current_state = None
    async_id = None
    api_data = None
    desired_name = body.get('name')
    endpoint = 'storage-systems/%s/async-mirrors' % ssid
    url = api_url + endpoint
    try:
        rc, data = request(url, url_username=api_usr, url_password=api_pwd, headers=HEADERS)
    except Exception as e:
        module.exit_json(msg="Error finding a match. Message: %s" % to_native(e), exception=traceback.format_exc())

    for async_group in data:
        if async_group['label'] == desired_name:
            label_exists = True
            api_data = async_group
            async_id = async_group['groupRef']
            current_state = dict(
                syncIntervalMinutes=async_group['syncIntervalMinutes'],
                syncWarnThresholdMinutes=async_group['syncCompletionTimeAlertThresholdMinutes'],
                recoveryWarnThresholdMinutes=async_group['recoveryPointAgeAlertThresholdMinutes'],
                repoUtilizationWarnThreshold=async_group['repositoryUtilizationWarnThreshold'],
            )

    if current_state == desired_state:
        matches_spec = True

    return label_exists, matches_spec, api_data, async_id
    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
예제 #23
0
    def group_id(self):
        if self.group:
            try:
                (rc, all_groups) = request(
                    self.url + 'storage-systems/%s/host-groups' % 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 groups. Array Id [%s]. Error [%s]."
                    % (self.ssid, to_native(err)))

            try:
                group_obj = list(
                    filter(lambda group: group['name'] == self.group,
                           all_groups))[0]
                return group_obj['id']
            except IndexError:
                self.module.fail_json(msg="No group with the name: %s exists" %
                                      self.group)
        else:
            # Return the value equivalent of no group
            return "0000000000000000000000000000000000000000"
예제 #24
0
    def update_host(self):
        if self.ports:
            if self.hostports_available:
                if self.force_port_update is True:
                    self.reassign_ports(apply=False)
                    # Make sure that only ports that arent being reassigned are passed into the ports attr
                    self.ports = [
                        port for port in self.ports
                        if not self.port_on_diff_host(port)
                    ]

                self.post_body['ports'] = self.ports

        if self.group:
            self.post_body['groupId'] = self.group_id

        self.post_body['hostType'] = dict(index=self.host_type_index)

        try:
            (rc, self.host_obj) = request(self.url +
                                          'storage-systems/%s/hosts/%s' %
                                          (self.ssid, self.host_obj['id']),
                                          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)))

        self.module.exit_json(changed=True, **self.host_obj)
예제 #25
0
    def get_expansion_candidate_drives(self):
        # sanity checks; don't call this if we can't/don't need to expand
        if not self.needs_expansion:
            self.module.fail_json(msg="can't get expansion candidates when pool doesn't need expansion")

        self.debug("fetching expansion candidate drives...")
        try:
            (rc, resp) = request(
                self.api_url + "/storage-systems/%s/storage-pools/%s/expand" % (self.ssid,
                                                                                self.pool_detail['id']),
                method='GET', url_username=self.api_usr, url_password=self.api_pwd, validate_certs=self.validate_certs,
                timeout=120)
        except Exception as err:
            pool_id = self.pool_detail['id']
            self.module.exit_json(
                msg="Failed to fetch candidate drives for storage pool. Pool id [%s]. Array id [%s].  Error[%s]." % (
                    pool_id, self.ssid, to_native(err)))

        current_drive_count = len(self.sp_drives)
        current_capacity_bytes = int(self.pool_detail['totalRaidedSpace'])  # TODO: is this the right attribute to use?

        if self.criteria_min_usable_capacity:
            requested_capacity_bytes = self.criteria_min_usable_capacity * self._size_unit_map[self.criteria_size_unit]
        else:
            requested_capacity_bytes = current_capacity_bytes

        if self.criteria_drive_count:
            minimum_disks_to_add = max((self.criteria_drive_count - current_drive_count), 1)
        else:
            minimum_disks_to_add = 1

        minimum_bytes_to_add = max(requested_capacity_bytes - current_capacity_bytes, 0)

        # FUTURE: allow more control over expansion candidate selection?
        # loop over candidate disk sets and add until we've met both criteria

        added_drive_count = 0
        added_capacity_bytes = 0

        drives_to_add = set()

        for s in resp:
            # don't trust the API not to give us duplicate drives across candidate sets, especially in multi-drive sets
            candidate_drives = s['drives']
            if len(drives_to_add.intersection(candidate_drives)) != 0:
                # duplicate, skip
                continue
            drives_to_add.update(candidate_drives)
            added_drive_count += len(candidate_drives)
            added_capacity_bytes += int(s['usableCapacity'])

            if added_drive_count >= minimum_disks_to_add and added_capacity_bytes >= minimum_bytes_to_add:
                break

        if (added_drive_count < minimum_disks_to_add) or (added_capacity_bytes < minimum_bytes_to_add):
            self.module.fail_json(
                msg="unable to find at least %s drives to add that would add at least %s bytes of capacity" % (
                    minimum_disks_to_add, minimum_bytes_to_add))

        return list(drives_to_add)
예제 #26
0
    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
예제 #27
0
def has_match(module, ssid, api_url, api_pwd, api_usr, body):
    compare_keys = ['syncIntervalMinutes', 'syncWarnThresholdMinutes',
                    'recoveryWarnThresholdMinutes', 'repoUtilizationWarnThreshold']
    desired_state = dict((x, (body.get(x))) for x in compare_keys)
    label_exists = False
    matches_spec = False
    current_state = None
    async_id = None
    api_data = None
    desired_name = body.get('name')
    endpoint = 'storage-systems/%s/async-mirrors' % ssid
    url = api_url + endpoint
    try:
        rc, data = request(url, url_username=api_usr, url_password=api_pwd, headers=HEADERS)
    except Exception:
        error = get_exception()
        module.exit_json(exception="Error finding a match. Message: %s" % str(error))

    for async_group in data:
        if async_group['label'] == desired_name:
            label_exists = True
            api_data = async_group
            async_id = async_group['groupRef']
            current_state = dict(
                syncIntervalMinutes=async_group['syncIntervalMinutes'],
                syncWarnThresholdMinutes=async_group['syncCompletionTimeAlertThresholdMinutes'],
                recoveryWarnThresholdMinutes=async_group['recoveryPointAgeAlertThresholdMinutes'],
                repoUtilizationWarnThreshold=async_group['repositoryUtilizationWarnThreshold'],
            )

    if current_state == desired_state:
        matches_spec = True

    return label_exists, matches_spec, api_data, async_id
    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
예제 #29
0
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
예제 #30
0
def remove_mapping(module, ssid, lun_mapping, api_url, user, pwd, validate_certs):
    lun_id = get_lun_id(module, ssid, lun_mapping, api_url, user, pwd)
    lun_del = "storage-systems/%s/volume-mappings/%s" % (ssid, lun_id)
    url = api_url + lun_del
    rc, data = request(url, method='DELETE', url_username=user, url_password=pwd, headers=HEADERS,
                       validate_certs=validate_certs)
    return data
    def get_storage_pool(self, storage_pool_name):
        # global ifilter
        self.debug("fetching storage pools")
        # map the storage pool name to its id
        try:
            (rc, resp) = request(self.api_url + "/storage-systems/%s/storage-pools" % (self.ssid),
                                 headers=dict(Accept="application/json"), url_username=self.api_usr,
                                 url_password=self.api_pwd, validate_certs=self.validate_certs)
        except Exception:
            err = get_exception()
            rc = err.args[0]
            if rc == 404 and self.state == 'absent':
                self.module.exit_json(
                    msg="Storage pool [%s] did not exist." % (self.name))
            else:
                err = get_exception()
                self.module.exit_json(
                    msg="Failed to get storage pools. Array id [%s].  Error[%s]. State[%s]. RC[%s]." %
                        (self.ssid, str(err), self.state, rc))

        self.debug("searching for storage pool '%s'", storage_pool_name)

        pool_detail = next(select(lambda a: a['name'] == storage_pool_name, resp), None)

        if pool_detail:
            found = 'found'
        else:
            found = 'not found'
        self.debug(found)

        return pool_detail
예제 #32
0
    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)
예제 #33
0
    def create_thin_volume(self, pool_id, name, size_unit, size,
                           thin_volume_repo_size, thin_volume_max_repo_size,
                           data_assurance_enabled):
        thin_volume_add_req = dict(
            name=name,
            poolId=pool_id,
            sizeUnit=size_unit,
            virtualSize=size,
            repositorySize=thin_volume_repo_size,
            maximumRepositorySize=thin_volume_max_repo_size,
            dataAssuranceEnabled=data_assurance_enabled,
        )

        self.debug("creating thin-volume '%s'" % name)
        try:
            (rc,
             resp) = request(self.api_url +
                             "/storage-systems/%s/thin-volumes" % (self.ssid),
                             data=json.dumps(thin_volume_add_req),
                             headers=HEADERS,
                             method='POST',
                             url_username=self.api_usr,
                             url_password=self.api_pwd,
                             validate_certs=self.validate_certs,
                             timeout=120)
        except Exception:
            err = get_exception()
            self.module.fail_json(
                msg=
                "Failed to create thin volume.  Volume [%s].  Array Id [%s]. Error[%s]."
                % (self.name, self.ssid, str(err)))
예제 #34
0
    def update_volume_properties(self):
        update_volume_req = dict()

        # conditionally add values so we ignore unspecified props
        if self.volume_ssdcache_setting_changed:
            update_volume_req['flashCache'] = self.ssd_cache_enabled

        self.debug("updating volume properties...")
        try:
            (rc, resp) = request(self.api_url + "/storage-systems/%s/%s/%s/" %
                                 (self.ssid, self.volume_resource_name,
                                  self.volume_detail['id']),
                                 data=json.dumps(update_volume_req),
                                 headers=HEADERS,
                                 method='POST',
                                 url_username=self.api_usr,
                                 url_password=self.api_pwd,
                                 validate_certs=self.validate_certs,
                                 timeout=120)
        except Exception:
            err = get_exception()
            self.module.fail_json(
                msg=
                "Failed to update volume properties.  Volume [%s].  Array Id [%s]. Error[%s]."
                % (self.name, self.ssid, str(err)))
예제 #35
0
    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)
예제 #36
0
    def get_storage_pool(self, storage_pool_name):
        self.debug("fetching storage pools")
        # map the storage pool name to its id
        try:
            (rc,
             resp) = request(self.api_url +
                             "/storage-systems/%s/storage-pools" % (self.ssid),
                             headers=dict(Accept="application/json"),
                             url_username=self.api_usr,
                             url_password=self.api_pwd,
                             validate_certs=self.validate_certs)
        except Exception:
            err = get_exception()
            self.module.fail_json(
                msg=
                "Failed to obtain list of storage pools.  Array Id [%s]. Error[%s]."
                % (self.ssid, str(err)))

        self.debug("searching for storage pool '%s'" % storage_pool_name)
        pool_detail = next(
            ifilter(lambda a: a['name'] == storage_pool_name, resp), None)

        if pool_detail:
            self.debug('found')
        else:
            self.debug('not found')

        return pool_detail
    def sp_drives(self, exclude_hotspares=True):
        if not self._sp_drives_cached:

            self.debug("fetching drive list...")
            try:
                (rc, resp) = request(
                    self.api_url + "/storage-systems/%s/drives" % (self.ssid),
                    method='GET',
                    url_username=self.api_usr,
                    url_password=self.api_pwd,
                    validate_certs=self.validate_certs)
            except Exception as err:
                pool_id = self.pool_detail['id']
                self.module.exit_json(
                    msg=
                    "Failed to fetch disk drives. Pool id [%s]. Array id [%s].  Error[%s]."
                    % (pool_id, self.ssid, to_native(err)))

            sp_id = self.pool_detail['id']
            if exclude_hotspares:
                self._sp_drives_cached = [
                    d for d in resp if d['currentVolumeGroupRef'] == sp_id
                    and not d['hotSpare']
                ]
            else:
                self._sp_drives_cached = [
                    d for d in resp if d['currentVolumeGroupRef'] == sp_id
                ]

        return self._sp_drives_cached
예제 #38
0
    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 reduce_drives(self, drive_list):
        if all(drive in drive_list for drive in self.sp_drives):
            # all the drives passed in are present in the system
            pass
        else:
            self.module.fail_json(
                msg=
                "One of the drives you wish to remove does not currently exist in the storage pool you specified"
            )

        try:
            (rc,
             resp) = request(self.api_url +
                             "/storage-systems/%s/storage-pools/%s/reduction" %
                             (self.ssid, self.pool_detail['id']),
                             data=json.dumps(drive_list),
                             headers=self.post_headers,
                             method='POST',
                             url_username=self.api_usr,
                             url_password=self.api_pwd,
                             validate_certs=self.validate_certs,
                             timeout=120)
        except Exception as err:
            pool_id = self.pool_detail['id']
            self.module.exit_json(
                msg=
                "Failed to remove drives from storage pool. Pool id [%s]. Array id [%s].  Error[%s]."
                % (pool_id, self.ssid, to_native(err)))
예제 #40
0
def find_valid_copy_pair_targets_and_sources(params):
    get_status = 'storage-systems/%s/volumes' % params['ssid']
    url = params['api_url'] + get_status

    (response_code, response_data) = request(url, ignore_errors=True, method='GET',
                                             url_username=params['api_username'], url_password=params['api_password'],
                                             headers=HEADERS,
                                             validate_certs=params['validate_certs'])

    if response_code == 200:
        source_capacity = None
        candidates = []
        for volume in response_data:
            if volume['id'] == params['search_volume_id']:
                source_capacity = volume['capacity']
            else:
                candidates.append(volume)

        potential_sources = []
        potential_targets = []

        for volume in candidates:
            if volume['capacity'] > source_capacity:
                if volume['volumeCopyTarget'] is False:
                    if volume['volumeCopySource'] is False:
                        potential_targets.append(volume['id'])
            else:
                if volume['volumeCopyTarget'] is False:
                    if volume['volumeCopySource'] is False:
                        potential_sources.append(volume['id'])

        return potential_targets, potential_sources

    else:
        raise Exception("Response [%s]" % response_code)
예제 #41
0
def move_lun(module, ssid, lun_map, vol_name, api_url, user, pwd, validate_certs):
    lun_id = get_lun_id(module, ssid, lun_map, api_url, user, pwd, validate_certs)
    move_lun = "storage-systems/%s/volume-mappings/%s/move" % (ssid, lun_id)
    url = api_url + move_lun
    post_body = json.dumps(dict(targetId=lun_map['mapRef'], lun=lun_map['lun']))
    rc, data = request(url, data=post_body, method='POST', url_username=user, url_password=pwd, headers=HEADERS,
                       validate_certs=validate_certs)
    return data
예제 #42
0
def get_volumes(module, ssid, api_url, user, pwd, mappable, validate_certs):
    volumes = 'storage-systems/%s/%s' % (ssid, mappable)
    url = api_url + volumes
    try:
        rc, data = request(url, url_username=user, url_password=pwd, validate_certs=validate_certs)
    except Exception as err:
        module.fail_json(
            msg="Failed to mappable objects. Type[%s. Id [%s]. Error [%s]." % (mappable, ssid, to_native(err)))
    return data
예제 #43
0
def get_hostgroups(module, ssid, api_url, user, pwd, validate_certs):
    groups = "storage-systems/%s/host-groups" % ssid
    url = api_url + groups
    try:
        rc, data = request(url, headers=HEADERS, url_username=user, url_password=pwd, validate_certs=validate_certs)
        return data
    except Exception:
        module.fail_json(msg="There was an issue with connecting, please check that your"
                             "endpoint is properly defined and your credentials are correct")
예제 #44
0
    def create_storage_pool(self):
        self.debug("creating storage pool...")

        sp_add_req = dict(
            raidLevel=self.raid_level,
            diskDriveIds=self.disk_ids,
            name=self.name
        )

        if self.erase_secured_drives:
            sp_add_req['eraseSecuredDrives'] = self.erase_secured_drives

        try:
            (rc, resp) = request(self.api_url + "/storage-systems/%s/storage-pools" % (self.ssid),
                                 data=json.dumps(sp_add_req), headers=self.post_headers, method='POST',
                                 url_username=self.api_usr, url_password=self.api_pwd,
                                 validate_certs=self.validate_certs,
                                 timeout=120)
        except:
            err = get_exception()
            pool_id = self.pool_detail['id']
            self.module.exit_json(
                msg="Failed to create storage pool. Pool id [%s]. Array id [%s].  Error[%s]." % (pool_id,
                                                                                                 self.ssid,
                                                                                                 str(err)))

        self.pool_detail = self.get_storage_pool(self.name)

        if self.secure_pool:
            secure_pool_data = dict(securePool=True)
            try:
                (retc, r) = request(
                    self.api_url + "/storage-systems/%s/storage-pools/%s" % (self.ssid, self.pool_detail['id']),
                    data=json.dumps(secure_pool_data), headers=self.post_headers, method='POST',
                    url_username=self.api_usr,
                    url_password=self.api_pwd, validate_certs=self.validate_certs, timeout=120, ignore_errors=True)
            except:
                err = get_exception()
                pool_id = self.pool_detail['id']
                self.module.exit_json(
                    msg="Failed to update storage pool. Pool id [%s]. Array id [%s].  Error[%s]." % (pool_id,
                                                                                                     self.ssid,
                                                                                                     str(err)))
예제 #45
0
    def expand_storage_pool(self):
        drives_to_add = self.get_expansion_candidate_drives()

        self.debug("adding %s drives to storage pool...", len(drives_to_add))
        sp_expand_req = dict(
            drives=drives_to_add
        )
        try:
            request(
                self.api_url + "/storage-systems/%s/storage-pools/%s/expand" % (self.ssid,
                                                                                self.pool_detail['id']),
                data=json.dumps(sp_expand_req), headers=self.post_headers, method='POST', url_username=self.api_usr,
                url_password=self.api_pwd, validate_certs=self.validate_certs, timeout=120)
        except Exception as err:
            pool_id = self.pool_detail['id']
            self.module.exit_json(
                msg="Failed to add drives to storage pool. Pool id [%s]. Array id [%s].  Error[%s]." % (pool_id,
                                                                                                        self.ssid,
                                                                                                        to_native(err)))
예제 #46
0
 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 remote host.  Host[%s]. Array Id [%s]. Error [%s]." % (self.host_obj['id'],
                                                                                   self.ssid,
                                                                                   to_native(err)))
예제 #47
0
    def get_candidate_disks(self):
        self.debug("getting candidate disks...")

        # driveCapacityMin is broken on /drives POST. Per NetApp request we built our own
        # switch back to commented code below if it gets fixed
        # drives_req = dict(
        #     driveCount = self.criteria_drive_count,
        #     sizeUnit = 'mb',
        #     raidLevel = self.raid_level
        # )
        #
        # if self.criteria_drive_type:
        #     drives_req['driveType'] = self.criteria_drive_type
        # if self.criteria_disk_min_aggregate_size_mb:
        #     drives_req['targetUsableCapacity'] = self.criteria_disk_min_aggregate_size_mb
        #
        # # TODO: this arg appears to be ignored, uncomment if it isn't
        # #if self.criteria_disk_min_size_gb:
        # #    drives_req['driveCapacityMin'] = self.criteria_disk_min_size_gb * 1024
        # (rc,drives_resp) = request(self.api_url + "/storage-systems/%s/drives" % (self.ssid), data=json.dumps(drives_req), headers=self.post_headers,
        #                            method='POST', url_username=self.api_usr, url_password=self.api_pwd, validate_certs=self.validate_certs)
        #
        # if rc == 204:
        #     self.module.fail_json(msg='Cannot find disks to match requested criteria for storage pool')

        # disk_ids = [d['id'] for d in drives_resp]

        try:
            (rc, drives_resp) = request(self.api_url + "/storage-systems/%s/drives" % (self.ssid), method='GET',
                                        url_username=self.api_usr, url_password=self.api_pwd,
                                        validate_certs=self.validate_certs)
        except:
            err = get_exception()
            self.module.exit_json(
                msg="Failed to fetch disk drives. Array id [%s].  Error[%s]." % (self.ssid, str(err)))

        try:
            candidate_set = self.filter_drives(drives_resp,
                                               exact_drive_count=self.criteria_drive_count,
                                               drive_type=self.criteria_drive_type,
                                               min_drive_size=self.criteria_drive_min_size,
                                               raid_level=self.raid_level,
                                               size_unit=self.criteria_size_unit,
                                               min_total_capacity=self.criteria_min_usable_capacity,
                                               interface_type=self.criteria_drive_interface_type,
                                               fde_required=self.criteria_drive_require_fde
                                               )
        except:
            err = get_exception()
            self.module.fail_json(
                msg="Failed to allocate adequate drive count. Id [%s]. Error [%s]." % (self.ssid, str(err)))

        disk_ids = [d['id'] for d in candidate_set]

        return disk_ids
예제 #48
0
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
예제 #49
0
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
예제 #50
0
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)
예제 #51
0
 def update_reserve_drive_count(self, qty):
     data = dict(reservedDriveCount=qty)
     try:
         (rc, resp) = request(
             self.api_url + "/storage-systems/%s/storage-pools/%s" % (self.ssid, self.pool_detail['id']),
             data=json.dumps(data), headers=self.post_headers, method='POST', url_username=self.api_usr,
             url_password=self.api_pwd, validate_certs=self.validate_certs, timeout=120)
     except Exception as err:
         pool_id = self.pool_detail['id']
         self.module.exit_json(
             msg="Failed to update reserve drive count. Pool id [%s]. Array id [%s].  Error[%s]." % (pool_id,
                                                                                                     self.ssid,
                                                                                                     to_native(err)))
예제 #52
0
def get_lun_mappings(ssid, api_url, user, pwd, validate_certs, get_all=None):
    mappings = 'storage-systems/%s/volume-mappings' % ssid
    url = api_url + mappings
    rc, data = request(url, url_username=user, url_password=pwd, validate_certs=validate_certs)

    if not get_all:
        remove_keys = ('ssid', 'perms', 'lunMappingRef', 'type', 'id')

        for key in remove_keys:
            for mapping in data:
                del mapping[key]

    return data
예제 #53
0
    def valid_host_type(self):
        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 = 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)
예제 #54
0
 def delete_volume(self):
     # delete the volume
     self.debug("deleting volume '%s'", self.volume_detail['name'])
     try:
         (rc, resp) = request(
             self.api_url + "/storage-systems/%s/%s/%s" % (self.ssid, self.volume_resource_name,
                                                           self.volume_detail['id']),
             method='DELETE', url_username=self.api_usr, url_password=self.api_pwd,
             validate_certs=self.validate_certs, timeout=120)
     except Exception as err:
         self.module.fail_json(
             msg="Failed to delete volume.  Volume [%s].  Array Id [%s]. Error[%s]." % (self.name, self.ssid,
                                                                                        to_native(err)))
예제 #55
0
def start_stop_copy(params):
    get_status = 'storage-systems/%s/volume-copy-jobs-control/%s?control=%s' % (
        params['ssid'], params['volume_copy_pair_id'], params['start_stop_copy'])
    url = params['api_url'] + get_status

    (response_code, response_data) = request(url, ignore_errors=True, method='POST',
                                             url_username=params['api_username'], url_password=params['api_password'],
                                             headers=HEADERS,
                                             validate_certs=params['validate_certs'])

    if response_code == 200:
        return True, response_data[0]['percentComplete']
    else:
        return False, response_data
예제 #56
0
def find_volume_copy_pair_id_from_source_volume_id_and_destination_volume_id(params):
    get_status = 'storage-systems/%s/volume-copy-jobs' % params['ssid']
    url = params['api_url'] + get_status

    (rc, resp) = request(url, method='GET', url_username=params['api_username'],
                         url_password=params['api_password'], headers=HEADERS,
                         validate_certs=params['validate_certs'])

    volume_copy_pair_id = None
    for potential_copy_pair in resp:
        if potential_copy_pair['sourceVolume'] == params['source_volume_id']:
            if potential_copy_pair['sourceVolume'] == params['source_volume_id']:
                volume_copy_pair_id = potential_copy_pair['id']

    return volume_copy_pair_id
예제 #57
0
    def host_exists(self):
        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)))

        self.all_hosts = all_hosts
        try:  # Try to grab the host object
            self.host_obj = filter(lambda host: host['label'] == self.name, all_hosts)[0]
            return True
        except IndexError:
            # Host with the name passed in does not exist
            return False
예제 #58
0
def create_copy_pair(params):
    get_status = 'storage-systems/%s/volume-copy-jobs' % params['ssid']
    url = params['api_url'] + get_status

    rData = {
        "sourceId": params['source_volume_id'],
        "targetId": params['destination_volume_id']
    }

    (rc, resp) = request(url, data=json.dumps(rData), ignore_errors=True, method='POST',
                         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)