def __init__(self, *args, **kwargs): super(InfortrendNASDriver, self).__init__(False, *args, **kwargs) self.configuration.append_config_values(infortrend_nas_opts) nas_ip = self.configuration.safe_get('infortrend_nas_ip') username = self.configuration.safe_get('infortrend_nas_user') password = self.configuration.safe_get('infortrend_nas_password') ssh_key = self.configuration.safe_get('infortrend_nas_ssh_key') retries = self.configuration.safe_get('infortrend_cli_max_retries') timeout = self.configuration.safe_get('infortrend_cli_timeout') if not nas_ip: msg = _('The infortrend_nas_ip is not set.') raise exception.InvalidParameterValue(err=msg) if not (password or ssh_key): msg = _('Either infortrend_nas_password or infortrend_nas_ssh_key ' 'should be set.') raise exception.InvalidParameterValue(err=msg) pool_list = self._init_pool_list() self.backend_name = self.configuration.safe_get('share_backend_name') self.ift_nas = infortrend_nas.InfortrendNAS(nas_ip, username, password, ssh_key, retries, timeout, pool_list)
def check_for_setup_error(self): """Returns an error if prerequisites aren't met.""" out, err = self._execute('sudo', 'vgs', '--noheadings', '-o', 'name') volume_groups = out.split() if self.configuration.lvm_share_volume_group not in volume_groups: msg = (_("share volume group %s doesn't exist") % self.configuration.lvm_share_volume_group) raise exception.InvalidParameterValue(err=msg) if not self.configuration.lvm_share_export_ip: msg = (_("share_export_ip isn't specified")) raise exception.InvalidParameterValue(err=msg)
def __init__(self, *args, **kwargs): """Do initialization.""" LOG.debug("Invoking base constructor for Manila HDS HNAS Driver.") super(HDSHNASDriver, self).__init__(False, *args, **kwargs) LOG.debug("Setting up attributes for Manila HDS HNAS Driver.") self.configuration.append_config_values(hds_hnas_opts) LOG.debug("Reading config parameters for Manila HDS HNAS Driver.") self.backend_name = self.configuration.safe_get('share_backend_name') hnas_ip = self.configuration.safe_get('hds_hnas_ip') hnas_username = self.configuration.safe_get('hds_hnas_user') hnas_password = self.configuration.safe_get('hds_hnas_password') hnas_evs_id = self.configuration.safe_get('hds_hnas_evs_id') self.hnas_evs_ip = self.configuration.safe_get('hds_hnas_evs_ip') fs_name = self.configuration.safe_get('hds_hnas_file_system_name') ssh_private_key = self.configuration.safe_get( 'hds_hnas_ssh_private_key') cluster_admin_ip0 = self.configuration.safe_get( 'hds_hnas_cluster_admin_ip0') self.private_storage = kwargs.get('private_storage') job_timeout = self.configuration.safe_get( 'hds_hnas_stalled_job_timeout') if hnas_evs_id is None: msg = _("The config parameter hds_hnas_evs_id is not set.") raise exception.InvalidParameterValue(err=msg) if self.hnas_evs_ip is None: msg = _("The config parameter hds_hnas_evs_ip is not set.") raise exception.InvalidParameterValue(err=msg) if hnas_ip is None: msg = _("The config parameter hds_hnas_ip is not set.") raise exception.InvalidParameterValue(err=msg) if hnas_username is None: msg = _("The config parameter hds_hnas_user is not set.") raise exception.InvalidParameterValue(err=msg) if hnas_password is None and ssh_private_key is None: msg = _("Credentials configuration parameters missing: " "you need to set hds_hnas_password or " "hds_hnas_ssh_private_key.") raise exception.InvalidParameterValue(err=msg) LOG.debug("Initializing HNAS Layer.") self.hnas = ssh.HNASSSHBackend(hnas_ip, hnas_username, hnas_password, ssh_private_key, cluster_admin_ip0, hnas_evs_id, self.hnas_evs_ip, fs_name, job_timeout)
def manage_existing_snapshot(self, snapshot, driver_options): """Manage existing share snapshot with manila.""" volID = self.private_storage.get(snapshot['share']['id'], 'volID') LOG.debug('volID: %s', volID) existing_share = self.api_executor.get_share_info( self.configuration.qnap_poolname, vol_no=volID) if existing_share is None: msg = _("The share id %s was not found on backend.") % volID LOG.error(msg) raise exception.ShareNotFound(msg) snapshot_id = snapshot.get('provider_location') snapshot_id_info = snapshot_id.split('@') if len(snapshot_id_info) == 2: share_name = snapshot_id_info[0] snapshot_name = snapshot_id_info[1] else: msg = _("Incorrect provider_location format. It should have the " "following format: share_name@snapshot_name.") LOG.error(msg) raise exception.InvalidParameterValue(msg) if share_name != existing_share.find('vol_label').text: msg = (_("The assigned share %(share_name)s was not matched " "%(vol_label)s on backend.") % { 'share_name': share_name, 'vol_label': existing_share.find('vol_label').text }) LOG.error(msg) raise exception.ShareNotFound(msg) check_snapshot = self.api_executor.get_snapshot_info( volID=volID, snapshot_name=snapshot_name) if check_snapshot is None: msg = (_("The snapshot %(snapshot_name)s was not " "found on backend.") % { 'snapshot_name': snapshot_name }) LOG.error(msg) raise exception.InvalidParameterValue(err=msg) _metadata = { 'snapshot_id': snapshot_id, } self.private_storage.update(snapshot['id'], _metadata) parent_size = check_snapshot.find('parent_size') snap_size_gb = None if parent_size is not None: snap_size_gb = math.ceil(float(parent_size.text) / units.Gi) return {'size': snap_size_gb}
def check_for_setup_error(self): """Returns an error if prerequisites aren't met.""" out, err = self._execute('vgs', '--noheadings', '-o', 'name', run_as_root=True) volume_groups = out.split() if self.configuration.lvm_share_volume_group not in volume_groups: msg = (_("Share volume group %s doesn't exist.") % self.configuration.lvm_share_volume_group) raise exception.InvalidParameterValue(err=msg) if not self.configuration.lvm_share_export_ips: msg = _("The option lvm_share_export_ips must be specified.") raise exception.InvalidParameterValue(err=msg)
def _get_managed_storage_pools(self, pools): matched_pools = set() if pools: # Get the real pools from the backend storage status, backend_pools = self._get_context('StoragePool').get_all() if status != constants.STATUS_OK: message = (_("Failed to get storage pool information. " "Reason: %s") % backend_pools) LOG.error(message) raise exception.EMCVnxXMLAPIError(err=message) real_pools = set([item for item in backend_pools]) conf_pools = set([item.strip() for item in pools]) matched_pools, unmatched_pools = vnx_utils.do_match_any( real_pools, conf_pools) if not matched_pools: msg = (_("None of the specified storage pools to be managed " "exist. Please check your configuration " "vnx_share_data_pools in manila.conf. " "The available pools in the backend are %s.") % ",".join(real_pools)) raise exception.InvalidParameterValue(err=msg) LOG.info("Storage pools: %s will be managed.", ",".join(matched_pools)) else: LOG.debug("No storage pool is specified, so all pools " "in storage system will be managed.") return matched_pools
def get_driver_mode(self, supported_driver_modes): """Verify and return driver mode. Call this method within share driver to get value for 'mode' attr, :param supported_driver_modes: list of supported modes by share driver, see list of available values in manila.common.constants.VALID_SHARE_DRIVER_MODES :returns: text_type -- name of enabled driver mode. :raises: exception.InvalidParameterValue """ msg = None if not len(supported_driver_modes): msg = "At least one mode should be supported by share driver." elif self.mode: if self.mode not in supported_driver_modes: data = {'mode': self.mode, 'supported': supported_driver_modes} msg = ("Unsupported driver mode '%(mode)s' is provided. " "List of supported is %(supported)s." % data) else: return self._validate_driver_mode(self.mode) elif len(supported_driver_modes) > 1: msg = ("Driver mode was not specified explicitly and amount of " "supported driver modes %s is bigger than one, please " "specify it using config option 'share_driver_mode'." % six.text_type(supported_driver_modes)) if msg: LOG.error(msg) raise exception.InvalidParameterValue(msg) return self._validate_driver_mode(supported_driver_modes[0])
def validate_public_share_policy(context, api_params, api='create'): """Validates if policy allows is_public parameter to be set to True. :arg api_params - A dictionary of values that may contain 'is_public' :returns api_params with 'is_public' item sanitized if present :raises exception.InvalidParameterValue if is_public is set but is Invalid exception.NotAuthorized if is_public is True but policy prevents it """ if 'is_public' not in api_params: return api_params policies = { 'create': 'create_public_share', 'update': 'set_public_share', } policy_to_check = policies[api] try: api_params['is_public'] = strutils.bool_from_string( api_params['is_public'], strict=True) except ValueError as e: raise exception.InvalidParameterValue(str(e)) public_shares_allowed = policy.check_policy( context, 'share', policy_to_check, do_raise=False) if api_params['is_public'] and not public_shares_allowed: message = _("User is not authorized to set 'is_public' to True in the " "request.") raise exception.NotAuthorized(message=message) return api_params
def _max_attempts(self): max_attempts = CONF.scheduler_max_attempts if max_attempts < 1: msg = _("Invalid value for 'scheduler_max_attempts', " "must be >=1") raise exception.InvalidParameterValue(err=msg) return max_attempts
def check_for_setup_error(self): """Check for setup error.""" max_ratio = self.configuration.safe_get('max_over_subscription_ratio') if not max_ratio or float(max_ratio) < 1.0: msg = (_("Invalid max_over_subscription_ratio '%s'. " "Valid value should be >= 1.0.") % max_ratio) raise exception.InvalidParameterValue(err=msg)
def _init_pool_list(self): pools_name = self.configuration.safe_get('infortrend_share_pools') if not pools_name: msg = _('The infortrend_share_pools is not set.') raise exception.InvalidParameterValue(err=msg) tmp_pool_list = pools_name.split(',') return [pool.strip() for pool in tmp_pool_list]
def _get_mover_by_id(self, mover_id): status, mover = self._XMLAPI_helper.get_mover_by_id(mover_id) if constants.STATUS_OK != status: message = _("Could not find Data Mover by id: %s.") % mover_id LOG.error(message) raise exception.InvalidParameterValue(err=message) return mover
def get_mover_ref_by_name(self, name): status, mover = self._XMLAPI_helper.get_mover_ref_by_name(name) if constants.STATUS_ERROR == status: message = _("Could not find Data Mover by name: %s.") % name LOG.error(message) raise exception.InvalidParameterValue(err=message) return mover
def update(self, context, share, fields): if 'is_public' in fields: try: fields['is_public'] = strutils.bool_from_string( fields['is_public'], strict=True) except ValueError as e: raise exception.InvalidParameterValue(six.text_type(e)) return self.db.share_update(context, share['id'], fields)
def _validate_driver_mode(self, mode): valid = constants.VALID_SHARE_DRIVER_MODES if mode not in valid: data = {'mode': mode, 'valid': valid} msg = ("Provided unsupported driver mode '%(mode)s'. List of " "valid driver modes is %(valid)s." % data) LOG.error(msg) raise exception.InvalidParameterValue(msg) return mode
def _write_export_file(self, name, confdict): """Write confdict to the export file of name.""" for k, v in ganesha_utils.walk(confdict): # values in the export block template that need to be # filled in by Manila are pre-fixed by '@' if isinstance(v, six.string_types) and v[0] == '@': msg = _("Incomplete export block: value %(val)s of attribute " "%(key)s is a stub.") % {'key': k, 'val': v} raise exception.InvalidParameterValue(err=msg) return self._write_conf_file(name, mkconf(confdict))
def matches_versioned_method(self, method): """Compares this version to that of a versioned method.""" if type(method) != versioned_method.VersionedMethod: msg = _('An API version request must be compared ' 'to a VersionedMethod object.') raise exception.InvalidParameterValue(err=msg) return self.matches(method.start_version, method.end_version, method.experimental)
def check_for_setup_error(self): """Returns an error if prerequisites aren't met.""" host_address_obj = types.HostAddress() for export_ip in self.config.cephfs_ganesha_export_ips: try: host_address_obj(export_ip) except ValueError: msg = (_("Invalid list member of 'cephfs_ganesha_export_ips' " "option supplied %s -- not a valid IP address or " "hostname.") % export_ip) raise exception.InvalidParameterValue(err=msg)
def check_for_setup_error(self): nodes = self.assistant.get_nodes_info() if len(nodes) == 0: msg = _('No valid node, be sure the NAS Port IP is configured') raise exception.ShareBackendException(msg=msg) pools = self.assistant.get_available_pools() not_exist = set(self.backend_pools).difference(set(pools)) if not_exist: msg = _('Pool %s not exist on the storage system') % not_exist raise exception.InvalidParameterValue(msg)
def get_bool_param(param_string, params, default=False): param = params.get(param_string, default) if not strutils.is_valid_boolstr(param): msg = _("Value '%(param)s' for '%(param_string)s' is not " "a boolean.") % { 'param': param, 'param_string': param_string } raise exception.InvalidParameterValue(err=msg) return strutils.bool_from_string(param, strict=True)
def check_for_setup_error(self): """Check for setup error.""" # To verify the input from Manila configuration status, out = self._get_context('Mover').get_ref(self.mover_name, True) if constants.STATUS_ERROR == status: message = (_("Could not find Data Mover by name: %s.") % self.mover_name) LOG.error(message) raise exception.InvalidParameterValue(err=message) self.pools = self._get_managed_storage_pools(self.pool_conf)
def check_for_setup_error(self): """Returns an error if prerequisites aren't met.""" if not self._check_gpfs_state(): msg = (_('GPFS is not active.')) LOG.error(msg) raise exception.GPFSException(msg) if not self.configuration.gpfs_share_export_ip: msg = (_('gpfs_share_export_ip must be specified.')) LOG.error(msg) raise exception.InvalidParameterValue(err=msg) gpfs_base_dir = self.configuration.gpfs_mount_point_base if not gpfs_base_dir.startswith('/'): msg = (_('%s must be an absolute path.') % gpfs_base_dir) LOG.error(msg) raise exception.GPFSException(msg) if not self._is_dir(gpfs_base_dir): msg = (_('%s is not a directory.') % gpfs_base_dir) LOG.error(msg) raise exception.GPFSException(msg) if not self._is_gpfs_path(gpfs_base_dir): msg = (_('%s is not on GPFS. Perhaps GPFS not mounted.') % gpfs_base_dir) LOG.error(msg) raise exception.GPFSException(msg) if self.configuration.gpfs_nfs_server_type not in ("KNFS", "CES"): msg = (_('Invalid gpfs_nfs_server_type value: %s. ' 'Valid values are: "KNFS", "CES".') % self.configuration.gpfs_nfs_server_type) LOG.error(msg) raise exception.InvalidParameterValue(err=msg) if ((not self.configuration.gpfs_nfs_server_list) and (self.configuration.gpfs_nfs_server_type != 'CES')): msg = (_('Missing value for gpfs_nfs_server_list.')) LOG.error(msg) raise exception.InvalidParameterValue(err=msg)
class ZFSSAShareDriver(driver.ShareDriver): """ZFSSA share driver: Supports NFS and CIFS protocols. Uses ZFSSA RESTful API to create shares and snapshots on backend. API version history: 1.0 - Initial version. """ VERSION = '1.0.0' PROTOCOL = 'NFS_CIFS' def __init__(self, False, *args, **kwargs): super(ZFSSAShareDriver, self).__init__(False, *args, **kwargs) self.configuration.append_config_values(ZFSSA_OPTS) self.zfssa = None self._stats = None self.mountpoint = '/export/' lcfg = self.configuration required = [ 'zfssa_host', 'zfssa_data_ip', 'zfssa_auth_user', 'zfssa_auth_password', 'zfssa_pool', 'zfssa_project' ] for prop in required: if not getattr(lcfg, prop, None): exception_msg = _('%s is required in manila.conf') % prop LOG.error(exception_msg) raise exception.InvalidParameterValue(exception_msg) self.default_args = { 'compression': lcfg.zfssa_nas_compression, 'logbias': lcfg.zfssa_nas_logbias, 'checksum': lcfg.zfssa_nas_checksum, 'vscan': lcfg.zfssa_nas_vscan, 'rstchown': lcfg.zfssa_nas_rstchown, } self.share_args = { 'sharedav': 'off', 'shareftp': 'off', 'sharesftp': 'off', 'sharetftp': 'off', 'root_permissions': '777', 'sharenfs': 'sec=sys', 'sharesmb': 'off', 'quota_snap': self.configuration.zfssa_nas_quota_snap, 'reservation_snap': self.configuration.zfssa_nas_quota_snap, }
def get_vdm_by_name(self, name, allow_absence=False): status, vdm = self._XMLAPI_helper.get_vdm_by_name(name) if constants.STATUS_OK != status: if allow_absence and constants.STATUS_NOT_FOUND == status: return None else: message = ( _("Could not find Virtual Data Mover by name: %s.") % name) LOG.error(message) raise exception.InvalidParameterValue(err=message) return vdm
def _get_vserver(self, share_server=None): if share_server is not None: msg = _('Share server must not be passed to the driver ' 'when the driver is not managing share servers.') raise exception.InvalidParameterValue(err=msg) if not self._vserver: msg = _('Vserver not specified in configuration.') raise exception.InvalidInput(reason=msg) if not self._client.vserver_exists(self._vserver): raise exception.VserverNotFound(vserver=self._vserver) vserver_client = self._get_api_client(self._vserver) return self._vserver, vserver_client
def _get_managed_storage_pools(self, pools): matched_pools = set() if pools: # Get the real pools from the backend storage status, backend_pools = self._get_context('StoragePool').get_all() if status != constants.STATUS_OK: message = (_("Failed to get storage pool information. " "Reason: %s") % backend_pools) LOG.error(message) raise exception.EMCVnxXMLAPIError(err=message) real_pools = set([item for item in backend_pools]) conf_pools = set([item.strip() for item in pools.split(",")]) for pool in real_pools: for matcher in conf_pools: if fnmatch.fnmatchcase(pool, matcher): matched_pools.add(pool) nonexistent_pools = real_pools.difference(matched_pools) if not matched_pools: msg = (_("All the specified storage pools to be managed " "do not exist. Please check your configuration " "emc_nas_pool_names in manila.conf. " "The available pools in the backend are %s") % ",".join(real_pools)) raise exception.InvalidParameterValue(err=msg) if nonexistent_pools: LOG.warning( _LW("The following specified storage pools " "do not exist: %(unexist)s. " "This host will only manage the storage " "pools: %(exist)s"), { 'unexist': ",".join(nonexistent_pools), 'exist': ",".join(matched_pools) }) else: LOG.debug("Storage pools: %s will be managed.", ",".join(matched_pools)) else: LOG.debug("No storage pool is specified, so all pools " "in storage system will be managed.") return matched_pools
def _get_available_pool_by_name(self, name): status, out = self._XMLAPI_helper.list_storage_pool() if constants.STATUS_OK != status: LOG.error(_LE("Could not get storage pool list.")) for pool in out: if name == pool['name']: self._pool = pool break if self._pool is None: message = (_("Could not find the storage pool by name: %s.") % name) LOG.error(message) raise exception.InvalidParameterValue(err=message) return self._pool
def __init__(self, *args, **kwargs): super(ZFSSAShareDriver, self).__init__(False, *args, **kwargs) self.configuration.append_config_values(ZFSSA_OPTS) self.zfssa = None self._stats = None self.mountpoint = '/export/' lcfg = self.configuration required = [ 'zfssa_host', 'zfssa_data_ip', 'zfssa_auth_user', 'zfssa_auth_password', 'zfssa_pool', 'zfssa_project' ] for prop in required: if not getattr(lcfg, prop, None): exception_msg = _('%s is required in manila.conf') % prop LOG.error(exception_msg) raise exception.InvalidParameterValue(exception_msg) self.default_args = { 'compression': lcfg.zfssa_nas_compression, 'logbias': lcfg.zfssa_nas_logbias, 'checksum': lcfg.zfssa_nas_checksum, 'vscan': lcfg.zfssa_nas_vscan, 'rstchown': lcfg.zfssa_nas_rstchown, } self.share_args = { 'sharedav': 'off', 'shareftp': 'off', 'sharesftp': 'off', 'sharetftp': 'off', 'root_permissions': '777', 'sharenfs': 'sec=sys', 'sharesmb': 'off', 'quota_snap': self.configuration.zfssa_nas_quota_snap, 'reservation_snap': self.configuration.zfssa_nas_quota_snap, 'custom:manila_managed': True, }
def _export_location(self, share): """Export share's location based on protocol used.""" lcfg = self.configuration arg = { 'host': lcfg.zfssa_data_ip, 'mountpoint': self.mountpoint, 'name': share['id'], } location = '' proto = share['share_proto'] if proto == 'NFS': location = ("%(host)s:%(mountpoint)s/%(name)s" % arg) elif proto == 'CIFS': location = ("\\\\%(host)s\\%(name)s" % arg) else: exception_msg = _('Protocol %s is not supported.') % proto LOG.error(exception_msg) raise exception.InvalidParameterValue(exception_msg) LOG.debug("Export location: %s.", location) return location
def lsfs(self, node_name=None, fsname=None): if fsname and not node_name: msg = _('Node name should be set when file system name is set.') LOG.error(msg) raise exception.InvalidParameterValue(msg) ssh_cmd = ['mcsinq', 'lsfs', '-delim', '!'] to_append = [] if node_name: to_append += ['-node', '"%s"' % node_name] if fsname: to_append += ['-name', '"%s"' % fsname] if not to_append: to_append += ['-all'] ssh_cmd += to_append return self.run_ssh_inq(ssh_cmd, with_header=True)