Skip to content

Commit ff7dd82

Browse files
authored
Merge pull request #40 from kpetremann/device_decommissioning__webui
Device decommissioning webui
2 parents 82bf5ce + 9bd00e9 commit ff7dd82

23 files changed

+230
-38
lines changed

netbox_cmdb/netbox_cmdb/api/bgp/serializers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.core.exceptions import ValidationError
22
from django.db.models import Q
33
from ipam.api.nested_serializers import NestedIPAddressSerializer
4+
from netbox.api.serializers import WritableNestedSerializer
45
from rest_framework import serializers
56
from rest_framework.serializers import (
67
IntegerField,
@@ -9,7 +10,6 @@
910
)
1011
from tenancy.api.nested_serializers import NestedTenantSerializer
1112

12-
from netbox.api.serializers import WritableNestedSerializer
1313
from netbox_cmdb.api.common_serializers import CommonDeviceSerializer
1414
from netbox_cmdb.choices import AssetMonitoringStateChoices
1515
from netbox_cmdb.constants import BGP_MAX_ASN, BGP_MIN_ASN

netbox_cmdb/netbox_cmdb/api/bgp/views.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
from django.db import transaction
33
from django_pglocks import advisory_lock
44
from drf_yasg.utils import swagger_auto_schema
5+
from netbox.api.viewsets.mixins import ObjectValidationMixin
56
from rest_framework import status
67
from rest_framework.exceptions import ValidationError
78
from rest_framework.response import Response
89
from rest_framework.views import APIView
910

10-
from netbox.api.viewsets.mixins import ObjectValidationMixin
1111
from netbox_cmdb import filtersets
1212
from netbox_cmdb.api.bgp.serializers import (
1313
AvailableAsnSerializer,

netbox_cmdb/netbox_cmdb/api/bgp_community_list/serializers.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""Route Policy serializers."""
22

3+
from rest_framework.serializers import ModelSerializer, ValidationError
4+
35
from netbox_cmdb.api.common_serializers import CommonDeviceSerializer
46
from netbox_cmdb.models.bgp_community_list import BGPCommunityList, BGPCommunityListTerm
5-
from rest_framework.serializers import ModelSerializer, ValidationError
67

78

89
class BGPCommunityListTermSerializer(ModelSerializer):

netbox_cmdb/netbox_cmdb/api/cmdb/views.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
from drf_yasg import openapi
44
from drf_yasg.openapi import Parameter
55
from drf_yasg.utils import swagger_auto_schema
6+
from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
67
from rest_framework import serializers, status
78
from rest_framework.response import Response
89
from rest_framework.views import APIView
910

10-
from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
1111
from netbox_cmdb.models.bgp import BGPPeerGroup, BGPSession, DeviceBGPSession
12+
from netbox_cmdb.models.bgp_community_list import BGPCommunityList
1213
from netbox_cmdb.models.prefix_list import PrefixList
1314
from netbox_cmdb.models.route_policy import RoutePolicy
1415
from netbox_cmdb.models.snmp import SNMP
@@ -37,8 +38,8 @@ def post(self, request):
3738
{"error": "Device name is required"}, status=status.HTTP_400_BAD_REQUEST
3839
)
3940

40-
with transaction.atomic():
41-
try:
41+
try:
42+
with transaction.atomic():
4243
# Delete objects in reverse order of dependencies
4344
BGPSession.objects.filter(
4445
Q(peer_a__device__name=device_name) | Q(peer_b__device__name=device_name)
@@ -47,9 +48,10 @@ def post(self, request):
4748
BGPPeerGroup.objects.filter(device__name=device_name).delete()
4849
RoutePolicy.objects.filter(device__name=device_name).delete()
4950
PrefixList.objects.filter(device__name=device_name).delete()
51+
BGPCommunityList.objects.filter(device_name=device_name).delete()
5052
SNMP.objects.filter(device__name=device_name).delete()
51-
except Exception as e:
52-
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
53+
except Exception as e:
54+
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
5355

5456
return Response(
5557
{"message": f"Objects related to device {device_name} have been deleted successfully"},

netbox_cmdb/netbox_cmdb/api/route_policy/serializers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
"""Route Policy serializers."""
22

33
from django.core.exceptions import ValidationError
4+
from netbox.api.serializers import WritableNestedSerializer
45
from rest_framework import serializers
56
from rest_framework.serializers import ModelSerializer, SerializerMethodField
67

7-
from netbox.api.serializers import WritableNestedSerializer
88
from netbox_cmdb.api.bgp.serializers import AsnSerializer
99
from netbox_cmdb.api.common_serializers import CommonDeviceSerializer
1010
from netbox_cmdb.models.bgp_community_list import BGPCommunityList

netbox_cmdb/netbox_cmdb/api/snmp/serializers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
from rest_framework.serializers import ModelSerializer, ValidationError
44

5-
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
65
from netbox_cmdb.api.common_serializers import CommonDeviceSerializer
76
from netbox_cmdb.constants import MAX_COMMUNITY_PER_DEVICE
7+
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
88

99

1010
class SNMPCommunitySerializer(ModelSerializer):

netbox_cmdb/netbox_cmdb/api/snmp/views.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
"""Route Policy views."""
22

3-
from netbox_cmdb import filtersets
3+
from rest_framework.response import Response
44

5-
from netbox_cmdb.api.viewsets import CustomNetBoxModelViewSet
6-
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
5+
from netbox_cmdb import filtersets
76
from netbox_cmdb.api.snmp.serializers import (
87
SNMPCommunitySerializer,
98
SNMPReadSerializer,
109
SNMPSerializer,
1110
)
12-
from rest_framework.response import Response
11+
from netbox_cmdb.api.viewsets import CustomNetBoxModelViewSet
12+
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
1313

1414

1515
class SNMPCommunityViewSet(CustomNetBoxModelViewSet):

netbox_cmdb/netbox_cmdb/filtersets.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import django_filters
22
from django.db.models import Q
3-
from netbox_cmdb.models.snmp import SNMP
3+
from netbox.filtersets import ChangeLoggedModelFilterSet
44
from tenancy.filtersets import TenancyFilterSet
55
from utilities.filters import MultiValueCharFilter
66

7-
from netbox.filtersets import ChangeLoggedModelFilterSet
87
from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession, DeviceBGPSession
98
from netbox_cmdb.models.route_policy import RoutePolicy
9+
from netbox_cmdb.models.snmp import SNMP
1010

1111
device_location_filterset = [
1212
"device__location__name",

netbox_cmdb/netbox_cmdb/forms.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
from django import forms
99
from django.utils.translation import gettext as _
1010
from extras.models import Tag
11+
from netbox.forms import NetBoxModelFilterSetForm, NetBoxModelForm
1112
from utilities.forms import DynamicModelMultipleChoiceField
1213
from utilities.forms.fields import DynamicModelChoiceField, MultipleChoiceField
1314

14-
from netbox.forms import NetBoxModelFilterSetForm, NetBoxModelForm
1515
from netbox_cmdb.choices import AssetMonitoringStateChoices, AssetStateChoices
1616
from netbox_cmdb.constants import MAX_COMMUNITY_PER_DEVICE
1717
from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession, DeviceBGPSession

netbox_cmdb/netbox_cmdb/models/bgp.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
from django.db import models
55
from django.db.models import Q
66
from django.urls import reverse
7+
from netbox.models import ChangeLoggedModel
78
from utilities.choices import ChoiceSet
89
from utilities.querysets import RestrictedQuerySet
910

10-
from netbox.models import ChangeLoggedModel
1111
from netbox_cmdb.choices import AssetMonitoringStateChoices, AssetStateChoices
1212
from netbox_cmdb.constants import BGP_MAX_ASN, BGP_MIN_ASN
1313

netbox_cmdb/netbox_cmdb/models/interface.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
from django.core.exceptions import ValidationError
12
from django.db import models
2-
from netbox_cmdb.choices import AssetStateChoices, AssetMonitoringStateChoices
33
from netbox.models import ChangeLoggedModel
4-
from django.core.exceptions import ValidationError
4+
5+
from netbox_cmdb.choices import AssetMonitoringStateChoices, AssetStateChoices
56

67
FEC_CHOICES = [
78
(None, "None"),

netbox_cmdb/netbox_cmdb/models/route_policy.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from django.core.exceptions import ValidationError
22
from django.db import models
33
from django.urls import reverse
4+
from netbox.models import ChangeLoggedModel
45
from utilities.querysets import RestrictedQuerySet
56

6-
from netbox.models import ChangeLoggedModel
77
from netbox_cmdb.choices import DecisionChoice
88
from netbox_cmdb.fields import CustomIPAddressField
99

@@ -27,7 +27,7 @@ class RoutePolicy(ChangeLoggedModel):
2727
objects = RestrictedQuerySet.as_manager()
2828

2929
def __str__(self):
30-
return str(self.name)
30+
return f"{self.device}-{self.name}"
3131

3232
def __repr__(self):
3333
return str(self.name)

netbox_cmdb/netbox_cmdb/models/snmp.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
from django.contrib.postgres.fields import ArrayField
2+
from django.core.exceptions import ValidationError
13
from django.db import models
2-
from netbox_cmdb.choices import SNMPCommunityType
34
from netbox.models import ChangeLoggedModel
4-
from django.core.exceptions import ValidationError
5-
from django.contrib.postgres.fields import ArrayField
5+
6+
from netbox_cmdb.choices import SNMPCommunityType
67

78

89
class SNMPCommunity(ChangeLoggedModel):
@@ -43,4 +44,4 @@ class Meta:
4344
verbose_name_plural = "SNMP"
4445

4546
def __str__(self):
46-
return f"SNMP configuration of {self.device.name}"
47+
return f"{self.device.name}-SNMP"

netbox_cmdb/netbox_cmdb/signals.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.db.models.signals import post_delete
22
from django.dispatch import receiver
3+
34
from netbox_cmdb.models.bgp import BGPSession
45

56

netbox_cmdb/netbox_cmdb/tables.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""Tables."""
22

33
import django_tables2 as tables
4-
54
from netbox.tables import NetBoxTable, columns
5+
66
from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession, DeviceBGPSession
77
from netbox_cmdb.models.route_policy import RoutePolicy
88
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from extras.plugins import PluginTemplateExtension
2+
3+
4+
class Decommisioning(PluginTemplateExtension):
5+
model = "dcim.device"
6+
7+
def buttons(self):
8+
return (
9+
f'<a href="#" hx-get="/plugins/cmdb/decommisioning/{self.context["object"].id}/delete" '
10+
'hx-target="#htmx-modal-content" class="btn btn-sm btn-danger" data-bs-toggle="modal" data-bs-target="#htmx-modal" '
11+
'class="btn btn-sm btn-danger">Decommission</a>'
12+
)
13+
14+
15+
template_extensions = [Decommisioning]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{% extends "base/layout.html" %}
2+
3+
{% block content-wrapper %}
4+
<div class="container mt-3 border rounded">
5+
{% if error %}
6+
<div class="alert alert-danger">{{ error }}</div>
7+
{% else %}
8+
<div class="mt-3 mb-2">
9+
<h5 class="mb-2">Deleted objects</h5>
10+
11+
<div class="card-header border-0">
12+
<h6 class="card-title">Device</h6>
13+
<div class="card-body table-responsive">
14+
<table class="table table-hover object-list">
15+
<tr>
16+
<td>{{ deleted_device }}</td>
17+
</tr>
18+
</table>
19+
</div>
20+
</div>
21+
22+
{% for key, objects in deleted_objects.items %}
23+
{% if objects %}
24+
<div class="card-header border-0">
25+
<h6 class="card-title">{{ key }}</h6>
26+
<div class="card-body table-responsive">
27+
<table class="table table-hover object-list">
28+
{% for obj in objects %}
29+
<tr>
30+
<td>{{ obj }}</td>
31+
</tr>
32+
{% endfor %}
33+
</table>
34+
</div>
35+
</div>
36+
{% endif %}
37+
{% endfor %}
38+
39+
40+
</div>
41+
{% endif %}
42+
</div>
43+
{% endblock content-wrapper%}

netbox_cmdb/netbox_cmdb/tests/bgp_community_list/test_bgp_community_list_serializer.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from dcim.models.devices import Device, DeviceRole, DeviceType, Manufacturer
22
from dcim.models.sites import Site
33
from django.test import TestCase
4+
from rest_framework.serializers import ValidationError
5+
46
from netbox_cmdb.api.bgp_community_list.serializers import BGPCommunityListSerializer
57
from netbox_cmdb.models.bgp_community_list import BGPCommunityList, BGPCommunityListTerm
6-
from rest_framework.serializers import ValidationError
78

89

910
def validate(device, data):

netbox_cmdb/netbox_cmdb/tests/common.py

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from django.test import TestCase
44
from ipam.models.ip import IPAddress
55
from tenancy.models.tenants import Tenant
6+
67
from netbox_cmdb.models.bgp import ASN
78

89

netbox_cmdb/netbox_cmdb/tests/prefix_list/test_prefix_list_models.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from django.forms import ValidationError
33
from django.test import TestCase
44
from netaddr import IPNetwork
5+
56
from netbox_cmdb.models.prefix_list import PrefixList, PrefixListTerm
67

78

netbox_cmdb/netbox_cmdb/tests/snmp/test_snmp_serializer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from netbox_cmdb.api.snmp.serializers import SNMPCommunitySerializer, SNMPSerializer
2-
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
32
from netbox_cmdb.choices import SNMPCommunityType
3+
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
44
from netbox_cmdb.tests.common import BaseTestCase
55

66

netbox_cmdb/netbox_cmdb/urls.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
55

66
from netbox_cmdb.models.bgp import *
7-
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
87
from netbox_cmdb.models.route_policy import RoutePolicy
8+
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
99
from netbox_cmdb.views import (
1010
ASNDeleteView,
1111
ASNEditView,
@@ -20,12 +20,7 @@
2020
BGPSessionEditView,
2121
BGPSessionListView,
2222
BGPSessionView,
23-
SNMPCommunityDeleteView,
24-
SNMPCommunityEditView,
25-
SNMPCommunityListView,
26-
SNMPDeleteView,
27-
SNMPEditView,
28-
SNMPListView,
23+
DecommissioningView,
2924
DeviceBGPSessionEditView,
3025
DeviceBGPSessionListView,
3126
DeviceBGPSessionView,
@@ -34,9 +29,20 @@
3429
RoutePolicyEditView,
3530
RoutePolicyListView,
3631
RoutePolicyView,
32+
SNMPCommunityDeleteView,
33+
SNMPCommunityEditView,
34+
SNMPCommunityListView,
35+
SNMPDeleteView,
36+
SNMPEditView,
37+
SNMPListView,
3738
)
3839

3940
urlpatterns = [
41+
path(
42+
"decommisioning/<int:pk>/delete",
43+
DecommissioningView.as_view(),
44+
name="decommisioning_delete",
45+
),
4046
# ASN
4147
path("asn/", ASNListView.as_view(), name="asn_list"),
4248
path("asn/add/", ASNEditView.as_view(), name="asn_add"),

0 commit comments

Comments
 (0)