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 = utils.bool_from_str(raw_value) image[API_DISK_CONFIG] = disk_config_to_api(value)
def _extract_server(self, node): """Marshal the server attribute of a parsed request""" server = {} server_node = self.find_first_child_named(node, 'server') attributes = [ "name", "imageRef", "flavorRef", "adminPass", "accessIPv4", "accessIPv6" ] for attr in attributes: if server_node.getAttribute(attr): server[attr] = server_node.getAttribute(attr) metadata_node = self.find_first_child_named(server_node, "metadata") if metadata_node is not None: server["metadata"] = self.extract_metadata(metadata_node) personality = self._extract_personality(server_node) if personality is not None: server["personality"] = personality networks = self._extract_networks(server_node) if networks is not None: server["networks"] = networks security_groups = self._extract_security_groups(server_node) if security_groups is not None: server["security_groups"] = security_groups auto_disk_config = server_node.getAttribute('auto_disk_config') if auto_disk_config: server['auto_disk_config'] = utils.bool_from_str(auto_disk_config) return server
def create(self, req, body): """Creates a new snapshot.""" context = req.environ['nova.context'] authorize(context) if not self.is_valid_body(body, 'snapshot'): raise exc.HTTPUnprocessableEntity() snapshot = body['snapshot'] volume_id = snapshot['volume_id'] volume = self.volume_api.get(context, volume_id) force = snapshot.get('force', False) LOG.audit(_("Create snapshot from volume %s"), volume_id, context=context) if not utils.is_valid_boolstr(force): msg = _("Invalid value '%s' for force. ") % force raise exception.InvalidParameterValue(err=msg) if utils.bool_from_str(force): new_snapshot = self.volume_api.create_snapshot_force(context, volume, snapshot.get('display_name'), snapshot.get('display_description')) else: new_snapshot = self.volume_api.create_snapshot(context, volume, snapshot.get('display_name'), snapshot.get('display_description')) retval = _translate_snapshot_detail_view(context, new_snapshot) return {'snapshot': retval}
def create(self, req, body): """Creates a new snapshot.""" context = req.environ['nova.context'] authorize(context) if not self.is_valid_body(body, 'snapshot'): raise exc.HTTPUnprocessableEntity() snapshot = body['snapshot'] volume_id = snapshot['volume_id'] vol = self.volume_api.get(context, volume_id) force = snapshot.get('force', False) LOG.audit(_("Create snapshot from volume %s"), volume_id, context=context) if not utils.is_valid_boolstr(force): msg = _("Invalid value '%s' for force. ") % force raise exception.InvalidParameterValue(err=msg) if utils.bool_from_str(force): new_snapshot = self.volume_api.create_snapshot_force(context, vol, snapshot.get('display_name'), snapshot.get('display_description')) else: new_snapshot = self.volume_api.create_snapshot(context, vol, snapshot.get('display_name'), snapshot.get('display_description')) retval = _translate_snapshot_detail_view(context, new_snapshot) return {'snapshot': retval}
def _extract_server(self, node): """Marshal the server attribute of a parsed request.""" server = {} server_node = self.find_first_child_named(node, 'server') attributes = ["name", "imageRef", "flavorRef", "adminPass", "accessIPv4", "accessIPv6"] for attr in attributes: if server_node.getAttribute(attr): server[attr] = server_node.getAttribute(attr) metadata_node = self.find_first_child_named(server_node, "metadata") if metadata_node is not None: server["metadata"] = self.extract_metadata(metadata_node) personality = self._extract_personality(server_node) if personality is not None: server["personality"] = personality networks = self._extract_networks(server_node) if networks is not None: server["networks"] = networks security_groups = self._extract_security_groups(server_node) if security_groups is not None: server["security_groups"] = security_groups auto_disk_config = server_node.getAttribute('auto_disk_config') if auto_disk_config: server['auto_disk_config'] = utils.bool_from_str(auto_disk_config) return server
def create(name, memory, vcpus, root_gb, ephemeral_gb=None, flavorid=None, swap=None, rxtx_factor=None, is_public=True): """Creates instance types.""" if flavorid is None: flavorid = utils.gen_uuid() if swap is None: swap = 0 if rxtx_factor is None: rxtx_factor = 1 if ephemeral_gb is None: ephemeral_gb = 0 kwargs = { 'memory_mb': memory, 'vcpus': vcpus, 'root_gb': root_gb, 'ephemeral_gb': ephemeral_gb, 'swap': swap, 'rxtx_factor': rxtx_factor, } # ensure name does not contain any special characters invalid_name = INVALID_NAME_REGEX.search(name) if invalid_name: msg = _("names can only contain [a-zA-Z0-9_.- ]") raise exception.InvalidInput(reason=msg) # ensure some attributes are integers and greater than or equal to 0 for option in kwargs: try: kwargs[option] = int(kwargs[option]) assert kwargs[option] >= 0 except (ValueError, AssertionError): msg = _("create arguments must be positive integers") raise exception.InvalidInput(reason=msg) # some value are required to be nonzero, not just positive for option in ['memory_mb', 'vcpus']: try: assert kwargs[option] > 0 except AssertionError: msg = _("create arguments must be positive integers") raise exception.InvalidInput(reason=msg) kwargs['name'] = name # NOTE(vish): Internally, flavorid is stored as a string but it comes # in through json as an integer, so we convert it here. kwargs['flavorid'] = unicode(flavorid) # ensure is_public attribute is boolean kwargs['is_public'] = utils.bool_from_str(is_public) try: return db.instance_type_create(context.get_admin_context(), kwargs) except exception.DBError, e: LOG.exception(_('DB error: %s') % e) raise exception.InstanceTypeCreateFailed()
def prop(prop_, prop_type=None): """Return the value of an image property.""" value = image_properties.get(prop_) if value is not None: if prop_type == 'bool': value = utils.bool_from_str(value) return value
def update(self, req, id, body): """Update server then pass on to version-specific controller.""" if len(req.body) == 0: raise exc.HTTPUnprocessableEntity() if not body: raise exc.HTTPUnprocessableEntity() if not 'server' in body: 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 is None: access_ipv4 = '' if access_ipv4: self._validate_access_ipv4(access_ipv4) update_dict['access_ip_v4'] = access_ipv4.strip() if 'accessIPv6' in body['server']: access_ipv6 = body['server']['accessIPv6'] if access_ipv6 is None: access_ipv6 = '' if access_ipv6: self._validate_access_ipv6(access_ipv6) update_dict['access_ip_v6'] = access_ipv6.strip() if 'auto_disk_config' in body['server']: auto_disk_config = utils.bool_from_str( 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) try: instance = self.compute_api.get(ctxt, id) req.cache_db_instance(instance) self.compute_api.update(ctxt, instance, **update_dict) except exception.NotFound: raise exc.HTTPNotFound() instance.update(update_dict) self._add_instance_faults(ctxt, [instance]) return self._view_builder.show(req, instance)
def _get_servers(self, req, is_detail): """Returns a list of servers, taking into account any search options specified. """ search_opts = {} search_opts.update(req.str_GET) context = req.environ['nova.context'] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Convert recurse_zones into a boolean search_opts['recurse_zones'] = utils.bool_from_str( search_opts.get('recurse_zones', False)) # If search by 'status', we need to convert it to 'vm_state' # to pass on to child zones. if 'status' in search_opts: status = search_opts['status'] state = common.vm_state_from_status(status) if state is None: reason = _('Invalid server status: %(status)s') % locals() raise exception.InvalidInput(reason=reason) search_opts['vm_state'] = state if 'changes-since' in search_opts: try: parsed = utils.parse_isotime(search_opts['changes-since']) except ValueError: msg = _('Invalid changes-since value') raise exc.HTTPBadRequest(explanation=msg) search_opts['changes-since'] = parsed # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: if 'changes-since' not in search_opts: # No 'changes-since', so we only want non-deleted servers search_opts['deleted'] = False instance_list = self.compute_api.get_all(context, search_opts=search_opts) limited_list = self._limit_items(instance_list, req) servers = [ self._build_view(req, inst, is_detail)['server'] for inst in limited_list ] return dict(servers=servers)
def _get_servers(self, req, is_detail): """Returns a list of servers, taking into account any search options specified. """ search_opts = {} search_opts.update(req.str_GET) context = req.environ['nova.context'] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Convert recurse_zones into a boolean search_opts['recurse_zones'] = utils.bool_from_str( search_opts.get('recurse_zones', False)) # If search by 'status', we need to convert it to 'state' # If the status is unknown, bail. # Leave 'state' in search_opts so compute can pass it on to # child zones.. if 'status' in search_opts: status = search_opts['status'] search_opts['state'] = common.power_states_from_status(status) if len(search_opts['state']) == 0: reason = _('Invalid server status: %(status)s') % locals() LOG.error(reason) raise exception.InvalidInput(reason=reason) # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: # Admin hasn't specified deleted filter if 'changes-since' not in search_opts: # No 'changes-since', so we need to find non-deleted servers search_opts['deleted'] = False else: # This is the default, but just in case.. search_opts['deleted'] = True instance_list = self.compute_api.get_all(context, search_opts=search_opts) # FIXME(comstud): 'changes-since' is not fully implemented. Where # should this be filtered? limited_list = self._limit_items(instance_list, req) servers = [ self._build_view(req, inst, is_detail)['server'] for inst in limited_list ] return dict(servers=servers)
def _get_servers(self, req, is_detail): """Returns a list of servers, taking into account any search options specified. """ search_opts = {} search_opts.update(req.str_GET) context = req.environ['nova.context'] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Convert local_zone_only into a boolean search_opts['local_zone_only'] = utils.bool_from_str( search_opts.get('local_zone_only', False)) # If search by 'status', we need to convert it to 'vm_state' # to pass on to child zones. if 'status' in search_opts: status = search_opts['status'] state = common.vm_state_from_status(status) if state is None: reason = _('Invalid server status: %(status)s') % locals() raise exception.InvalidInput(reason=reason) search_opts['vm_state'] = state if 'changes-since' in search_opts: try: parsed = utils.parse_isotime(search_opts['changes-since']) except ValueError: msg = _('Invalid changes-since value') raise exc.HTTPBadRequest(explanation=msg) search_opts['changes-since'] = parsed # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: if 'changes-since' not in search_opts: # No 'changes-since', so we only want non-deleted servers search_opts['deleted'] = False instance_list = self.compute_api.get_all(context, search_opts=search_opts) limited_list = self._limit_items(instance_list, req) if is_detail: self._add_instance_faults(context, limited_list) return self._view_builder.detail(req, limited_list) else: return self._view_builder.index(req, limited_list)
def _get_servers(self, req, is_detail): """Returns a list of servers, taking into account any search options specified. """ search_opts = {} search_opts.update(req.str_GET) context = req.environ['nova.context'] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Convert recurse_zones into a boolean search_opts['recurse_zones'] = utils.bool_from_str( search_opts.get('recurse_zones', False)) # If search by 'status', we need to convert it to 'state' # If the status is unknown, bail. # Leave 'state' in search_opts so compute can pass it on to # child zones.. if 'status' in search_opts: status = search_opts['status'] search_opts['state'] = common.power_states_from_status(status) if len(search_opts['state']) == 0: reason = _('Invalid server status: %(status)s') % locals() LOG.error(reason) raise exception.InvalidInput(reason=reason) # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: # Admin hasn't specified deleted filter if 'changes-since' not in search_opts: # No 'changes-since', so we need to find non-deleted servers search_opts['deleted'] = False else: # This is the default, but just in case.. search_opts['deleted'] = True instance_list = self.compute_api.get_all( context, search_opts=search_opts) # FIXME(comstud): 'changes-since' is not fully implemented. Where # should this be filtered? limited_list = self._limit_items(instance_list, req) servers = [self._build_view(req, inst, is_detail)['server'] for inst in limited_list] return dict(servers=servers)
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"] if not context.is_admin: msg = _("Instance evacuate is admin only functionality") raise exc.HTTPForbidden(explanation=msg) authorize(context) try: if len(body) != 1: raise exc.HTTPBadRequest(_("Malformed request body")) evacuate_body = body["evacuate"] host = evacuate_body["host"] on_shared_storage = utils.bool_from_str( 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() except (TypeError, KeyError): msg = _("host and onSharedStorage must be specified.") raise exc.HTTPBadRequest(explanation=msg) try: instance = self.compute_api.get(context, id) 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') except Exception as e: msg = _("Error in evacuate, %s") % e LOG.exception(msg, instance=instance) raise exc.HTTPBadRequest(explanation=msg) if password: return {'adminPass': password}
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"] if not context.is_admin: msg = _("Instance evacuate is admin only functionality") raise exc.HTTPForbidden(explanation=msg) authorize(context) try: if len(body) != 1: raise exc.HTTPBadRequest(_("Malformed request body")) evacuate_body = body["evacuate"] host = evacuate_body["host"] on_shared_storage = utils.bool_from_str( 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() except (TypeError, KeyError): msg = _("host and onSharedStorage must be specified.") raise exc.HTTPBadRequest(explanation=msg) try: instance = self.compute_api.get(context, id) 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') except Exception as e: msg = _("Error in evacuate, %s") % e LOG.exception(msg, instance=instance) raise exc.HTTPBadRequest(explanation=msg) if password: return {'adminPass': password}
def _GET_images(self, req, res, body): images = self._extract_resource_from_body(res, body, singular='image', singular_template=ImageDiskConfigTemplate(), plural='images', plural_template=ImagesDiskConfigTemplate()) for image in images: metadata = image['metadata'] if self.INTERNAL_DISK_CONFIG in metadata: raw_value = metadata[self.INTERNAL_DISK_CONFIG] value = utils.bool_from_str(raw_value) image[self.API_DISK_CONFIG] = disk_config_to_api(value) return res
def _get_servers(self, req, is_detail): """Returns a list of servers, taking into account any search options specified. """ search_opts = {} search_opts.update(req.str_GET) context = req.environ["nova.context"] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Convert recurse_zones into a boolean search_opts["recurse_zones"] = utils.bool_from_str(search_opts.get("recurse_zones", False)) # If search by 'status', we need to convert it to 'vm_state' # to pass on to child zones. if "status" in search_opts: status = search_opts["status"] state = common.vm_state_from_status(status) if state is None: reason = _("Invalid server status: %(status)s") % locals() raise exception.InvalidInput(reason=reason) search_opts["vm_state"] = state if "changes-since" in search_opts: try: parsed = utils.parse_isotime(search_opts["changes-since"]) except ValueError: msg = _("Invalid changes-since value") raise exc.HTTPBadRequest(explanation=msg) search_opts["changes-since"] = parsed # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if "deleted" not in search_opts: if "changes-since" not in search_opts: # No 'changes-since', so we only want non-deleted servers search_opts["deleted"] = False instance_list = self.compute_api.get_all(context, search_opts=search_opts) limited_list = self._limit_items(instance_list, req) servers = [self._build_view(req, inst, is_detail)["server"] for inst in limited_list] return dict(servers=servers)
def show(self, req, id): context = req.environ['nova.context'] authorize_action(context, 'show') params = self._request_params(req) remaining = False if 'remaining' in params: remaining = utils.bool_from_str(params["remaining"][0]) user_id = None if 'user_id' in params: user_id = params["user_id"][0] try: sqlalchemy_api.authorize_project_context(context, id) return self._format_quota_set( id, self._get_quotas(context, id, user_id, remaining)) except exception.NotAuthorized: raise webob.exc.HTTPForbidden()
def show(self, req, id): context = req.environ['nova.context'] authorize_action(context, 'show') params = self._request_params(req) remaining = False if 'remaining' in params: remaining = utils.bool_from_str(params["remaining"][0]) user_id = None if 'user_id' in params: user_id = params["user_id"][0] try: sqlalchemy_api.authorize_project_context(context, id) return self._format_quota_set(id, self._get_quotas(context, id, user_id, remaining)) except exception.NotAuthorized: raise webob.exc.HTTPForbidden()
def _GET_images(self, req, res, body): images = self._extract_resource_from_body( res, body, singular='image', singular_template=ImageDiskConfigTemplate(), plural='images', plural_template=ImagesDiskConfigTemplate()) for image in images: metadata = image['metadata'] if self.INTERNAL_DISK_CONFIG in metadata: raw_value = metadata[self.INTERNAL_DISK_CONFIG] value = utils.bool_from_str(raw_value) image[self.API_DISK_CONFIG] = disk_config_to_api(value) return res
def update(self, req, id, body): """Update server then pass on to version-specific controller""" if len(req.body) == 0: raise exc.HTTPUnprocessableEntity() if not body: 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'] self._validate_access_ipv4(access_ipv4) update_dict['access_ip_v4'] = access_ipv4.strip() if 'accessIPv6' in body['server']: access_ipv6 = body['server']['accessIPv6'] self._validate_access_ipv6(access_ipv6) update_dict['access_ip_v6'] = access_ipv6.strip() if 'auto_disk_config' in body['server']: auto_disk_config = utils.bool_from_str( body['server']['auto_disk_config']) update_dict['auto_disk_config'] = auto_disk_config instance = self.compute_api.routing_get(ctxt, id) try: self.compute_api.update(ctxt, instance, **update_dict) except exception.NotFound: raise exc.HTTPNotFound() instance.update(update_dict) self._add_instance_faults(ctxt, [instance]) return self._view_builder.show(req, instance)
def _items(self, req, is_detail): """Returns a list of servers for a given user. builder - the response model builder """ query_str = req.str_GET reservation_id = query_str.get("reservation_id") project_id = query_str.get("project_id") fixed_ip = query_str.get("fixed_ip") recurse_zones = utils.bool_from_str(query_str.get("recurse_zones")) instance_list = self.compute_api.get_all( req.environ["nova.context"], reservation_id=reservation_id, project_id=project_id, fixed_ip=fixed_ip, recurse_zones=recurse_zones, ) limited_list = self._limit_items(instance_list, req) servers = [self._build_view(req, inst, is_detail)["server"] for inst in limited_list] return dict(servers=servers)
def _items(self, req, is_detail): """Returns a list of servers for a given user. builder - the response model builder """ query_str = req.str_GET reservation_id = query_str.get('reservation_id') project_id = query_str.get('project_id') fixed_ip = query_str.get('fixed_ip') recurse_zones = utils.bool_from_str(query_str.get('recurse_zones')) instance_list = self.compute_api.get_all(req.environ['nova.context'], reservation_id=reservation_id, project_id=project_id, fixed_ip=fixed_ip, recurse_zones=recurse_zones) limited_list = self._limit_items(instance_list, req) servers = [ self._build_view(req, inst, is_detail)['server'] for inst in limited_list ] return dict(servers=servers)
def test_bool_from_str(self): self.assertTrue(utils.bool_from_str("1")) self.assertTrue(utils.bool_from_str("2")) self.assertTrue(utils.bool_from_str("-1")) self.assertTrue(utils.bool_from_str("true")) self.assertTrue(utils.bool_from_str("True")) self.assertTrue(utils.bool_from_str("tRuE")) self.assertTrue(utils.bool_from_str("yes")) self.assertTrue(utils.bool_from_str("Yes")) self.assertTrue(utils.bool_from_str("YeS")) self.assertTrue(utils.bool_from_str("y")) self.assertTrue(utils.bool_from_str("Y")) self.assertFalse(utils.bool_from_str("False")) self.assertFalse(utils.bool_from_str("false")) self.assertFalse(utils.bool_from_str("no")) self.assertFalse(utils.bool_from_str("No")) self.assertFalse(utils.bool_from_str("n")) self.assertFalse(utils.bool_from_str("N")) self.assertFalse(utils.bool_from_str("0")) self.assertFalse(utils.bool_from_str(None)) self.assertFalse(utils.bool_from_str("junk"))
def test_bool_from_str(self): self.assertTrue(utils.bool_from_str('1')) self.assertTrue(utils.bool_from_str('2')) self.assertTrue(utils.bool_from_str('-1')) self.assertTrue(utils.bool_from_str('true')) self.assertTrue(utils.bool_from_str('True')) self.assertTrue(utils.bool_from_str('tRuE')) self.assertFalse(utils.bool_from_str('False')) self.assertFalse(utils.bool_from_str('false')) self.assertFalse(utils.bool_from_str('0')) self.assertFalse(utils.bool_from_str(None)) self.assertFalse(utils.bool_from_str('junk'))
def create(name, memory, vcpus, root_gb, ephemeral_gb=None, flavorid=None, swap=None, rxtx_factor=None, is_public=True): """Creates instance types.""" if flavorid is None: flavorid = uuid.uuid4() if swap is None: swap = 0 if rxtx_factor is None: rxtx_factor = 1.0 if ephemeral_gb is None: ephemeral_gb = 0 kwargs = { 'memory_mb': memory, 'vcpus': vcpus, 'root_gb': root_gb, 'ephemeral_gb': ephemeral_gb, 'swap': swap, 'rxtx_factor': rxtx_factor, } # ensure name does not contain any special characters invalid_name = INVALID_NAME_REGEX.search(name) if invalid_name: msg = _("names can only contain [a-zA-Z0-9_.- ]") raise exception.InvalidInput(reason=msg) # ensure some attributes are integers and greater than or equal to 0 for option in ['memory_mb', 'vcpus', 'root_gb', 'ephemeral_gb', 'swap']: try: kwargs[option] = int(kwargs[option]) assert kwargs[option] >= 0 except (ValueError, AssertionError): msg = _("'%s' argument must be a positive integer") % option raise exception.InvalidInput(reason=msg) # rxtx_factor should be a positive float try: kwargs['rxtx_factor'] = float(kwargs['rxtx_factor']) assert kwargs['rxtx_factor'] > 0 except (ValueError, AssertionError): msg = _("'rxtx_factor' argument must be a positive float") raise exception.InvalidInput(reason=msg) # some value are required to be nonzero, not just positive for option in ['memory_mb', 'vcpus']: try: assert kwargs[option] > 0 except AssertionError: msg = _("'%s' argument must be greater than 0") % option raise exception.InvalidInput(reason=msg) kwargs['name'] = name # NOTE(vish): Internally, flavorid is stored as a string but it comes # in through json as an integer, so we convert it here. kwargs['flavorid'] = unicode(flavorid) # ensure is_public attribute is boolean if not utils.is_valid_boolstr(is_public): msg = _("is_public must be a boolean") raise exception.InvalidInput(reason=msg) kwargs['is_public'] = utils.bool_from_str(is_public) try: return db.instance_type_create(context.get_admin_context(), kwargs) except exception.DBError, e: LOG.exception(_('DB error: %s') % e) raise exception.InstanceTypeCreateFailed()
def create(name, memory, vcpus, root_gb, ephemeral_gb=None, flavorid=None, swap=None, rxtx_factor=None, is_public=True): """Creates instance types.""" if flavorid is None: flavorid = uuid.uuid4() if swap is None: swap = 0 if rxtx_factor is None: rxtx_factor = 1.0 if ephemeral_gb is None: ephemeral_gb = 0 kwargs = { "memory_mb": memory, "vcpus": vcpus, "root_gb": root_gb, "ephemeral_gb": ephemeral_gb, "swap": swap, "rxtx_factor": rxtx_factor, } # ensure name does not contain any special characters invalid_name = INVALID_NAME_REGEX.search(name) if invalid_name: msg = _("names can only contain [a-zA-Z0-9_.- ]") raise exception.InvalidInput(reason=msg) # ensure some attributes are integers and greater than or equal to 0 for option in ["memory_mb", "vcpus", "root_gb", "ephemeral_gb", "swap"]: try: kwargs[option] = int(kwargs[option]) assert kwargs[option] >= 0 except (ValueError, AssertionError): msg = _("'%s' argument must be a positive integer") % option raise exception.InvalidInput(reason=msg) # rxtx_factor should be a positive float try: kwargs["rxtx_factor"] = float(kwargs["rxtx_factor"]) assert kwargs["rxtx_factor"] > 0 except (ValueError, AssertionError): msg = _("'rxtx_factor' argument must be a positive float") raise exception.InvalidInput(reason=msg) # some value are required to be nonzero, not just positive for option in ["memory_mb", "vcpus"]: try: assert kwargs[option] > 0 except AssertionError: msg = _("'%s' argument must be greater than 0") % option raise exception.InvalidInput(reason=msg) kwargs["name"] = name # NOTE(vish): Internally, flavorid is stored as a string but it comes # in through json as an integer, so we convert it here. kwargs["flavorid"] = unicode(flavorid) # ensure is_public attribute is boolean if not utils.is_valid_boolstr(is_public): msg = _("is_public must be a boolean") raise exception.InvalidInput(reason=msg) kwargs["is_public"] = utils.bool_from_str(is_public) try: return db.instance_type_create(context.get_admin_context(), kwargs) except exception.DBError, e: LOG.exception(_("DB error: %s") % e) raise exception.InstanceTypeCreateFailed()
def test_bool_from_str(self): self.assertTrue(utils.bool_from_str('1')) self.assertTrue(utils.bool_from_str('2')) self.assertTrue(utils.bool_from_str('-1')) self.assertTrue(utils.bool_from_str('true')) self.assertTrue(utils.bool_from_str('True')) self.assertTrue(utils.bool_from_str('tRuE')) self.assertTrue(utils.bool_from_str('yes')) self.assertTrue(utils.bool_from_str('Yes')) self.assertTrue(utils.bool_from_str('YeS')) self.assertTrue(utils.bool_from_str('y')) self.assertTrue(utils.bool_from_str('Y')) self.assertFalse(utils.bool_from_str('False')) self.assertFalse(utils.bool_from_str('false')) self.assertFalse(utils.bool_from_str('no')) self.assertFalse(utils.bool_from_str('No')) self.assertFalse(utils.bool_from_str('n')) self.assertFalse(utils.bool_from_str('N')) self.assertFalse(utils.bool_from_str('0')) self.assertFalse(utils.bool_from_str(None)) self.assertFalse(utils.bool_from_str('junk'))