Пример #1
0
    def all(self):
        """Queries the 'ListView' of a given endpoint.

        Returns all objects from an endpoint.

        :Returns: List of :py:class:`.Record` objects.

        :Examples:

        >>> nb.dcim.devices.all()
        [test1-a3-oobsw2, test1-a3-oobsw3, test1-a3-oobsw4]
        >>>
        """
        req = Request(
            base="{}/".format(self.url),
            token=self.token,
            session_key=self.session_key,
            http_session=self.api.http_session,
            threading=self.api.threading,
        )

        get_req = req.get()
        self.api.api_version = req.api_version

        return response_loader(get_req, self.return_obj, self)
Пример #2
0
 def test_get_manual_pagination(self):
     test_obj = Request(
         http_session=Mock(),
         base="http://localhost:8001/api/dcim/devices",
         limit=10,
         offset=20,
     )
     test_obj.http_session.get.return_value.json.return_value = {
         "count": 4,
         "next":
         "http://localhost:8001/api/dcim/devices?limit=10&offset=30",
         "previous": False,
         "results": [1, 2, 3, 4],
     }
     expected = call(
         "http://localhost:8001/api/dcim/devices/",
         params={
             "offset": 20,
             "limit": 10
         },
         headers={"accept": "application/json;"},
     )
     test_obj.http_session.get.ok = True
     generator = test_obj.get()
     self.assertEqual(len(list(generator)), 4)
     test_obj.http_session.get.assert_called_with(
         "http://localhost:8001/api/dcim/devices/",
         params={
             "offset": 20,
             "limit": 10
         },
         headers={"accept": "application/json;"},
         json=None,
     )
Пример #3
0
    def get(self, *args, **kwargs):
        r"""Queries the DetailsView of a given endpoint.

        :arg int,optional key: id for the item to be
            retrieved.

        :arg str,optional \**kwargs: Accepts the same keyword args as
            filter(). Any search argument the endpoint accepts can
            be added as a keyword arg.

        :returns: A single :py:class:`.Record` object or None

        :raises ValueError: if kwarg search return more than one value.

        :Examples:

        Referencing with a kwarg that only returns one value.

        >>> nb.dcim.devices.get(name='test1-a3-tor1b')
        test1-a3-tor1b
        >>>

        Referencing with an id.

        >>> nb.dcim.devices.get(1)
        test1-edge1
        >>>
        """

        try:
            key = args[0]
        except IndexError:
            key = None

        if not key:
            filter_lookup = self.filter(**kwargs)
            if filter_lookup:
                if len(filter_lookup) > 1:
                    raise ValueError(
                        "get() returned more than one result. "
                        "Check that the kwarg(s) passed are valid for this "
                        "endpoint or use filter() or all() instead."
                    )
                else:
                    return filter_lookup[0]
            return None

        try:
            req = Request(
                key=key,
                base=self.url,
                token=self.token,
                session_key=self.session_key,
                http_session=self.api.http_session,
            )
        except RequestError:
            return None

        return response_loader(req.get(), self.return_obj, self)
Пример #4
0
    def getnext(self, *args):

        try:
            offset = args[0]
        except IndexError:
            offset = 0

        req = Request(
            offset=offset,
            base=self.url,
            token=self.token,
            session_key=self.session_key,
            http_session=self.api.http_session,
        )

        return response_loader(req.get(), self.return_obj, self)
Пример #5
0
    def trace(self):
        req = Request(
            key=str(self.id) + "/trace",
            base=self.endpoint.url,
            token=self.api.token,
            session_key=self.api.session_key,
            http_session=self.api.http_session,
        )
        uri_to_obj_class_map = {
            "dcim/cables": Cables,
            "dcim/front-ports": FrontPorts,
            "dcim/interfaces": Interfaces,
            "dcim/rear-ports": RearPorts,
        }
        ret = []
        for (termination_a_data, cable_data, termination_b_data) in req.get():
            this_hop_ret = []
            for hop_item_data in (termination_a_data, cable_data,
                                  termination_b_data):
                # if not fully terminated then some items will be None
                if not hop_item_data:
                    this_hop_ret.append(hop_item_data)
                    continue

                # TODO: Move this to a more general function.
                app_endpoint = "/".join(
                    urlsplit(hop_item_data["url"]
                             [len(self.api.base_url):]).path.split("/")[1:3])

                return_obj_class = uri_to_obj_class_map.get(
                    app_endpoint,
                    Record,
                )

                this_hop_ret.append(
                    return_obj_class(hop_item_data, self.endpoint.api,
                                     self.endpoint))

            ret.append(this_hop_ret)

        return ret
Пример #6
0
    def full_details(self):
        """Queries the hyperlinked endpoint if 'url' is defined.

        This method will populate the attributes from the detail
        endpoint when it's called. Sets the class-level `has_details`
        attribute when it's called to prevent being called more
        than once.

        :returns: True
        """
        if self.url:
            req = Request(
                base=self.url,
                token=self.api.token,
                session_key=self.api.session_key,
                http_session=self.api.http_session,
            )
            self._parse_values(next(req.get()))
            self.has_details = True
            return True
        return False
Пример #7
0
    def all(self):
        """Queries the 'ListView' of a given endpoint.

        Returns all objects from an endpoint.

        :Returns: List of :py:class:`.Record` objects.

        :Examples:

        >>> nb.dcim.devices.all()
        [test1-a3-oobsw2, test1-a3-oobsw3, test1-a3-oobsw4]
        >>>
        """
        req = Request(
            base="{}/".format(self.url),
            token=self.token,
            session_key=self.session_key,
            ssl_verify=self.ssl_verify,
        )

        return [self._response_loader(i) for i in req.get()]
Пример #8
0
    def list(self, **kwargs):
        r"""The view operation for a detail endpoint

        Returns the response from NetBox for a detail endpoint.

        :args \**kwargs: key/value pairs that get converted into url
            parameters when passed to the endpoint.
            E.g. ``.list(method='get_facts')`` would be converted to
            ``.../?method=get_facts``.

        :returns: A dictionary or list of dictionaries retrieved from
            NetBox.
        """
        req = Request(**self.request_kwargs)
        resp = req.get(add_params=kwargs)

        self.api.api_version = req.api_version

        if self.custom_return:
            return response_loader(resp, self.custom_return,
                                   self.parent_obj.endpoint)
        return req
Пример #9
0
    def filter(self, *args, **kwargs):
        r"""Queries the 'ListView' of a given endpoint.

        Takes named arguments that match the usable filters on a
        given endpoint. If an argument is passed then it's used as a
        freeform search argument if the endpoint supports it.

        :arg str,optional \*args: Freeform search string that's
            accepted on given endpoint.
        :arg str,optional \**kwargs: Any search argument the
            endpoint accepts can be added as a keyword arg.

        :Returns: A list of :py:class:`.Record` objects.

        :Examples:

        To return a list of objects matching a named argument filter.

        >>> nb.dcim.devices.filter(role='leaf-switch')
        [test1-a3-tor1b, test1-a3-tor1c, test1-a3-tor1d, test1-a3-tor2a]
        >>>

        Using a freeform query along with a named argument.

        >>> nb.dcim.devices.filter('a3', role='leaf-switch')
        [test1-a3-tor1b, test1-a3-tor1c, test1-a3-tor1d, test1-a3-tor2a]
        >>>

        Chaining multiple named arguments.

        >>> nb.dcim.devices.filter(role='leaf-switch', status=True)
        [test1-leaf2]
        >>>

        Passing a list as a named argument adds multiple filters of the
        same value.

        >>> nb.dcim.devices.filter(role=['leaf-switch', 'spine-switch'])
        [test1-a3-spine1, test1-a3-spine2, test1-a3-leaf1]
        >>>
        """

        if args:
            kwargs.update({"q": args[0]})

        if not kwargs:
            raise ValueError(
                "filter must be passed kwargs. Perhaps use all() instead."
            )
        if any(i in RESERVED_KWARGS for i in kwargs):
            raise ValueError(
                "A reserved {} kwarg was passed. Please remove it "
                "try again.".format(RESERVED_KWARGS)
            )

        req = Request(
            filters=kwargs,
            base=self.url,
            token=self.token,
            session_key=self.session_key,
            ssl_verify=self.ssl_verify,
            http_session=self.api.http_session,
            threading=self.api.threading,
        )

        ret = [self._response_loader(i) for i in req.get()]
        return ret
Пример #10
0
    def test_pagination(self):
        test_obj = Request(http_session=Mock(),
                           base="http://localhost:8001/api/dcim/devices/",
                           limit=2,
                           external_proxy=False)

        test_obj.http_session.get.return_value.json.return_value = {
            "count":
            6,
            "next":
            "http://localhost:8001/api/dcim/devices/?limit=2&offset=2",
            "previous":
            None,
            "results": [
                {
                    'id': 87861,
                    'url': 'https://localhost:8001/api/dcim/devices/87861/',
                    'name': 'test87861'
                },
                {
                    'id': 87862,
                    'url': 'https://localhost:8001/api/dcim/devices/87862/',
                    'name': 'test87862'
                },
            ],
        }
        test = test_obj.get()
        req = next(test)
        test_obj.http_session.get.assert_called_with(
            "http://localhost:8001/api/dcim/devices/",
            headers={"accept": "application/json;"},
            params={"limit": 2},
            json=None,
        )
        self.assertEqual(
            req, {
                'id': 87861,
                'url': 'https://localhost:8001/api/dcim/devices/87861/',
                'name': 'test87861'
            })
        req = next(test)
        self.assertEqual(
            req, {
                'id': 87862,
                'url': 'https://localhost:8001/api/dcim/devices/87862/',
                'name': 'test87862'
            })

        test_obj.http_session.get.return_value.json.return_value = {
            "count":
            2,
            "next":
            "http://localhost:8001/api/dcim/devices/?limit=2&offset=4",
            "previous":
            "http://localhost:8001/api/dcim/devices/?limit=2",
            "results": [
                {
                    'id': 87863,
                    'url': 'https://localhost:8001/api/dcim/devices/87863/',
                    'name': 'test87863'
                },
                {
                    'id': 87864,
                    'url': 'https://localhost:8001/api/dcim/devices/87864/',
                    'name': 'test87864'
                },
            ],
        }
        req = next(test)
        test_obj.http_session.get.assert_called_with(
            "http://localhost:8001/api/dcim/devices/",
            headers={"accept": "application/json;"},
            params={
                "limit": 2,
                "offset": 2
            },
            json=None,
        )
        self.assertEqual(
            req, {
                'id': 87863,
                'url': 'https://localhost:8001/api/dcim/devices/87863/',
                'name': 'test87863'
            })
        req = next(test)
        self.assertEqual(
            req, {
                'id': 87864,
                'url': 'https://localhost:8001/api/dcim/devices/87864/',
                'name': 'test87864'
            })

        test_obj.http_session.get.return_value.json.return_value = {
            "count":
            2,
            "next":
            None,
            "previous":
            "http://localhost:8001/api/dcim/devices/?limit=2&offset=4",
            "results": [
                {
                    'id': 87865,
                    'url': 'https://localhost:8001/api/dcim/devices/87865/',
                    'name': 'test87865'
                },
                {
                    'id': 87866,
                    'url': 'https://localhost:8001/api/dcim/devices/87866/',
                    'name': 'test87866'
                },
            ],
        }
        req = next(test)
        test_obj.http_session.get.assert_called_with(
            "http://localhost:8001/api/dcim/devices/?limit=2&offset=4",
            headers={"accept": "application/json;"},
            params={},
            json=None,
        )
        self.assertEqual(
            req, {
                'id': 87865,
                'url': 'https://localhost:8001/api/dcim/devices/87865/',
                'name': 'test87865'
            })
        req = next(test)
        self.assertEqual(
            req, {
                'id': 87866,
                'url': 'https://localhost:8001/api/dcim/devices/87866/',
                'name': 'test87866'
            })