Ejemplo n.º 1
0
 def validate_cpg(self, cpg_name):
     try:
         self.client.getCPG(cpg_name)
     except hpeexceptions.HTTPNotFound:
         err = (_("CPG (%s) doesn't exist on array") % cpg_name)
         LOG.error(err)
         raise exception.InvalidInput(reason=err)
    def initialize_iscsi_ports(self, common):
        # map iscsi_ip-> ip_port
        #             -> iqn
        #             -> nsp
        self.iscsi_ips = {}
        temp_iscsi_ip = {}

        # use the 3PAR ip_addr list for iSCSI configuration
        if len(self.configuration.hpe3par_iscsi_ips) > 0:
            # add port values to ip_addr, if necessary
            for ip_addr in self.configuration.hpe3par_iscsi_ips:
                ip = ip_addr.split(':')
                if len(ip) == 1:
                    temp_iscsi_ip[ip_addr] = {'ip_port': DEFAULT_ISCSI_PORT}
                elif len(ip) == 2:
                    temp_iscsi_ip[ip[0]] = {'ip_port': ip[1]}
                else:
                    LOG.warning(_LW("Invalid IP address format '%s'"), ip_addr)

        # add the single value iscsi_ip_address option to the IP dictionary.
        # This way we can see if it's a valid iSCSI IP. If it's not valid,
        # we won't use it and won't bother to report it, see below
        if (self.configuration.iscsi_ip_address not in temp_iscsi_ip):
            ip = self.configuration.iscsi_ip_address
            ip_port = self.configuration.iscsi_port
            temp_iscsi_ip[ip] = {'ip_port': ip_port}

        # get all the valid iSCSI ports from 3PAR
        # when found, add the valid iSCSI ip, ip port, iqn and nsp
        # to the iSCSI IP dictionary
        iscsi_ports = common.get_active_iscsi_target_ports()

        for port in iscsi_ports:
            ip = port['IPAddr']
            if ip in temp_iscsi_ip:
                ip_port = temp_iscsi_ip[ip]['ip_port']
                self.iscsi_ips[ip] = {
                    'ip_port': ip_port,
                    'nsp': port['nsp'],
                    'iqn': port['iSCSIName']
                }
                del temp_iscsi_ip[ip]

        # if the single value iscsi_ip_address option is still in the
        # temp dictionary it's because it defaults to $my_ip which doesn't
        # make sense in this context. So, if present, remove it and move on.
        if (self.configuration.iscsi_ip_address in temp_iscsi_ip):
            del temp_iscsi_ip[self.configuration.iscsi_ip_address]

        # lets see if there are invalid iSCSI IPs left in the temp dict
        if len(temp_iscsi_ip) > 0:
            LOG.warning(
                _LW("Found invalid iSCSI IP address(s) in "
                    "configuration option(s) hpe3par_iscsi_ips or "
                    "iscsi_ip_address '%s.'"), (", ".join(temp_iscsi_ip)))

        if not len(self.iscsi_ips) > 0:
            msg = _('At least one valid iSCSI IP address must be set.')
            LOG.error(msg)
            raise exception.InvalidInput(reason=msg)
Ejemplo n.º 3
0
    def client_login(self):
        try:
            LOG.debug("Connecting to 3PAR")
            self.client.login(self.config.hpe3par_username,
                              self.config.hpe3par_password)
        except hpeexceptions.HTTPUnauthorized as ex:
            msg = (_("Failed to Login to 3PAR (%(url)s) because %(err)s") % {
                'url': self.config.hpe3par_api_url,
                'err': ex
            })
            LOG.error(msg)
            raise exception.InvalidInput(reason=msg)

        known_hosts_file = CONF.ssh_hosts_key_file
        policy = "AutoAddPolicy"
        if CONF.strict_ssh_host_key_policy:
            policy = "RejectPolicy"
        self.client.setSSHOptions(self.config.san_ip,
                                  self.config.san_login,
                                  self.config.san_password,
                                  port=self.config.san_ssh_port,
                                  conn_timeout=self.config.ssh_conn_timeout,
                                  privatekey=self.config.san_private_key,
                                  missing_key_policy=policy,
                                  known_hosts_file=known_hosts_file)
Ejemplo n.º 4
0
    def create_volume(self, volume):
        """Creates a volume."""
        # check for valid provisioning type
        prov_value = volume['provisioning']
        if prov_value not in self.valid_prov_values:
            err = (_("Must specify a valid provisioning type %(valid)s, "
                     "value '%(prov)s' is invalid.") %
                   {'valid': self.valid_prov_values,
                    'prov': prov_value})
            LOG.error(err)
            raise exception.InvalidInput(reason=err)

        thin_prov = True

        if prov_value == "full":
            thin_prov = False
        elif prov_value == "dedup":
            err = (_("Dedup is not supported in the StoreVirtual driver."))
            LOG.error(err)
            raise exception.InvalidInput(reason=err)

        client = self._login()
        try:
            optional = {'isThinProvisioned': thin_prov,
                        'dataProtectionLevel': 0}

            clusterName = self.configuration.hpelefthand_clustername
            optional['clusterName'] = clusterName

            volume_info = client.createVolume(
                volume['name'], self.cluster_id,
                volume['size'] * units.Gi,
                optional)

            model_update = self._update_provider(volume_info)
            volume['provider_location'] = model_update['provider_location']
            volume['provider_auth'] = ''
        except Exception as ex:
            raise exception.VolumeBackendAPIException(data=ex)
        finally:
            self._logout(client)
Ejemplo n.º 5
0
 def do_setup(self):
     """Set up LeftHand client."""
     if hpelefthandclient.version < MIN_CLIENT_VERSION:
         ex_msg = (_("Invalid hpelefthandclient version found ("
                     "%(found)s). Version %(minimum)s or greater "
                     "required. Run 'pip install --upgrade "
                     "python-lefthandclient' to upgrade the "
                     "hpelefthandclient.")
                   % {'found': hpelefthandclient.version,
                      'minimum': MIN_CLIENT_VERSION})
         LOG.error(ex_msg)
         raise exception.InvalidInput(reason=ex_msg)
Ejemplo n.º 6
0
    def get_domain(self, cpg_name):
        try:
            cpg = self.client.getCPG(cpg_name)
        except hpeexceptions.HTTPNotFound:
            err = (_("Failed to get domain because CPG (%s) doesn't "
                     "exist on array.") % cpg_name)
            LOG.error(err)
            raise exception.InvalidInput(reason=err)

        if 'domain' in cpg:
            return cpg['domain']
        return None
Ejemplo n.º 7
0
    def do_setup(self):
        if hpe3parclient is None:
            msg = _('You must install hpe3parclient before using 3PAR'
                    ' drivers. Run "pip install python-3parclient" to'
                    ' install the hpe3parclient.')
            raise exception.VolumeBackendAPIException(data=msg)
        try:
            self.client = self._create_client()
            wsapi_version = self.client.getWsApiVersion()
            self.API_VERSION = wsapi_version['build']
        except hpeexceptions.UnsupportedVersion as ex:
            raise exception.InvalidInput(ex)

        if self.config.hpe3par_debug:
            self.client.debug_rest(True)
Ejemplo n.º 8
0
    def _create_client(self):
        cl = client.HPE3ParClient(
            self.config.hpe3par_api_url,
            suppress_ssl_warnings=CONF.suppress_requests_ssl_warnings)
        client_version = hpe3parclient.version

        if client_version < MIN_CLIENT_VERSION:
            ex_msg = (_('Invalid hpe3parclient version found (%(found)s). '
                        'Version %(minimum)s or greater required. Run "pip'
                        ' install --upgrade python-3parclient" to upgrade'
                        ' the hpe3parclient.') % {
                            'found': client_version,
                            'minimum': MIN_CLIENT_VERSION
                        })
            LOG.error(ex_msg)
            raise exception.InvalidInput(reason=ex_msg)

        return cl
Ejemplo n.º 9
0
    def get_flash_cache_policy(self, flash_cache):
        if flash_cache is not None:
            # If requested, see if supported on back end
            if self.API_VERSION < FLASH_CACHE_API_VERSION:
                err = (_("Flash Cache Policy requires "
                         "WSAPI version '%(fcache_version)s' "
                         "version '%(version)s' is installed.") % {
                             'fcache_version': FLASH_CACHE_API_VERSION,
                             'version': self.API_VERSION
                         })
                LOG.error(err)
                raise exception.InvalidInput(reason=err)
            else:
                if flash_cache.lower() == 'true':
                    return self.client.FLASH_CACHE_ENABLED
                else:
                    return self.client.FLASH_CACHE_DISABLED

        return None
Ejemplo n.º 10
0
    def create_volume(self, volume):
        LOG.debug(
            'CREATE VOLUME (%(disp_name)s: %(vol_name)s %(id)s on '
            '%(host)s)', {
                'disp_name': volume['display_name'],
                'vol_name': volume['name'],
                'id': self._get_3par_vol_name(volume['id']),
                'host': volume['host']
            })
        try:
            comments = {
                'volume_id': volume['id'],
                'name': volume['name'],
                'type': 'Docker'
            }

            name = volume.get('display_name', None)
            if name:
                comments['display_name'] = name

            # TODO(leeantho): Choose the first CPG for now. In the future
            # support selecting different CPGs if multiple are provided.
            cpg = self.config.hpe3par_cpg[0]

            # check for valid provisioning type
            prov_value = volume['provisioning']
            if prov_value not in self.valid_prov_values:
                err = (_("Must specify a valid provisioning type %(valid)s, "
                         "value '%(prov)s' is invalid.") % {
                             'valid': self.valid_prov_values,
                             'prov': prov_value
                         })
                LOG.error(err)
                raise exception.InvalidInput(reason=err)

            tpvv = True
            tdvv = False

            if prov_value == "full":
                tpvv = False
            elif prov_value == "dedup":
                tpvv = False
                tdvv = True

            if tdvv and (self.API_VERSION < DEDUP_API_VERSION):
                err = (_("Dedup is a valid provisioning type, "
                         "but requires WSAPI version '%(dedup_version)s' "
                         "version '%(version)s' is installed.") % {
                             'dedup_version': DEDUP_API_VERSION,
                             'version': self.API_VERSION
                         })
                LOG.error(err)
                raise exception.InvalidInput(reason=err)

            extras = {
                'comment': json.dumps(comments),
                'tpvv': tpvv,
            }

            # Only set the dedup option if the backend supports it.
            if self.API_VERSION >= DEDUP_API_VERSION:
                extras['tdvv'] = tdvv

            capacity = self._capacity_from_size(volume['size'])
            volume_name = self._get_3par_vol_name(volume['id'])
            self.client.createVolume(volume_name, cpg, capacity, extras)

            # Check if flash cache needs to be enabled
            flash_cache = self.get_flash_cache_policy(volume['flash_cache'])

            if flash_cache is not None:
                try:
                    self._add_volume_to_volume_set(volume, volume_name, cpg,
                                                   flash_cache)
                except exception.InvalidInput as ex:
                    # Delete the volume if unable to add it to the volume set
                    self.client.deleteVolume(volume_name)
                    LOG.error(_LE("Exception: %s"), ex)
                    raise exception.PluginException(ex)
        except hpeexceptions.HTTPConflict:
            msg = _("Volume (%s) already exists on array") % volume_name
            LOG.error(msg)
            raise exception.Duplicate(msg)
        except hpeexceptions.HTTPBadRequest as ex:
            LOG.error(_LE("Exception: %s"), ex)
            raise exception.Invalid(ex.get_description())
        except exception.InvalidInput as ex:
            LOG.error(_LE("Exception: %s"), ex)
            raise
        except exception.PluginException as ex:
            LOG.error(_LE("Exception: %s"), ex)
            raise
        except Exception as ex:
            LOG.error(_LE("Exception: %s"), ex)
            raise exception.PluginException(ex)
Ejemplo n.º 11
0
 def check_flags(self, options, required_flags):
     for flag in required_flags:
         if not getattr(options, flag, None):
             msg = _('%s is not set') % flag
             LOG.error(msg)
             raise exception.InvalidInput(reason=msg)