Exemple #1
0
    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})
Exemple #2
0
    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}
Exemple #5
0
    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
Exemple #6
0
    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)
Exemple #7
0
    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}
Exemple #8
0
 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)
Exemple #9
0
    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
Exemple #10
0
 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)}
Exemple #11
0
    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
Exemple #13
0
 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())
Exemple #14
0
    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)}
Exemple #15
0
    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)
Exemple #16
0
    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)
Exemple #17
0
    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)
Exemple #18
0
    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)
Exemple #19
0
    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 {}
Exemple #20
0
    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])
Exemple #21
0
    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)
Exemple #23
0
    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)
Exemple #24
0
    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}
Exemple #25
0
 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}
Exemple #26
0
    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)
Exemple #27
0
    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)
Exemple #28
0
    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
Exemple #29
0
    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)
Exemple #30
0
    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)
Exemple #31
0
    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}
Exemple #32
0
    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 _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)
Exemple #34
0
    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}
Exemple #35
0
    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
        })
Exemple #36
0
    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
Exemple #38
0
    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}
Exemple #40
0
    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)