def _migrate_live(self, req, id, body): """Permit admins to (live) migrate a server to a new host.""" context = req.environ["nova.context"] authorize(context, 'migrateLive') try: block_migration = body["os-migrateLive"]["block_migration"] disk_over_commit = body["os-migrateLive"]["disk_over_commit"] host = body["os-migrateLive"]["host"] except (TypeError, KeyError): msg = _("host, block_migration and disk_over_commit must " "be specified for live migration.") raise exc.HTTPBadRequest(explanation=msg) try: block_migration = strutils.bool_from_string(block_migration, strict=True) disk_over_commit = strutils.bool_from_string(disk_over_commit, strict=True) except ValueError as err: raise exc.HTTPBadRequest(explanation=six.text_type(err)) instance = common.get_instance(self.compute_api, context, id, want_objects=True) try: self.compute_api.live_migrate(context, instance, block_migration, disk_over_commit, host) except (exception.NoValidHost, exception.ComputeServiceUnavailable, exception.InvalidHypervisorType, exception.InvalidCPUInfo, exception.UnableToMigrateToSelf, exception.DestinationHypervisorTooOld, exception.InvalidLocalStorage, exception.InvalidSharedStorage, exception.HypervisorUnavailable, exception.InstanceNotRunning, exception.MigrationPreCheckError, exception.LiveMigrationWithOldNovaNotSafe) as ex: raise exc.HTTPBadRequest(explanation=ex.format_message()) except exception.InstanceNotFound as e: raise exc.HTTPNotFound(explanation=e.format_message()) except exception.InstanceIsLocked as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state( state_error, 'os-migrateLive', id) except Exception: if host is None: msg = _("Live migration of instance %s to another host " "failed") % id else: msg = _("Live migration of instance %(id)s to host %(host)s " "failed") % { 'id': id, 'host': host } LOG.exception(msg) # Return messages from scheduler raise exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def _migrate_live(self, req, id, body): """Permit admins to (live) migrate a server to a new host.""" context = req.environ["nova.context"] authorize(context, 'migrate_live') block_migration = body["os-migrateLive"]["block_migration"] disk_over_commit = body["os-migrateLive"]["disk_over_commit"] host = body["os-migrateLive"]["host"] block_migration = strutils.bool_from_string(block_migration, strict=True) disk_over_commit = strutils.bool_from_string(disk_over_commit, strict=True) try: instance = common.get_instance(self.compute_api, context, id, want_objects=True) self.compute_api.live_migrate(context, instance, block_migration, disk_over_commit, host) except (exception.NoValidHost, exception.ComputeServiceUnavailable, exception.InvalidHypervisorType, exception.InvalidCPUInfo, exception.UnableToMigrateToSelf, exception.DestinationHypervisorTooOld, exception.InvalidLocalStorage, exception.InvalidSharedStorage, exception.HypervisorUnavailable, exception.InstanceNotRunning, exception.MigrationPreCheckError) as ex: raise exc.HTTPBadRequest(explanation=ex.format_message()) except exception.InstanceIsLocked as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state( state_error, 'os-migrateLive', id)
def _migrate_live(self, req, id, body): """Permit admins to (live) migrate a server to a new host.""" context = req.environ["nova.context"] authorize(context, 'migrateLive') try: block_migration = body["os-migrateLive"]["block_migration"] disk_over_commit = body["os-migrateLive"]["disk_over_commit"] host = body["os-migrateLive"]["host"] except (TypeError, KeyError): msg = _("host, block_migration and disk_over_commit must " "be specified for live migration.") raise exc.HTTPBadRequest(explanation=msg) try: block_migration = strutils.bool_from_string(block_migration, strict=True) disk_over_commit = strutils.bool_from_string(disk_over_commit, strict=True) except ValueError as err: raise exc.HTTPBadRequest(explanation=six.text_type(err)) instance = common.get_instance(self.compute_api, context, id, want_objects=True) try: self.compute_api.live_migrate(context, instance, block_migration, disk_over_commit, host) except (exception.NoValidHost, exception.ComputeServiceUnavailable, exception.InvalidHypervisorType, exception.InvalidCPUInfo, exception.UnableToMigrateToSelf, exception.DestinationHypervisorTooOld, exception.InvalidLocalStorage, exception.InvalidSharedStorage, exception.HypervisorUnavailable, exception.InstanceNotRunning, exception.MigrationPreCheckError, exception.LiveMigrationWithOldNovaNotSafe) as ex: raise exc.HTTPBadRequest(explanation=ex.format_message()) except exception.InstanceNotFound as e: raise exc.HTTPNotFound(explanation=e.format_message()) except exception.InstanceIsLocked as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'os-migrateLive', id) except Exception: if host is None: msg = _("Live migration of instance %s to another host " "failed") % id else: msg = _("Live migration of instance %(id)s to host %(host)s " "failed") % {'id': id, 'host': host} LOG.exception(msg) # Return messages from scheduler raise exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def password(self): if self._validate_string(self.args.os_password): return self.args.os_password verify_pass = ( strutils.bool_from_string(cliutils.env("OS_VERIFY_PASSWORD")) ) return self._prompt_password(verify_pass)
def _set_bootable(self, req, id, body): """Update bootable status of a volume.""" context = req.environ['cinder.context'] try: volume = self.volume_api.get(context, id) except exception.VolumeNotFound as error: raise webob.exc.HTTPNotFound(explanation=error.msg) try: bootable = body['os-set_bootable']['bootable'] except KeyError: msg = _("Must specify bootable in request.") raise webob.exc.HTTPBadRequest(explanation=msg) if isinstance(bootable, basestring): try: bootable = strutils.bool_from_string(bootable, strict=True) except ValueError: msg = _("Bad value for 'bootable'") raise webob.exc.HTTPBadRequest(explanation=msg) elif not isinstance(bootable, bool): msg = _("'bootable' not string or bool") raise webob.exc.HTTPBadRequest(explanation=msg) update_dict = {'bootable': bootable} self.volume_api.update(context, volume, update_dict) return webob.Response(status_int=200)
def delete(self, req, id): """Deletes an existing qos specs.""" context = req.environ['cinder.context'] authorize(context) force = req.params.get('force', None) #convert string to bool type in strict manner force = strutils.bool_from_string(force) LOG.debug("Delete qos_spec: %(id)s, force: %(force)s" % { 'id': id, 'force': force }) try: qos_specs.delete(context, id, force) notifier_info = dict(id=id) rpc.get_notifier('QoSSpecs').info(context, 'qos_specs.delete', notifier_info) except exception.QoSSpecsNotFound as err: notifier_err = dict(id=id, error_message=err) self._notify_qos_specs_error(context, 'qos_specs.delete', notifier_err) raise webob.exc.HTTPNotFound(explanation=six.text_type(err)) except exception.QoSSpecsInUse as err: notifier_err = dict(id=id, error_message=err) self._notify_qos_specs_error(context, 'qos_specs.delete', notifier_err) if force: msg = _('Failed to disassociate qos specs.') raise webob.exc.HTTPInternalServerError(explanation=msg) msg = _('Qos specs still in use.') raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202)
def setUp(self): """Run before each test method to initialize test environment.""" super(TestCase, self).setUp() test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0) try: test_timeout = int(test_timeout) except ValueError: # If timeout value is invalid do not set a timeout. test_timeout = 0 if test_timeout > 0: self.useFixture(fixtures.Timeout(test_timeout, gentle=True)) self.useFixture(fixtures.NestedTempfile()) self.useFixture(fixtures.TempHomeDir()) environ_enabled = (lambda var_name: strutils.bool_from_string(os.environ.get(var_name))) if environ_enabled('OS_STDOUT_CAPTURE'): stdout = self.useFixture(fixtures.StringStream('stdout')).stream self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) if environ_enabled('OS_STDERR_CAPTURE'): stderr = self.useFixture(fixtures.StringStream('stderr')).stream self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) if environ_enabled('OS_LOG_CAPTURE'): log_format = '%(levelname)s [%(name)s] %(message)s' if environ_enabled('OS_DEBUG'): level = logging.DEBUG else: level = logging.INFO self.useFixture(fixtures.LoggerFixture(nuke_handlers=False, format=log_format, level=level))
def __init__(self, app, conf): """Common initialization code.""" self.app = app self.logger = logging.getLogger(conf.get('log_name', __name__)) self.logger.debug('Starting the %s component', PROTOCOL_NAME) self.logger.warning( 'This middleware module is deprecated as of v0.11.0 in favor of ' 'keystonemiddleware.s3_token - please update your WSGI pipeline ' 'to reference the new middleware package.') self.reseller_prefix = conf.get('reseller_prefix', 'AUTH_') # where to find the auth service (we use this to validate tokens) auth_host = conf.get('auth_host') auth_port = int(conf.get('auth_port', 35357)) auth_protocol = conf.get('auth_protocol', 'https') self.request_uri = '%s://%s:%s' % (auth_protocol, auth_host, auth_port) # SSL insecure = strutils.bool_from_string(conf.get('insecure', False)) cert_file = conf.get('certfile') key_file = conf.get('keyfile') if insecure: self.verify = False elif cert_file and key_file: self.verify = (cert_file, key_file) elif cert_file: self.verify = cert_file else: self.verify = None
def _volume_readonly_update(self, req, id, body): """Update volume readonly flag.""" context = req.environ['cinder.context'] try: volume = self.volume_api.get(context, id) except exception.VolumeNotFound as error: raise webob.exc.HTTPNotFound(explanation=error.msg) try: readonly_flag = body['os-update_readonly_flag']['readonly'] except KeyError: msg = _("Must specify readonly in request.") raise webob.exc.HTTPBadRequest(explanation=msg) if isinstance(readonly_flag, basestring): try: readonly_flag = strutils.bool_from_string(readonly_flag, strict=True) except ValueError: msg = _("Bad value for 'readonly'") raise webob.exc.HTTPBadRequest(explanation=msg) elif not isinstance(readonly_flag, bool): msg = _("'readonly' not string or bool") raise webob.exc.HTTPBadRequest(explanation=msg) self.volume_api.update_readonly_flag(context, volume, readonly_flag) return webob.Response(status_int=202)
def server_rebuild(self, rebuild_dict, rebuild_kwargs, body_deprecated_param=None): if 'preserve_ephemeral' in rebuild_dict: rebuild_kwargs['preserve_ephemeral'] = strutils.bool_from_string( rebuild_dict['preserve_ephemeral'], strict=True)
def _do_authenticate(self, http_client): token = self.opts.get('token') or self.opts.get('auth_token') endpoint = self.opts.get('endpoint') if not (token and endpoint): project_id = (self.opts.get('project_id') or self.opts.get('tenant_id')) project_name = (self.opts.get('project_name') or self.opts.get('tenant_name')) ks_kwargs = { 'username': self.opts.get('username'), 'password': self.opts.get('password'), 'user_id': self.opts.get('user_id'), 'user_domain_id': self.opts.get('user_domain_id'), 'user_domain_name': self.opts.get('user_domain_name'), 'project_id': project_id, 'project_name': project_name, 'project_domain_name': self.opts.get('project_domain_name'), 'project_domain_id': self.opts.get('project_domain_id'), 'auth_url': self.opts.get('auth_url'), 'cacert': self.opts.get('cacert'), 'cert': self.opts.get('cert'), 'key': self.opts.get('key'), 'insecure': strutils.bool_from_string( self.opts.get('insecure')), 'endpoint_type': self.opts.get('endpoint_type'), } # retrieve session ks_session = _get_keystone_session(**ks_kwargs) token = lambda: ks_session.get_token() endpoint = (self.opts.get('endpoint') or _get_endpoint(ks_session, **ks_kwargs)) self.opts['token'] = token self.opts['endpoint'] = endpoint
def _migrate_enabled_from_extra(migrate_engine, endpoint_table): """Remove `enabled` from `extra`, put it in the `enabled` column.""" eps = list(endpoint_table.select().execute()) for ep in eps: extra_dict = jsonutils.loads(ep.extra) if 'enabled' not in extra_dict: # `enabled` and `extra` are already as expected. continue enabled = extra_dict.pop('enabled') if enabled is None: enabled = True else: enabled = strutils.bool_from_string(enabled, default=True) new_values = { 'enabled': enabled, 'extra': jsonutils.dumps(extra_dict), } f = endpoint_table.c.id == ep.id update = endpoint_table.update().where(f).values(new_values) migrate_engine.execute(update)
def _add_disk_config(self, context, images): for image in images: metadata = image['metadata'] if INTERNAL_DISK_CONFIG in metadata: raw_value = metadata[INTERNAL_DISK_CONFIG] value = strutils.bool_from_string(raw_value) image[API_DISK_CONFIG] = disk_config_to_api(value)
def _do_authenticate(self, http_client): token = self.opts.get('token') or self.opts.get('auth_token') endpoint = self.opts.get('endpoint') if not (token and endpoint): project_id = (self.opts.get('project_id') or self.opts.get('tenant_id')) project_name = (self.opts.get('project_name') or self.opts.get('tenant_name')) ks_kwargs = { 'username': self.opts.get('username'), 'password': self.opts.get('password'), 'user_id': self.opts.get('user_id'), 'user_domain_id': self.opts.get('user_domain_id'), 'user_domain_name': self.opts.get('user_domain_name'), 'project_id': project_id, 'project_name': project_name, 'project_domain_name': self.opts.get('project_domain_name'), 'project_domain_id': self.opts.get('project_domain_id'), 'auth_url': self.opts.get('auth_url'), 'cacert': self.opts.get('cacert'), 'cert': self.opts.get('cert'), 'key': self.opts.get('key'), 'insecure': strutils.bool_from_string(self.opts.get('insecure')), 'endpoint_type': self.opts.get('endpoint_type'), } # retrieve session ks_session = _get_keystone_session(**ks_kwargs) token = lambda: ks_session.get_token() endpoint = (self.opts.get('endpoint') or _get_endpoint(ks_session, **ks_kwargs)) self.opts['token'] = token self.opts['endpoint'] = endpoint
def _migrate_volume(self, req, id, body): """Migrate a volume to the specified host.""" context = req.environ['cinder.context'] self.authorize(context, 'migrate_volume') try: volume = self._get(context, id) except exception.NotFound: raise exc.HTTPNotFound() params = body['os-migrate_volume'] try: host = params['host'] except KeyError: raise exc.HTTPBadRequest(explanation=_("Must specify 'host'")) force_host_copy = params.get('force_host_copy', False) if isinstance(force_host_copy, basestring): try: force_host_copy = strutils.bool_from_string(force_host_copy, strict=True) except ValueError: raise exc.HTTPBadRequest( explanation=_("Bad value for 'force_host_copy'")) elif not isinstance(force_host_copy, bool): raise exc.HTTPBadRequest( explanation=_("'force_host_copy' not string or bool")) self.volume_api.migrate_volume(context, volume, host, force_host_copy) return webob.Response(status_int=202)
def server_create(self, server_dict, create_kwargs, body_deprecated_param): block_device_mapping = server_dict.get(ATTRIBUTE_NAME, []) block_device_mapping_v2 = server_dict.get(ATTRIBUTE_NAME_V2, []) if block_device_mapping and block_device_mapping_v2: expl = _('Using different block_device_mapping syntaxes ' 'is not allowed in the same request.') raise exc.HTTPBadRequest(explanation=expl) if not isinstance(block_device_mapping, list): msg = _('block_device_mapping must be a list') raise exc.HTTPBadRequest(explanation=msg) for bdm in block_device_mapping: try: block_device.validate_device_name(bdm.get("device_name")) block_device.validate_and_default_volume_size(bdm) except exception.InvalidBDMFormat as e: raise exc.HTTPBadRequest(explanation=e.format_message()) if 'delete_on_termination' in bdm: bdm['delete_on_termination'] = strutils.bool_from_string( bdm['delete_on_termination']) if block_device_mapping: create_kwargs['block_device_mapping'] = block_device_mapping # Sets the legacy_bdm flag if we got a legacy block device mapping. create_kwargs['legacy_bdm'] = True
def get_image_meta_from_headers(response): """ Processes HTTP headers from a supplied response that match the x-image-meta and x-image-meta-property and returns a mapping of image metadata and properties :param response: Response to process """ result = {} properties = {} if hasattr(response, 'getheaders'): # httplib.HTTPResponse headers = response.getheaders() else: # webob.Response headers = response.headers.items() for key, value in headers: key = str(key.lower()) if key.startswith('x-image-meta-property-'): field_name = key[len('x-image-meta-property-'):].replace('-', '_') properties[field_name] = value or None elif key.startswith('x-image-meta-'): field_name = key[len('x-image-meta-'):].replace('-', '_') if 'x-image-meta-' + field_name not in IMAGE_META_HEADERS: msg = _("Bad header: %(header_name)s") % {'header_name': key} raise exc.HTTPBadRequest(msg, content_type="text/plain") result[field_name] = value or None result['properties'] = properties for key, nullable in [('size', False), ('min_disk', False), ('min_ram', False), ('virtual_size', True)]: if key in result: try: result[key] = int(result[key]) except ValueError: if nullable and result[key] == str(None): result[key] = None else: extra = (_("Cannot convert image %(key)s '%(value)s' " "to an integer.") % { 'key': key, 'value': result[key] }) raise exception.InvalidParameterValue(value=result[key], param=key, extra_msg=extra) if result[key] < 0 and result[key] is not None: extra = (_("Image %(key)s must be >= 0 " "('%(value)s' specified).") % { 'key': key, 'value': result[key] }) raise exception.InvalidParameterValue(value=result[key], param=key, extra_msg=extra) for key in ('is_public', 'deleted', 'protected'): if key in result: result[key] = strutils.bool_from_string(result[key]) return result
def sync_instances(self, req, body): """Tell all cells to sync instance info.""" context = req.environ['nova.context'] authorize(context) authorize(context, action="sync_instances") project_id = body.pop('project_id', None) deleted = body.pop('deleted', False) updated_since = body.pop('updated_since', None) if body: msg = _("Only 'updated_since', 'project_id' and 'deleted' are " "understood.") raise exc.HTTPBadRequest(explanation=msg) if isinstance(deleted, six.string_types): try: deleted = strutils.bool_from_string(deleted, strict=True) except ValueError as err: raise exc.HTTPBadRequest(explanation=six.text_type(err)) if updated_since: try: timeutils.parse_isotime(updated_since) except ValueError: msg = _('Invalid changes-since value') raise exc.HTTPBadRequest(explanation=msg) self.cells_rpcapi.sync_instances(context, project_id=project_id, updated_since=updated_since, deleted=deleted)
def create(self, req, body): """Creates a new snapshot.""" context = req.environ['nova.context'] authorize(context) if not self.is_valid_body(body, 'snapshot'): msg = _("snapshot not specified") raise exc.HTTPBadRequest(explanation=msg) snapshot = body['snapshot'] volume_id = snapshot['volume_id'] force = snapshot.get('force', False) try: force = strutils.bool_from_string(force, strict=True) except ValueError: msg = _("Invalid value '%s' for force.") % force raise exc.HTTPBadRequest(explanation=msg) if force: create_func = self.volume_api.create_snapshot_force else: create_func = self.volume_api.create_snapshot new_snapshot = create_func(context, volume_id, snapshot.get('display_name'), snapshot.get('display_description')) retval = _translate_snapshot_detail_view(context, new_snapshot) return {'snapshot': retval}
def _make_client(cls, parsed_url, options, default_socket_timeout): kwargs = {} if parsed_url.hostname: kwargs['host'] = parsed_url.hostname if parsed_url.port: kwargs['port'] = parsed_url.port else: if not parsed_url.path: raise ValueError("Expected socket path in parsed urls path") kwargs['unix_socket_path'] = parsed_url.path if parsed_url.password: kwargs['password'] = parsed_url.password for a in cls._CLIENT_ARGS: if a not in options: continue # The reason the last index is used is that when multiple options # of the same name are given via a url the values will be # accumulated in a list (and not just be a single value)... # # For ex: the following is a valid url which will have 2 values # for the 'timeout' argument: # # redis://localhost:6379?timeout=5&timeout=2 if a in cls._CLIENT_BOOL_ARGS: v = strutils.bool_from_string(options[a][-1]) elif a in cls._CLIENT_INT_ARGS: v = int(options[a][-1]) else: v = options[a][-1] kwargs[a] = v if 'socket_timeout' not in kwargs: kwargs['socket_timeout'] = default_socket_timeout return redis.StrictRedis(**kwargs)
def to_schema_type(self, value): """Returns the value in the schema's data type.""" try: # We have to be backwards-compatible for Integer and Number # Schema types and try to convert string representations of # number into "real" number types, therefore calling # str_to_num below. if self.type == self.INTEGER: num = Schema.str_to_num(value) if isinstance(num, float): raise ValueError(_('%s is not an integer.') % num) return num elif self.type == self.NUMBER: return Schema.str_to_num(value) elif self.type == self.STRING: return str(value) elif self.type == self.BOOLEAN: return strutils.bool_from_string(str(value), strict=True) except ValueError: raise ValueError( _('Value "%(val)s" is invalid for data type ' '"%(type)s".') % { 'val': value, 'type': self.type }) return value
def create(self, req, body): """Creates a new snapshot.""" context = req.environ['nova.context'] authorize(context) if not self.is_valid_body(body, 'snapshot'): msg = _("snapshot not specified") raise exc.HTTPBadRequest(explanation=msg) snapshot = body['snapshot'] volume_id = snapshot['volume_id'] LOG.audit(_("Create snapshot from volume %s"), volume_id, context=context) force = snapshot.get('force', False) try: force = strutils.bool_from_string(force, strict=True) except ValueError: msg = _("Invalid value '%s' for force.") % force raise exc.HTTPBadRequest(explanation=msg) if force: create_func = self.volume_api.create_snapshot_force else: create_func = self.volume_api.create_snapshot new_snapshot = create_func(context, volume_id, snapshot.get('display_name'), snapshot.get('display_description')) retval = _translate_snapshot_detail_view(context, new_snapshot) return {'snapshot': retval}
def _validate(self, bdm_dict): """Basic data format validations.""" dict_fields = set(key for key, _ in bdm_dict.iteritems()) # Check that there are no bogus fields if not (dict_fields <= (self._fields | self._db_only_fields)): raise exception.InvalidBDMFormat( details=_("Some fields are invalid.")) if bdm_dict.get('no_device'): return # Check that all required fields are there if (self._required_fields and not ((dict_fields & self._required_fields) == self._required_fields)): raise exception.InvalidBDMFormat( details=_("Some required fields are missing")) if 'delete_on_termination' in bdm_dict: bdm_dict['delete_on_termination'] = strutils.bool_from_string( bdm_dict['delete_on_termination']) if bdm_dict.get('device_name') is not None: validate_device_name(bdm_dict['device_name']) validate_and_default_volume_size(bdm_dict) if bdm_dict.get('boot_index'): try: bdm_dict['boot_index'] = int(bdm_dict['boot_index']) except ValueError: raise exception.InvalidBDMFormat( details=_("Boot index is invalid."))
def _validate(self, bdm_dict): """Basic data format validations.""" dict_fields = set(key for key, _ in bdm_dict.iteritems()) # Check that there are no bogus fields if not (dict_fields <= (self._fields | self._db_only_fields)): raise exception.InvalidBDMFormat( details=_("Some fields are invalid.")) if bdm_dict.get('no_device'): return # Check that all required fields are there if (self._required_fields and not ( (dict_fields & self._required_fields) == self._required_fields)): raise exception.InvalidBDMFormat( details=_("Some required fields are missing")) if 'delete_on_termination' in bdm_dict: bdm_dict['delete_on_termination'] = strutils.bool_from_string( bdm_dict['delete_on_termination']) if bdm_dict.get('device_name') is not None: validate_device_name(bdm_dict['device_name']) validate_and_default_volume_size(bdm_dict) if bdm_dict.get('boot_index'): try: bdm_dict['boot_index'] = int(bdm_dict['boot_index']) except ValueError: raise exception.InvalidBDMFormat( details=_("Boot index is invalid."))
def get_flavors_detail(self, **kw): flavors = { 'flavors': [{ 'id': 1, 'name': '256 MB Server', 'ram': 256, 'disk': 10, 'ephemeral': 10, 'flavor-access:is_public': True, 'links': {} }, { 'id': 2, 'name': '512 MB Server', 'ram': 512, 'disk': 20, 'ephemeral': 20, 'flavor-access:is_public': False, 'links': {} }, { 'id': 4, 'name': '1024 MB Server', 'ram': 1024, 'disk': 10, 'ephemeral': 10, 'flavor-access:is_public': True, 'links': {} }, { 'id': 'aa1', 'name': '128 MB Server', 'ram': 128, 'disk': 0, 'ephemeral': 0, 'flavor-access:is_public': True, 'links': {} }] } if 'is_public' not in kw: filter_is_public = True else: if kw['is_public'].lower() == 'none': filter_is_public = None else: filter_is_public = strutils.bool_from_string( kw['is_public'], True) if filter_is_public is not None: if filter_is_public: flavors['flavors'] = [ v for v in flavors['flavors'] if v['flavor-access:is_public'] ] else: flavors['flavors'] = [ v for v in flavors['flavors'] if not v['flavor-access:is_public'] ] return (200, {}, flavors)
def extract_bool(subject): ''' Convert any true/false string to its corresponding boolean value, regardless of case. ''' if str(subject).lower() not in ('true', 'false'): raise ValueError(_('Unrecognized value "%(value)s", acceptable ' 'values are: true, false.') % {'value': subject}) return strutils.bool_from_string(subject, strict=True)
def create(self, req, body): """Creates a new snapshot.""" kwargs = {} context = req.environ['cinder.context'] if not self.is_valid_body(body, 'snapshot'): msg = (_("Missing required element '%s' in request body") % 'snapshot') raise exc.HTTPBadRequest(explanation=msg) 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: msg = _("Volume could not be found") raise exc.HTTPNotFound(explanation=msg) force = snapshot.get('force', False) msg = _("Create snapshot from volume %s") LOG.info(msg, volume_id, context=context) # NOTE(thingee): v2 API allows name instead of display_name if 'name' in snapshot: snapshot['display_name'] = snapshot.get('name') del snapshot['name'] 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('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) retval = _translate_snapshot_detail_view(context, new_snapshot) return {'snapshot': retval}
def get_image_meta_from_headers(response): """ Processes HTTP headers from a supplied response that match the x-image-meta and x-image-meta-property and returns a mapping of image metadata and properties :param response: Response to process """ result = {} properties = {} if hasattr(response, 'getheaders'): # httplib.HTTPResponse headers = response.getheaders() else: # webob.Response headers = response.headers.items() for key, value in headers: key = str(key.lower()) if key.startswith('x-image-meta-property-'): field_name = key[len('x-image-meta-property-'):].replace('-', '_') properties[field_name] = value or None elif key.startswith('x-image-meta-'): field_name = key[len('x-image-meta-'):].replace('-', '_') if 'x-image-meta-' + field_name not in IMAGE_META_HEADERS: msg = _("Bad header: %(header_name)s") % {'header_name': key} raise exc.HTTPBadRequest(msg, content_type="text/plain") result[field_name] = value or None result['properties'] = properties for key, nullable in [('size', False), ('min_disk', False), ('min_ram', False), ('virtual_size', True)]: if key in result: try: result[key] = int(result[key]) except ValueError: if nullable and result[key] == str(None): result[key] = None else: extra = (_("Cannot convert image %(key)s '%(value)s' " "to an integer.") % {'key': key, 'value': result[key]}) raise exception.InvalidParameterValue(value=result[key], param=key, extra_msg=extra) if result[key] < 0 and result[key] is not None: extra = (_("Image %(key)s must be >= 0 " "('%(value)s' specified).") % {'key': key, 'value': result[key]}) raise exception.InvalidParameterValue(value=result[key], param=key, extra_msg=extra) for key in ('is_public', 'deleted', 'protected'): if key in result: result[key] = strutils.bool_from_string(result[key]) return result
def _as_bool(value): if isinstance(value, bool): return value # This is different than strutils, but imho is an acceptable difference. if value is None: return False # NOTE(harlowja): prefer strictness to avoid users getting accustomed # to passing bad values in and this *just working* (which imho is a bad # habit to encourage). return strutils.bool_from_string(value, strict=True)
def attr_as_boolean(val_attr): """Returns the boolean value, decoded from a string. We test explicitly for a value meaning False, which can be one of several formats as specified in oslo strutils.FALSE_STRINGS. All other string values (including an empty string) are treated as meaning True. """ return strutils.bool_from_string(val_attr, default=True)
def test_unicode_bool_from_string(self): self._test_bool_from_string(six.text_type) self.assertFalse(strutils.bool_from_string(u'使用', strict=False)) exc = self.assertRaises(ValueError, strutils.bool_from_string, u'使用', strict=True) expected_msg = (u"Unrecognized value '使用', acceptable values are:" u" '0', '1', 'f', 'false', 'n', 'no', 'off', 'on'," u" 't', 'true', 'y', 'yes'") self.assertEqual(expected_msg, six.text_type(exc))
def create(self, name, ram, vcpus, disk, flavorid="auto", ephemeral=0, swap=0, rxtx_factor=1.0, is_public=True): """ Create a flavor. :param name: Descriptive name of the flavor :param ram: Memory in MB for the flavor :param vcpus: Number of VCPUs for the flavor :param disk: Size of local disk in GB :param flavorid: ID for the flavor (optional). You can use the reserved value ``"auto"`` to have Nova generate a UUID for the flavor in cases where you cannot simply pass ``None``. :param swap: Swap space in MB :param rxtx_factor: RX/TX factor :rtype: :class:`Flavor` """ try: ram = int(ram) except (TypeError, ValueError): raise exceptions.CommandError(_("Ram must be an integer.")) try: vcpus = int(vcpus) except (TypeError, ValueError): raise exceptions.CommandError(_("VCPUs must be an integer.")) try: disk = int(disk) except (TypeError, ValueError): raise exceptions.CommandError(_("Disk must be an integer.")) if flavorid == "auto": flavorid = None try: swap = int(swap) except (TypeError, ValueError): raise exceptions.CommandError(_("Swap must be an integer.")) try: ephemeral = int(ephemeral) except (TypeError, ValueError): raise exceptions.CommandError(_("Ephemeral must be an integer.")) try: rxtx_factor = float(rxtx_factor) except (TypeError, ValueError): raise exceptions.CommandError(_("rxtx_factor must be a float.")) try: is_public = strutils.bool_from_string(is_public, True) except Exception: raise exceptions.CommandError(_("is_public must be a boolean.")) body = self._build_body(name, ram, vcpus, disk, flavorid, swap, ephemeral, rxtx_factor, is_public) return self._create("/flavors", body, "flavor")
def process_request(self, request): headers = request.headers all_tenants = strutils.bool_from_string( headers.get('X-Test-All-Tenants', 'False')) self.make_context( request, user=headers.get('X-Test-User-ID', self.default_user_id), tenant=headers.get('X-Test-Tenant-ID', self.default_tenant_id), all_tenants=all_tenants)
def parse_instance_info(node): """Gets the instance specific Node deployment info. This method validates whether the 'instance_info' property of the supplied node contains the required information for this driver to deploy images to the node. :param node: a single Node. :returns: A dict with the instance_info values. :raises: MissingParameterValue, if any of the required parameters are missing. :raises: InvalidParameterValue, if any of the parameters have invalid value. """ info = node.instance_info i_info = {} i_info['image_source'] = info.get('image_source') i_info['root_gb'] = info.get('root_gb') error_msg = _("Cannot validate iSCSI deploy") deploy_utils.check_for_missing_params(i_info, error_msg) # Internal use only i_info['deploy_key'] = info.get('deploy_key') i_info['swap_mb'] = info.get('swap_mb', 0) i_info['ephemeral_gb'] = info.get('ephemeral_gb', 0) i_info['ephemeral_format'] = info.get('ephemeral_format') err_msg_invalid = _("Cannot validate parameter for iSCSI deploy. " "Invalid parameter %(param)s. Reason: %(reason)s") for param in ('root_gb', 'swap_mb', 'ephemeral_gb'): try: int(i_info[param]) except ValueError: reason = _("'%s' is not an integer value.") % i_info[param] raise exception.InvalidParameterValue(err_msg_invalid % { 'param': param, 'reason': reason }) if i_info['ephemeral_gb'] and not i_info['ephemeral_format']: i_info['ephemeral_format'] = CONF.pxe.default_ephemeral_format preserve_ephemeral = info.get('preserve_ephemeral', False) try: i_info['preserve_ephemeral'] = strutils.bool_from_string( preserve_ephemeral, strict=True) except ValueError as e: raise exception.InvalidParameterValue(err_msg_invalid % { 'param': 'preserve_ephemeral', 'reason': e }) return i_info
def should_use_agent(instance): sys_meta = utils.instance_sys_meta(instance) if USE_AGENT_SM_KEY not in sys_meta: return CONF.xenserver.use_agent_default else: use_agent_raw = sys_meta[USE_AGENT_SM_KEY] try: return strutils.bool_from_string(use_agent_raw, strict=True) except ValueError: LOG.warn(_("Invalid 'agent_present' value. " "Falling back to the default."), instance=instance) return CONF.xenserver.use_agent_default
def required_by(instance): image_prop = utils.instance_sys_meta(instance).get( utils.SM_IMAGE_PROP_PREFIX + 'img_config_drive', 'optional') if image_prop not in ['optional', 'mandatory']: LOG.warn(_LW('Image config drive option %(image_prop)s is invalid ' 'and will be ignored') % {'image_prop': image_prop}, instance=instance) return (instance.get('config_drive') or 'always' == CONF.force_config_drive or strutils.bool_from_string(CONF.force_config_drive) or image_prop == 'mandatory')
def test_strict_bool_from_string(self): # None isn't allowed in strict mode exc = self.assertRaises(ValueError, strutils.bool_from_string, None, strict=True) expected_msg = ("Unrecognized value 'None', acceptable values are:" " '0', '1', 'f', 'false', 'n', 'no', 'off', 'on'," " 't', 'true', 'y', 'yes'") self.assertEqual(expected_msg, str(exc)) # Unrecognized strings aren't allowed self.assertFalse(strutils.bool_from_string('Other', strict=False)) exc = self.assertRaises(ValueError, strutils.bool_from_string, 'Other', strict=True) expected_msg = ("Unrecognized value 'Other', acceptable values are:" " '0', '1', 'f', 'false', 'n', 'no', 'off', 'on'," " 't', 'true', 'y', 'yes'") self.assertEqual(expected_msg, str(exc)) # Unrecognized numbers aren't allowed exc = self.assertRaises(ValueError, strutils.bool_from_string, 2, strict=True) expected_msg = ("Unrecognized value '2', acceptable values are:" " '0', '1', 'f', 'false', 'n', 'no', 'off', 'on'," " 't', 'true', 'y', 'yes'") self.assertEqual(expected_msg, str(exc)) # False-like values are allowed self.assertFalse(strutils.bool_from_string('f', strict=True)) self.assertFalse(strutils.bool_from_string('false', strict=True)) self.assertFalse(strutils.bool_from_string('off', strict=True)) self.assertFalse(strutils.bool_from_string('n', strict=True)) self.assertFalse(strutils.bool_from_string('no', strict=True)) self.assertFalse(strutils.bool_from_string('0', strict=True)) self.assertTrue(strutils.bool_from_string('1', strict=True)) # Avoid font-similarity issues (one looks like lowercase-el, zero like # oh, etc...) for char in ('O', 'o', 'L', 'l', 'I', 'i'): self.assertRaises(ValueError, strutils.bool_from_string, char, strict=True)
def update(self, req, id, body): """Update server then pass on to version-specific controller.""" if not self.is_valid_body(body, 'server'): raise exc.HTTPUnprocessableEntity() ctxt = req.environ['nova.context'] update_dict = {} if 'name' in body['server']: name = body['server']['name'] self._validate_server_name(name) update_dict['display_name'] = name.strip() if 'accessIPv4' in body['server']: access_ipv4 = body['server']['accessIPv4'] if access_ipv4: self._validate_access_ipv4(access_ipv4) update_dict['access_ip_v4'] = ( access_ipv4 and access_ipv4.strip() or None) if 'accessIPv6' in body['server']: access_ipv6 = body['server']['accessIPv6'] if access_ipv6: self._validate_access_ipv6(access_ipv6) update_dict['access_ip_v6'] = ( access_ipv6 and access_ipv6.strip() or None) if 'auto_disk_config' in body['server']: auto_disk_config = strutils.bool_from_string( body['server']['auto_disk_config']) update_dict['auto_disk_config'] = auto_disk_config if 'hostId' in body['server']: msg = _("HostId cannot be updated.") raise exc.HTTPBadRequest(explanation=msg) if 'personality' in body['server']: msg = _("Personality cannot be updated.") raise exc.HTTPBadRequest(explanation=msg) instance = self._get_server(ctxt, req, id) try: policy.enforce(ctxt, 'compute:update', instance) instance.update(update_dict) # Note instance.save can throw a NotFound exception instance.save() except exception.NotFound: msg = _("Instance could not be found") raise exc.HTTPNotFound(explanation=msg) return self._view_builder.show(req, instance)
def update(self, req, id, body): """Update server then pass on to version-specific controller.""" if not self.is_valid_body(body, 'server'): raise exc.HTTPUnprocessableEntity() ctxt = req.environ['nova.context'] update_dict = {} if 'name' in body['server']: name = body['server']['name'] self._validate_server_name(name) update_dict['display_name'] = name.strip() if 'accessIPv4' in body['server']: access_ipv4 = body['server']['accessIPv4'] if access_ipv4: self._validate_access_ipv4(access_ipv4) update_dict['access_ip_v4'] = (access_ipv4 and access_ipv4.strip() or None) if 'accessIPv6' in body['server']: access_ipv6 = body['server']['accessIPv6'] if access_ipv6: self._validate_access_ipv6(access_ipv6) update_dict['access_ip_v6'] = (access_ipv6 and access_ipv6.strip() or None) if 'auto_disk_config' in body['server']: auto_disk_config = strutils.bool_from_string( body['server']['auto_disk_config']) update_dict['auto_disk_config'] = auto_disk_config if 'hostId' in body['server']: msg = _("HostId cannot be updated.") raise exc.HTTPBadRequest(explanation=msg) if 'personality' in body['server']: msg = _("Personality cannot be updated.") raise exc.HTTPBadRequest(explanation=msg) instance = self._get_server(ctxt, req, id) try: policy.enforce(ctxt, 'compute:update', instance) instance.update(update_dict) # Note instance.save can throw a NotFound exception instance.save() except exception.NotFound: msg = _("Instance could not be found") raise exc.HTTPNotFound(explanation=msg) return self._view_builder.show(req, instance)
def parse_instance_info(node): """Gets the instance specific Node deployment info. This method validates whether the 'instance_info' property of the supplied node contains the required information for this driver to deploy images to the node. :param node: a single Node. :returns: A dict with the instance_info values. :raises: MissingParameterValue, if any of the required parameters are missing. :raises: InvalidParameterValue, if any of the parameters have invalid value. """ info = node.instance_info i_info = {} i_info['image_source'] = info.get('image_source') i_info['root_gb'] = info.get('root_gb') error_msg = _("Cannot validate iSCSI deploy. Some parameters were missing" " in node's instance_info") deploy_utils.check_for_missing_params(i_info, error_msg) # Internal use only i_info['deploy_key'] = info.get('deploy_key') i_info['swap_mb'] = info.get('swap_mb', 0) i_info['ephemeral_gb'] = info.get('ephemeral_gb', 0) i_info['ephemeral_format'] = info.get('ephemeral_format') err_msg_invalid = _("Cannot validate parameter for iSCSI deploy. " "Invalid parameter %(param)s. Reason: %(reason)s") for param in ('root_gb', 'swap_mb', 'ephemeral_gb'): try: int(i_info[param]) except ValueError: reason = _("'%s' is not an integer value.") % i_info[param] raise exception.InvalidParameterValue(err_msg_invalid % {'param': param, 'reason': reason}) if i_info['ephemeral_gb'] and not i_info['ephemeral_format']: i_info['ephemeral_format'] = CONF.pxe.default_ephemeral_format preserve_ephemeral = info.get('preserve_ephemeral', False) try: i_info['preserve_ephemeral'] = strutils.bool_from_string( preserve_ephemeral, strict=True) except ValueError as e: raise exception.InvalidParameterValue(err_msg_invalid % {'param': 'preserve_ephemeral', 'reason': e}) return i_info
def _evacuate(self, req, id, body): """Permit admins to evacuate a server from a failed host to a new one. """ context = req.environ["nova.context"] authorize(context) evacuate_body = body["evacuate"] host = evacuate_body.get("host") on_shared_storage = strutils.bool_from_string( evacuate_body["onSharedStorage"]) password = None if 'adminPass' in evacuate_body: # check that if requested to evacuate server on shared storage # password not specified if on_shared_storage: msg = _("admin password can't be changed on existing disk") raise exc.HTTPBadRequest(explanation=msg) password = evacuate_body['adminPass'] elif not on_shared_storage: password = utils.generate_password() if host is not None: try: self.host_api.service_get_by_compute_host(context, host) except exception.NotFound: msg = _("Compute host %s not found.") % host raise exc.HTTPNotFound(explanation=msg) instance = common.get_instance(self.compute_api, context, id, want_objects=True) if instance.host == host: msg = _("The target host can't be the same one.") raise exc.HTTPBadRequest(explanation=msg) try: self.compute_api.evacuate(context, instance, host, on_shared_storage, password) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'evacuate', id) except exception.ComputeServiceInUse as e: raise exc.HTTPBadRequest(explanation=e.format_message()) if CONF.enable_instance_password: return {'adminPass': password} else: return {}
def _parse_is_public(self, is_public): """Parse is_public into something usable.""" if is_public is None: # preserve default value of showing only public flavors return True elif utils.is_none_string(is_public): return None else: try: return strutils.bool_from_string(is_public, strict=True) except ValueError: msg = _('Invalid is_public filter [%s]') % is_public raise webob.exc.HTTPBadRequest(explanation=msg)
def sync_instances(self, req, body): """Tell all cells to sync instance info.""" context = req.environ['nova.context'] authorize(context) authorize(context, action="sync_instances") project_id = body.pop('project_id', None) deleted = body.pop('deleted', False) updated_since = body.pop('updated_since', None) if isinstance(deleted, six.string_types): deleted = strutils.bool_from_string(deleted, strict=True) self.cells_rpcapi.sync_instances(context, project_id=project_id, updated_since=updated_since, deleted=deleted)
def password(self): # Cache password so we prompt user at most once if self._password: pass elif self._validate_string(self.args.os_password): self._password = self.args.os_password else: verify_pass = strutils.bool_from_string(utils.env("OS_VERIFY_PASSWORD", default=False), True) self._password = self._prompt_password(verify_pass) if not self._password: raise exc.CommandError( "Expecting a password provided via either " "--os-password, env[OS_PASSWORD], or " "prompted response" ) return self._password
def _extract_bdm(self, server_dict): legacy_bdm = True block_device_mapping = None block_device_mapping_v2 = None if not self.ext_mgr.is_loaded('os-volumes'): return legacy_bdm, None block_device_mapping = server_dict.get('block_device_mapping', []) if not isinstance(block_device_mapping, list): msg = _('block_device_mapping must be a list') raise exc.HTTPBadRequest(explanation=msg) for bdm in block_device_mapping: try: block_device.validate_device_name(bdm.get("device_name")) block_device.validate_and_default_volume_size(bdm) except exception.InvalidBDMFormat as e: raise exc.HTTPBadRequest(explanation=e.format_message()) if 'delete_on_termination' in bdm: bdm['delete_on_termination'] = strutils.bool_from_string( bdm['delete_on_termination']) if self.ext_mgr.is_loaded('os-block-device-mapping-v2-boot'): # Consider the new data format for block device mapping block_device_mapping_v2 = server_dict.get( 'block_device_mapping_v2', []) # NOTE (ndipanov): Disable usage of both legacy and new # block device format in the same request if block_device_mapping and block_device_mapping_v2: expl = _('Using different block_device_mapping syntaxes ' 'is not allowed in the same request.') raise exc.HTTPBadRequest(explanation=expl) if not isinstance(block_device_mapping_v2, list): msg = _('block_device_mapping_v2 must be a list') raise exc.HTTPBadRequest(explanation=msg) # Assume legacy format legacy_bdm = not bool(block_device_mapping_v2) try: block_device_mapping_v2 = [ block_device.BlockDeviceDict.from_api(bdm_dict) for bdm_dict in block_device_mapping_v2 ] except exception.InvalidBDMFormat as e: raise exc.HTTPBadRequest(explanation=e.format_message()) bdm = (block_device_mapping or block_device_mapping_v2) return legacy_bdm, bdm