def get_all(self, context, search_opts=None, marker=None, limit=None, offset=None, sort_keys=None, sort_dirs=None): context.authorize(policy.GET_ALL_POLICY) search_opts = search_opts or {} all_tenants = search_opts.pop('all_tenants', '0') if not strutils.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 = objects.BackupList.get_all(context, search_opts, marker, limit, offset, sort_keys, sort_dirs) else: backups = objects.BackupList.get_all_by_project( context, context.project_id, search_opts, marker, limit, offset, sort_keys, sort_dirs) return backups
def _create(self, req, body): """Creates a new volume type.""" context = req.environ['cinder.context'] authorize(context) self.assert_valid_body(body, 'volume_type') vol_type = body['volume_type'] name = vol_type.get('name', None) description = vol_type.get('description') specs = vol_type.get('extra_specs', {}) utils.validate_dictionary_string_length(specs) is_public = vol_type.get('os-volume-type-access:is_public', True) if name is None or len(name.strip()) == 0: msg = _("Volume type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) utils.check_string_length(name, 'Type name', min_length=1, max_length=255) if description is not None: utils.check_string_length(description, 'Type description', min_length=0, max_length=255) if not strutils.is_valid_boolstr(is_public): msg = _("Invalid value '%s' for is_public. Accepted values: " "True or False.") % is_public raise webob.exc.HTTPBadRequest(explanation=msg) try: volume_types.create(context, name, specs, is_public, description=description) vol_type = volume_types.get_volume_type_by_name(context, name) req.cache_resource(vol_type, name='types') self._notify_volume_type_info(context, 'volume_type.create', vol_type) except exception.VolumeTypeExists as err: self._notify_volume_type_error(context, 'volume_type.create', err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeNotFoundByName as err: self._notify_volume_type_error(context, 'volume_type.create', err, name=name) # Not found exception will be handled at the wsgi level raise return self._view_builder.show(req, vol_type)
def update(self, req, id, body): # Update description for a given group type. context = req.environ['cinder.context'] self._check_policy(context) self.assert_valid_body(body, 'group_type') grp_type = body['group_type'] description = grp_type.get('description') name = grp_type.get('name') is_public = grp_type.get('is_public') # Name and description can not be both None. # If name specified, name can not be empty. if name and len(name.strip()) == 0: msg = _("Group type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) if name is None and description is None and is_public is None: msg = _("Specify group type name, description or " "a combination thereof.") raise webob.exc.HTTPBadRequest(explanation=msg) if is_public is not None and not strutils.is_valid_boolstr(is_public): msg = _("Invalid value '%s' for is_public. Accepted values: " "True or False.") % is_public raise webob.exc.HTTPBadRequest(explanation=msg) if name: utils.check_string_length(name, 'Type name', min_length=1, max_length=255) if description is not None: utils.check_string_length(description, 'Type description', min_length=0, max_length=255) try: group_types.update(context, id, name, description, is_public=is_public) # Get the updated grp_type = group_types.get_group_type(context, id) req.cache_resource(grp_type, name='group_types') self._notify_group_type_info( context, 'group_type.update', grp_type) except exception.GroupTypeNotFound as err: self._notify_group_type_error( context, 'group_type.update', err, id=id) raise webob.exc.HTTPNotFound(explanation=six.text_type(err)) except exception.GroupTypeExists as err: self._notify_group_type_error( context, 'group_type.update', err, group_type=grp_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.GroupTypeUpdateFailed as err: self._notify_group_type_error( context, 'group_type.update', err, group_type=grp_type) raise webob.exc.HTTPInternalServerError( explanation=six.text_type(err)) return self._view_builder.show(req, grp_type)
def get_bool_param(param_string, params): param = params.get(param_string, False) 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 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 get_bool_param(param_string, params): param = params.get(param_string, False) 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 _create(self, req, body): """Creates a new volume type.""" context = req.environ['cinder.context'] authorize(context) self.assert_valid_body(body, 'volume_type') vol_type = body['volume_type'] name = vol_type.get('name', None) description = vol_type.get('description') specs = vol_type.get('extra_specs', {}) utils.validate_dictionary_string_length(specs) is_public = vol_type.get('os-volume-type-access:is_public', True) if name is None or len(name.strip()) == 0: msg = _("Volume type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) utils.check_string_length(name, 'Type name', min_length=1, max_length=255) if description is not None: utils.check_string_length(description, 'Type description', min_length=0, max_length=255) if not strutils.is_valid_boolstr(is_public): msg = _("Invalid value '%s' for is_public. Accepted values: " "True or False.") % is_public raise webob.exc.HTTPBadRequest(explanation=msg) try: volume_types.create(context, name, specs, is_public, description=description) vol_type = volume_types.get_volume_type_by_name(context, name) req.cache_resource(vol_type, name='types') self._notify_volume_type_info( context, 'volume_type.create', vol_type) except exception.VolumeTypeExists as err: self._notify_volume_type_error( context, 'volume_type.create', err, volume_type=vol_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.VolumeTypeNotFoundByName as err: self._notify_volume_type_error( context, 'volume_type.create', err, name=name) # Not found exception will be handled at the wsgi level raise return self._view_builder.show(req, vol_type)
def _validate_reservation_params(self, values): if 'amount' in values: try: values['amount'] = strutils.validate_integer( values['amount'], "amount", 1, db_api.DB_MAX_INT) except ValueError as e: raise mgr_exceptions.MalformedParameter(six.text_type(e)) if 'affinity' in values: if (values['affinity'] not in NONE_VALUES and not strutils.is_valid_boolstr(values['affinity'])): raise mgr_exceptions.MalformedParameter( param='affinity (must be a bool value or None)')
def create(self, req, body): """Creates a new snapshot.""" kwargs = {} context = req.environ['cinder.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) # Not found exception will be handled at the wsgi level volume = self.volume_api.get(context, volume_id) force = snapshot.get('force', False) msg = _LI("Create snapshot from volume %s") LOG.info(msg, volume_id) if not strutils.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 extract_extra_specs(extra_specs, specs_to_add): for item in specs_to_add: (key, value) = item.split('=', 1) if key in extra_specs: msg = ("Argument '%s' value specified twice." % key) raise exceptions.CommandError(msg) elif key in constants.BOOL_SPECS: if strutils.is_valid_boolstr(value): extra_specs[key] = value.capitalize() else: msg = ("Argument '%s' is of boolean " "type and has invalid value: %s" % (key, six.text_type(value))) raise exceptions.CommandError(msg) else: extra_specs[key] = value return extra_specs
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 strutils.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 = objects.BackupList.get_all(context, search_opts, marker, limit, offset, sort_keys, sort_dirs) else: backups = objects.BackupList.get_all_by_project( context, context.project_id, search_opts, marker, limit, offset, sort_keys, sort_dirs ) return backups
def is_local_link_information_valid(local_link_information_list): if not local_link_information_list: return False if len(local_link_information_list) > 1: LOG.warning( "'local_link_information' must have only one value") return False switch_info = common.switch_info_from_local_link_information_list( local_link_information_list) if not switch_info: LOG.warning( "'local_link_information' must contain 'switch_info'.") return False server_hardware = ( common.server_hardware_from_local_link_information_list( self.oneview_client, local_link_information_list)) server_hardware_id = server_hardware.get('uuid') if strutils.is_valid_boolstr(switch_info.get('bootable')): bootable = strutils.bool_from_string( switch_info.get('bootable')) else: bootable = switch_info.get('bootable') if not (server_hardware_id or bootable): LOG.warning("'local_link_information' must contain " "'server_hardware_id' and 'bootable'.") return False if not isinstance(bootable, bool): LOG.warning("'bootable' must be a boolean.") return False return True
def extract_extra_specs(extra_specs, specs_to_add, bool_specs=constants.BOOL_SPECS): try: for item in specs_to_add: (key, value) = item.split('=', 1) if key in extra_specs: msg = ("Argument '%s' value specified twice." % key) raise exceptions.CommandError(msg) elif key in bool_specs: if strutils.is_valid_boolstr(value): extra_specs[key] = value.capitalize() else: msg = ("Argument '%s' is of boolean " "type and has invalid value: %s" % (key, str(value))) raise exceptions.CommandError(msg) else: extra_specs[key] = value except ValueError: msg = LOG.error(_("Wrong format: specs should be key=value pairs.")) raise exceptions.CommandError(msg) return extra_specs
def test_is_valid_boolstr(self): self.assertTrue(strutils.is_valid_boolstr('true')) self.assertTrue(strutils.is_valid_boolstr('false')) self.assertTrue(strutils.is_valid_boolstr('yes')) self.assertTrue(strutils.is_valid_boolstr('no')) self.assertTrue(strutils.is_valid_boolstr('y')) self.assertTrue(strutils.is_valid_boolstr('n')) self.assertTrue(strutils.is_valid_boolstr('1')) self.assertTrue(strutils.is_valid_boolstr('0')) self.assertTrue(strutils.is_valid_boolstr(1)) self.assertTrue(strutils.is_valid_boolstr(0)) self.assertFalse(strutils.is_valid_boolstr('maybe')) self.assertFalse(strutils.is_valid_boolstr('only on tuesdays'))
def update(self, req, id, body): # Update description for a given group type. context = req.environ['cinder.context'] self._check_policy(context) self.assert_valid_body(body, 'group_type') grp_type = body['group_type'] description = grp_type.get('description') name = grp_type.get('name') is_public = grp_type.get('is_public') # Name and description can not be both None. # If name specified, name can not be empty. if name and len(name.strip()) == 0: msg = _("Group type name can not be empty.") raise webob.exc.HTTPBadRequest(explanation=msg) if name is None and description is None and is_public is None: msg = _("Specify group type name, description or " "a combination thereof.") raise webob.exc.HTTPBadRequest(explanation=msg) if is_public is not None and not strutils.is_valid_boolstr(is_public): msg = _("Invalid value '%s' for is_public. Accepted values: " "True or False.") % is_public raise webob.exc.HTTPBadRequest(explanation=msg) if name: utils.check_string_length(name, 'Type name', min_length=1, max_length=255) if description is not None: utils.check_string_length(description, 'Type description', min_length=0, max_length=255) try: group_types.update(context, id, name, description, is_public=is_public) # Get the updated grp_type = group_types.get_group_type(context, id) req.cache_resource(grp_type, name='group_types') self._notify_group_type_info(context, 'group_type.update', grp_type) except exception.GroupTypeNotFound as err: self._notify_group_type_error(context, 'group_type.update', err, id=id) raise webob.exc.HTTPNotFound(explanation=six.text_type(err)) except exception.GroupTypeExists as err: self._notify_group_type_error(context, 'group_type.update', err, group_type=grp_type) raise webob.exc.HTTPConflict(explanation=six.text_type(err)) except exception.GroupTypeUpdateFailed as err: self._notify_group_type_error(context, 'group_type.update', err, group_type=grp_type) raise webob.exc.HTTPInternalServerError( explanation=six.text_type(err)) return self._view_builder.show(req, grp_type)
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 will be applied to the resources if the update succeeds """ context = req.environ['cinder.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') # TODO(wxy): Change "skip_validation"'s default value to False in # Queens. # 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 strutils.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) if skip_flag: LOG.warning("It's unsafe to skip validating the existing " "resource's quota when updating it. Cinder will force " "validate it in Queens, please try to use " "skip_validation=False for quota updating now.") 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 GROUP_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) group_quota_values = GROUP_QUOTAS.get_project_quotas(context, target_project_id, defaults=False) quota_values.update(group_quota_values) 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.msg) 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. project_quotas = self._get_quotas(context, target_project_id) domain_quota_sync.check_valid(context, target_project_id, valid_quotas.copy(), project_quotas.copy()) 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)}
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 will be applied to the resources if the update succeeds """ context = req.environ["cinder.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 strutils.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.msg) 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)}