Пример #1
0
    def head(self, session):
        """Get headers from a remote resource based on this instance.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`

        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_head` is not set to ``True``.
        """
        if not self.allow_head:
            raise exceptions.MethodNotSupported(self, "head")

        request = self._prepare_request()

        endpoint_override = self.service.get_endpoint_override()
        response = session.head(request.uri,
                                endpoint_filter=self.service,
                                endpoint_override=endpoint_override,
                                headers={"Accept": ""})

        self._translate_response(response)
        return self
Пример #2
0
    def head_data_by_id(cls, session, resource_id, path_args=None):
        """Get a dictionary representing the headers of a remote resource.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param resource_id: This resource's identifier, if needed by
                            the request. The default is ``None``.
        :param dict path_args: A dictionary of arguments to construct
                               a compound URL.
                               See `How path_args are used`_ for details.

        :return: A ``dict`` containing the headers.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_head` is not set to ``True``.
        """
        if not cls.allow_head:
            raise exceptions.MethodNotSupported(cls, 'head')

        url = cls._get_url(path_args, resource_id)

        data = session.head(url, service=cls.service, accept=None).headers

        return {HEADERS: data}
    def delete_by_id(cls, session, resource_id, path_args=None,
                     error_message=None):
        """Delete a remote resource with the given id.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`
        :param resource_id: This resource's identifier, if needed by
                            the request.
        :param dict path_args: A dictionary of arguments to construct
                               a compound URL.
                               See `How path_args are used`_ for details.

        :return: ``None``
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_delete` is not set to ``True``.
        """
        if not cls.allow_delete:
            raise exceptions.MethodNotSupported(cls, 'delete')

        url = cls._get_url(path_args, resource_id)
        headers = {'Accept': ''}
        response = session.delete(url, headers=headers)
        exceptions.raise_from_response(response, error_message=error_message)
Пример #4
0
    def get(self, session, requires_id=True, error_message=None):
        """Get a remote resource based on this instance.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`
        :param boolean requires_id: A boolean indicating whether resource ID
                                    should be part of the requested URI.
        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_get` is not set to ``True``.
        """
        if not self.allow_get:
            raise exceptions.MethodNotSupported(self, "get")

        request = self._prepare_request(requires_id=requires_id)
        session = self._get_session(session)
        response = session.get(request.url)
        kwargs = {}
        if error_message:
            kwargs['error_message'] = error_message

        self._translate_response(response, **kwargs)
        return self
Пример #5
0
    def delete(self, session, error_message=None):
        """Delete the remote resource based on this instance.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`

        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_update` is not set to ``True``.
        """
        if not self.allow_delete:
            raise exceptions.MethodNotSupported(self, "delete")

        request = self._prepare_request()
        session = self._get_session(session)

        response = session.delete(request.url, headers={"Accept": ""})
        kwargs = {}
        if error_message:
            kwargs['error_message'] = error_message

        self._translate_response(response, has_body=False, **kwargs)
        return self
Пример #6
0
    def get(self, session, requires_id=True):
        """Get a remote resource based on this instance.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param boolean requires_id: A boolean indicating whether resource ID
                                    should be part of the requested URI.
        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_get` is not set to ``True``.
        """
        if not self.allow_get:
            raise exceptions.MethodNotSupported(self, "get")

        request = self._prepare_request(requires_id=requires_id)
        endpoint_override = self.service.get_endpoint_override()
        service = self.get_service_filter(self, session)
        response = session.get(request.uri,
                               endpoint_filter=self.service,
                               microversion=service.microversion,
                               endpoint_override=endpoint_override)
        self._translate_response(response)
        return self
    def list_once(cls, session, **params):
        """
        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param dict params: These keyword arguments are passed through the
            :meth:`~openstack.resource2.QueryParamter._transpose` method
            to find if any of them match expected query parameters to be
            sent in the *params* argument to
            :meth:`~openstack.session.Session.get`. They are additionally
            checked against the
            :data:`~openstack.resource2.Resource.base_path` format string
            to see if any path fragments need to be filled in by the contents
            of this argument.

        :return: A instance of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")
        query_params = cls._query_mapping._transpose(params)
        uri = cls.get_list_uri(params)
        service = cls.get_service_filter(cls, session)
        endpoint_override = cls.service.get_endpoint_override()

        resp = session.get(uri, endpoint_filter=cls.service,
                           microversion=service.microversion,
                           endpoint_override=endpoint_override,
                           headers={"Accept": "application/json"},
                           params=query_params)

        response_json = resp.json()
        if not response_json:
            return

        value = cls.existing(**response_json)
        return value
Пример #8
0
    def create(self, session, prepend_key=True, has_body=False):
        """Create a remote resource based on this instance.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param prepend_key: A boolean indicating whether the resource_key
                            should be prepended in a resource creation
                            request. Default to True.
        :param bool has_body: should mapping response body to resource.

        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_create` is not set to ``True``.
        """
        if not self.allow_create:
            raise exceptions.MethodNotSupported(self, "create")

        endpoint_override = self.service.get_endpoint_override()
        if self.put_create:
            request = self._prepare_request(requires_id=True,
                                            prepend_key=prepend_key)
            response = session.put(request.uri,
                                   endpoint_filter=self.service,
                                   endpoint_override=endpoint_override,
                                   json=request.body,
                                   headers=request.headers)
        else:
            request = self._prepare_request(requires_id=False,
                                            prepend_key=prepend_key)
            response = session.post(request.uri,
                                    endpoint_filter=self.service,
                                    endpoint_override=endpoint_override,
                                    json=request.body,
                                    headers=request.headers)

        self._translate_response(response, has_body=has_body)
        return self
Пример #9
0
    def delete(self, session, error_message=None,
               endpoint_override=None, headers=None,
               requests_auth=None, params=None):
        """Delete the remote resource based on this instance.

        This function overrides default Resource.delete to enable headers

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`

        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_update` is not set to ``True``.
        """
        if not self.allow_delete:
            raise exceptions.MethodNotSupported(self, "delete")

        request = self._prepare_request()
        session = self._get_session(session)

        # Build additional arguments to the DELETE call
        delete_args = self._prepare_override_args(
            endpoint_override=endpoint_override,
            request_headers=request.headers,
            additional_headers=headers,
            requests_auth=requests_auth)
        if params:
            delete_args['params'] = params

        response = session.delete(request.url,
                                  **delete_args)
        kwargs = {}
        if error_message:
            kwargs['error_message'] = error_message

        self._translate_response(response, has_body=False, **kwargs)
        return self
Пример #10
0
    def get_data_by_id(cls, session, resource_id, path_args=None,
                       include_headers=False):
        """Get a the attributes of a remote resource from an id.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param resource_id: This resource's identifier, if needed by
                            the request. The default is ``None``.
        :param dict path_args: A dictionary of arguments to construct
                               a compound URL.
                               See `How path_args are used`_ for details.
        :param bool include_headers: ``True`` if header data should be
                                     included in the response body,
                                     ``False`` if not.

        :return: A ``dict`` representing the response body.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_retrieve` is not set to ``True``.
        """
        if not cls.allow_retrieve:
            raise exceptions.MethodNotSupported('retrieve')

        if path_args:
            url = cls.base_path % path_args
        else:
            url = cls.base_path
        url = utils.urljoin(url, resource_id)
        response = session.get(url, service=cls.service)
        body = response.body

        if cls.resource_key:
            body = body[cls.resource_key]

        if include_headers:
            body[HEADERS] = response.headers

        return body
Пример #11
0
    def list(cls,
             session,
             paginated=False,
             endpoint_override=None,
             headers=None,
             requests_auth=None,
             **params):
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")

        cls._query_mapping._validate(params, base_path=cls.base_path)
        query_params = cls._query_mapping._transpose(params, cls)

        response = session.get(session.get_endpoint(),
                               params=query_params.copy(),
                               requests_auth=requests_auth)

        root = ET.fromstring(response.content)

        if root.tag != ET.QName(cls.OBS_NS, 'ListAllMyBucketsResult'):
            _logger.warn('Namespace in the response does not match '
                         'expectation')
            cls.OBS_NS = root.tag.split('}', 1)[0][1:]

        for elements in root:

            if elements.tag == ET.QName(cls.OBS_NS, cls.resources_key):
                for el in elements:
                    if el.tag == ET.QName(cls.OBS_NS, cls.resource_key):
                        # Convert XML part into dict
                        dict_raw_resource = cls.etree_to_dict(el)
                        # extract resource data
                        dict_resource = dict_raw_resource[cls.resource_key]
                        value = cls.existing(**dict_resource)
                        yield value

        return
Пример #12
0
    def update(self, session, prepend_key=True, has_body=True):
        """Update the remote resource based on this instance.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`
        :param prepend_key: A boolean indicating whether the resource_key
                            should be prepended in a resource update request.
                            Default to True.

        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_update` is not set to ``True``.
        """
        # The id cannot be dirty for an update
        self._body._dirty.discard("id")

        # Only try to update if we actually have anything to update.
        if not any([self._body.dirty, self._header.dirty]):
            return self

        if not self.allow_update:
            raise exceptions.MethodNotSupported(self, "update")

        request = self._prepare_request(prepend_key=prepend_key)

        if self.patch_update:
            response = session.patch(request.url,
                                     json=request.body,
                                     headers=request.headers)
        else:
            response = session.put(request.url,
                                   json=request.body,
                                   headers=request.headers)

        self._translate_response(response, has_body=has_body)
        return self
Пример #13
0
    def delete_by_id(cls, session, resource_id, path_args=None):
        """Delete a remote resource with the given id.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param resource_id: This resource's identifier, if needed by
                            the request. The default is ``None``.
        :param dict path_args: A dictionary of arguments to construct
                               a compound URL.
                               See `How path_args are used`_ for details.

        :return: ``None``
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_delete` is not set to ``True``.
        """
        if not cls.allow_delete:
            raise exceptions.MethodNotSupported(cls, 'delete')

        if path_args:
            url = cls.base_path % path_args
        else:
            url = cls.base_path
        url = utils.urljoin(url, resource_id)
        session.delete(url, service=cls.service, accept=None)
Пример #14
0
    def create_by_id(cls, session, attrs, r_id=None, path_args=None):
        if not cls.allow_create:
            raise exceptions.MethodNotSupported('create')

        if cls.resource_key:
            body = {cls.resource_key: attrs}
        else:
            body = attrs

        if path_args:
            url = cls.base_path % path_args
        else:
            url = cls.base_path
        if r_id:
            url = utils.urljoin(url, r_id)
            resp = session.put(url, service=cls.service, json=body).body
        else:
            resp = session.post(url, service=cls.service,
                                json=body).body

        if cls.resource_key:
            resp = resp[cls.resource_key]

        return resp
Пример #15
0
    def list(cls,
             session,
             paginated=True,
             base_path=None,
             allow_unknown_params=False,
             **params):

        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")
        session = cls._get_session(session)
        microversion = cls._get_microversion_for_list(session)

        if base_path is None:
            base_path = cls.base_path

        datastore_type = params.get('datastore_name', 'DDS-Community')
        uri = utils.urljoin(base_path, datastore_type, 'versions')

        response = session.get(uri,
                               headers={"Accept": "application/json"},
                               microversion=microversion)
        exceptions.raise_from_response(response)
        data = response.json()

        resources = data['versions']

        if not isinstance(resources, list):
            resources = [resources]

        for raw_resource in resources:
            value = cls.existing(microversion=microversion,
                                 connection=session._get_connection(),
                                 type=datastore_type,
                                 storage_engine='wiredTiger',
                                 version=raw_resource)
            yield value
Пример #16
0
    def update(self, session, prepend_key=True, has_body=True):
        """Update the remote resource based on this instance.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param prepend_key: A boolean indicating whether the resource_key
                            should be prepended in a resource update request.
                            Default to True.

        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_update` is not set to ``True``.
        """
        # The id cannot be dirty for an update
        self._body._dirty.discard("id")
        id_mapping_name = self._body_mapping()["id"]
        self._body._dirty.discard(id_mapping_name)

        if not self.allow_update:
            raise exceptions.MethodNotSupported(self, "update")

        request = self._prepare_request(requires_id=False,
                                        prepend_key=prepend_key)
        request.body = None
        service = self.get_service_filter(self, session)
        endpoint_override = self.service.get_endpoint_override() if self.service.get_endpoint_override() \
            else self.get_endpoint_override(session)
        response = session.put(request.uri,
                               endpoint_filter=self.service,
                               microversion=service.microversion,
                               endpoint_override=endpoint_override,
                               json=request.body,
                               headers=request.headers)

        self._translate_response(response, has_body=has_body)
        return self
Пример #17
0
    def delete(self, session, has_body=False, params=None):
        """Delete the remote resource based on this instance.
        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :return: This :class:`Resource` instance.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_update` is not set to ``True``.

        """

        if not self.allow_delete:
            raise exceptions.MethodNotSupported(self, "delete")
        request = self._prepare_request()
        endpoint_override = self.service.get_endpoint_override()
        if endpoint_override is None:
            request.uri = self._get_custom_url(session, request.uri)
        else:
            endpoint_override = self._get_custom_override(endpoint_override)
        response = session.delete(request.uri,
                                  endpoint_filter=self.service,
                                  endpoint_override=endpoint_override,
                                  headers=request.headers)
        self._translate_response(response, has_body=False)
        return self
Пример #18
0
    def create(self,
               session,
               prepend_key=True,
               endpoint_override=None,
               headers=None,
               requests_auth=None):

        if not self.allow_create:
            raise exceptions.MethodNotSupported(self, "create")

        session = self._get_session(session)

        request = self._prepare_request()

        req_args = self._prepare_override_args(
            endpoint_override=endpoint_override,
            request_headers=request.headers,
            additional_headers=headers,
            requests_auth=requests_auth)

        response = session.put(request.url, data=request.body, **req_args)

        self._translate_response(response)
        return self
Пример #19
0
    def list_by_offset(cls, session, paginated=False, **params):
        """This method is a generator which yields resource objects.

        This resource object list generator handles pagination and takes query
        params for response filtering.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param bool paginated: ``True`` if a GET to this resource returns
                               a paginated series of responses, or ``False``
                               if a GET returns only one page of data.
                               **When paginated is False only one
                               page of data will be returned regardless
                               of the API's support of pagination.**
        :param dict params: These keyword arguments are passed through the
            :meth:`~openstack.resource2.QueryParamter._transpose` method
            to find if any of them match expected query parameters to be
            sent in the *params* argument to
            :meth:`~openstack.session.Session.get`. They are additionally
            checked against the
            :data:`~openstack.resource2.Resource.base_path` format string
            to see if any path fragments need to be filled in by the contents
            of this argument.

        :return: A generator of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")

        more_data = True
        query_params = cls._query_mapping._transpose(params)
        uri = cls.get_list_uri(params)
        offset = query_params.get("offset")
        limit = query_params.get("limit")

        while more_data:
            endpoint_override = cls.service.get_endpoint_override()
            resp = session.get(uri,
                               endpoint_filter=cls.service,
                               endpoint_override=endpoint_override,
                               headers={"Accept": "application/json"},
                               params=query_params)
            response_json = resp.json()
            resources = response_json

            if not resources:
                return

            resources.pop("self", None)
            value = cls.existing(**resources)
            yield value

            if not paginated:
                return

            if offset is None:
                return

            if limit is None:
                return

            resource_list = resources[cls.resources_key]
            current_page_size = len(resource_list)

            # Check if you need to continue sending requests.
            if current_page_size < int(limit):
                return
            else:
                if int(query_params.get("offset")) == 0:
                    query_params["offset"] = 2
                else:
                    query_params["offset"] = int(
                        query_params.get("offset")) + 1
Пример #20
0
    def list(cls, session, paginated=False, base_path=None, **params):
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")

        session = cls._get_session(session)

        # pop scaling_group_id, as it should not be also present in the query
        scaling_group_id = params.pop('scaling_group_id', None)
        uri_params = {}

        if scaling_group_id:
            uri_params = {'scaling_group_id': scaling_group_id}

        cls._query_mapping._validate(params, base_path=cls.base_path)
        query_params = cls._query_mapping._transpose(params, cls)
        uri = cls.base_path % uri_params

        limit = query_params.get('limit')

        total_yielded = 0
        while uri:
            response = session.get(uri, params=query_params.copy())
            exceptions.raise_from_response(response)
            data = response.json()

            # Discard any existing pagination keys
            query_params.pop('marker', None)
            query_params.pop('limit', None)

            if cls.resources_key:
                resources = cls.find_value_by_accessor(data, cls.resources_key)
            else:
                resources = data

            if not isinstance(resources, list):
                resources = [resources]

            marker = None
            for raw_resource in resources:
                # Do not allow keys called "self" through. Glance chose
                # to name a key "self", so we need to pop it out because
                # we can't send it through cls.existing and into the
                # Resource initializer. "self" is already the first
                # argument and is practically a reserved word.
                raw_resource.pop("self", None)

                if cls.resource_key and cls.resource_key in raw_resource:
                    raw_resource = raw_resource[cls.resource_key]

                value = cls.existing(**raw_resource)

                marker = value.id
                yield value
                total_yielded += 1

            if resources and paginated:
                uri, next_params = cls._get_next_link(uri, response, data,
                                                      marker, limit,
                                                      total_yielded)
                query_params.update(next_params)
            else:
                return
Пример #21
0
    def list(cls, session, paginated=False, **params):
        """This method is a generator which yields resource objects.

        This resource object list generator handles pagination and takes query
        params for response filtering.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`
        :param bool paginated: ``True`` if a GET to this resource returns
                               a paginated series of responses, or ``False``
                               if a GET returns only one page of data.
                               **When paginated is False only one
                               page of data will be returned regardless
                               of the API's support of pagination.**
        :param dict params: These keyword arguments are passed through the
            :meth:`~openstack.resource.QueryParamter._transpose` method
            to find if any of them match expected query parameters to be
            sent in the *params* argument to
            :meth:`~keystoneauth1.adapter.Adapter.get`. They are additionally
            checked against the
            :data:`~openstack.resource.Resource.base_path` format string
            to see if any path fragments need to be filled in by the contents
            of this argument.

        :return: A generator of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        :raises: :exc:`~openstack.exceptions.InvalidResourceQuery` if query
                 contains invalid params.
        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")
        session = cls._get_session(session)

        cls._query_mapping._validate(params, base_path=cls.base_path)
        query_params = cls._query_mapping._transpose(params)
        uri = cls.base_path % params

        limit = query_params.get('limit')

        # Track the total number of resources yielded so we can paginate
        # swift objects
        total_yielded = 0
        while uri:
            # Copy query_params due to weird mock unittest interactions
            response = session.get(uri,
                                   headers={"Accept": "application/json"},
                                   params=query_params.copy())
            exceptions.raise_from_response(response)
            data = response.json()

            # Discard any existing pagination keys
            query_params.pop('marker', None)
            query_params.pop('limit', None)

            if cls.resources_key:
                resources = data[cls.resources_key]
            else:
                resources = data

            if not isinstance(resources, list):
                resources = [resources]

            marker = None
            for raw_resource in resources:
                # Do not allow keys called "self" through. Glance chose
                # to name a key "self", so we need to pop it out because
                # we can't send it through cls.existing and into the
                # Resource initializer. "self" is already the first
                # argument and is practically a reserved word.
                raw_resource.pop("self", None)

                value = cls.existing(**raw_resource)
                marker = value.id
                yield value
                total_yielded += 1

            if resources and paginated:
                uri, next_params = cls._get_next_link(uri, response, data,
                                                      marker, limit,
                                                      total_yielded)
                query_params.update(next_params)
            else:
                return
Пример #22
0
    def list(cls, session, paginated=False, **params):
        """This method is a generator which yields resource objects.

        This resource object list generator handles pagination and takes query
        params for response filtering.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param bool paginated: ``True`` if a GET to this resource returns
                               a paginated series of responses, or ``False``
                               if a GET returns only one page of data.
                               **When paginated is False only one
                               page of data will be returned regardless
                               of the API's support of pagination.**
        :param dict params: These keyword arguments are passed through the
            :meth:`~openstack.resource2.QueryParamter._transpose` method
            to find if any of them match expected query parameters to be
            sent in the *params* argument to
            :meth:`~openstack.session.Session.get`. They are additionally
            checked against the
            :data:`~openstack.resource2.Resource.base_path` format string
            to see if any path fragments need to be filled in by the contents
            of this argument.

        :return: A generator of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")

        more_data = True
        query_params = cls._query_mapping._transpose(params)
        uri = cls.base_path % params

        while more_data:
            endpoint_override = cls.service.get_endpoint_override()
            if endpoint_override is None:
                uri = cls._get_custom_url(session, uri)
            else:
                endpoint_override = cls._get_custom_override(endpoint_override)

            resp = session.get(uri,
                               endpoint_filter=cls.service,
                               endpoint_override=endpoint_override,
                               headers={
                                   "Content-type": "application/json",
                                   "X-Language": "en-us"
                               },
                               params=query_params)
            resp = resp.json()
            if cls.resources_key:
                resp = resp[cls.resources_key]

            if not resp:
                more_data = False

            # Keep track of how many items we've yielded. If we yielded
            # less than our limit, we don't need to do an extra request
            # to get back an empty data set, which acts as a sentinel.
            yielded = 0
            new_marker = None
            for data in resp:
                # Do not allow keys called "self" through. Glance chose
                # to name a key "self", so we need to pop it out because
                # we can't send it through cls.existing and into the
                # Resource initializer. "self" is already the first
                # argument and is practically a reserved word.
                data.pop("self", None)

                if cls.resource_key and cls.resource_key in data:
                    data = data[cls.resource_key]

                value = cls.existing(**data)
                new_marker = value.id
                yielded += 1
                yield value

            if not paginated:
                return
            if "limit" in query_params and yielded < query_params["limit"]:
                return
            query_params["limit"] = yielded
            query_params["marker"] = new_marker
 def test_method_not_supported(self):
     exc = exceptions.MethodNotSupported(self.__class__, 'list')
     expected = ('The list method is not supported for ' +
                 'openstack.tests.unit.test_exceptions.Test_Exception')
     self.assertEqual(expected, str(exc))
Пример #24
0
    def list(cls,
             session,
             limit=None,
             marker=None,
             path_args=None,
             paginated=False,
             **params):
        """Get a response that is a list of objects.

        This method starts at ``limit`` and ``marker`` (both defaulting to
        None), advances the marker to the last item received in each response,
        and continues making requests for more resources until no results
        are returned.

        When no ``limit`` is provided, the server will return its maximum
        amount of items per page. After that response, the limit will be
        determined and sent in subsequent requests to the server. That limit
        will be used to calculate when all items have been received.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param limit: The maximum amount of results to retrieve.
                      The default is ``None``, which means no limit will be
                      set, and the underlying API will return its default
                      amount of responses.
        :param marker: The position in the list to begin requests from.
                       The type of value to use for ``marker`` depends on
                       the API being called.
        :param dict path_args: A dictionary of arguments to construct
                               a compound URL.
                               See `How path_args are used`_ for details.
        :param bool paginated: ``True`` if a GET to this resource returns
                               a paginated series of responses, or ``False``
                               if a GET returns only one page of data.
                               **When paginated is False only one
                               page of data will be returned regardless
                               of the API's support of pagination.**
        :param dict params: Parameters to be passed into the underlying
                            :meth:`~openstack.session.Session.get` method.

        :return: A generator of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, 'list')

        more_data = True

        while more_data:
            resp = cls.page(session, limit, marker, path_args, **params)

            if not resp:
                more_data = False

            # Keep track of how many items we've yielded. If we yielded
            # less than our limit, we don't need to do an extra request
            # to get back an empty data set, which acts as a sentinel.
            yielded = 0
            for data in resp:
                value = cls.existing(**data)
                marker = value.id
                yielded += 1
                yield value

            if not paginated or limit and yielded < limit:
                more_data = False

            limit = yielded
    def list(cls,
             session,
             paginated=False,
             base_path=None,
             allow_unknown_params=False,
             **params):

        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")
        session = cls._get_session(session)
        microversion = cls._get_microversion_for_list(session)

        if base_path is None:
            base_path = cls.base_path
        params = cls._query_mapping._validate(
            params,
            base_path=base_path,
            allow_unknown_params=allow_unknown_params)

        query_params = cls._query_mapping._transpose(params, cls)
        uri = base_path % params

        limit = query_params.get('limit')

        # Track the total number of resources yielded so we can paginate
        # swift objects
        total_yielded = query_params.get('start', 0)
        while uri:
            # Copy query_params due to weird mock unittest interactions
            response = session.get(uri,
                                   headers={"Accept": "application/json"},
                                   params=query_params.copy(),
                                   microversion=microversion)
            exceptions.raise_from_response(response)
            data = response.json()

            # Discard any existing pagination keys
            query_params.pop('start', None)
            query_params.pop('limit', None)

            if cls.resources_key:
                resources = data[cls.resources_key]
            else:
                resources = data

            if not isinstance(resources, list):
                resources = [resources]

            marker = None
            for raw_resource in resources:
                value = cls.existing(microversion=microversion,
                                     connection=session._get_connection(),
                                     **raw_resource)
                marker = total_yielded + 1
                yield value
                total_yielded += 1

            if resources and paginated:
                uri, next_params = cls._get_next_link(uri, response, data,
                                                      marker, limit,
                                                      total_yielded)
                query_params.update(next_params)
            else:
                return
Пример #26
0
    def list(cls, session, path_args=None, paginated=False, params=None):
        """This method is a generator which yields resource objects.

        This resource object list generator handles pagination and takes query
        params for response filtering.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param dict path_args: A dictionary of arguments to construct
                               a compound URL.
                               See `How path_args are used`_ for details.
        :param bool paginated: ``True`` if a GET to this resource returns
                               a paginated series of responses, or ``False``
                               if a GET returns only one page of data.
                               **When paginated is False only one
                               page of data will be returned regardless
                               of the API's support of pagination.**
        :param dict params: Query parameters to be passed into the underlying
                            :meth:`~openstack.session.Session.get` method.
                            Values that the server may support include `limit`
                            and `marker`.

        :return: A generator of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, 'list')

        more_data = True
        params = {} if params is None else params
        url = cls._get_url(path_args)
        headers = {'Accept': 'application/json'}
        while more_data:
            resp = session.get(url,
                               endpoint_filter=cls.service,
                               headers=headers,
                               params=params)
            resp = resp.json()
            if cls.resources_key:
                resp = resp[cls.resources_key]

            if not resp:
                more_data = False

            # Keep track of how many items we've yielded. If we yielded
            # less than our limit, we don't need to do an extra request
            # to get back an empty data set, which acts as a sentinel.
            yielded = 0
            new_marker = None
            for data in resp:
                value = cls.existing(**data)
                new_marker = value.id
                yielded += 1
                yield value

            if not paginated:
                return
            if 'limit' in params and yielded < params['limit']:
                return
            params['limit'] = yielded
            params['marker'] = new_marker
Пример #27
0
    def list(cls, session, paginated=True, base_path=None, **params):
        """This method is a generator which yields resource objects.

        This resource object list generator handles pagination and takes query
        params for response filtering.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`
        :param bool paginated: ``True`` if a GET to this resource returns
                               a paginated series of responses, or ``False``
                               if a GET returns only one page of data.
                               **When paginated is False only one
                               page of data will be returned regardless
                               of the API's support of pagination.**
        :param str base_path: Base part of the URI for listing resources, if
                              different from
                              :data:`~openstack.resource.Resource.base_path`.
        :param dict params: These keyword arguments are passed through the
            :meth:`~openstack.resource.QueryParamter._transpose` method
            to find if any of them match expected query parameters to be
            sent in the *params* argument to
            :meth:`~keystoneauth1.adapter.Adapter.get`. They are additionally
            checked against the
            :data:`~openstack.resource.Resource.base_path` format string
            to see if any path fragments need to be filled in by the contents
            of this argument.

        :return: A generator of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        :raises: :exc:`~openstack.exceptions.InvalidResourceQuery` if query
                 contains invalid params.
        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")
        session = cls._get_session(session)
        microversion = cls._get_microversion_for_list(session)

        if base_path is None:
            base_path = cls.base_path
        cls._query_mapping._validate(params, base_path=base_path)
        query_params = cls._query_mapping._transpose(params, cls)

        uri = base_path % params

        # Copy query_params due to weird mock unittest interactions
        response = session.get(uri,
                               headers={
                                   "Accept": "application/json",
                                   "Content-type": "application/json"
                               },
                               params=query_params.copy(),
                               microversion=microversion)
        exceptions.raise_from_response(response)
        data = response.json()

        resources = data['backups']
        for raw_resource in resources:
            raw_resource.pop("self", None)

            value = cls.existing(
                microversion=microversion,
                connection=session._get_connection(),
                # version="1.0",
                **raw_resource)
            yield value
Пример #28
0
    def list(cls,
             session,
             paginated=True,
             endpoint_override=None,
             headers=None,
             **kwargs):

        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")

        uri = None
        if not hasattr(cls, 'list_path'):
            uri = cls.base_path
        else:
            uri = cls.list_path

        body = {}
        limit = None
        if 'limit' in kwargs:
            limit = kwargs['limit']
            body['limit'] = limit
        if 'marker' in kwargs:
            body['marker'] = kwargs['marker']
        if 'key_state' in kwargs:
            body['key_state'] = kwargs['key_state']
        if 'sequence' in kwargs:
            body['sequence'] = kwargs['sequence']

        total_yielded = 0
        while uri:

            session = cls._get_session(session)

            args = cls._prepare_override_args(
                endpoint_override=endpoint_override,
                additional_headers=headers)

            response = session.post(uri, json=body, **args)

            data = response.json()

            if cls.resources_key:
                resources = data[cls.resources_key]
            else:
                resources = data

            if not isinstance(resources, list):
                resources = [resources]

            marker = None
            for raw_resource in resources:
                raw_resource.pop("self", None)

                if cls.resource_key and cls.resource_key in raw_resource:
                    raw_resource = raw_resource[cls.resource_key]

                value = cls.existing(**raw_resource)

                marker = value.id
                yield value
                total_yielded += 1

            if resources and paginated:
                uri, next_params = cls._get_next_link(uri, response, data,
                                                      marker, limit,
                                                      total_yielded)
                body.update(next_params)
            else:
                return
Пример #29
0
    def list(cls, session, paginated=False, **params):
        """This method is a generator which yields resource objects.

        This resource object list generator handles pagination and takes query
        params for response filtering.

        :param session: The session to use for making this request.
        :type session: :class:`~openstack.session.Session`
        :param bool paginated: ``True`` if a GET to this resource returns
                               a paginated series of responses, or ``False``
                               if a GET returns only one page of data.
                               **When paginated is False only one
                               page of data will be returned regardless
                               of the API's support of pagination.**
        :param dict params: These keyword arguments are passed through the
            :meth:`~openstack.resource2.QueryParamter._transpose` method
            to find if any of them match expected query parameters to be
            sent in the *params* argument to
            :meth:`~openstack.session.Session.get`. They are additionally
            checked against the
            :data:`~openstack.resource2.Resource.base_path` format string
            to see if any path fragments need to be filled in by the contents
            of this argument.

        :return: A generator of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")

        more_data = True
        query_params = cls._query_mapping._transpose(params)
        uri = cls.get_list_uri(params)

        while more_data:
            endpoint_override = cls.service.get_endpoint_override()
            resp = session.get(uri,
                               endpoint_filter=cls.service,
                               endpoint_override=endpoint_override,
                               headers={"Accept": "application/json"},
                               params=query_params)
            response_json = resp.json()
            if cls.resources_key:
                resources = cls.find_value_by_accessor(response_json,
                                                       cls.resources_key)
            else:
                resources = response_json

            if not resources:
                more_data = False

            # Keep track of how many items we've yielded. If we yielded
            # less than our limit, we don't need to do an extra request
            # to get back an empty data set, which acts as a sentinel.
            yielded = 0
            new_marker = None
            for data in resources:
                # Do not allow keys called "self" through. Glance chose
                # to name a key "self", so we need to pop it out because
                # we can't send it through cls.existing and into the
                # Resource initializer. "self" is already the first
                # argument and is practically a reserved word.
                data.pop("self", None)

                value = cls.existing(**data)
                new_marker = value.id
                yielded += 1
                yield value

            query_params = dict(query_params)
            # if `next marker path` is explicit specified, use it as marker
            next_marker = cls.get_next_marker(response_json, yielded,
                                              query_params)
            if next_marker:
                new_marker = next_marker if next_marker != -1 else None

            # if cls.next_marker_path:
            #     if isinstance(cls.next_marker_path, six.string_types):
            #         new_marker = cls.find_value_by_accessor(response_json,
            #                                                 cls.next_marker_path)
            #     elif callable(cls.next_marker_path):
            #         new_marker = cls.next_marker_path(response_json, yielded)

            if not new_marker:
                return
            if not paginated:
                return
            if cls.query_limit_key in query_params:
                if yielded < query_params["limit"]:
                    return
            query_params[cls.query_limit_key] = yielded
            query_params[cls.query_marker_key] = new_marker
Пример #30
0
    def list_ext(cls,
                 session,
                 paginated=False,
                 endpoint_override=None,
                 headers=None,
                 **params):
        """Override default list to incorporate endpoint overriding
        and custom headers

        Since SDK Resource.list method is passing hardcoded headers
        do override the function

        This resource object list generator handles pagination and takes query
        params for response filtering.

        :param session: The session to use for making this request.
        :type session: :class:`~keystoneauth1.adapter.Adapter`
        :param bool paginated: ``True`` if a GET to this resource returns
                               a paginated series of responses, or ``False``
                               if a GET returns only one page of data.
                               **When paginated is False only one
                               page of data will be returned regardless
                               of the API's support of pagination.**
        :param dict params: These keyword arguments are passed through the
            :meth:`~openstack.resource.QueryParamter._transpose` method
            to find if any of them match expected query parameters to be
            sent in the *params* argument to
            :meth:`~keystoneauth1.adapter.Adapter.get`. They are additionally
            checked against the
            :data:`~openstack.resource.Resource.base_path` format string
            to see if any path fragments need to be filled in by the contents
            of this argument.

        :return: A generator of :class:`Resource` objects.
        :raises: :exc:`~openstack.exceptions.MethodNotSupported` if
                 :data:`Resource.allow_list` is not set to ``True``.
        :raises: :exc:`~openstack.exceptions.InvalidResourceQuery` if query
                 contains invalid params.

        """
        if not cls.allow_list:
            raise exceptions.MethodNotSupported(cls, "list")

        session = cls._get_session(session)

        # pop scaling_group_id, as it should not be also present in the query
        scaling_group_id = params.pop('scaling_group_id', None)
        uri_params = {}

        if scaling_group_id:
            uri_params = {'scaling_group_id': scaling_group_id}

        cls._query_mapping._validate(params, base_path=cls.base_path)
        query_params = cls._query_mapping._transpose(params)
        uri = None
        if not hasattr(cls, 'list_path'):
            uri = cls.base_path % uri_params
        else:
            uri = cls.list_path % uri_params

        limit = query_params.get('limit')

        # Build additional arguments to the GET call
        get_args = cls._prepare_override_args(
            endpoint_override=endpoint_override,
            # request_headers=request.headers,
            additional_headers=headers)

        total_yielded = 0
        while uri:
            response = session.get(uri, params=query_params.copy(), **get_args)
            exceptions.raise_from_response(response)
            data = response.json()

            # Discard any existing pagination keys
            query_params.pop('marker', None)
            query_params.pop('limit', None)

            if cls.resources_key:
                resources = cls.find_value_by_accessor(data, cls.resources_key)
            else:
                resources = data

            if not isinstance(resources, list):
                resources = [resources]

            marker = None
            for raw_resource in resources:
                # Do not allow keys called "self" through. Glance chose
                # to name a key "self", so we need to pop it out because
                # we can't send it through cls.existing and into the
                # Resource initializer. "self" is already the first
                # argument and is practically a reserved word.
                raw_resource.pop("self", None)

                if cls.resource_key and cls.resource_key in raw_resource:
                    raw_resource = raw_resource[cls.resource_key]

                value = cls.existing(**raw_resource)

                marker = value.id
                yield value
                total_yielded += 1

            if resources and paginated:
                uri, next_params = cls._get_next_link(uri, response, data,
                                                      marker, limit,
                                                      total_yielded)
                query_params.update(next_params)
            else:
                return