def _max_attempts(self): max_attempts = CONF.storage_scheduler_max_attempts if max_attempts < 1: raise exception.InvalidParameterValue( err=_("Invalid value for 'storage_scheduler_max_attempts', " "must be >=1")) return max_attempts
def get_all(self, context, search_opts=None, marker=None, limit=None, offset=None, sort_keys=None, sort_dirs=None): check_policy(context, 'get_all') search_opts = search_opts or {} all_tenants = search_opts.pop('all_tenants', '0') if not utils.is_valid_boolstr(all_tenants): msg = _("all_tenants must be a boolean, got '%s'.") % all_tenants raise exception.InvalidParameterValue(err=msg) if context.is_admin and strutils.bool_from_string(all_tenants): backups = storage.BackupList.get_all(context, search_opts, marker, limit, offset, sort_keys, sort_dirs) else: backups = storage.BackupList.get_all_by_project( context, context.project_id, search_opts, marker, limit, offset, sort_keys, sort_dirs) return backups
def show_target(self, iscsi_target, iqn, **kwargs): if iqn is None: raise exception.InvalidParameterValue( err=_('valid iqn needed for show_target')) tid = self._get_target(iqn) if tid is None: raise exception.NotFound()
def get_bool_param(param_string, params): param = params.get(param_string, False) if not 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 show_target(self, tid, iqn): if iqn is None: raise exception.InvalidParameterValue( err=_('valid iqn needed for show_target')) tid = self._get_target(iqn) if tid is None: raise exception.ISCSITargetHelperCommandFailed( error_message="Target not found")
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 create(self, req, body): """Creates a new snapshot.""" kwargs = {} context = req.environ['storage.context'] self.assert_valid_body(body, 'snapshot') snapshot = body['snapshot'] kwargs['metadata'] = snapshot.get('metadata', None) try: volume_id = snapshot['volume_id'] except KeyError: msg = _("'volume_id' must be specified") raise exc.HTTPBadRequest(explanation=msg) try: volume = self.volume_api.get(context, volume_id) except exception.VolumeNotFound as error: raise exc.HTTPNotFound(explanation=error.msg) force = snapshot.get('force', False) msg = _LI("Create snapshot from volume %s") LOG.info(msg, volume_id, context=context) self.validate_name_and_description(snapshot) # NOTE(thingee): v2 API allows name instead of display_name if 'name' in snapshot: snapshot['display_name'] = snapshot.pop('name') try: force = strutils.bool_from_string(force, strict=True) except ValueError as error: err_msg = encodeutils.exception_to_unicode(error) msg = _("Invalid value for 'force': '%s'") % err_msg raise exception.InvalidParameterValue(err=msg) if force: new_snapshot = self.volume_api.create_snapshot_force( context, volume, snapshot.get('display_name'), snapshot.get('description'), **kwargs) else: new_snapshot = self.volume_api.create_snapshot( context, volume, snapshot.get('display_name'), snapshot.get('description'), **kwargs) req.cache_db_snapshot(new_snapshot) return self._view_builder.detail(req, new_snapshot)
def create(self, req, body): """Creates a new snapshot.""" kwargs = {} context = req.environ['storage.context'] if not self.is_valid_body(body, 'snapshot'): raise exc.HTTPUnprocessableEntity() snapshot = body['snapshot'] kwargs['metadata'] = snapshot.get('metadata', None) try: volume_id = snapshot['volume_id'] except KeyError: msg = _("'volume_id' must be specified") raise exc.HTTPBadRequest(explanation=msg) try: volume = self.volume_api.get(context, volume_id) except exception.NotFound: raise exc.HTTPNotFound() force = snapshot.get('force', False) msg = _LI("Create snapshot from volume %s") LOG.info(msg, volume_id, context=context) if not utils.is_valid_boolstr(force): msg = _("Invalid value '%s' for force. ") % force raise exception.InvalidParameterValue(err=msg) if strutils.bool_from_string(force): new_snapshot = self.volume_api.create_snapshot_force( context, volume, snapshot.get('display_name'), snapshot.get('display_description'), **kwargs) else: new_snapshot = self.volume_api.create_snapshot( context, volume, snapshot.get('display_name'), snapshot.get('display_description'), **kwargs) req.cache_db_snapshot(new_snapshot) retval = _translate_snapshot_detail_view(new_snapshot) return {'snapshot': retval}
def _parse_ns_output(self, switch_data): """Parses name server data. Parses nameserver raw data and adds the device port wwns to the list :returns: List -- list of device port wwn from ns info """ return_list = [] for line in switch_data: if not(" N " in line): continue linesplit = line.split() if len(linesplit) > 2: node_port_wwn = linesplit[2] return_list.append(node_port_wwn) else: msg = _("Malformed show fcns database string: %s") % line LOG.error(msg) raise exception.InvalidParameterValue(err=msg) return return_list
def get_device_mapping_from_network(self, initiator_wwn_list, target_wwn_list): """Provides the initiator/target map for available SAN contexts. Looks up fcns database of each fc SAN configured to find logged in devices and returns a map of initiator and target port WWNs for each fabric. :param initiator_wwn_list: List of initiator port WWN :param target_wwn_list: List of target port WWN :returns: List -- device wwn map in following format { <San name>: { 'initiator_port_wwn_list': ('200000051e55a100', '200000051e55a121'..) 'target_port_wwn_list': ('100000051e55a100', '100000051e55a121'..) } } :raises: Exception when connection to fabric is failed """ device_map = {} formatted_target_list = [] formatted_initiator_list = [] fabric_map = {} fabric_names = self.configuration.fc_fabric_names if not fabric_names: raise exception.InvalidParameterValue( err=_("Missing Fibre Channel SAN configuration " "param - fc_fabric_names")) fabrics = [x.strip() for x in fabric_names.split(',')] LOG.debug("FC Fabric List: %s", fabrics) if fabrics: for t in target_wwn_list: formatted_target_list.append(zm_utils.get_formatted_wwn(t)) for i in initiator_wwn_list: formatted_initiator_list.append(zm_utils.get_formatted_wwn(i)) for fabric_name in fabrics: self.switch_ip = self.fabric_configs[fabric_name].safe_get( 'cisco_fc_fabric_address') self.switch_user = self.fabric_configs[fabric_name].safe_get( 'cisco_fc_fabric_user') self.switch_pwd = self.fabric_configs[fabric_name].safe_get( 'cisco_fc_fabric_password') self.switch_port = self.fabric_configs[fabric_name].safe_get( 'cisco_fc_fabric_port') zoning_vsan = self.fabric_configs[fabric_name].safe_get( 'cisco_zoning_vsan') # Get name server data from fabric and find the targets # logged in nsinfo = '' LOG.debug("show fcns database for vsan %s", zoning_vsan) nsinfo = self.get_nameserver_info(zoning_vsan) LOG.debug("Lookup service:fcnsdatabase-%s", nsinfo) LOG.debug("Lookup service:initiator list from caller-%s", formatted_initiator_list) LOG.debug("Lookup service:target list from caller-%s", formatted_target_list) visible_targets = [ x for x in nsinfo if x in formatted_target_list ] visible_initiators = [ x for x in nsinfo if x in formatted_initiator_list ] if visible_targets: LOG.debug("Filtered targets is: %s", visible_targets) # getting rid of the : before returning for idx, elem in enumerate(visible_targets): elem = str(elem).replace(':', '') visible_targets[idx] = elem else: LOG.debug( "No targets are in the fcns database" " for vsan %s", zoning_vsan) if visible_initiators: # getting rid of the : before returning ~sk for idx, elem in enumerate(visible_initiators): elem = str(elem).replace(':', '') visible_initiators[idx] = elem else: LOG.debug( "No initiators are in the fcns database" " for vsan %s", zoning_vsan) fabric_map = { 'initiator_port_wwn_list': visible_initiators, 'target_port_wwn_list': visible_targets } device_map[zoning_vsan] = fabric_map LOG.debug("Device map for SAN context: %s", device_map) return device_map
def get_device_mapping_from_network(self, initiator_wwn_list, target_wwn_list): """Provides the initiator/target map for available SAN contexts. Looks up nameserver of each fc SAN configured to find logged in devices and returns a map of initiator and target port WWNs for each fabric. :param initiator_wwn_list: List of initiator port WWN :param target_wwn_list: List of target port WWN :returns: List -- device wwn map in following format { <San name>: { 'initiator_port_wwn_list': ('200000051e55a100', '200000051e55a121'..) 'target_port_wwn_list': ('100000051e55a100', '100000051e55a121'..) } } :raises: Exception when connection to fabric is failed """ device_map = {} formatted_target_list = [] formatted_initiator_list = [] fabric_map = {} fabric_names = self.configuration.fc_fabric_names fabrics = None if not fabric_names: raise exception.InvalidParameterValue( err=_("Missing Fibre Channel SAN configuration " "param - fc_fabric_names")) fabrics = [x.strip() for x in fabric_names.split(',')] LOG.debug("FC Fabric List: %s", fabrics) if fabrics: for t in target_wwn_list: formatted_target_list.append(fczm_utils.get_formatted_wwn(t)) for i in initiator_wwn_list: formatted_initiator_list.append( fczm_utils.get_formatted_wwn(i)) for fabric_name in fabrics: fabric_ip = self.fabric_configs[fabric_name].safe_get( 'fc_fabric_address') # Get name server data from fabric and find the targets # logged in nsinfo = '' try: LOG.debug("Getting name server data for " "fabric %s", fabric_ip) conn = self._get_southbound_client(fabric_name) nsinfo = conn.get_nameserver_info() except exception.FCSanLookupServiceException: with excutils.save_and_reraise_exception(): LOG.error( _LE("Failed collecting name server info from" " fabric %s"), fabric_ip) except Exception as e: msg = _("SSH connection failed " "for %(fabric)s with error: %(err)s") % { 'fabric': fabric_ip, 'err': e } LOG.error(msg) raise exception.FCSanLookupServiceException(message=msg) LOG.debug("Lookup service:nsinfo-%s", nsinfo) LOG.debug("Lookup service:initiator list from " "caller-%s", formatted_initiator_list) LOG.debug("Lookup service:target list from " "caller-%s", formatted_target_list) visible_targets = [ x for x in nsinfo if x in formatted_target_list ] visible_initiators = [ x for x in nsinfo if x in formatted_initiator_list ] if visible_targets: LOG.debug("Filtered targets is: %s", visible_targets) # getting rid of the : before returning for idx, elem in enumerate(visible_targets): elem = str(elem).replace(':', '') visible_targets[idx] = elem else: LOG.debug("No targets are in the nameserver for SAN %s", fabric_name) if visible_initiators: # getting rid of the : before returning ~sk for idx, elem in enumerate(visible_initiators): elem = str(elem).replace(':', '') visible_initiators[idx] = elem else: LOG.debug( "No initiators are in the nameserver " "for SAN %s", fabric_name) fabric_map = { 'initiator_port_wwn_list': visible_initiators, 'target_port_wwn_list': visible_targets } device_map[fabric_name] = fabric_map LOG.debug("Device map for SAN context: %s", device_map) return device_map
def update(self, req, id, body): """Update Quota for a particular tenant This works for hierarchical and non-hierarchical projects. For hierarchical projects only immediate parent admin or the CLOUD admin are able to perform an update. :param req: request :param id: target project id that needs to be updated :param body: key, value pair that that will be applied to the resources if the update succeeds """ context = req.environ['storage.context'] authorize_update(context) self.validate_string_length(id, 'quota_set_name', min_length=1, max_length=255) self.assert_valid_body(body, 'quota_set') # Get the optional argument 'skip_validation' from body, # if skip_validation is False, then validate existing resource. skip_flag = body.get('skip_validation', True) if not utils.is_valid_boolstr(skip_flag): msg = _("Invalid value '%s' for skip_validation.") % skip_flag raise exception.InvalidParameterValue(err=msg) skip_flag = strutils.bool_from_string(skip_flag) target_project_id = id bad_keys = [] # NOTE(ankit): Pass #1 - In this loop for body['quota_set'].items(), # we figure out if we have any bad keys. for key, value in body['quota_set'].items(): if (key not in QUOTAS and key not in NON_QUOTA_KEYS): bad_keys.append(key) continue if len(bad_keys) > 0: msg = _("Bad key(s) in quota set: %s") % ",".join(bad_keys) raise webob.exc.HTTPBadRequest(explanation=msg) # Saving off this value since we need to use it multiple times use_nested_quotas = QUOTAS.using_nested_quotas() if use_nested_quotas: # Get the parent_id of the target project to verify whether we are # dealing with hierarchical namespace or non-hierarchical namespace target_project = quota_utils.get_project_hierarchy( context, target_project_id, parents_as_ids=True) parent_id = target_project.parent_id if parent_id: # Get the children of the project which the token is scoped to # in order to know if the target_project is in its hierarchy. context_project = quota_utils.get_project_hierarchy( context, context.project_id, subtree_as_ids=True, is_admin_project=context.is_admin) self._authorize_update_or_delete(context_project, target_project.id, parent_id) # NOTE(ankit): Pass #2 - In this loop for body['quota_set'].keys(), # we validate the quota limits to ensure that we can bail out if # any of the items in the set is bad. Meanwhile we validate value # to ensure that the value can't be lower than number of existing # resources. quota_values = QUOTAS.get_project_quotas(context, target_project_id, defaults=False) valid_quotas = {} reservations = [] for key in body['quota_set'].keys(): if key in NON_QUOTA_KEYS: continue value = utils.validate_integer(body['quota_set'][key], key, min_value=-1, max_value=db.MAX_INT) # Can't skip the validation of nested quotas since it could mess up # hierarchy if parent limit is less than childrens' current usage if not skip_flag or use_nested_quotas: self._validate_existing_resource(key, value, quota_values) if use_nested_quotas: try: reservations += self._update_nested_quota_allocated( context, target_project, quota_values, key, value) except exception.OverQuota as e: if reservations: db.reservation_rollback(context, reservations) raise webob.exc.HTTPBadRequest(explanation=e.message) valid_quotas[key] = value # NOTE(ankit): Pass #3 - At this point we know that all the keys and # values are valid and we can iterate and update them all in one shot # without having to worry about rolling back etc as we have done # the validation up front in the 2 loops above. for key, value in valid_quotas.items(): try: db.quota_update(context, target_project_id, key, value) except exception.ProjectQuotaNotFound: db.quota_create(context, target_project_id, key, value) except exception.AdminRequired: raise webob.exc.HTTPForbidden() if reservations: db.reservation_commit(context, reservations) return {'quota_set': self._get_quotas(context, target_project_id)}