Skip to content

Commit 736b789

Browse files
author
Zach Moody
authored
Merge pull request #112 from digitalocean/106-ru-detail-endpoint
Fixes #106 - Rack Unit DetailEndpoint
2 parents 0626ef7 + 7168f48 commit 736b789

File tree

5 files changed

+111
-25
lines changed

5 files changed

+111
-25
lines changed

pynetbox/dcim.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,7 @@ def napalm(self):
6060
{"get_facts": {"interface_list": ["ge-0/0/0"]}}
6161
6262
"""
63-
return RODetailEndpoint(
64-
'napalm',
65-
parent_obj=self,
66-
)
63+
return RODetailEndpoint(self, 'napalm')
6764

6865

6966
class InterfaceConnections(Record):
@@ -92,3 +89,29 @@ class VirtualChassis(Record):
9289

9390
def __str__(self):
9491
return self.master.display_name
92+
93+
94+
class RUs(Record):
95+
96+
device = Devices
97+
98+
99+
class Racks(Record):
100+
101+
@property
102+
def units(self):
103+
""" Represents the ``units`` detail endpoint.
104+
105+
Returns a DetailEndpoint object that is the interface for
106+
viewing response from the units endpoint.
107+
108+
:returns: :py:class:`.DetailEndpoint`
109+
110+
:Examples:
111+
112+
>>> rack = nb.dcim.racks.get(123)
113+
>>> rack.units.list()
114+
{"get_facts": {"interface_list": ["ge-0/0/0"]}}
115+
116+
"""
117+
return RODetailEndpoint(self, 'units', custom_return=RUs)

pynetbox/ipam.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@ def available_ips(self):
5757
>>> len(create)
5858
2
5959
"""
60-
return DetailEndpoint(
61-
'available-ips',
62-
parent_obj=self,
63-
)
60+
return DetailEndpoint(self, 'available-ips')
6461

6562
@property
6663
def available_prefixes(self):
@@ -91,10 +88,7 @@ def available_prefixes(self):
9188
u'10.1.1.56/29'
9289
9390
'''
94-
return DetailEndpoint(
95-
'available-prefixes',
96-
parent_obj=self,
97-
)
91+
return DetailEndpoint(self, 'available-prefixes')
9892

9993

10094
class Aggregates(IPRecord):

pynetbox/lib/endpoint.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -305,22 +305,20 @@ class DetailEndpoint(object):
305305
traditional endpoints are handled with this class.
306306
'''
307307

308-
def __init__(self, name, parent_obj=None):
309-
self.token = parent_obj.api_kwargs.get('token')
310-
self.version = parent_obj.api_kwargs.get('version')
311-
self.session_key = parent_obj.api_kwargs.get('session_key')
312-
self.ssl_verify = parent_obj.api_kwargs.get('ssl_verify')
308+
def __init__(self, parent_obj, name, custom_return=None):
309+
self.parent_obj = parent_obj
310+
self.custom_return = custom_return
313311
self.url = "{}/{}/{}/".format(
314312
parent_obj.endpoint_meta.get('url'),
315313
parent_obj.id,
316314
name
317315
)
318316
self.request_kwargs = dict(
319317
base=self.url,
320-
token=self.token,
321-
session_key=self.session_key,
322-
version=self.version,
323-
ssl_verify=self.ssl_verify,
318+
token=parent_obj.api_kwargs.get('token'),
319+
session_key=parent_obj.api_kwargs.get('session_key'),
320+
version=parent_obj.api_kwargs.get('version'),
321+
ssl_verify=parent_obj.api_kwargs.get('ssl_verify'),
324322
)
325323

326324
def list(self, **kwargs):
@@ -333,16 +331,32 @@ def list(self, **kwargs):
333331
E.g. ``.list(method='get_facts')`` would be converted to
334332
``.../?method=get_facts``.
335333
336-
:returns: A dictionary or list of dictionaries its retrieved
337-
from NetBox.
334+
:returns: A dictionary or list of dictionaries retrieved from
335+
NetBox.
338336
"""
339337
if kwargs:
340338
self.request_kwargs['base'] = '{}{}'.format(
341339
self.url,
342340
url_param_builder(kwargs)
343341
)
344-
345-
return Request(**self.request_kwargs).get()
342+
req = Request(**self.request_kwargs).get()
343+
344+
if self.custom_return:
345+
if isinstance(req, list):
346+
return [
347+
self.custom_return(
348+
i,
349+
api_kwargs=self.parent_obj.api_kwargs,
350+
endpoint_meta=self.parent_obj.endpoint_meta
351+
)
352+
for i in req
353+
]
354+
return self.custom_return(
355+
req,
356+
api_kwargs=self.parent_obj.api_kwargs,
357+
endpoint_meta=self.parent_obj.endpoint_meta
358+
)
359+
return req
346360

347361
def create(self, data={}):
348362
"""The write operation for a detail endpoint.

tests/fixtures/dcim/rack_u.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"count": 3,
3+
"next": null,
4+
"previous": null,
5+
"results": [
6+
{
7+
"id": 48,
8+
"name": "U1",
9+
"face": 0,
10+
"device": {
11+
"id": 130,
12+
"url": "http://localhost:8000/api/dcim/devices/1/",
13+
"name": "tst-device1",
14+
"display_name": "tst-device1"
15+
}
16+
},
17+
{
18+
"id": 47,
19+
"name": "U2",
20+
"face": 0,
21+
"device": null
22+
},
23+
{
24+
"id": 46,
25+
"name": "U3",
26+
"face": 0,
27+
"device": {
28+
"id": 1859,
29+
"url": "http://localhost:8000/api/dcim/devices/2/",
30+
"name": "tst-device2",
31+
"display_name": "tst-device2"
32+
}
33+
}
34+
]
35+
}

tests/test_dcim.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,26 @@ def test_get_all(self, mock):
381381
class RackTestCase(unittest.TestCase, GenericTest):
382382
name = 'racks'
383383

384+
@patch(
385+
'pynetbox.lib.query.requests.get',
386+
side_effect=[
387+
Response(fixture='dcim/rack.json'),
388+
Response(fixture='dcim/rack_u.json'),
389+
]
390+
)
391+
def test_get_units(self, mock):
392+
test = nb.racks.get(1)
393+
ret = test.units.list()
394+
mock.assert_called_with(
395+
'http://localhost:8000/api/dcim/racks/1/units/',
396+
headers=HEADERS,
397+
verify=True,
398+
)
399+
self.assertTrue(ret)
400+
self.assertTrue(
401+
isinstance(ret[0].device, pynetbox.dcim.Devices)
402+
)
403+
384404

385405
class RackRoleTestCase(unittest.TestCase, GenericTest):
386406
name = 'rack_roles'

0 commit comments

Comments
 (0)