Пример #1
0
    def index(self, req, server_id):
        """Returns the list of actions recorded for a given instance."""
        context = req.environ["nova.context"]
        instance = self._get_instance(req, context, server_id)
        context.can(ia_policies.BASE_POLICY_NAME, instance)
        search_opts = {}
        search_opts.update(req.GET)
        if 'changes-since' in search_opts:
            search_opts['changes-since'] = timeutils.parse_isotime(
                search_opts['changes-since'])

        limit, marker = common.get_limit_and_marker(req)
        try:
            actions_raw = self.action_api.actions_get(context, instance,
                                                      limit=limit,
                                                      marker=marker,
                                                      filters=search_opts)
        except exception.MarkerNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        actions = [self._format_action(action, ACTION_KEYS_V258)
                   for action in actions_raw]
        actions_dict = {'instanceActions': actions}
        actions_links = self._view_builder.get_links(req, server_id, actions)
        if actions_links:
            actions_dict['links'] = actions_links
        return actions_dict
Пример #2
0
    def _index(self, req, user_id=None, links=False, **keypair_filters):
        """List of keypairs for a user."""
        context = req.environ['nova.context']
        user_id = user_id or context.user_id
        context.can(kp_policies.POLICY_ROOT % 'index',
                    target={'user_id': user_id,
                            'project_id': context.project_id})

        if api_version_request.is_supported(req, min_version='2.35'):
            limit, marker = common.get_limit_and_marker(req)
        else:
            limit = marker = None

        try:
            key_pairs = self.api.get_key_pairs(
                context, user_id, limit=limit, marker=marker)
        except exception.MarkerNotFound as e:
            raise webob.exc.HTTPBadRequest(explanation=e.format_message())

        key_pairs = [self._filter_keypair(key_pair, **keypair_filters)
                     for key_pair in key_pairs]

        keypairs_list = [{'keypair': key_pair} for key_pair in key_pairs]
        keypairs_dict = {'keypairs': keypairs_list}

        if links:
            keypairs_links = self._view_builder.get_links(req, key_pairs)

            if keypairs_links:
                keypairs_dict['keypairs_links'] = keypairs_links

        return keypairs_dict
Пример #3
0
    def _index(self, req, links=False):
        context = req.environ['nova.context']

        context.can(stu_policies.POLICY_ROOT % 'list')

        try:
            (period_start, period_stop, detailed) = self._get_datetime_range(
                req)
        except exception.InvalidStrTime as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        now = timeutils.parse_isotime(timeutils.utcnow().isoformat())
        if period_stop > now:
            period_stop = now

        marker = None
        limit = CONF.api.max_limit
        if links:
            limit, marker = common.get_limit_and_marker(req)

        try:
            usages, server_usages = self._tenant_usages_for_period(
                context, period_start, period_stop, detailed=detailed,
                limit=limit, marker=marker)
        except exception.MarkerNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        tenant_usages = {'tenant_usages': usages}

        if links:
            usages_links = self._view_builder.get_links(req, server_usages)
            if usages_links:
                tenant_usages['tenant_usages_links'] = usages_links

        return tenant_usages
Пример #4
0
    def _index(self, req, key_type=False, user_id=None, links=False):
        """List of keypairs for a user."""
        context = req.environ['nova.context']
        user_id = user_id or context.user_id
        context.can(kp_policies.POLICY_ROOT % 'index',
                    target={
                        'user_id': user_id,
                        'project_id': context.project_id
                    })

        if api_version_request.is_supported(req, min_version='2.35'):
            limit, marker = common.get_limit_and_marker(req)
        else:
            limit = marker = None

        try:
            key_pairs = self.api.get_key_pairs(context,
                                               user_id,
                                               limit=limit,
                                               marker=marker)
        except exception.MarkerNotFound as e:
            raise webob.exc.HTTPBadRequest(explanation=e.format_message())

        return self._view_builder.index(req,
                                        key_pairs,
                                        key_type=key_type,
                                        links=links)
Пример #5
0
    def _index(self, req, links=False):
        context = req.environ['nova.context']

        context.can(stu_policies.POLICY_ROOT % 'list')

        try:
            (period_start, period_stop, detailed) = self._get_datetime_range(
                req)
        except exception.InvalidStrTime as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        now = timeutils.parse_isotime(timeutils.utcnow().isoformat())
        if period_stop > now:
            period_stop = now

        marker = None
        limit = CONF.api.max_limit
        if links:
            limit, marker = common.get_limit_and_marker(req)

        try:
            usages, server_usages = self._tenant_usages_for_period(
                context, period_start, period_stop, detailed=detailed,
                limit=limit, marker=marker)
        except exception.MarkerNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        tenant_usages = {'tenant_usages': usages}

        if links:
            usages_links = self._view_builder.get_links(req, server_usages)
            if usages_links:
                tenant_usages['tenant_usages_links'] = usages_links

        return tenant_usages
Пример #6
0
    def index(self, req, server_id):
        """Returns the list of actions recorded for a given instance."""
        context = req.environ["nova.context"]
        instance = self._get_instance(req, context, server_id)
        context.can(ia_policies.BASE_POLICY_NAME, instance)
        search_opts = {}
        search_opts.update(req.GET)
        if 'changes-since' in search_opts:
            search_opts['changes-since'] = timeutils.parse_isotime(
                search_opts['changes-since'])

        limit, marker = common.get_limit_and_marker(req)
        try:
            actions_raw = self.action_api.actions_get(context, instance,
                                                      limit=limit,
                                                      marker=marker,
                                                      filters=search_opts)
        except exception.MarkerNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        actions = [self._format_action(action, ACTION_KEYS_V258)
                   for action in actions_raw]
        actions_dict = {'instanceActions': actions}
        actions_links = self._view_builder.get_links(req, server_id, actions)
        if actions_links:
            actions_dict['links'] = actions_links
        return actions_dict
Пример #7
0
 def index(self, req):
     """Return all migrations using the query parameters as filters."""
     limit, marker = common.get_limit_and_marker(req)
     return self._index(req, add_link=True, next_link=True, add_uuid=True,
                        sort_keys=['created_at', 'id'],
                        sort_dirs=['desc', 'desc'],
                        limit=limit, marker=marker,
                        allow_changes_since=True)
Пример #8
0
 def index(self, req):
     """Return all migrations using the query parameters as filters."""
     limit, marker = common.get_limit_and_marker(req)
     return self._index(req, add_link=True, next_link=True, add_uuid=True,
                        sort_keys=['created_at', 'id'],
                        sort_dirs=['desc', 'desc'],
                        limit=limit, marker=marker,
                        allow_changes_since=True)
Пример #9
0
 def detail(self, req):
     """Starting with the 2.53 microversion, the id field in the response
     is the compute_nodes.uuid value. Also, the search and servers routes
     are superseded and replaced with query parameters for listing
     hypervisors by a hostname pattern and whether or not to include
     hosted servers in the response.
     """
     limit, marker = common.get_limit_and_marker(req)
     return self._detail(req, limit=limit, marker=marker, links=True)
Пример #10
0
 def detail(self, req):
     """Starting with the 2.53 microversion, the id field in the response
     is the compute_nodes.uuid value. Also, the search and servers routes
     are superseded and replaced with query parameters for listing
     hypervisors by a hostname pattern and whether or not to include
     hosted servers in the response.
     """
     limit, marker = common.get_limit_and_marker(req)
     return self._detail(req, limit=limit, marker=marker, links=True)
Пример #11
0
    def _show(self, req, id, links=False):
        tenant_id = id
        context = req.environ['nova.context']

        context.can(stu_policies.POLICY_ROOT % 'show',
                    {'project_id': tenant_id})

        try:
            (period_start, period_stop, ignore) = self._get_datetime_range(req)
        except exception.InvalidStrTime as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        now = timeutils.parse_isotime(timeutils.utcnow().isoformat())
        if period_stop > now:
            period_stop = now

        marker = None
        limit = CONF.api.max_limit
        if links:
            limit, marker = common.get_limit_and_marker(req)

        try:
            usage, server_usages = self._tenant_usages_for_period(
                context,
                period_start,
                period_stop,
                tenant_id=tenant_id,
                detailed=True,
                limit=limit,
                marker=marker)
        except exception.MarkerNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if len(usage):
            usage = list(usage)[0]
        else:
            usage = {}

        tenant_usage = {'tenant_usage': usage}

        if links:
            usages_links = self._view_builder.get_links(req,
                                                        server_usages,
                                                        tenant_id=tenant_id)
            if usages_links:
                tenant_usage['tenant_usage_links'] = usages_links

        return tenant_usage
Пример #12
0
    def _get_flavors(self, req):
        """Helper function that returns a list of flavor dicts."""
        filters = {}
        sort_key = req.params.get('sort_key') or 'flavorid'
        sort_dir = req.params.get('sort_dir') or 'asc'
        limit, marker = common.get_limit_and_marker(req)

        context = req.environ['nova.context']
        if context.is_admin:
            # Only admin has query access to all flavor types
            filters['is_public'] = self._parse_is_public(
                req.params.get('is_public', None))
        else:
            filters['is_public'] = True
            filters['disabled'] = False

        if 'minRam' in req.params:
            try:
                filters['min_memory_mb'] = int(req.params['minRam'])
            except ValueError:
                msg = _('Invalid min_ram filter [%s]') % req.params['minRam']
                raise webob.exc.HTTPBadRequest(explanation=msg)

        if 'minDisk' in req.params:
            try:
                filters['min_root_gb'] = int(req.params['minDisk'])
            except ValueError:
                msg = (_('Invalid minDisk filter [%s]') %
                       req.params['minDisk'])
                raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            limited_flavors = flavors.get_all_flavors_sorted_list(
                context,
                filters=filters,
                sort_key=sort_key,
                sort_dir=sort_dir,
                limit=limit,
                marker=marker)
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return limited_flavors
Пример #13
0
    def _show(self, req, id, links=False):
        tenant_id = id
        context = req.environ['nova.context']

        context.can(stu_policies.POLICY_ROOT % 'show',
                    {'project_id': tenant_id})

        try:
            (period_start, period_stop, ignore) = self._get_datetime_range(
                req)
        except exception.InvalidStrTime as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        now = timeutils.parse_isotime(timeutils.utcnow().isoformat())
        if period_stop > now:
            period_stop = now

        marker = None
        limit = CONF.api.max_limit
        if links:
            limit, marker = common.get_limit_and_marker(req)

        try:
            usage, server_usages = self._tenant_usages_for_period(
                context, period_start, period_stop, tenant_id=tenant_id,
                detailed=True, limit=limit, marker=marker)
        except exception.MarkerNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if len(usage):
            usage = list(usage)[0]
        else:
            usage = {}

        tenant_usage = {'tenant_usage': usage}

        if links:
            usages_links = self._view_builder.get_links(
                req, server_usages, tenant_id=tenant_id)
            if usages_links:
                tenant_usage['tenant_usage_links'] = usages_links

        return tenant_usage
Пример #14
0
    def _get_flavors(self, req):
        """Helper function that returns a list of flavor dicts."""
        filters = {}
        sort_key = req.params.get('sort_key') or 'flavorid'
        sort_dir = req.params.get('sort_dir') or 'asc'
        limit, marker = common.get_limit_and_marker(req)

        context = req.environ['nova.context']
        if context.is_admin:
            # Only admin has query access to all flavor types
            filters['is_public'] = self._parse_is_public(
                    req.params.get('is_public', None))
        else:
            filters['is_public'] = True
            filters['disabled'] = False

        if 'minRam' in req.params:
            try:
                filters['min_memory_mb'] = int(req.params['minRam'])
            except ValueError:
                msg = _('Invalid min_ram filter [%s]') % req.params['minRam']
                raise webob.exc.HTTPBadRequest(explanation=msg)

        if 'minDisk' in req.params:
            try:
                filters['min_root_gb'] = int(req.params['minDisk'])
            except ValueError:
                msg = (_('Invalid minDisk filter [%s]') %
                       req.params['minDisk'])
                raise webob.exc.HTTPBadRequest(explanation=msg)

        try:
            limited_flavors = flavors.get_all_flavors_sorted_list(context,
                filters=filters, sort_key=sort_key, sort_dir=sort_dir,
                limit=limit, marker=marker)
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise webob.exc.HTTPBadRequest(explanation=msg)

        return limited_flavors
Пример #15
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ['nova.context']
        remove_invalid_options(context, search_opts,
                               self._get_server_search_options())

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        search_opts.pop('status', None)
        if 'status' in req.GET.keys():
            statuses = req.GET.getall('status')
            states = common.task_and_vm_state_from_status(statuses)
            vm_state, task_state = states
            if not vm_state and not task_state:
                return {'servers': []}
            search_opts['vm_state'] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if 'default' not in task_state:
                search_opts['task_state'] = task_state

        if 'changes-since' in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts['changes-since'])
            except ValueError:
                msg = _('Invalid changes-since value')
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts['changes-since'] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes-since' is specified, because 'changes-since'
        # should return recently deleted images according to the API spec.

        if 'deleted' not in search_opts:
            if 'changes-since' not in search_opts:
                # No 'changes-since', so we only want non-deleted servers
                search_opts['deleted'] = False

        if search_opts.get("vm_state") == ['deleted']:
            if context.is_admin:
                search_opts['deleted'] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPForbidden(explanation=msg)

        # If all tenants is passed with 0 or false as the value
        # then remove it from the search options. Nothing passed as
        # the value for all_tenants is considered to enable the feature
        all_tenants = search_opts.get('all_tenants')
        if all_tenants:
            try:
                if not strutils.bool_from_string(all_tenants, True):
                    del search_opts['all_tenants']
            except ValueError as err:
                raise exception.InvalidInput(six.text_type(err))

        if 'all_tenants' in search_opts:
            policy.enforce(context, 'compute:get_all_tenants', {
                'project_id': context.project_id,
                'user_id': context.user_id
            })
            del search_opts['all_tenants']
        else:
            if context.project_id:
                search_opts['project_id'] = context.project_id
            else:
                search_opts['user_id'] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        # Sorting by multiple keys and directions is conditionally enabled
        sort_keys, sort_dirs = None, None
        if self.ext_mgr.is_loaded('os-server-sort-keys'):
            sort_keys, sort_dirs = common.get_sort_params(req.params)
        try:
            instance_list = self.compute_api.get_all(context,
                                                     search_opts=search_opts,
                                                     limit=limit,
                                                     marker=marker,
                                                     want_objects=True,
                                                     sort_keys=sort_keys,
                                                     sort_dirs=sort_dirs)
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            LOG.debug("Flavor '%s' could not be found", search_opts['flavor'])
            instance_list = objects.InstanceList()

        if is_detail:
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Пример #16
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ['nova.context']
        remove_invalid_options(context, search_opts,
                               self._get_server_search_options())

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        search_opts.pop('status', None)
        if 'status' in req.GET.keys():
            statuses = req.GET.getall('status')
            states = common.task_and_vm_state_from_status(statuses)
            vm_state, task_state = states
            if not vm_state and not task_state:
                return {'servers': []}
            search_opts['vm_state'] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if 'default' not in task_state:
                search_opts['task_state'] = task_state

        if 'changes-since' in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts['changes-since'])
            except ValueError:
                msg = _('Invalid changes-since value')
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts['changes-since'] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes-since' is specified, because 'changes-since'
        # should return recently deleted images according to the API spec.

        if 'deleted' not in search_opts:
            if 'changes-since' not in search_opts:
                # No 'changes-since', so we only want non-deleted servers
                search_opts['deleted'] = False

        if search_opts.get("vm_state") == ['deleted']:
            if context.is_admin:
                search_opts['deleted'] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPForbidden(explanation=msg)

        # If tenant_id is passed as a search parameter this should
        # imply that all_tenants is also enabled unless explicitly
        # disabled. Note that the tenant_id parameter is filtered out
        # by remove_invalid_options above unless the requestor is an
        # admin.

        # TODO(gmann): 'all_tenants' flag should not be required while
        # searching with 'tenant_id'. Ref bug# 1185290
        # +microversions to achieve above mentioned behavior by
        # uncommenting below code.

        # if 'tenant_id' in search_opts and 'all_tenants' not in search_opts:
        # We do not need to add the all_tenants flag if the tenant
        # id associated with the token is the tenant id
        # specified. This is done so a request that does not need
        # the all_tenants flag does not fail because of lack of
        # policy permission for compute:get_all_tenants when it
        # doesn't actually need it.
        # if context.project_id != search_opts.get('tenant_id'):
        #    search_opts['all_tenants'] = 1

        # If all tenants is passed with 0 or false as the value
        # then remove it from the search options. Nothing passed as
        # the value for all_tenants is considered to enable the feature
        all_tenants = search_opts.get('all_tenants')
        if all_tenants:
            try:
                if not strutils.bool_from_string(all_tenants, True):
                    del search_opts['all_tenants']
            except ValueError as err:
                raise exception.InvalidInput(six.text_type(err))

        if 'all_tenants' in search_opts:
            policy.enforce(context, 'compute:get_all_tenants', {
                'project_id': context.project_id,
                'user_id': context.user_id
            })
            del search_opts['all_tenants']
        else:
            if context.project_id:
                search_opts['project_id'] = context.project_id
            else:
                search_opts['user_id'] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        sort_keys, sort_dirs = common.get_sort_params(req.params)
        try:
            instance_list = self.compute_api.get_all(
                context,
                search_opts=search_opts,
                limit=limit,
                marker=marker,
                want_objects=True,
                expected_attrs=['pci_devices'],
                sort_keys=sort_keys,
                sort_dirs=sort_dirs)
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            LOG.debug("Flavor '%s' could not be found ", search_opts['flavor'])
            instance_list = objects.InstanceList()

        if is_detail:
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Пример #17
0
 def index(self, req):
     limit, marker = common.get_limit_and_marker(req)
     return self._index(req, limit=limit, marker=marker, links=True)
Пример #18
0
 def detail(self, req):
     limit, marker = common.get_limit_and_marker(req)
     return self._detail(req, limit=limit, marker=marker, links=True)
Пример #19
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ['nova.context']
        remove_invalid_options(context, search_opts,
                self._get_server_search_options(req))

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        search_opts.pop('status', None)
        if 'status' in req.GET.keys():
            statuses = req.GET.getall('status')
            states = common.task_and_vm_state_from_status(statuses)
            vm_state, task_state = states
            if not vm_state and not task_state:
                return {'servers': []}
            search_opts['vm_state'] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if 'default' not in task_state:
                search_opts['task_state'] = task_state

        if 'changes-since' in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts['changes-since'])
            except ValueError:
                msg = _('Invalid changes-since value')
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts['changes-since'] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes-since' is specified, because 'changes-since'
        # should return recently deleted instances according to the API spec.

        if 'deleted' not in search_opts:
            if 'changes-since' not in search_opts:
                # No 'changes-since', so we only want non-deleted servers
                search_opts['deleted'] = False
        else:
            # Convert deleted filter value to a valid boolean.
            # Return non-deleted servers if an invalid value
            # is passed with deleted filter.
            search_opts['deleted'] = strutils.bool_from_string(
                search_opts['deleted'], default=False)

        if search_opts.get("vm_state") == ['deleted']:
            if context.is_admin:
                search_opts['deleted'] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPForbidden(explanation=msg)

        if api_version_request.is_supported(req, min_version='2.26'):
            for tag_filter in TAG_SEARCH_FILTERS:
                if tag_filter in search_opts:
                    search_opts[tag_filter] = search_opts[
                        tag_filter].split(',')

        # If tenant_id is passed as a search parameter this should
        # imply that all_tenants is also enabled unless explicitly
        # disabled. Note that the tenant_id parameter is filtered out
        # by remove_invalid_options above unless the requestor is an
        # admin.

        # TODO(gmann): 'all_tenants' flag should not be required while
        # searching with 'tenant_id'. Ref bug# 1185290
        # +microversions to achieve above mentioned behavior by
        # uncommenting below code.

        # if 'tenant_id' in search_opts and 'all_tenants' not in search_opts:
            # We do not need to add the all_tenants flag if the tenant
            # id associated with the token is the tenant id
            # specified. This is done so a request that does not need
            # the all_tenants flag does not fail because of lack of
            # policy permission for compute:get_all_tenants when it
            # doesn't actually need it.
            # if context.project_id != search_opts.get('tenant_id'):
            #    search_opts['all_tenants'] = 1

        all_tenants = common.is_all_tenants(search_opts)
        # use the boolean from here on out so remove the entry from search_opts
        # if it's present
        search_opts.pop('all_tenants', None)

        elevated = None
        if all_tenants:
            if is_detail:
                context.can(server_policies.SERVERS % 'detail:get_all_tenants')
            else:
                context.can(server_policies.SERVERS % 'index:get_all_tenants')
            elevated = context.elevated()
        else:
            if context.project_id:
                search_opts['project_id'] = context.project_id
            else:
                search_opts['user_id'] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        sort_keys, sort_dirs = common.get_sort_params(req.params)

        expected_attrs = ['pci_devices']
        if is_detail:
            if api_version_request.is_supported(req, '2.26'):
                expected_attrs.append("tags")

            # merge our expected attrs with what the view builder needs for
            # showing details
            expected_attrs = self._view_builder.get_show_expected_attrs(
                                                                expected_attrs)

        try:
            instance_list = self.compute_api.get_all(elevated or context,
                    search_opts=search_opts, limit=limit, marker=marker,
                    expected_attrs=expected_attrs,
                    sort_keys=sort_keys, sort_dirs=sort_dirs)
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            LOG.debug("Flavor '%s' could not be found ",
                      search_opts['flavor'])
            instance_list = objects.InstanceList()

        if is_detail:
            instance_list._context = context
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Пример #20
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ["nova.context"]
        remove_invalid_options(context, search_opts, self._get_server_search_options(req))

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        search_opts.pop("status", None)
        if "status" in req.GET.keys():
            statuses = req.GET.getall("status")
            states = common.task_and_vm_state_from_status(statuses)
            vm_state, task_state = states
            if not vm_state and not task_state:
                return {"servers": []}
            search_opts["vm_state"] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if "default" not in task_state:
                search_opts["task_state"] = task_state

        if "changes-since" in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts["changes-since"])
            except ValueError:
                msg = _("Invalid changes-since value")
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts["changes-since"] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes-since' is specified, because 'changes-since'
        # should return recently deleted images according to the API spec.

        if "deleted" not in search_opts:
            if "changes-since" not in search_opts:
                # No 'changes-since', so we only want non-deleted servers
                search_opts["deleted"] = False
        else:
            # Convert deleted filter value to a valid boolean.
            # Return non-deleted servers if an invalid value
            # is passed with deleted filter.
            search_opts["deleted"] = strutils.bool_from_string(search_opts["deleted"], default=False)

        if search_opts.get("vm_state") == ["deleted"]:
            if context.is_admin:
                search_opts["deleted"] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPForbidden(explanation=msg)

        # If tenant_id is passed as a search parameter this should
        # imply that all_tenants is also enabled unless explicitly
        # disabled. Note that the tenant_id parameter is filtered out
        # by remove_invalid_options above unless the requestor is an
        # admin.

        # TODO(gmann): 'all_tenants' flag should not be required while
        # searching with 'tenant_id'. Ref bug# 1185290
        # +microversions to achieve above mentioned behavior by
        # uncommenting below code.

        # if 'tenant_id' in search_opts and 'all_tenants' not in search_opts:
        # We do not need to add the all_tenants flag if the tenant
        # id associated with the token is the tenant id
        # specified. This is done so a request that does not need
        # the all_tenants flag does not fail because of lack of
        # policy permission for compute:get_all_tenants when it
        # doesn't actually need it.
        # if context.project_id != search_opts.get('tenant_id'):
        #    search_opts['all_tenants'] = 1

        all_tenants = common.is_all_tenants(search_opts)
        # use the boolean from here on out so remove the entry from search_opts
        # if it's present
        search_opts.pop("all_tenants", None)

        elevated = None
        if all_tenants:
            if is_detail:
                authorize(context, action="detail:get_all_tenants")
            else:
                authorize(context, action="index:get_all_tenants")
            elevated = context.elevated()
        else:
            if context.project_id:
                search_opts["project_id"] = context.project_id
            else:
                search_opts["user_id"] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        sort_keys, sort_dirs = common.get_sort_params(req.params)

        expected_attrs = ["pci_devices"]
        if is_detail:
            # merge our expected attrs with what the view builder needs for
            # showing details
            expected_attrs = self._view_builder.get_show_expected_attrs(expected_attrs)

        try:
            instance_list = self.compute_api.get_all(
                elevated or context,
                search_opts=search_opts,
                limit=limit,
                marker=marker,
                want_objects=True,
                expected_attrs=expected_attrs,
                sort_keys=sort_keys,
                sort_dirs=sort_dirs,
            )
        except exception.MarkerNotFound:
            msg = _("marker [%s] not found") % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            LOG.debug("Flavor '%s' could not be found ", search_opts["flavor"])
            instance_list = objects.InstanceList()

        if is_detail:
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Пример #21
0
 def index(self, req):
     limit, marker = common.get_limit_and_marker(req)
     return self._index(req, limit=limit, marker=marker, links=True)
Пример #22
0
 def detail(self, req):
     limit, marker = common.get_limit_and_marker(req)
     return self._detail(req, limit=limit, marker=marker, links=True)
Пример #23
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ["nova.context"]
        remove_invalid_options(context, search_opts, self._get_server_search_options())

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state for compute_api.
        status = search_opts.pop("status", None)
        if status is not None:
            state = common.vm_state_from_status(status)
            if state is None:
                msg = _("Invalid server status: %(status)s") % locals()
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts["vm_state"] = state

        if "changes-since" in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts["changes-since"])
            except ValueError:
                msg = _("Invalid changes-since value")
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts["changes-since"] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes-since' is specified, because 'changes-since'
        # should return recently deleted images according to the API spec.

        if "deleted" not in search_opts:
            if "changes-since" not in search_opts:
                # No 'changes-since', so we only want non-deleted servers
                search_opts["deleted"] = False

        if search_opts.get("vm_state") == "deleted":
            if context.is_admin:
                search_opts["deleted"] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPBadRequest(explanation=msg)

        # NOTE(dprince) This prevents computes' get_all() from returning
        # instances from multiple tenants when an admin accounts is used.
        # By default non-admin accounts are always limited to project/user
        # both here and in the compute API.
        if not context.is_admin or (context.is_admin and "all_tenants" not in search_opts):
            if context.project_id:
                search_opts["project_id"] = context.project_id
            else:
                search_opts["user_id"] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        instance_list = self.compute_api.get_all(context, search_opts=search_opts, limit=limit, marker=marker)

        if is_detail:
            self._add_instance_faults(context, instance_list)
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Пример #24
0
    def _get_servers_domain(self, req, is_detail):
        """Returns a list of servers, based on a given domain."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ['nova.context']
        remove_invalid_options(context, search_opts,
                self._get_server_search_options())

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        status = search_opts.pop('status', None)
        if status is not None:
            vm_state, task_state = common.task_and_vm_state_from_status(status)
            if not vm_state and not task_state:
                return {'servers': []}
            search_opts['vm_state'] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if 'default' not in task_state:
                search_opts['task_state'] = task_state

        if 'changes_since' in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts['changes_since'])
            except ValueError:
                msg = _('Invalid changes_since value')
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts['changes_since'] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes_since' is specified, because 'changes_since'
        # should return recently deleted images according to the API spec.

        if 'deleted' not in search_opts:
            if 'changes_since' not in search_opts:
                # No 'changes_since', so we only want non-deleted servers
                search_opts['deleted'] = False

        if 'changes_since' in search_opts:
            search_opts['changes-since'] = search_opts.pop('changes_since')

        if search_opts.get("vm_state") == ['deleted']:
            if context.is_admin:
                search_opts['deleted'] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPBadRequest(explanation=msg)

        if context.domain_id:
            search_opts['project_domain_id'] = context.domain_id

        limit, marker = common.get_limit_and_marker(req)
        try:
            instance_list = self.compute_api.get_all(context,
                    search_opts=search_opts, limit=limit, marker=marker,
                    want_objects=True, expected_attrs=['pci_devices'])
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            log_msg = _("Flavor '%s' could not be found ")
            LOG.debug(log_msg, search_opts['flavor'])
            instance_list = []

        if is_detail:
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Пример #25
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ['nova.context']
        remove_invalid_options(context, search_opts,
                self._get_server_search_options())

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        status = search_opts.pop('status', None)
        if status is not None:
            vm_state, task_state = common.task_and_vm_state_from_status(status)
            if not vm_state and not task_state:
                return {'servers': []}
            search_opts['vm_state'] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if 'default' not in task_state:
                search_opts['task_state'] = task_state

        if 'changes_since' in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts['changes_since'])
            except ValueError:
                msg = _('Invalid changes_since value')
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts['changes_since'] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes_since' is specified, because 'changes_since'
        # should return recently deleted images according to the API spec.

        if 'deleted' not in search_opts:
            if 'changes_since' not in search_opts:
                # No 'changes_since', so we only want non-deleted servers
                search_opts['deleted'] = False

        if 'changes_since' in search_opts:
            search_opts['changes-since'] = search_opts.pop('changes_since')

        if search_opts.get("vm_state") == ['deleted']:
            if context.is_admin:
                search_opts['deleted'] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPBadRequest(explanation=msg)

        # If tenant_id is passed as a search parameter this should
        # imply that all_tenants is also enabled unless explicitly
        # disabled. Note that the tenant_id parameter is filtered out
        # by remove_invalid_options above unless the requestor is an
        # admin.
        if 'tenant_id' in search_opts and not 'all_tenants' in search_opts:
            # We do not need to add the all_tenants flag if the tenant
            # id associated with the token is the tenant id
            # specified. This is done so a request that does not need
            # the all_tenants flag does not fail because of lack of
            # policy permission for compute:get_all_tenants when it
            # doesn't actually need it.
            if context.project_id != search_opts.get('tenant_id'):
                search_opts['all_tenants'] = 1

        # If all tenants is passed with 0 or false as the value
        # then remove it from the search options. Nothing passed as
        # the value for all_tenants is considered to enable the feature
        all_tenants = search_opts.get('all_tenants')
        if all_tenants:
            try:
                if not strutils.bool_from_string(all_tenants, True):
                    del search_opts['all_tenants']
            except ValueError as err:
                raise exception.InvalidInput(str(err))

        if 'all_tenants' in search_opts:
            policy.enforce(context, 'compute:get_all_tenants',
                           {'project_id': context.project_id,
                            'user_id': context.user_id})
            del search_opts['all_tenants']
        else:
            if context.project_id:
                search_opts['project_id'] = context.project_id
            else:
                search_opts['user_id'] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        try:
            instance_list = self.compute_api.get_all(context,
                    search_opts=search_opts, limit=limit, marker=marker,
                    want_objects=True, expected_attrs=['pci_devices'])
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            log_msg = _("Flavor '%s' could not be found ")
            LOG.debug(log_msg, search_opts['flavor'])
            instance_list = []

        if is_detail:
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response
Пример #26
0
    def _get_servers(self, req, is_detail):
        """Returns a list of servers, based on any search options specified."""

        search_opts = {}
        search_opts.update(req.GET)

        context = req.environ['nova.context']
        remove_invalid_options(context, search_opts,
                self._get_server_search_options())

        # Verify search by 'status' contains a valid status.
        # Convert it to filter by vm_state or task_state for compute_api.
        search_opts.pop('status', None)
        if 'status' in req.GET.keys():
            statuses = req.GET.getall('status')
            states = common.task_and_vm_state_from_status(statuses)
            vm_state, task_state = states
            if not vm_state and not task_state:
                return {'servers': []}
            search_opts['vm_state'] = vm_state
            # When we search by vm state, task state will return 'default'.
            # So we don't need task_state search_opt.
            if 'default' not in task_state:
                search_opts['task_state'] = task_state

        if 'changes-since' in search_opts:
            try:
                parsed = timeutils.parse_isotime(search_opts['changes-since'])
            except ValueError:
                msg = _('Invalid changes-since value')
                raise exc.HTTPBadRequest(explanation=msg)
            search_opts['changes-since'] = parsed

        # By default, compute's get_all() will return deleted instances.
        # If an admin hasn't specified a 'deleted' search option, we need
        # to filter out deleted instances by setting the filter ourselves.
        # ... Unless 'changes-since' is specified, because 'changes-since'
        # should return recently deleted images according to the API spec.

        if 'deleted' not in search_opts:
            if 'changes-since' not in search_opts:
                # No 'changes-since', so we only want non-deleted servers
                search_opts['deleted'] = False

        if search_opts.get("vm_state") == ['deleted']:
            if context.is_admin:
                search_opts['deleted'] = True
            else:
                msg = _("Only administrators may list deleted instances")
                raise exc.HTTPForbidden(explanation=msg)

        # If all tenants is passed with 0 or false as the value
        # then remove it from the search options. Nothing passed as
        # the value for all_tenants is considered to enable the feature
        all_tenants = search_opts.get('all_tenants')
        if all_tenants:
            try:
                if not strutils.bool_from_string(all_tenants, True):
                    del search_opts['all_tenants']
            except ValueError as err:
                raise exception.InvalidInput(six.text_type(err))

        if 'all_tenants' in search_opts:
            policy.enforce(context, 'compute:get_all_tenants',
                           {'project_id': context.project_id,
                            'user_id': context.user_id})
            del search_opts['all_tenants']
        else:
            if context.project_id:
                search_opts['project_id'] = context.project_id
            else:
                search_opts['user_id'] = context.user_id

        limit, marker = common.get_limit_and_marker(req)
        # Sorting by multiple keys and directions is conditionally enabled
        sort_keys, sort_dirs = None, None
        if self.ext_mgr.is_loaded('os-server-sort-keys'):
            sort_keys, sort_dirs = common.get_sort_params(req.params)
        try:
            instance_list = self.compute_api.get_all(context,
                                                     search_opts=search_opts,
                                                     limit=limit,
                                                     marker=marker,
                                                     want_objects=True,
                                                     sort_keys=sort_keys,
                                                     sort_dirs=sort_dirs)
        except exception.MarkerNotFound:
            msg = _('marker [%s] not found') % marker
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            LOG.debug("Flavor '%s' could not be found", search_opts['flavor'])
            instance_list = objects.InstanceList()

        if is_detail:
            instance_list.fill_faults()
            response = self._view_builder.detail(req, instance_list)
        else:
            response = self._view_builder.index(req, instance_list)
        req.cache_db_instances(instance_list)
        return response