Skip to content

Commit a7b78cf

Browse files
authored
Merge pull request #256 from cruse1977/develop
Add ASPATH, fix graphql filters
2 parents 2cfb03c + 7ee8f30 commit a7b78cf

File tree

19 files changed

+708
-15
lines changed

19 files changed

+708
-15
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PYTHON_VER?=3.10
2-
NETBOX_VER?=v4.0.2
2+
NETBOX_VER?=v4.3.2
33

44
NAME=netbox-bgp
55

develop/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
ARG python_ver=3.12
22
FROM python:${python_ver}
33

4-
ARG netbox_ver=v4.3.1
4+
ARG netbox_ver=v4.3.2
55
ENV PYTHONUNBUFFERED 1
66

77
RUN mkdir -p /opt

netbox_bgp/api/serializers.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,53 @@
1818
PrefixListRule,
1919
CommunityList,
2020
CommunityListRule,
21+
ASPathList,
22+
ASPathListRule
2123
)
2224

2325
from netbox_bgp.choices import CommunityStatusChoices, SessionStatusChoices
2426

2527

28+
class ASPathListSerializer(NetBoxModelSerializer):
29+
url = HyperlinkedIdentityField(view_name="plugins-api:netbox_bgp-api:aspathlist-detail")
30+
31+
class Meta:
32+
model = ASPathList
33+
fields = [
34+
"id",
35+
"url",
36+
"name",
37+
"display",
38+
"description",
39+
"tags",
40+
"custom_fields",
41+
"comments",
42+
]
43+
brief_fields = ("id", "url", "display", "name", "description")
44+
45+
46+
class ASPathListRuleSerializer(NetBoxModelSerializer):
47+
aspath_list = ASPathListSerializer(nested=True)
48+
49+
class Meta:
50+
model = ASPathListRule
51+
fields = [
52+
"id",
53+
"description",
54+
"tags",
55+
"custom_fields",
56+
"display",
57+
"aspath_list",
58+
"created",
59+
"last_updated",
60+
"index",
61+
"action",
62+
"pattern",
63+
"comments",
64+
]
65+
brief_fields = ("id", "display", "description")
66+
67+
2668
class RoutingPolicySerializer(NetBoxModelSerializer):
2769
url = HyperlinkedIdentityField(view_name="plugins-api:netbox_bgp-api:routingpolicy-detail")
2870

@@ -286,6 +328,14 @@ class RoutingPolicyRuleSerializer(NetBoxModelSerializer):
286328
allow_null=True,
287329
many=True,
288330
)
331+
match_aspath_list = SerializedPKRelatedField(
332+
queryset=ASPathList.objects.all(),
333+
serializer=ASPathListSerializer,
334+
nested=True,
335+
required=False,
336+
allow_null=True,
337+
many=True,
338+
)
289339

290340
class Meta:
291341
model = RoutingPolicyRule
@@ -298,6 +348,7 @@ class Meta:
298348
"routing_policy",
299349
"match_community",
300350
"match_community_list",
351+
"match_aspath_list",
301352
"match_custom",
302353
"set_actions",
303354
"match_ipv6_address",
@@ -335,3 +386,4 @@ class Meta:
335386
"comments",
336387
)
337388
brief_fields = ("id", "display", "description")
389+

netbox_bgp/api/urls.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from .views import (
44
BGPSessionViewSet, RoutingPolicyViewSet, BGPPeerGroupViewSet, CommunityViewSet,
55
PrefixListViewSet, PrefixListRuleViewSet, RoutingPolicyRuleViewSet,
6-
CommunityListViewSet, CommunityListRuleViewSet, RootView
6+
CommunityListViewSet, CommunityListRuleViewSet, RootView,
7+
ASPathListViewSet, ASPathListRuleViewSet
78
)
89

910

@@ -20,5 +21,7 @@
2021
router.register('prefix-list-rule', PrefixListRuleViewSet)
2122
router.register('community-list', CommunityListViewSet)
2223
router.register('community-list-rule', CommunityListRuleViewSet)
24+
router.register('aspath-list', ASPathListViewSet)
25+
router.register('aspath-list-rule', ASPathListRuleViewSet)
2326

2427
urlpatterns = router.urls

netbox_bgp/api/views.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44
from .serializers import (
55
BGPSessionSerializer, RoutingPolicySerializer, BGPPeerGroupSerializer,
66
CommunitySerializer, PrefixListSerializer, PrefixListRuleSerializer,
7-
RoutingPolicyRuleSerializer, CommunityListSerializer, CommunityListRuleSerializer
7+
RoutingPolicyRuleSerializer, CommunityListSerializer, CommunityListRuleSerializer,
8+
ASPathListSerializer, ASPathListRuleSerializer
89
)
910
from netbox_bgp.models import (
1011
BGPSession, RoutingPolicy, BGPPeerGroup,
1112
Community, PrefixList, PrefixListRule,
12-
RoutingPolicyRule, CommunityList, CommunityListRule
13+
RoutingPolicyRule, CommunityList, CommunityListRule,
14+
ASPathList, ASPathListRule
1315
)
1416
from netbox_bgp.filtersets import (
1517
BGPSessionFilterSet, RoutingPolicyFilterSet, BGPPeerGroupFilterSet,
1618
CommunityFilterSet, PrefixListFilterSet, PrefixListRuleFilterSet,
17-
RoutingPolicyRuleFilterSet, CommunityListFilterSet, CommunityListRuleFilterSet
19+
RoutingPolicyRuleFilterSet, CommunityListFilterSet, CommunityListRuleFilterSet,
20+
ASPathListFilterSet, ASPathListRuleFilterSet
1821
)
1922

2023
class RootView(APIRootView):
@@ -74,3 +77,15 @@ class PrefixListRuleViewSet(NetBoxModelViewSet):
7477
queryset = PrefixListRule.objects.all()
7578
serializer_class = PrefixListRuleSerializer
7679
filterset_class = PrefixListRuleFilterSet
80+
81+
82+
class ASPathListViewSet(NetBoxModelViewSet):
83+
queryset = ASPathList.objects.all()
84+
serializer_class = ASPathListSerializer
85+
filterset_class = ASPathListFilterSet
86+
87+
88+
class ASPathListRuleViewSet(NetBoxModelViewSet):
89+
queryset = ASPathListRule.objects.all()
90+
serializer_class = ASPathListRuleSerializer
91+
filterset_class = ASPathListRuleFilterSet

netbox_bgp/filtersets.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,48 @@
88
from .models import (
99
Community, BGPSession, RoutingPolicy, RoutingPolicyRule,
1010
BGPPeerGroup, PrefixList, PrefixListRule, CommunityList,
11-
CommunityListRule
11+
CommunityListRule, ASPathList, ASPathListRule
1212
)
1313
from ipam.models import IPAddress, ASN
1414
from dcim.models import Device, Site
1515
from virtualization.models import VirtualMachine
1616

17+
18+
class ASPathListFilterSet(NetBoxModelFilterSet):
19+
20+
class Meta:
21+
model = ASPathList
22+
fields = ['id', 'name', 'description']
23+
24+
def search(self, queryset, name, value):
25+
"""Perform the filtered search."""
26+
if not value.strip():
27+
return queryset
28+
qs_filter = (
29+
Q(name__icontains=value)
30+
| Q(description__icontains=value)
31+
)
32+
return queryset.filter(qs_filter)
33+
34+
35+
class ASPathListRuleFilterSet(NetBoxModelFilterSet):
36+
37+
class Meta:
38+
model = ASPathListRule
39+
fields = ['id', 'action', 'aspath_list', 'aspath_list_id']
40+
41+
def search(self, queryset, name, value):
42+
"""Perform the filtered search."""
43+
if not value.strip():
44+
return queryset
45+
qs_filter = (
46+
Q(action__icontains=value)
47+
| Q(aspath_list__icontains=value)
48+
| Q(aspath_list_id__icontains=value)
49+
)
50+
return queryset.filter(qs_filter)
51+
52+
1753
class CommunityFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
1854

1955
class Meta:

netbox_bgp/forms.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
PrefixListRule,
4141
CommunityList,
4242
CommunityListRule,
43+
ASPathList,
44+
ASPathListRule,
4345
)
4446

4547
from .choices import (
@@ -50,6 +52,59 @@
5052

5153
from virtualization.models import VirtualMachine
5254

55+
class ASPathListFilterForm(NetBoxModelFilterSetForm):
56+
model = ASPathList
57+
q = forms.CharField(required=False, label="Search")
58+
59+
tag = TagFilterField(model)
60+
61+
class ASPathListRuleFilterForm(NetBoxModelFilterSetForm):
62+
model = ASPathListRule
63+
q = forms.CharField(required=False, label="Search")
64+
aspath_list = DynamicModelChoiceField(queryset=ASPathList.objects.all(), required=False)
65+
tag = TagFilterField(model)
66+
67+
68+
class ASPathListForm(NetBoxModelForm):
69+
70+
comments = CommentField()
71+
72+
class Meta:
73+
model = ASPathList
74+
fields = ["name", "description", "tags", "comments"]
75+
76+
77+
class ASPathListBulkEditForm(NetBoxModelBulkEditForm):
78+
description = forms.CharField(max_length=200, required=False)
79+
80+
model = ASPathList
81+
nullable_fields = [
82+
"description",
83+
]
84+
85+
86+
class ASPathListImportForm(NetBoxModelImportForm):
87+
88+
class Meta:
89+
model = ASPathList
90+
fields = ["name", "description", "tags"]
91+
92+
93+
class ASPathListRuleImportForm(NetBoxModelImportForm):
94+
95+
class Meta:
96+
model = ASPathListRule
97+
fields = ["aspath_list", "index", "action", "pattern", "description", "tags", "comments"]
98+
99+
100+
class ASPathListRuleForm(NetBoxModelForm):
101+
comments = CommentField()
102+
103+
class Meta:
104+
model = ASPathListRule
105+
fields = ["aspath_list", "index", "action", "pattern", "description", "tags", "comments"]
106+
107+
53108
class CommunityForm(NetBoxModelForm):
54109
status = forms.ChoiceField(
55110
required=False,
@@ -647,6 +702,11 @@ class RoutingPolicyRuleForm(NetBoxModelForm):
647702
}
648703
)
649704

705+
match_aspath_list = DynamicModelMultipleChoiceField(
706+
queryset=ASPathList.objects.all(),
707+
required=False,
708+
)
709+
650710
match_custom = forms.JSONField(
651711
label="Custom Match",
652712
help_text='Any custom match statements, e.g., {"ip nexthop": "1.1.1.1"}',
@@ -674,6 +734,7 @@ class Meta:
674734
"match_community_list",
675735
"match_ip_address",
676736
"match_ipv6_address",
737+
"match_aspath_list",
677738
"match_custom",
678739
"set_actions",
679740
"description",

netbox_bgp/graphql/enums.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
"NetBoxBGPIPAddressFamilyEnum",
1515
)
1616

17-
NetBoxBGPCommunityStatusEnum = strawberry.enum(CommunityStatusChoices.as_enum())
18-
NetBoxBGPSessionStatusEnum = strawberry.enum(SessionStatusChoices.as_enum())
19-
NetBoxBGPActionEnum = strawberry.enum(ActionChoices.as_enum())
20-
NetBoxBGPIPAddressFamilyEnum = strawberry.enum(IPAddressFamilyChoices.as_enum())
17+
NetBoxBGPCommunityStatusEnum = strawberry.enum(CommunityStatusChoices.as_enum(), name="NetBoxBGPCommunityStatusEnum" )
18+
NetBoxBGPSessionStatusEnum = strawberry.enum(SessionStatusChoices.as_enum(), name="NetBoxBGPSessionStatusEnum")
19+
NetBoxBGPActionEnum = strawberry.enum(ActionChoices.as_enum(), name="NetBoxBGPActionEnum")
20+
NetBoxBGPIPAddressFamilyEnum = strawberry.enum(IPAddressFamilyChoices.as_enum(), name="NetBoxBGPIPAddressFamilyEnum")
2121

netbox_bgp/graphql/filters.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from netbox.graphql.filter_mixins import NetBoxModelFilterMixin
88
from tenancy.graphql.filter_mixins import TenancyFilterMixin
99
from ipam.graphql.filters import IPAddressFilter, ASNFilter
10-
from dcim.graphql.filter import DeviceFilter
10+
from dcim.graphql.filters import DeviceFilter
1111

1212
from netbox_bgp.models import (
1313
Community,
@@ -19,6 +19,8 @@
1919
PrefixListRule,
2020
CommunityList,
2121
CommunityListRule,
22+
ASPathList,
23+
ASPathListRule
2224
)
2325

2426
from netbox_bgp.filtersets import (
@@ -31,6 +33,8 @@
3133
PrefixListRuleFilterSet,
3234
CommunityListFilterSet,
3335
CommunityListRuleFilterSet,
36+
ASPathListFilterSet,
37+
ASPathListRuleFilterSet
3438
)
3539

3640
from netbox_bgp.graphql.enums import (
@@ -51,8 +55,31 @@
5155
"NetBoxBGPPrefixListRuleFilter",
5256
"NetBoxBGPCommunityListFilter",
5357
"NetBoxBGPCommunityListRuleFilter",
58+
"NetBoxBGPASPathListFilter",
59+
"NetBoxBGPASPathListRuleFilter"
5460
)
5561

62+
@strawberry_django.filter_type(ASPathList, lookups=True)
63+
class NetBoxBGPASPathListFilter(NetBoxModelFilterMixin):
64+
name: FilterLookup[str] | None = strawberry_django.filter_field()
65+
description: FilterLookup[str] | None = strawberry_django.filter_field()
66+
67+
@strawberry_django.filter_type(ASPathListRule, lookups=True)
68+
class NetBoxBGPASPathListRuleFilter(NetBoxModelFilterMixin):
69+
value: FilterLookup[str] | None = strawberry_django.filter_field()
70+
aspath_list: (
71+
Annotated[
72+
"NetBoxBGPASPathListFilter", strawberry.lazy("netbox_bgp.graphql.filters")
73+
]
74+
| None
75+
) = strawberry_django.filter_field()
76+
aspath_list_id: ID | None = strawberry_django.filter_field()
77+
action: (
78+
Annotated[
79+
"NetBoxBGPActionEnum", strawberry.lazy("netbox_bgp.graphql.enums")
80+
]
81+
| None
82+
) = strawberry_django.filter_field()
5683

5784
@strawberry_django.filter_type(Community, lookups=True)
5885
class NetBoxBGPCommunityFilter(TenancyFilterMixin, NetBoxModelFilterMixin):
@@ -152,6 +179,13 @@ class NetBoxBGPRoutingPolicyRuleFilter(NetBoxModelFilterMixin):
152179
]
153180
| None
154181
) = strawberry_django.filter_field()
182+
aspath_list: (
183+
Annotated[
184+
"NetBoxBGPASPathListFilter", strawberry.lazy("netbox_bgp.graphql.filters")
185+
]
186+
| None
187+
) = strawberry_django.filter_field()
188+
aspath_list_id: ID | None = strawberry_django.filter_field()
155189

156190

157191
@strawberry_django.filter_type(PrefixList, lookups=True)

0 commit comments

Comments
 (0)