Skip to content

Commit 2d1cc44

Browse files
authored
Merge pull request #91 from k01ek/develop
Develop
2 parents 307f3bd + b6d1b1f commit 2d1cc44

File tree

4 files changed

+164
-13
lines changed

4 files changed

+164
-13
lines changed

netbox_bgp/forms.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from ipam.models import IPAddress
1212
from ipam.formfields import IPNetworkFormField
1313
from utilities.forms import (
14-
BootstrapMixin, DynamicModelChoiceField, BulkEditForm,
14+
DynamicModelChoiceField,
1515
DynamicModelMultipleChoiceField, StaticSelect,
1616
APISelect, APISelectMultiple, StaticSelectMultiple, TagFilterField
1717
)
@@ -33,7 +33,7 @@ class ASNField(forms.CharField):
3333

3434
def to_python(self, value):
3535
if not re.match(r'^\d+(\.\d+)?$', value):
36-
raise ValidationError('Invalid AS Number: {}'.format(value))
36+
raise ValidationError('Invalid AS Number: {}'.format(value))
3737
if '.' in value:
3838
if int(value.split('.')[0]) > 65535 or int(value.split('.')[1]) > 65535:
3939
raise ValidationError('Invalid AS Number: {}'.format(value))
@@ -157,7 +157,7 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
157157
)
158158

159159

160-
class CommunityForm(BootstrapMixin, forms.ModelForm):
160+
class CommunityForm(NetBoxModelForm):
161161
tags = DynamicModelMultipleChoiceField(
162162
queryset=Tag.objects.all(),
163163
required=False
@@ -179,7 +179,7 @@ class Meta:
179179
]
180180

181181

182-
class CommunityFilterForm(BootstrapMixin, forms.ModelForm):
182+
class CommunityFilterForm(NetBoxModelFilterSetForm):
183183
q = forms.CharField(
184184
required=False,
185185
label='Search'
@@ -200,12 +200,10 @@ class CommunityFilterForm(BootstrapMixin, forms.ModelForm):
200200

201201
tag = TagFilterField(Community)
202202

203-
class Meta:
204-
model = Community
205-
fields = ['q', 'status', 'tenant']
203+
model = Community
206204

207205

208-
class CommunityBulkEditForm(BulkEditForm):
206+
class CommunityBulkEditForm(NetBoxModelBulkEditForm):
209207
pk = forms.ModelMultipleChoiceField(
210208
queryset=Community.objects.all(),
211209
widget=forms.MultipleHiddenInput
@@ -224,10 +222,10 @@ class CommunityBulkEditForm(BulkEditForm):
224222
widget=StaticSelect()
225223
)
226224

227-
class Meta:
228-
nullable_fields = [
229-
'tenant', 'description',
230-
]
225+
model = Community
226+
nullable_fields = [
227+
'tenant', 'description',
228+
]
231229

232230

233231
class BGPSessionForm(NetBoxModelForm):

netbox_bgp/graphql.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from graphene import ObjectType, Field
2+
3+
from netbox.graphql.scalars import BigInt
4+
from netbox.graphql.types import NetBoxObjectType
5+
from netbox.graphql.fields import ObjectField, ObjectListField
6+
7+
from . import models, filters
8+
9+
10+
class CommunityType(NetBoxObjectType):
11+
class Meta:
12+
model = models.Community
13+
fields = '__all__'
14+
filterset_class = filters.CommunityFilterSet
15+
16+
17+
class AsnType(NetBoxObjectType):
18+
number = Field(BigInt)
19+
20+
class Meta:
21+
model = models.ASN
22+
fields = '__all__'
23+
filterset_class = filters.ASNFilterSet
24+
25+
26+
class BgpSessionType(NetBoxObjectType):
27+
class Meta:
28+
model = models.BGPSession
29+
fields = '__all__'
30+
filterset_class = filters.BGPSessionFilterSet
31+
32+
33+
class PeerGroupType(NetBoxObjectType):
34+
class Meta:
35+
model = models.BGPPeerGroup
36+
fields = '__all__'
37+
filterset_class = filters.BGPPeerGroupFilterSet
38+
39+
40+
class RoutingPolicyType(NetBoxObjectType):
41+
class Meta:
42+
model = models.RoutingPolicy
43+
fields = '__all__'
44+
filterset_class = filters.RoutingPolicyFilterSet
45+
46+
47+
class BGPQuery(ObjectType):
48+
community = ObjectField(CommunityType)
49+
community_list = ObjectListField(CommunityType)
50+
51+
bgp_asn = ObjectField(AsnType)
52+
bgp_asn_list = ObjectListField(AsnType)
53+
54+
bgp_session = ObjectField(BgpSessionType)
55+
bgp_session_list = ObjectListField(BgpSessionType)
56+
57+
peer_group = ObjectField(PeerGroupType)
58+
peer_group_list = ObjectListField(PeerGroupType)
59+
60+
routing_policy = ObjectField(RoutingPolicyType)
61+
routing_policy_list = ObjectListField(RoutingPolicyType)
62+
63+
64+
schema = BGPQuery

netbox_bgp/tests/test_api.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import json
2+
13
from django.contrib.auth.models import User
24
from django.test import TestCase
5+
from django.test.client import Client
36
from django.urls import reverse
47
from rest_framework import status
58
from rest_framework.test import APIClient, APITestCase
@@ -18,8 +21,10 @@ class BaseTestCase(TestCase):
1821
def setUp(self):
1922
self.user = User.objects.create(username='testuser', is_superuser=True)
2023
self.token = Token.objects.create(user=self.user)
24+
# todo change to Client
2125
self.client = APIClient()
2226
self.client.credentials(HTTP_AUTHORIZATION=f'Token {self.token.key}')
27+
self.gql_client = Client(HTTP_AUTHORIZATION=f'Token {self.token.key}')
2328

2429

2530
class ASNTestCase(BaseTestCase):
@@ -92,6 +97,27 @@ def test_uniqueconstraint_asn(self):
9297
response = self.client.post(url, data, format='json')
9398
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
9499

100+
def test_graphql(self):
101+
url = reverse('graphql')
102+
query = 'query bgp_asn($id: Int!){bgp_asn(id: $id){number}}'
103+
response = self.gql_client.post(
104+
url,
105+
json.dumps({'query': query, 'variables': {'id': self.asn1.pk}}),
106+
content_type='application/json'
107+
)
108+
self.assertEqual(response.status_code, status.HTTP_200_OK)
109+
self.assertEqual(json.loads(response.content)['data']['bgp_asn']['number'], self.asn1.number)
110+
111+
def test_graphql_list(self):
112+
url = reverse('graphql')
113+
query = '{bgp_asn_list{number}}'
114+
response = self.gql_client.post(
115+
url,
116+
json.dumps({'query': query}),
117+
content_type='application/json'
118+
)
119+
self.assertEqual(response.status_code, status.HTTP_200_OK)
120+
95121

96122
class CommunityTestCase(BaseTestCase):
97123
def setUp(self):
@@ -126,6 +152,27 @@ def test_update_community(self):
126152
def test_delete_community(self):
127153
pass
128154

155+
def test_graphql(self):
156+
url = reverse('graphql')
157+
query = 'query community($id: Int!){community(id: $id){value}}'
158+
response = self.gql_client.post(
159+
url,
160+
json.dumps({'query': query, 'variables': {'id': self.community1.pk}}),
161+
content_type='application/json'
162+
)
163+
self.assertEqual(response.status_code, status.HTTP_200_OK)
164+
self.assertEqual(json.loads(response.content)['data']['community']['value'], self.community1.value)
165+
166+
def test_graphql_list(self):
167+
url = reverse('graphql')
168+
query = '{community_list{value}}'
169+
response = self.gql_client.post(
170+
url,
171+
json.dumps({'query': query}),
172+
content_type='application/json'
173+
)
174+
self.assertEqual(response.status_code, status.HTTP_200_OK)
175+
129176

130177
class PeerGroupTestCase(BaseTestCase):
131178
def setUp(self):
@@ -160,6 +207,27 @@ def test_update_peer_group(self):
160207
def test_delete_peer_group(self):
161208
pass
162209

210+
def test_graphql(self):
211+
url = reverse('graphql')
212+
query = 'query peer_group($id: Int!){peer_group(id: $id){name}}'
213+
response = self.gql_client.post(
214+
url,
215+
json.dumps({'query': query, 'variables': {'id': self.peer_group.pk}}),
216+
content_type='application/json'
217+
)
218+
self.assertEqual(response.status_code, status.HTTP_200_OK)
219+
self.assertEqual(json.loads(response.content)['data']['peer_group']['name'], self.peer_group.name)
220+
221+
def test_graphql_list(self):
222+
url = reverse('graphql')
223+
query = '{peer_group_list{name}}'
224+
response = self.gql_client.post(
225+
url,
226+
json.dumps({'query': query}),
227+
content_type='application/json'
228+
)
229+
self.assertEqual(response.status_code, status.HTTP_200_OK)
230+
163231

164232
class SessionTestCase(BaseTestCase):
165233
def setUp(self):
@@ -251,3 +319,24 @@ def test_session_no_device(self):
251319
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
252320
self.assertEqual(BGPSession.objects.get(pk=response.data['id']).name, 'test_session')
253321
self.assertEqual(BGPSession.objects.get(pk=response.data['id']).description, 'session_descr')
322+
323+
def test_graphql(self):
324+
url = reverse('graphql')
325+
query = 'query bgp_session($id: Int!){bgp_session(id: $id){name}}'
326+
response = self.gql_client.post(
327+
url,
328+
json.dumps({'query': query, 'variables': {'id': self.session.pk}}),
329+
content_type='application/json'
330+
)
331+
self.assertEqual(response.status_code, status.HTTP_200_OK)
332+
self.assertEqual(json.loads(response.content)['data']['bgp_session']['name'], self.session.name)
333+
334+
def test_graphql_list(self):
335+
url = reverse('graphql')
336+
query = '{bgp_session_list{name}}'
337+
response = self.gql_client.post(
338+
url,
339+
json.dumps({'query': query}),
340+
content_type='application/json'
341+
)
342+
self.assertEqual(response.status_code, status.HTTP_200_OK)

netbox_bgp/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.6.0"
1+
__version__ = "0.6.1"

0 commit comments

Comments
 (0)