def update(self, req, id, body): """Add or modify domain entry.""" context = req.environ['nova.context'] authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. nova_context.require_admin_context(context) fqdomain = _unquote_domain(id) try: entry = body['domain_entry'] scope = entry['scope'] except (TypeError, KeyError): raise webob.exc.HTTPUnprocessableEntity() project = entry.get('project', None) av_zone = entry.get('availability_zone', None) if (scope not in ('private', 'public') or project and av_zone or scope == 'private' and project or scope == 'public' and av_zone): raise webob.exc.HTTPUnprocessableEntity() if scope == 'private': create_dns_domain = self.network_api.create_private_dns_domain area_name, area = 'availability_zone', av_zone else: create_dns_domain = self.network_api.create_public_dns_domain area_name, area = 'project', project try: create_dns_domain(context, fqdomain, area) except NotImplementedError: msg = _("Unable to create dns domain") raise webob.exc.HTTPNotImplemented(explanation=msg) return _translate_domain_entry_view({'domain': fqdomain, 'scope': scope, area_name: area})
def update(self, req, id, body): """Update a child cell entry. 'id' is the cell name to update.""" context = req.environ['nova.context'] authorize(context) authorize(context, action="update") # NOTE(eliqiao): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) if 'cell' not in body: msg = _("No cell information in request") raise exc.HTTPBadRequest(explanation=msg) cell = body['cell'] cell.pop('id', None) if 'name' in cell: self._validate_cell_name(cell['name']) try: # NOTE(Vek): There is a race condition here if multiple # callers are trying to update the cell # information simultaneously. Since this # operation is administrative in nature, and # will be going away in the future, I don't see # it as much of a problem... existing = self.cells_rpcapi.cell_get(context, id) except exception.CellNotFound: raise exc.HTTPNotFound() self._normalize_cell(cell, existing) try: cell = self.cells_rpcapi.cell_update(context, id, cell) except exception.CellNotFound: raise exc.HTTPNotFound() except exception.CellsUpdateUnsupported as e: raise exc.HTTPForbidden(explanation=e.format_message()) return dict(cell=_scrub_cell(cell))
def _get_floating_ip_info(self, context, host=None): floating_ip_info = {"floating_ip_info": []} # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. nova_context.require_admin_context(context) if host is None: try: floating_ips = objects.FloatingIPList.get_all(context) except exception.NoFloatingIpsDefined: return floating_ip_info else: try: floating_ips = objects.FloatingIPList.get_by_host(context, host) except exception.FloatingIpNotFoundForHost as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) for floating_ip in floating_ips: instance_uuid = None fixed_ip = None if floating_ip.fixed_ip: instance_uuid = floating_ip.fixed_ip.instance_uuid fixed_ip = str(floating_ip.fixed_ip.address) result = {'address': str(floating_ip.address), 'pool': floating_ip.pool, 'interface': floating_ip.interface, 'project_id': floating_ip.project_id, 'instance_uuid': instance_uuid, 'fixed_ip': fixed_ip} floating_ip_info['floating_ip_info'].append(result) return floating_ip_info
def create(self, req, body): context = sg._authorize_context(req) authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. nova_context.require_admin_context(context) sg_rule = self._from_body(body, 'security_group_default_rule') try: values = self._rule_args_to_dict(to_port=sg_rule.get('to_port'), from_port=sg_rule.get('from_port'), ip_protocol=sg_rule.get('ip_protocol'), cidr=sg_rule.get('cidr')) except Exception as exp: raise exc.HTTPBadRequest(explanation=six.text_type(exp)) if values is None: msg = _('Not enough parameters to build a valid rule.') raise exc.HTTPBadRequest(explanation=msg) if self.security_group_api.default_rule_exists(context, values): msg = _('This default rule already exists.') raise exc.HTTPConflict(explanation=msg) security_group_rule = self.security_group_api.add_default_rules( context, [values])[0] fmt_rule = self._format_security_group_default_rule( security_group_rule) return {'security_group_default_rule': fmt_rule}
def _get_services(self, req): api_services = ('nova-osapi_compute', 'nova-ec2', 'nova-metadata') context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks nova_context.require_admin_context(context) services = [ s for s in self.host_api.service_get_all(context, set_zones=True) if s['binary'] not in api_services ] host = '' if 'host' in req.GET: host = req.GET['host'] binary = '' if 'binary' in req.GET: binary = req.GET['binary'] if host: services = [s for s in services if s['host'] == host] if binary: services = [s for s in services if s['binary'] == binary] return services
def servers(self, req, id): context = req.environ['nova.context'] authorize(context) # NOTE(eliqiao): back-compatible with db layer hard-code admin # permission checks. This has to be left only for API v2.0 because # this version has to be stable even if it means that only admins # can call this method while the policy could be changed. nova_context.require_admin_context(context) compute_nodes = self.host_api.compute_node_search_by_hypervisor( context, id) if not compute_nodes: msg = _("No hypervisor matching '%s' could be found.") % id raise webob.exc.HTTPNotFound(explanation=msg) hypervisors = [] for compute_node in compute_nodes: instances = self.host_api.instance_get_all_by_host(context, compute_node.host) service = self.host_api.service_get_by_compute_host( context, compute_node.host) hyp = self._view_hypervisor(compute_node, service, False, instances) hypervisors.append(hyp) return dict(hypervisors=hypervisors)
def index(self, req): """Returns a dict in the format: | {'hosts': [{'host_name': 'some.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'some.other.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'some.celly.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'console1.host.com', | 'service': 'consoleauth', | 'zone': 'internal'}, | {'host_name': 'network1.host.com', | 'service': 'network', | 'zone': 'internal'}, | {'host_name': 'netwwork2.host.com', | 'service': 'network', | 'zone': 'internal'}, | {'host_name': 'compute1.host.com', | 'service': 'compute', | 'zone': 'nova'}, | {'host_name': 'compute2.host.com', | 'service': 'compute', | 'zone': 'nova'}, | {'host_name': 'sched1.host.com', | 'service': 'scheduler', | 'zone': 'internal'}, | {'host_name': 'sched2.host.com', | 'service': 'scheduler', | 'zone': 'internal'}, | {'host_name': 'vol1.host.com', | 'service': 'volume', | 'zone': 'internal'}]} """ context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks nova_context.require_admin_context(context) filters = {'disabled': False} zone = req.GET.get('zone', None) if zone: filters['availability_zone'] = zone services = self.api.service_get_all(context, filters=filters, set_zones=True) hosts = [] api_services = ('nova-osapi_compute', 'nova-ec2', 'nova-metadata') for service in services: if service.binary not in api_services: hosts.append({'host_name': service['host'], 'service': service['topic'], 'zone': service['availability_zone']}) return {'hosts': hosts}
def detail(self, req): """Returns a detailed list of availability zone.""" context = req.environ['nova.context'] authorize_detail(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) return self._describe_availability_zones_verbose(context)
def update(self, req, id, body): """Updates a specified body. :param body: example format {'status': 'enable', 'maintenance_mode': 'enable'} """ def read_enabled(orig_val, msg): """Checks a specified orig_val and returns True for 'enabled' and False for 'disabled'. :param orig_val: A string with either 'enable' or 'disable'. May be surrounded by whitespace, and case doesn't matter :param msg: The message to be passed to HTTPBadRequest. A single %s will be replaced with orig_val. """ val = orig_val.strip().lower() if val == "enable": return True elif val == "disable": return False else: raise webob.exc.HTTPBadRequest(explanation=msg % orig_val) context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. This has to be left only for API v2.0 because # this version has to be stable even if it means that only admins # can call this method while the policy could be changed. nova_context.require_admin_context(context) # See what the user wants to 'update' params = {k.strip().lower(): v for k, v in six.iteritems(body)} orig_status = status = params.pop('status', None) orig_maint_mode = maint_mode = params.pop('maintenance_mode', None) # Validate the request if len(params) > 0: # Some extra param was passed. Fail. explanation = _("Invalid update setting: '%s'") % list( params.keys())[0] raise webob.exc.HTTPBadRequest(explanation=explanation) if orig_status is not None: status = read_enabled(orig_status, _("Invalid status: '%s'")) if orig_maint_mode is not None: maint_mode = read_enabled(orig_maint_mode, _("Invalid mode: '%s'")) if status is None and maint_mode is None: explanation = _("'status' or 'maintenance_mode' needed for " "host update") raise webob.exc.HTTPBadRequest(explanation=explanation) # Make the calls and merge the results result = {'host': id} if status is not None: result['status'] = self._set_enabled_status(context, id, status) if maint_mode is not None: result['maintenance_mode'] = self._set_host_maintenance(context, id, maint_mode) return result
def index(self, req): """Return all migrations in progress.""" context = req.environ['nova.context'] authorize(context, "index") # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) migrations = self.compute_api.get_migrations(context, req.GET) return {'migrations': output(migrations)}
def _create(self, req, body): context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) if not self.is_valid_body(body, 'flavor'): msg = _("Invalid request body") raise webob.exc.HTTPBadRequest(explanation=msg) vals = body['flavor'] name = vals.get('name') if name is None: msg = _("A valid name parameter is required") raise webob.exc.HTTPBadRequest(explanation=msg) flavorid = vals.get('id') memory = vals.get('ram') if memory is None: msg = _("A valid ram parameter is required") raise webob.exc.HTTPBadRequest(explanation=msg) vcpus = vals.get('vcpus') if vcpus is None: msg = _("A valid vcpus parameter is required") raise webob.exc.HTTPBadRequest(explanation=msg) root_gb = vals.get('disk') if root_gb is None: msg = _("A valid disk parameter is required") raise webob.exc.HTTPBadRequest(explanation=msg) ephemeral_gb = vals.get('OS-FLV-EXT-DATA:ephemeral', 0) swap = vals.get('swap', 0) rxtx_factor = vals.get('rxtx_factor', 1.0) is_public = vals.get('os-flavor-access:is_public', True) try: flavor = flavors.create(name, memory, vcpus, root_gb, ephemeral_gb=ephemeral_gb, flavorid=flavorid, swap=swap, rxtx_factor=rxtx_factor, is_public=is_public) req.cache_db_flavor(flavor) except (exception.FlavorExists, exception.FlavorIdExists) as err: raise webob.exc.HTTPConflict(explanation=err.format_message()) except exception.InvalidInput as exc: raise webob.exc.HTTPBadRequest(explanation=exc.format_message()) except exception.FlavorCreateFailed as exc: raise webob.exc.HTTPInternalServerError(explanation= exc.format_message()) return self._view_builder.show(req, flavor)
def update(self, req, id, body): """Enable/Disable scheduling for a service.""" context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks nova_context.require_admin_context(context) ext_loaded = self.ext_mgr.is_loaded('os-extended-services') if id == "enable": disabled = False status = "enabled" elif (id == "disable" or (id == "disable-log-reason" and ext_loaded)): disabled = True status = "disabled" else: msg = _("Unknown action") raise webob.exc.HTTPNotFound(explanation=msg) try: host = body['host'] binary = body['binary'] ret_value = { 'service': { 'host': host, 'binary': binary, 'status': status, }, } status_detail = { 'disabled': disabled, 'disabled_reason': None, } if id == "disable-log-reason": reason = body['disabled_reason'] if not self._is_valid_as_reason(reason): msg = _('The string containing the reason for disabling ' 'the service contains invalid characters or is ' 'too long.') raise webob.exc.HTTPBadRequest(explanation=msg) status_detail['disabled_reason'] = reason ret_value['service']['disabled_reason'] = reason except (TypeError, KeyError): msg = _('Invalid attribute in the request') if 'host' in body and 'binary' in body: msg = _('Missing disabled reason field') raise webob.exc.HTTPBadRequest(explanation=msg) try: self.host_api.service_update(context, host, binary, status_detail) except exception.HostBinaryNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) return ret_value
def delete(self, req, id): """Deletes an existing agent build.""" context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) try: agent = objects.Agent(context=context, id=id) agent.destroy() except exception.AgentBuildNotFound as ex: raise webob.exc.HTTPNotFound(explanation=ex.format_message())
def create(self, req, body): context = req.environ["nova.context"] authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. call db API objects.Network.create nova_context.require_admin_context(context) def bad(e): return exc.HTTPBadRequest(explanation=e) if not (body and body.get("network")): raise bad(_("Missing network in body")) params = body["network"] if not params.get("label"): raise bad(_("Network label is required")) cidr = params.get("cidr") or params.get("cidr_v6") if not cidr: raise bad(_("Network cidr or cidr_v6 is required")) if params.get("project_id") == "": params["project_id"] = None params["num_networks"] = 1 try: params["network_size"] = netaddr.IPNetwork(cidr).size except netaddr.AddrFormatError: msg = _("%s is not a valid ip network") % cidr raise exc.HTTPBadRequest(explanation=msg) if not self.extended: create_params = ("allowed_start", "allowed_end") for field in extended_fields + create_params: if field in params: del params[field] try: network = self.network_api.create(context, **params)[0] except ( exception.InvalidCidr, exception.InvalidIntValue, exception.InvalidAddress, exception.NetworkNotCreated, ) as ex: raise exc.HTTPBadRequest(explanation=ex.format_message) except exception.CidrConflict as ex: raise exc.HTTPConflict(explanation=ex.format_message()) return {"network": network_dict(context, network, self.extended)}
def _disassociate_host_and_project(self, req, id, body): context = req.environ["nova.context"] authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. call db API objects.Network.associate nova_context.require_admin_context(context) try: self.network_api.associate(context, id, host=None, project=None) except exception.NetworkNotFound: msg = _("Network not found") raise exc.HTTPNotFound(explanation=msg) except NotImplementedError: msg = _("Disassociate network is not implemented by the " "configured Network API") raise exc.HTTPNotImplemented(explanation=msg) return webob.Response(status_int=202)
def index(self, req, flavor_id): context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) flavor = common.get_flavor(context, flavor_id) # public flavor to all projects if flavor.is_public: explanation = _("Access list not available for public flavors.") raise webob.exc.HTTPNotFound(explanation=explanation) # private flavor to listed projects only return _marshall_flavor_access(flavor)
def delete(self, req, id): """Deletes the specified service.""" if not self.ext_mgr.is_loaded('os-extended-services-delete'): raise webob.exc.HTTPMethodNotAllowed() context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks nova_context.require_admin_context(context) try: self.host_api.service_delete(context, id) except exception.ServiceNotFound: explanation = _("Service %s not found.") % id raise webob.exc.HTTPNotFound(explanation=explanation)
def _delete(self, req, id): context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) try: flavor = flavors.get_flavor_by_flavor_id( id, ctxt=context, read_deleted="no") except exception.FlavorNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) flavors.destroy(flavor['name']) return webob.Response(status_int=202)
def delete(self, req, id): """Delete a child or parent cell entry. 'id' is a cell name.""" context = req.environ['nova.context'] authorize(context) authorize(context, action="delete") # NOTE(eliqiao): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) try: num_deleted = self.cells_rpcapi.cell_delete(context, id) except exception.CellsUpdateUnsupported as e: raise exc.HTTPForbidden(explanation=e.format_message()) if num_deleted == 0: raise exc.HTTPNotFound() return {}
def index(self, req): context = req.environ['nova.context'] authorize(context) # NOTE(eliqiao): back-compatible with db layer hard-code admin # permission checks. This has to be left only for API v2.0 because # this version has to be stable even if it means that only admins # can call this method while the policy could be changed. nova_context.require_admin_context(context) compute_nodes = self.host_api.compute_node_get_all(context) req.cache_db_compute_nodes(compute_nodes) return dict(hypervisors=[self._view_hypervisor( hyp, self.host_api.service_get_by_compute_host( context, hyp.host), False) for hyp in compute_nodes])
def update(self, req, id, body): """Update an existing agent build.""" context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) try: para = body['para'] url = para['url'] md5hash = para['md5hash'] version = para['version'] except (TypeError, KeyError) as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) try: utils.check_string_length(url, 'url', max_length=255) utils.check_string_length(md5hash, 'md5hash', max_length=255) utils.check_string_length(version, 'version', max_length=255) except exception.InvalidInput as exc: raise webob.exc.HTTPBadRequest(explanation=exc.format_message()) try: agent = objects.Agent(context=context, id=id) agent.obj_reset_changes() agent.version = version agent.url = url agent.md5hash = md5hash agent.save() except ValueError as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) except exception.AgentBuildNotFound as ex: raise webob.exc.HTTPNotFound(explanation=ex.format_message()) # NOTE(alex_xu): The agent_id should be integer that consistent with # create/index actions. But parameter 'id' is string type that parsed # from url. This is a bug, but because back-compatibility, it can't be # fixed for v2 API. This will be fixed after v3 API feature exposed by # micro-version in the future. lp bug #1333494 return {"agent": {'agent_id': id, 'version': version, 'url': url, 'md5hash': md5hash}}
def delete(self, req, id): context = sg._authorize_context(req) authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. nova_context.require_admin_context(context) try: id = self.security_group_api.validate_id(id) except exception.Invalid as ex: raise exc.HTTPBadRequest(explanation=ex.format_message()) try: rule = self.security_group_api.get_default_rule(context, id) self.security_group_api.remove_default_rules(context, [rule['id']]) except exception.SecurityGroupDefaultRuleNotFound as ex: raise exc.HTTPNotFound(explanation=ex.format_message()) return webob.Response(status_int=204)
def delete(self, req, id): """Delete the domain identified by id.""" context = req.environ['nova.context'] authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. nova_context.require_admin_context(context) domain = _unquote_domain(id) # Delete the whole domain try: self.network_api.delete_dns_domain(context, domain) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) except NotImplementedError: msg = _("Unable to delete dns domain") raise webob.exc.HTTPNotImplemented(explanation=msg) return webob.Response(status_int=202)
def create(self, req, body): """Creates a new agent build.""" context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) try: agent = body['agent'] hypervisor = agent['hypervisor'] os = agent['os'] architecture = agent['architecture'] version = agent['version'] url = agent['url'] md5hash = agent['md5hash'] except (TypeError, KeyError) as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) try: utils.check_string_length(hypervisor, 'hypervisor', max_length=255) utils.check_string_length(os, 'os', max_length=255) utils.check_string_length(architecture, 'architecture', max_length=255) utils.check_string_length(version, 'version', max_length=255) utils.check_string_length(url, 'url', max_length=255) utils.check_string_length(md5hash, 'md5hash', max_length=255) except exception.InvalidInput as exc: raise webob.exc.HTTPBadRequest(explanation=exc.format_message()) try: agent_obj = objects.Agent(context=context) agent_obj.hypervisor = hypervisor agent_obj.os = os agent_obj.architecture = architecture agent_obj.version = version agent_obj.url = url agent_obj.md5hash = md5hash agent_obj.create() agent['agent_id'] = agent_obj.id except exception.AgentBuildExists as ex: raise webob.exc.HTTPConflict(explanation=ex.format_message()) return {'agent': agent}
def _host_power_action(self, req, host_name, action): """Reboots, shuts down or powers up the host.""" context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. This has to be left only for API v2.0 because # this version has to be stable even if it means that only admins # can call this method while the policy could be changed. nova_context.require_admin_context(context) try: result = self.api.host_power_action(context, host_name=host_name, action=action) except NotImplementedError: msg = _("Virt driver does not implement host power management.") raise webob.exc.HTTPNotImplemented(explanation=msg) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) except exception.ComputeServiceUnavailable as e: raise webob.exc.HTTPBadRequest(explanation=e.format_message()) return {"host": host_name, "power_action": result}
def add(self, req, body): context = req.environ["nova.context"] authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. call db API objects.Network.associate nova_context.require_admin_context(context) if not body: raise exc.HTTPUnprocessableEntity() network_id = body.get("id", None) project_id = context.project_id try: self.network_api.add_network_to_project(context, project_id, network_id) except NotImplementedError: msg = _("VLAN support must be enabled") raise exc.HTTPNotImplemented(explanation=msg) except (exception.NoMoreNetworks, exception.NetworkNotFoundForUUID) as e: raise exc.HTTPBadRequest(explanation=e.format_message()) return webob.Response(status_int=202)
def _removeTenantAccess(self, req, id, body): context = req.environ['nova.context'] authorize(context, action="removeTenantAccess") # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) self._check_body(body) vals = body['removeTenantAccess'] tenant = vals.get('tenant') if not tenant: msg = _("Missing tenant parameter") raise webob.exc.HTTPBadRequest(explanation=msg) flavor = objects.Flavor(context=context, flavorid=id) try: flavor.remove_access(tenant) except (exception.FlavorNotFound, exception.FlavorAccessNotFound) as err: raise webob.exc.HTTPNotFound(explanation=err.format_message()) return _marshall_flavor_access(flavor)
def _get_services(self, req): context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks nova_context.require_admin_context(context) services = self.host_api.service_get_all( context, set_zones=True) host = '' if 'host' in req.GET: host = req.GET['host'] binary = '' if 'binary' in req.GET: binary = req.GET['binary'] if host: services = [s for s in services if s['host'] == host] if binary: services = [s for s in services if s['binary'] == binary] return services
def _remove_host(self, req, id, host): """Removes a host from the specified aggregate.""" context = _get_context(req) authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. This has to be left only for API v2.0 because # this version has to be stable even if it means that only admins # can call this method while the policy could be changed. nova_context.require_admin_context(context) try: aggregate = self.api.remove_host_from_aggregate(context, id, host) except (exception.AggregateNotFound, exception.AggregateHostNotFound, exception.ComputeHostNotFound): msg = _('Cannot remove host %(host)s in aggregate' ' %(id)s: not found') % {'host': host, 'id': id} raise exc.HTTPNotFound(explanation=msg) except exception.InvalidAggregateAction: msg = _('Cannot remove host %(host)s in aggregate' ' %(id)s: invalid') % {'host': host, 'id': id} raise exc.HTTPConflict(explanation=msg) return self._marshall_aggregate(aggregate)
def add(self, req, body): context = req.environ['nova.context'] authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. call db API objects.Network.associate nova_context.require_admin_context(context) if not body: raise exc.HTTPUnprocessableEntity() network_id = body.get('id', None) project_id = context.project_id try: self.network_api.add_network_to_project(context, project_id, network_id) except NotImplementedError: msg = (_("VLAN support must be enabled")) raise exc.HTTPNotImplemented(explanation=msg) except (exception.NoMoreNetworks, exception.NetworkNotFoundForUUID) as e: raise exc.HTTPBadRequest(explanation=e.format_message()) return webob.Response(status_int=202)
def index(self, req): """Return a list of all agent builds. Filter by hypervisor.""" context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) hypervisor = None agents = [] if 'hypervisor' in req.GET: hypervisor = req.GET['hypervisor'] builds = objects.AgentList.get_all(context, hypervisor=hypervisor) for agent_build in builds: agents.append({'hypervisor': agent_build.hypervisor, 'os': agent_build.os, 'architecture': agent_build.architecture, 'version': agent_build.version, 'md5hash': agent_build.md5hash, 'agent_id': agent_build.id, 'url': agent_build.url}) return {'agents': agents}
def _addTenantAccess(self, req, id, body): context = req.environ['nova.context'] authorize(context, action="addTenantAccess") # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) self._check_body(body) vals = body['addTenantAccess'] tenant = vals.get('tenant') if not tenant: msg = _("Missing tenant parameter") raise webob.exc.HTTPBadRequest(explanation=msg) flavor = objects.Flavor(context=context, flavorid=id) try: flavor.add_access(tenant) except exception.FlavorAccessExists as err: raise webob.exc.HTTPConflict(explanation=err.format_message()) except exception.FlavorNotFound as err: raise webob.exc.HTTPNotFound(explanation=err.format_message()) return _marshall_flavor_access(flavor)
def show(self, req, id): """Shows the physical/usage resource given by hosts. :param id: hostname :returns: expected to use HostShowTemplate. ex.:: {'host': {'resource':D},..} D: {'host': 'hostname','project': 'admin', 'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30} """ context = req.environ['nova.context'] # NOTE(eliqiao): back-compatible with db layer hard-code admin # permission checks. This has to be left only for API v2.0 because # this version has to be stable even if it means that only admins # can call this method while the policy could be changed. nova_context.require_admin_context(context) host_name = id try: compute_node = ( objects.ComputeNode.get_first_node_by_host_for_old_compat( context, host_name)) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) instances = self.api.instance_get_all_by_host(context, host_name) resources = [self._get_total_resources(host_name, compute_node)] resources.append(self._get_used_now_resources(host_name, compute_node)) resources.append(self._get_resource_totals_from_instances(host_name, instances)) by_proj_resources = self._get_resources_by_project(host_name, instances) for resource in six.itervalues(by_proj_resources): resources.append({'resource': resource}) return {'host': resources}
def update(self, req, id, body): """Add or modify domain entry.""" context = req.environ['nova.context'] authorize(context) # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. nova_context.require_admin_context(context) fqdomain = _unquote_domain(id) try: entry = body['domain_entry'] scope = entry['scope'] except (TypeError, KeyError): raise webob.exc.HTTPUnprocessableEntity() project = entry.get('project', None) av_zone = entry.get('availability_zone', None) if (scope not in ('private', 'public') or project and av_zone or scope == 'private' and project or scope == 'public' and av_zone): raise webob.exc.HTTPUnprocessableEntity() if scope == 'private': create_dns_domain = self.network_api.create_private_dns_domain area_name, area = 'availability_zone', av_zone else: create_dns_domain = self.network_api.create_public_dns_domain area_name, area = 'project', project try: create_dns_domain(context, fqdomain, area) except NotImplementedError: msg = _("Unable to create dns domain") raise webob.exc.HTTPNotImplemented(explanation=msg) return _translate_domain_entry_view({ 'domain': fqdomain, 'scope': scope, area_name: area })
def create(self, req, body): """Create a child cell entry.""" context = req.environ['nova.context'] authorize(context) authorize(context, action="create") # NOTE(eliqiao): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) if 'cell' not in body: msg = _("No cell information in request") raise exc.HTTPBadRequest(explanation=msg) cell = body['cell'] if 'name' not in cell: msg = _("No cell name in request") raise exc.HTTPBadRequest(explanation=msg) self._validate_cell_name(cell['name']) self._normalize_cell(cell) try: cell = self.cells_rpcapi.cell_create(context, cell) except exception.CellsUpdateUnsupported as e: raise exc.HTTPForbidden(explanation=e.format_message()) return dict(cell=_scrub_cell(cell))
def _get_floating_ip_info(self, context, host=None): floating_ip_info = {"floating_ip_info": []} # NOTE(shaohe-feng): back-compatible with db layer hard-code # admin permission checks. nova_context.require_admin_context(context) if host is None: try: floating_ips = objects.FloatingIPList.get_all(context) except exception.NoFloatingIpsDefined: return floating_ip_info else: try: floating_ips = objects.FloatingIPList.get_by_host( context, host) except exception.FloatingIpNotFoundForHost as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) for floating_ip in floating_ips: instance_uuid = None fixed_ip = None if floating_ip.fixed_ip: instance_uuid = floating_ip.fixed_ip.instance_uuid fixed_ip = str(floating_ip.fixed_ip.address) result = { 'address': str(floating_ip.address), 'pool': floating_ip.pool, 'interface': floating_ip.interface, 'project_id': floating_ip.project_id, 'instance_uuid': instance_uuid, 'fixed_ip': fixed_ip } floating_ip_info['floating_ip_info'].append(result) return floating_ip_info
def index(self, req): """Returns a dict in the format: | {'hosts': [{'host_name': 'some.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'some.other.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'some.celly.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'console1.host.com', | 'service': 'consoleauth', | 'zone': 'internal'}, | {'host_name': 'network1.host.com', | 'service': 'network', | 'zone': 'internal'}, | {'host_name': 'netwwork2.host.com', | 'service': 'network', | 'zone': 'internal'}, | {'host_name': 'compute1.host.com', | 'service': 'compute', | 'zone': 'nova'}, | {'host_name': 'compute2.host.com', | 'service': 'compute', | 'zone': 'nova'}, | {'host_name': 'sched1.host.com', | 'service': 'scheduler', | 'zone': 'internal'}, | {'host_name': 'sched2.host.com', | 'service': 'scheduler', | 'zone': 'internal'}, | {'host_name': 'vol1.host.com', | 'service': 'volume', | 'zone': 'internal'}]} """ context = req.environ['nova.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks nova_context.require_admin_context(context) filters = {'disabled': False} zone = req.GET.get('zone', None) if zone: filters['availability_zone'] = zone services = self.api.service_get_all(context, filters=filters, set_zones=True) hosts = [] api_services = ('nova-osapi_compute', 'nova-ec2', 'nova-metadata') for service in services: if service.binary not in api_services: hosts.append({ 'host_name': service['host'], 'service': service['topic'], 'zone': service['availability_zone'] }) return {'hosts': hosts}
def _evacuate(self, req, id, body): """Permit admins to evacuate a server from a failed host to a new one. If host is empty, the scheduler will select one. """ context = req.environ["nova.context"] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. This has to be left only for API v2.0 because # this version has to be stable even if it means that only admins # can call this method while the policy could be changed. nova_context.require_admin_context(context) if not self.is_valid_body(body, "evacuate"): raise exc.HTTPBadRequest(_("Malformed request body")) evacuate_body = body["evacuate"] host = evacuate_body.get("host") if (not host and not self.ext_mgr.is_loaded('os-extended-evacuate-find-host')): msg = _("host must be specified.") raise exc.HTTPBadRequest(explanation=msg) try: on_shared_storage = strutils.bool_from_string( evacuate_body["onSharedStorage"]) except (TypeError, KeyError): msg = _("onSharedStorage must be specified.") raise exc.HTTPBadRequest(explanation=msg) 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) try: if instance.host == host: msg = _("The target host can't be the same one.") raise exc.HTTPBadRequest(explanation=msg) 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.InstanceNotFound as e: raise exc.HTTPNotFound(explanation=e.format_message()) except exception.ComputeServiceInUse as e: raise exc.HTTPBadRequest(explanation=e.format_message()) if password: return {'adminPass': password}
def _get_audit_task_logs(self, context, begin=None, end=None, before=None): """Returns a full log for all instance usage audit tasks on all computes. :param begin: datetime beginning of audit period to get logs for, Defaults to the beginning of the most recently completed audit period prior to the 'before' date. :param end: datetime ending of audit period to get logs for, Defaults to the ending of the most recently completed audit period prior to the 'before' date. :param before: By default we look for the audit period most recently completed before this datetime. Has no effect if both begin and end are specified. """ # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) defbegin, defend = utils.last_completed_audit_period(before=before) if begin is None: begin = defbegin if end is None: end = defend task_logs = self.host_api.task_log_get_all(context, "instance_usage_audit", begin, end) # We do this in this way to include disabled compute services, # which can have instances on them. (mdragon) filters = {'topic': CONF.compute_topic} services = self.host_api.service_get_all(context, filters=filters) hosts = set(serv['host'] for serv in services) seen_hosts = set() done_hosts = set() running_hosts = set() total_errors = 0 total_items = 0 for tlog in task_logs: seen_hosts.add(tlog['host']) if tlog['state'] == "DONE": done_hosts.add(tlog['host']) if tlog['state'] == "RUNNING": running_hosts.add(tlog['host']) total_errors += tlog['errors'] total_items += tlog['task_items'] log = { tl['host']: dict(state=tl['state'], instances=tl['task_items'], errors=tl['errors'], message=tl['message']) for tl in task_logs } missing_hosts = hosts - seen_hosts overall_status = "%s hosts done. %s errors." % ( 'ALL' if len(done_hosts) == len(hosts) else "%s of %s" % (len(done_hosts), len(hosts)), total_errors) return dict(period_beginning=str(begin), period_ending=str(end), num_hosts=len(hosts), num_hosts_done=len(done_hosts), num_hosts_running=len(running_hosts), num_hosts_not_run=len(missing_hosts), hosts_not_run=list(missing_hosts), total_instances=total_items, total_errors=total_errors, overall_status=overall_status, log=log)