Skip to content

Commit c02c172

Browse files
authored
Merge pull request #3 from k01ek/develop
add device extension; add name filed for session;
2 parents 798a236 + d76d09d commit c02c172

20 files changed

+138
-16
lines changed

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ Restart NetBox and add `netbox-bgp` to your local_requirements.txt
2020

2121
## Configuration
2222

23-
The plugin is not configurable
23+
The following options are available:
24+
* `device_ext_page`: String (default right) Device related BGP sessions table position. The following values are available:
25+
left, right, full_width. Set empty value for disable.
2426

2527
## Screenshots
2628

@@ -30,6 +32,9 @@ BGP Session Object
3032
BGP Session Table
3133
![BGP Session Table](docs/img/bgp_sess_list.png)
3234

35+
Device Extension
36+
![Device Session Table](docs/img/dev_sess_list.png)
37+
3338
ASN Object
3439
![ASN](docs/img/asn.png)
3540

docs/img/asn.png

-1.68 KB
Loading

docs/img/bgp_sess.png

6.26 KB
Loading

docs/img/bgp_sess_list.png

24.6 KB
Loading

docs/img/dev_sess_list.png

407 KB
Loading

netbox_bgp/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ class BGPConfig(PluginConfig):
1111
author_email = '[email protected]'
1212
base_url = 'bgp'
1313
required_settings = []
14-
default_settings = {}
15-
14+
default_settings = {
15+
'device_ext_page': 'right'
16+
}
1617

1718

1819
config = BGPConfig # noqa

netbox_bgp/admin.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ class CommunityAdmin(admin.ModelAdmin):
1414

1515
@admin.register(BGPSession)
1616
class BGPSessionAdmin(admin.ModelAdmin):
17-
fields = ('local_address', 'local_as', 'remote_address', 'remote_as' 'description')
17+
fields = ('name', 'local_address', 'local_as', 'remote_address', 'remote_as', 'description')

netbox_bgp/api/serializers.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
from rest_framework.serializers import ModelSerializer
22

33
from netbox.api import ChoiceField
4-
4+
from dcim.api.nested_serializers import NestedSiteSerializer
5+
from tenancy.api.nested_serializers import NestedTenantSerializer
6+
from extras.api.serializers import TaggedObjectSerializer
7+
from extras.api.customfields import CustomFieldModelSerializer
58
from netbox_bgp.models import ASN, ASNStatusChoices, BGPSession, SessionStatusChoices
69

710

8-
class ASNSerializer(ModelSerializer):
11+
class ASNSerializer(TaggedObjectSerializer, CustomFieldModelSerializer):
912
status = ChoiceField(choices=ASNStatusChoices, required=False)
13+
site = NestedSiteSerializer(required=False, allow_null=True)
14+
tenant = NestedTenantSerializer(required=False, allow_null=True)
1015

1116
class Meta:
1217
model = ASN
13-
fields = ['number', 'id', 'status']
18+
fields = ['number', 'id', 'status', 'description', 'site', 'tenant', 'tags']
1419

1520

1621
class BGPSessionSerializer(ModelSerializer):

netbox_bgp/filters.py

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def search(self, queryset, name, value):
7272
return queryset
7373
qs_filter = (
7474
Q(remote_as__number__icontains=value)
75+
| Q(name__icontains=value)
7576
| Q(local_as__number__icontains=value)
7677
| Q(description__icontains=value)
7778
)

netbox_bgp/forms.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ class Meta:
156156

157157

158158
class BGPSessionForm(BootstrapMixin, forms.ModelForm):
159+
name = forms.CharField(
160+
max_length=64,
161+
required=True
162+
)
159163
tags = DynamicModelMultipleChoiceField(
160164
queryset=Tag.objects.all(),
161165
required=False
@@ -177,7 +181,6 @@ class BGPSessionForm(BootstrapMixin, forms.ModelForm):
177181
)
178182
local_as = DynamicModelChoiceField(
179183
queryset=ASN.objects.all(),
180-
null_option=None,
181184
query_params={
182185
'site_id': '$site'
183186
},
@@ -209,7 +212,7 @@ class BGPSessionForm(BootstrapMixin, forms.ModelForm):
209212
class Meta:
210213
model = BGPSession
211214
fields = [
212-
'site', 'device',
215+
'name', 'site', 'device',
213216
'local_as', 'remote_as', 'local_address', 'remote_address',
214217
'description', 'status', 'tenant', 'tags',
215218
]
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 3.1.3 on 2021-04-14 09:57
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('netbox_bgp', '0005_netbox_bgp'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='bgpsession',
15+
name='name',
16+
field=models.CharField(blank=True, max_length=100, null=True),
17+
),
18+
]
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 3.1.3 on 2021-04-14 10:26
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('netbox_bgp', '0006_netbox_bgp'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='bgpsession',
15+
name='name',
16+
field=models.CharField(blank=True, max_length=64, null=True),
17+
),
18+
]

netbox_bgp/models.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ def get_absolute_url(self):
170170

171171
@extras_features('export_templates', 'webhooks')
172172
class BGPSession(ChangeLoggedModel):
173+
name = models.CharField(
174+
max_length=64,
175+
blank=True,
176+
null=True
177+
)
173178
site = models.ForeignKey(
174179
to='dcim.Site',
175180
on_delete=models.SET_NULL,
@@ -225,7 +230,7 @@ class Meta:
225230
verbose_name_plural = 'BGP Sessions'
226231

227232
def __str__(self):
228-
return f"{self.device}->{self.remote_as}({self.remote_address})"
233+
return f"{self.device}:{self.name}"
229234

230235
def get_status_class(self):
231236
return SessionStatusChoices.CSS_CLASSES.get(self.status)

netbox_bgp/tables.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Meta(BaseTable.Meta):
4545

4646
class BGPSessionTable(BaseTable):
4747
pk = ToggleColumn()
48-
id = tables.LinkColumn()
48+
name = tables.LinkColumn()
4949
device = tables.LinkColumn()
5050
remote_address = tables.LinkColumn()
5151
remote_as = tables.LinkColumn()
@@ -61,5 +61,5 @@ class BGPSessionTable(BaseTable):
6161
class Meta(BaseTable.Meta):
6262
model = BGPSession
6363
fields = (
64-
'pk', 'id', 'device', 'remote_as', 'remote_address', 'local_as', 'description', 'site', 'status'
64+
'pk', 'name', 'device', 'remote_as', 'remote_address', 'local_as', 'description', 'site', 'status'
6565
)

netbox_bgp/template_content.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from extras.plugins import PluginTemplateExtension
2+
3+
from .models import BGPSession
4+
from .tables import BGPSessionTable
5+
6+
7+
class DeviceBGPSession(PluginTemplateExtension):
8+
model = 'dcim.device'
9+
10+
def left_page(self):
11+
if self.context['config'].get('device_ext_page') == 'left':
12+
return self.x_page()
13+
return ''
14+
15+
def right_page(self):
16+
if self.context['config'].get('device_ext_page') == 'right':
17+
return self.x_page()
18+
return ''
19+
20+
def full_width_page(self):
21+
if self.context['config'].get('device_ext_page') == 'full_width':
22+
return self.x_page()
23+
return ''
24+
25+
def x_page(self):
26+
obj = self.context['object']
27+
sess = BGPSession.objects.filter(device=obj)
28+
sess_table = BGPSessionTable(sess)
29+
return self.render(
30+
'netbox_bgp/device_extend.html',
31+
extra_context={
32+
'related_session_table': sess_table
33+
}
34+
)
35+
36+
37+
template_extensions = [DeviceBGPSession]

netbox_bgp/templates/netbox_bgp/asn.html

+8-2
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,14 @@ <h1>{% block title %}AS{{ object }}{% endblock %}</h1>
7575
</div>
7676
<table class="table table-hover panel-body attr-table">
7777
<tr>
78-
<td>Site</td>
79-
<td>{{ object.site }}</td>
78+
<td>Site</td>
79+
<td>
80+
{% if object.site %}
81+
<a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a>
82+
{% else %}
83+
<span class="text-muted">None</span>
84+
{% endif %}
85+
</td>
8086
</tr>
8187
<tr>
8288
<td>Number</td>

netbox_bgp/templates/netbox_bgp/bgpsession.html

+21-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
</a>
5050
{% endif %}
5151
</div>
52-
<h1>{% block title %}BGP Session: {{ object }}{% endblock %}</h1>
52+
<h1>{% block title %}BGP Session {{ object }}{% endblock %}</h1>
5353
{% include 'inc/created_updated.html' %}
5454
<div class="pull-right noprint">
5555
{% custom_links object %}
@@ -74,6 +74,26 @@ <h1>{% block title %}BGP Session: {{ object }}{% endblock %}</h1>
7474
<strong>BGP Session</strong>
7575
</div>
7676
<table class="table table-hover panel-body attr-table">
77+
<tr>
78+
<td>Name</td>
79+
<td>
80+
{% if object.name %}
81+
{{ object.name }}
82+
{% else %}
83+
<span class="text-muted">None</span>
84+
{% endif %}
85+
</td>
86+
</tr>
87+
<tr>
88+
<td>Device</td>
89+
<td>
90+
{% if object.device %}
91+
<a href="{{ object.device.get_absolute_url }}">{{ object.device }}</a>
92+
{% else %}
93+
<span class="text-muted">None</span>
94+
{% endif %}
95+
</td>
96+
</tr>
7797
<tr>
7898
<td>Local AS</td>
7999
<td>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{% load render_table from django_tables2 %}
2+
{% include 'utilities/obj_table.html' with table=related_session_table table_template='panel_table.html' heading='Related BGP Sessions' panel_class='default noprint' %}

netbox_bgp/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.2"
1+
__version__ = "0.1.0"

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
with open("README.md", "r") as fh:
88
long_description = fh.read()
99

10+
1011
def read(rel_path):
1112
here = os.path.abspath(os.path.dirname(__file__))
1213
with codecs.open(os.path.join(here, rel_path), 'r') as fp:

0 commit comments

Comments
 (0)