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)
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)
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)
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)
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
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)
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
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
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)
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)