From eb9f2b36ab740eae2ac33a38814f92ff8c82115d Mon Sep 17 00:00:00 2001 From: Brian Candler Date: Sun, 15 Aug 2021 16:04:38 +0000 Subject: [PATCH 01/10] Display device names in front of device front/rear images Fixes #6879 --- netbox/dcim/svg.py | 6 + netbox/project-static/dist/netbox.js | Bin 322508 -> 322556 bytes netbox/project-static/dist/netbox.js.map | Bin 310799 -> 310813 bytes netbox/project-static/src/racks.ts | 132 +++++++++--------- .../project-static/src/stores/rackImages.ts | 6 +- netbox/templates/dcim/rack.html | 9 +- .../templates/dcim/rack_elevation_list.html | 10 +- 7 files changed, 87 insertions(+), 76 deletions(-) diff --git a/netbox/dcim/svg.py b/netbox/dcim/svg.py index f8e7bdf10..5601bc591 100644 --- a/netbox/dcim/svg.py +++ b/netbox/dcim/svg.py @@ -112,6 +112,9 @@ class RackElevationSVG: ) image.fit(scale='slice') link.add(image) + link.add(drawing.text(str(name), insert=text, stroke='black', + stroke_width='0.2em', stroke_linejoin='round', class_='device-image-label')) + link.add(drawing.text(str(name), insert=text, fill='white', class_='device-image-label')) def _draw_device_rear(self, drawing, device, start, end, text): rect = drawing.rect(start, end, class_="slot blocked") @@ -129,6 +132,9 @@ class RackElevationSVG: ) image.fit(scale='slice') drawing.add(image) + drawing.add(drawing.text(str(device), insert=text, stroke='black', + stroke_width='0.2em', stroke_linejoin='round', class_='device-image-label')) + drawing.add(drawing.text(str(device), insert=text, fill='white', class_='device-image-label')) @staticmethod def _draw_empty(drawing, rack, start, end, text, id_, face_id, class_, reservation): diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index 24524fad37ab67fb5c75fb4c80eb9ec14dc382a0..cc12e4855709dd686515e62961911c0a21a59033 100644 GIT binary patch delta 14958 zcmb7rcYIsb_4w!B_q;Q396NF1#J21>QgW@>*|GAHShnRY$&y#>7)O?#hOK37F9H-w zNy11ja9Lrrw6u&2obuQd8Ym;s252dx%(6-s6j~sR-+52A0&Ty)-}m>2b>AKD+;h)9 z=RTi&G4IP4^De)K>+%XTV9r1An^LaTD=>czDyDhp$GFu?|B4D1dYtMmuf`b&sbjWK ziN7S^Ea{@}p&h7^s<9V-uf*R+t+a@P=jn^Ng9z2rqO^7JYfgJNvpuR2woSB0>CL(M z)SA97uUQ$8K}D^?n5fq1n&~y^!`K+5yALcxBXmi|63!e|P@=)@*-MGTDwv}c6{RCl zt=;DJswb*z)=rUXjm}6%GYXNJ?#n1!G7_EA=wzt1At9kwx0#7W*~k*5rN#O5jk7Z8 zI~nGs!>Qe!R$*dF8wpq=A&=js8 zPcHg2Ye}X-0c1!HT%Vmow`FfcdK%3(VEyctS@f0c^+i2V86k_AjHmVB(ijz5VWbsCHWPn@)P;17(d}w~L}-j^!$GenqE=~D8d68!&KXC&^z1pM zOIuQybVP-=5Ma=2ebh9! z4T}zXXzpUUk>>6%@;l_^1~Z8`WU-L>RUa0HWhsczH%pgIPtKc*w&=~oqs)68S}_p} zgd$;~6!uj3+pO?++)M%~5Fv*`HeCQfET%8dUxGsP)A{S+chy-X$VOYwDs+Y&f@*Nk z9teq*!{NcO+ZGZXgM%t!vI?En{;*?Uax!66haF@B_OYGW*JPd9*R1T@Z6@~AzO`1N zT_%#(A&fw)Q`;2;Ue8F+F7Z10BLGwFr5~Sl-TY|kojR)!_0zzD68b=HF>=sXb1UGN zTVN`6rq;Aug(}hvz-Tu5 z974Seu*oX;DOy-cYxDEzZ?bt>wTsVmIn*-17;RkGBX>MX=O+u#TiTEUWB|c&006yJ z0i9n8;{)g`~Q#hQ9&+?o{s!5Ji)!@{^#>j>DRJ`p6i$0`gu)XiZ{ zMTOF8?IFPkrbx(c#>vOz*yeC*&*2D+8)t1 z(rydFx|9M%#)2Z4?q+(!k`+R;Lo=(v7DcYZMq*6CbimPM<~!p_sWO9p#nq}2aV)Ho zt!`4fvWR&`#+6oZ#z87HQ#0yP=aDttW+WB`tc5l&Ednd*T-uC=r;jczMEOlXxQNyz zMu;ISKe=sTGD=@7T80et%c4>=Oy69Vk4EYGWoj_S1Mq90-(S|Jj7R1+Ip8%i>L5

!^PLa zZ(qqC)I(n`DW`9g=7X|j(W25y)J@G!doJO*fN~IdK6DFD}dzC@A zku;_dv4E_|TMx$tpWHUZg)UhsS{?Mwtc7$~b#z7J84gW&{C02DA%<&O9qQ65kO;p+ zOqiTCt#o@?!MctVSUu>4EOMhW;LGDeFM!p~tS5%JP$#>W4!~V_3N?o2<`wSs0cCj1NJ7q8+us;Z9;7!e_?>W| z4iGq5h+9CILC16j?S9}e>_pK}fqyFN`jq?KXOVLiD8(z}cQj2dY zOP}7Nu05>(_+@ar^^XlkXiQ!oPGbWu9E zT3;Mg79@We@z7z;o zrx1i==zKHi=g?DRS++sZ%332CqMs3x?vf80n_g9EMkq!nv}@t_u(k{h(dV=mqA^;n zE1>>0nea4AFrWdwa!n6vkmvY#Cz#xfsuj?!tny`8mEEn=H&>>*CV{7}D zcREuhqrP*7qqWKsvyqtSs T33e%$b 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¥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 Az5oCK diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index be7ed66c0701aa6c317101644c1248000206b25f..a67c6cbd814471217b565895629019f22877c9f2 100644 GIT binary patch delta 755 zcmbVKJxc>Y5G7`@4iO7GI}5ikK~c-u%_W@2e6wkkh@j0dJ3BM)&6~L%#qUP(i*BSl)r~%ir(Tk(N@j>$X%p4h z)vHQsB1<|PZ7R}Rtc)xX9dK3sm#WVH%Dz?kh1GkZs*yE`G%f zUk74t?=Jw@pbaQ5@dE(%0w!k5HZ$>=UOjxd6|-yll*vY5ao2s6cRxV7B-@V3n~&)Sk2Dug(Sq~IL?qV2paW*A3+jqv9k`ah(!L^V zfSc~t$Ob@zW~j4XiZn9jx#a`2d@@t*YKD$24l`Fy zHY5jT+rEy(!mbOJgK_8>Fm>&m#)N|nB}o+%pNI6GaxQ}I+QFk(S!z#zLh+s<{ZA*F ixQb=_JrJw5GZu3>U?UnZpfxfn?n{G7;1BIs+

- +
+ +
Front Rear From 6d1f07df0589ad4600d8d8702e001e98151dce10 Mon Sep 17 00:00:00 2001 From: HumanEquivalentUnit Date: Thu, 7 Oct 2021 00:51:07 +0100 Subject: [PATCH 02/10] Mention data in custom fields, link Jinja2 docs. Resolves #7367 --- docs/models/extras/customlink.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/models/extras/customlink.md b/docs/models/extras/customlink.md index 44c8f403f..3b502cab2 100644 --- a/docs/models/extras/customlink.md +++ b/docs/models/extras/customlink.md @@ -1,8 +1,8 @@ # Custom Links -Custom links allow users to display arbitrary hyperlinks to external content within NetBox object views. These are helpful for cross-referencing related records in systems outside NetBox. For example, you might create a custom link on the device view which links to the current device in a network monitoring system. +Custom links allow users to display arbitrary hyperlinks to external content within NetBox object views. These are helpful for cross-referencing related records in systems outside NetBox. For example, you might create a custom link on the device view which links to the current device in a Network Monitoring System (NMS). -Custom links are created by navigating to Customization > Custom Links. Each link is associated with a particular NetBox object type (site, device, prefix, etc.) and will be displayed on relevant views. Each link is assigned text and a URL, both of which support Jinja2 templating. The text and URL are rendered with the context variable `obj` representing the current object. +Custom links are created by navigating to Customization > Custom Links. Each link is associated with a particular NetBox object type (site, device, prefix, etc.) and will be displayed on relevant views. Each link has display text and a URL, and data from the Netbox item being viewed can be included in the link using [Jinja2 template code](https://jinja2docs.readthedocs.io/en/stable/) through the variable `obj`, and custom fields through `obj.cf`. For example, you might define a link like this: From f28761202faf15332b27ae83c0cc715b8c84d3b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Hofst=C3=A4tter?= <6820505+alexanderhofstaetter@users.noreply.github.com> Date: Thu, 7 Oct 2021 14:31:54 +0200 Subject: [PATCH 03/10] Added "USB Micro AB" combo type to choices --- netbox/dcim/choices.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index f8fbab86b..acea294f8 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -192,6 +192,7 @@ class ConsolePortTypeChoices(ChoiceSet): TYPE_USB_MINI_B = 'usb-mini-b' TYPE_USB_MICRO_A = 'usb-micro-a' TYPE_USB_MICRO_B = 'usb-micro-b' + TYPE_USB_MICRO_AB = 'usb-micro-ab' TYPE_OTHER = 'other' CHOICES = ( @@ -210,6 +211,7 @@ class ConsolePortTypeChoices(ChoiceSet): (TYPE_USB_MINI_B, 'USB Mini B'), (TYPE_USB_MICRO_A, 'USB Micro A'), (TYPE_USB_MICRO_B, 'USB Micro B'), + (TYPE_USB_MICRO_AB, 'USB Micro AB'), )), ('Other', ( (TYPE_OTHER, 'Other'), @@ -337,6 +339,7 @@ class PowerPortTypeChoices(ChoiceSet): TYPE_USB_MINI_B = 'usb-mini-b' TYPE_USB_MICRO_A = 'usb-micro-a' TYPE_USB_MICRO_B = 'usb-micro-b' + TYPE_USB_MICRO_AB = 'usb-micro-ab' TYPE_USB_3_B = 'usb-3-b' TYPE_USB_3_MICROB = 'usb-3-micro-b' # Direct current (DC) @@ -444,6 +447,7 @@ class PowerPortTypeChoices(ChoiceSet): (TYPE_USB_MINI_B, 'USB Mini B'), (TYPE_USB_MICRO_A, 'USB Micro A'), (TYPE_USB_MICRO_B, 'USB Micro B'), + (TYPE_USB_MICRO_AB, 'USB Micro AB'), (TYPE_USB_3_B, 'USB 3.0 Type B'), (TYPE_USB_3_MICROB, 'USB 3.0 Micro B'), )), From 3f766ffea805a96c4bbb9621ac26b722ac7354e8 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 7 Oct 2021 09:37:21 -0400 Subject: [PATCH 04/10] Fixes #7474: Fix AttributeError exception when rendering a report or custom script --- docs/release-notes/version-3.0.md | 8 ++++++++ netbox/templates/extras/report.html | 4 ++++ netbox/templates/extras/script.html | 4 ++++ netbox/templates/generic/object.html | 12 +++++++----- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index 41c551d9c..6f647d472 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -1,5 +1,13 @@ # NetBox v3.0 +## v3.0.7 (FUTURE) + +### Bug Fixes + +* [#7474](https://github.com/netbox-community/netbox/issues/7474) - Fix AttributeError exception when rendering a report or custom script + +--- + ## v3.0.6 (2021-10-06) ### Enhancements diff --git a/netbox/templates/extras/report.html b/netbox/templates/extras/report.html index 2d65dc88e..c61cc92c5 100644 --- a/netbox/templates/extras/report.html +++ b/netbox/templates/extras/report.html @@ -3,6 +3,10 @@ {% block title %}{{ report.name }}{% endblock %} +{% block object_identifier %} + {{ report.full_name }} +{% endblock %} + {% block breadcrumbs %} diff --git a/netbox/templates/extras/script.html b/netbox/templates/extras/script.html index 2c59afe6d..3a50e09a1 100644 --- a/netbox/templates/extras/script.html +++ b/netbox/templates/extras/script.html @@ -5,6 +5,10 @@ {% block title %}{{ script }}{% endblock %} +{% block object_identifier %} + {{ script.full_name }} +{% endblock %} + {% block breadcrumbs %} diff --git a/netbox/templates/generic/object.html b/netbox/templates/generic/object.html index 7be7f811c..24285846f 100644 --- a/netbox/templates/generic/object.html +++ b/netbox/templates/generic/object.html @@ -9,15 +9,17 @@ {# Breadcrumbs #} {{ block.super }} From b73db750e540474937be01928899dbdce7bc3b5b Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 7 Oct 2021 09:58:42 -0400 Subject: [PATCH 05/10] Fixes #7471: Correct redirect URL when attaching images via "add another" button --- docs/release-notes/version-3.0.md | 1 + netbox/netbox/views/generic.py | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index 6f647d472..d7afbfa8e 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -4,6 +4,7 @@ ### Bug Fixes +* [#7471](https://github.com/netbox-community/netbox/issues/7471) - Correct redirect URL when attaching images via "add another" button * [#7474](https://github.com/netbox-community/netbox/issues/7474) - Fix AttributeError exception when rendering a report or custom script --- diff --git a/netbox/netbox/views/generic.py b/netbox/netbox/views/generic.py index 41a8cee25..f9c121cc0 100644 --- a/netbox/netbox/views/generic.py +++ b/netbox/netbox/views/generic.py @@ -282,14 +282,11 @@ class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View): messages.success(request, mark_safe(msg)) if '_addanother' in request.POST: - redirect_url = request.path - return_url = request.GET.get('return_url') - if return_url is not None and is_safe_url(url=return_url, allowed_hosts=request.get_host()): - redirect_url = f'{redirect_url}?return_url={return_url}' + redirect_url = request.get_full_path() # If the object has clone_fields, pre-populate a new instance of the form if hasattr(obj, 'clone_fields'): - redirect_url += f"{'&' if return_url else '?'}{prepare_cloned_fields(obj)}" + redirect_url += f"{'&' if '?' in redirect_url else '?'}{prepare_cloned_fields(obj)}" return redirect(redirect_url) From 53154746fc49c421f312e82a80127bf047c9d339 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 7 Oct 2021 10:40:51 -0400 Subject: [PATCH 06/10] Changelog for #7485 --- docs/release-notes/version-3.0.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index d7afbfa8e..09fb14a4b 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -2,6 +2,10 @@ ## v3.0.7 (FUTURE) +### Enhancements + +* [#7485](https://github.com/netbox-community/netbox/issues/7485) - Add USB micro AB type + ### Bug Fixes * [#7471](https://github.com/netbox-community/netbox/issues/7471) - Correct redirect URL when attaching images via "add another" button From b31ba4e9d2cdbceee829e240780a33d58a65c87e Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 7 Oct 2021 12:41:24 -0400 Subject: [PATCH 07/10] Changelog & UI tweaks for #6879 --- docs/release-notes/version-3.0.md | 1 + netbox/templates/dcim/rack.html | 12 +++++++----- netbox/templates/dcim/rack_elevation_list.html | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index 09fb14a4b..d6e92499c 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -4,6 +4,7 @@ ### Enhancements +* [#6879](https://github.com/netbox-community/netbox/issues/6879) - Improve ability to toggle images/labels in rack elevations * [#7485](https://github.com/netbox-community/netbox/issues/7485) - Add USB micro AB type ### Bug Fixes diff --git a/netbox/templates/dcim/rack.html b/netbox/templates/dcim/rack.html index 98009cb55..5d44e2125 100644 --- a/netbox/templates/dcim/rack.html +++ b/netbox/templates/dcim/rack.html @@ -18,11 +18,6 @@ {% endblock %} {% block extra_controls %} - Previous @@ -272,6 +267,13 @@ {% plugin_left_page object %}
+
+ +
diff --git a/netbox/templates/dcim/rack_elevation_list.html b/netbox/templates/dcim/rack_elevation_list.html index f5641c944..312b543a6 100644 --- a/netbox/templates/dcim/rack_elevation_list.html +++ b/netbox/templates/dcim/rack_elevation_list.html @@ -8,7 +8,7 @@
- From 00328226ecfbc70cb83473bad18c2930ac8d6b24 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 7 Oct 2021 13:15:59 -0400 Subject: [PATCH 08/10] Fixes #7051: Fix permissions evaluation and improve error handling for connected device REST API endpoint --- docs/release-notes/version-3.0.md | 1 + netbox/dcim/api/views.py | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index d6e92499c..dbc04e3b5 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -9,6 +9,7 @@ ### Bug Fixes +* [#7051](https://github.com/netbox-community/netbox/issues/7051) - Fix permissions evaluation and improve error handling for connected device REST API endpoint * [#7471](https://github.com/netbox-community/netbox/issues/7471) - Correct redirect URL when attaching images via "add another" button * [#7474](https://github.com/netbox-community/netbox/issues/7474) - Fix AttributeError exception when rendering a report or custom script diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 3d23cde5c..2b9d9734c 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -2,7 +2,7 @@ import socket from collections import OrderedDict from django.conf import settings -from django.http import HttpResponseForbidden, HttpResponse +from django.http import Http404, HttpResponse, HttpResponseForbidden from django.shortcuts import get_object_or_404 from drf_yasg import openapi from drf_yasg.openapi import Parameter @@ -17,10 +17,10 @@ from dcim import filtersets from dcim.models import * from extras.api.views import ConfigContextQuerySetMixin, CustomFieldModelViewSet from ipam.models import Prefix, VLAN -from netbox.api.views import ModelViewSet from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired from netbox.api.exceptions import ServiceUnavailable from netbox.api.metadata import ContentTypeMetadata +from netbox.api.views import ModelViewSet from utilities.api import get_serializer_for_model from utilities.utils import count_related, decode_dict from virtualization.models import VirtualMachine @@ -675,15 +675,25 @@ class ConnectedDeviceViewSet(ViewSet): if not peer_device_name or not peer_interface_name: raise MissingFilterException(detail='Request must include "peer_device" and "peer_interface" filters.') - # Determine local interface from peer interface's connection + # Determine local endpoint from peer interface's connection + peer_device = get_object_or_404( + Device.objects.restrict(request.user, 'view'), + name=peer_device_name + ) peer_interface = get_object_or_404( - Interface.objects.all(), - device__name=peer_device_name, + Interface.objects.restrict(request.user, 'view'), + device=peer_device, name=peer_interface_name ) - local_interface = peer_interface.connected_endpoint + endpoint = peer_interface.connected_endpoint - if local_interface is None: - return Response() + # If an Interface, return the parent device + if type(endpoint) is Interface: + device = get_object_or_404( + Device.objects.restrict(request.user, 'view'), + pk=endpoint.device_id + ) + return Response(serializers.DeviceSerializer(device, context={'request': request}).data) - return Response(serializers.DeviceSerializer(local_interface.device, context={'request': request}).data) + # Connected endpoint is none or not an Interface + raise Http404 From af6237e12ec144ea40498dadd071c919dec4ac92 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 7 Oct 2021 13:57:00 -0400 Subject: [PATCH 09/10] Fixes #7479: Fix parent interface choices when bulk editing VM interfaces --- docs/release-notes/version-3.0.md | 1 + netbox/netbox/views/generic.py | 2 ++ netbox/templates/virtualization/virtualmachine/interfaces.html | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index dbc04e3b5..015935884 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -12,6 +12,7 @@ * [#7051](https://github.com/netbox-community/netbox/issues/7051) - Fix permissions evaluation and improve error handling for connected device REST API endpoint * [#7471](https://github.com/netbox-community/netbox/issues/7471) - Correct redirect URL when attaching images via "add another" button * [#7474](https://github.com/netbox-community/netbox/issues/7474) - Fix AttributeError exception when rendering a report or custom script +* [#7479](https://github.com/netbox-community/netbox/issues/7479) - Fix parent interface choices when bulk editing VM interfaces --- diff --git a/netbox/netbox/views/generic.py b/netbox/netbox/views/generic.py index f9c121cc0..4baf2e0e9 100644 --- a/netbox/netbox/views/generic.py +++ b/netbox/netbox/views/generic.py @@ -877,6 +877,8 @@ class BulkEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View): initial_data['device'] = request.GET.get('device') elif 'device_type' in request.GET: initial_data['device_type'] = request.GET.get('device_type') + elif 'virtual_machine' in request.GET: + initial_data['virtual_machine'] = request.GET.get('virtual_machine') form = self.form(model, initial=initial_data) restrict_form_fields(form, request.user) diff --git a/netbox/templates/virtualization/virtualmachine/interfaces.html b/netbox/templates/virtualization/virtualmachine/interfaces.html index 496b0a8a6..143c8c70b 100644 --- a/netbox/templates/virtualization/virtualmachine/interfaces.html +++ b/netbox/templates/virtualization/virtualmachine/interfaces.html @@ -13,7 +13,7 @@ - {% endif %} From c63766c4c6535c5d0eaf46975ee8d62e593fbe0c Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 7 Oct 2021 14:19:29 -0400 Subject: [PATCH 10/10] Fix test for #7051 --- netbox/dcim/tests/test_api.py | 36 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index 002a4513f..e5977b760 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -1,4 +1,5 @@ from django.contrib.auth.models import User +from django.test import override_settings from django.urls import reverse from rest_framework import status @@ -1490,40 +1491,35 @@ class ConnectedDeviceTest(APITestCase): super().setUp() - self.site1 = Site.objects.create(name='Test Site 1', slug='test-site-1') - self.site2 = Site.objects.create(name='Test Site 2', slug='test-site-2') - manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') - self.devicetype1 = DeviceType.objects.create( - manufacturer=manufacturer, model='Test Device Type 1', slug='test-device-type-1' - ) - self.devicetype2 = DeviceType.objects.create( - manufacturer=manufacturer, model='Test Device Type 2', slug='test-device-type-2' - ) - self.devicerole1 = DeviceRole.objects.create( - name='Test Device Role 1', slug='test-device-role-1', color='ff0000' - ) - self.devicerole2 = DeviceRole.objects.create( - name='Test Device Role 2', slug='test-device-role-2', color='00ff00' - ) + site = Site.objects.create(name='Site 1', slug='site-1') + manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1') + devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1', slug='device-type-1') + devicerole = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1', color='ff0000') self.device1 = Device.objects.create( - device_type=self.devicetype1, device_role=self.devicerole1, name='TestDevice1', site=self.site1 + device_type=devicetype, device_role=devicerole, name='TestDevice1', site=site ) self.device2 = Device.objects.create( - device_type=self.devicetype1, device_role=self.devicerole1, name='TestDevice2', site=self.site1 + device_type=devicetype, device_role=devicerole, name='TestDevice2', site=site ) self.interface1 = Interface.objects.create(device=self.device1, name='eth0') self.interface2 = Interface.objects.create(device=self.device2, name='eth0') + self.interface3 = Interface.objects.create(device=self.device1, name='eth1') # Not connected cable = Cable(termination_a=self.interface1, termination_b=self.interface2) cable.save() + @override_settings(EXEMPT_VIEW_PERMISSIONS=['*']) def test_get_connected_device(self): - url = reverse('dcim-api:connected-device-list') - response = self.client.get(url + '?peer_device=TestDevice2&peer_interface=eth0', **self.header) + url_params = f'?peer_device={self.device1.name}&peer_interface={self.interface1.name}' + response = self.client.get(url + url_params, **self.header) self.assertHttpStatus(response, status.HTTP_200_OK) - self.assertEqual(response.data['name'], self.device1.name) + self.assertEqual(response.data['name'], self.device2.name) + + url_params = f'?peer_device={self.device1.name}&peer_interface={self.interface3.name}' + response = self.client.get(url + url_params, **self.header) + self.assertHttpStatus(response, status.HTTP_404_NOT_FOUND) class VirtualChassisTest(APIViewTestCases.APIViewTestCase):