Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions voipbox_plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ class VOIPBoxConfig(PluginConfig):
caching_config = {
'*': None
}
template_extensions = 'template_content.template_extensions'

config = VOIPBoxConfig
5 changes: 3 additions & 2 deletions voipbox_plugin/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from rest_framework import serializers

from circuits.api.serializers import ProviderSerializer
from dcim.api.serializers import RegionSerializer, SiteSerializer
from dcim.api.serializers import DeviceSerializer, RegionSerializer, SiteSerializer
from netbox.api.fields import ContentTypeField
from netbox.api.serializers import NetBoxModelSerializer
from tenancy.api.serializers import TenantSerializer
Expand All @@ -24,13 +24,14 @@ class PoolSerializer(NetBoxModelSerializer):
tenant = TenantSerializer(required=False, allow_null=True, nested=True)
region = RegionSerializer(required=False, allow_null=True, nested=True)
site = SiteSerializer(required=False, allow_null=True, nested=True)
device = DeviceSerializer(required=False, allow_null=True, nested=True)
provider = ProviderSerializer(required=False, allow_null=True, nested=True)
forward_to = serializers.PrimaryKeyRelatedField(queryset=Pool.objects.all(), required=False, allow_null=True)

class Meta:
model = Pool
fields = (
"id", "name", "url", "parent", "display", "start", "end", "tenant", "site", "region", "forward_to", "description", "provider", "tags",
"id", "name", "url", "parent", "display", "start", "end", "tenant", "site", "region", "device", "forward_to", "description", "provider", "tags",
)
brief_fields = ("id", "url", "start", "end", "display")

Expand Down
10 changes: 8 additions & 2 deletions voipbox_plugin/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.db.models import Q

from circuits.models import Provider
from dcim.models import Region, Site
from dcim.models import Region, Site, Device
from extras.filters import TagFilter
from netbox.filtersets import BaseFilterSet
from tenancy.models import Tenant
Expand Down Expand Up @@ -32,6 +32,12 @@ class PoolFilterSet(BaseFilterSet):
to_field_name='id',
label='Site (id)',
)
device = django_filters.ModelMultipleChoiceFilter(
queryset=Device.objects.all(),
field_name='device__id',
to_field_name='id',
label='Device (id)',
)
provider = django_filters.ModelMultipleChoiceFilter(
queryset=Provider.objects.all(),
field_name='provider__id',
Expand All @@ -48,7 +54,7 @@ class PoolFilterSet(BaseFilterSet):

class Meta():
model = Pool
fields = ('end', 'start', 'parent', 'tags')
fields = ('end', 'start', 'parent', 'device', 'tags')

def search(self, queryset, start, value):
if not value.strip():
Expand Down
17 changes: 15 additions & 2 deletions voipbox_plugin/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class PoolEditForm(NetBoxModelForm):
)
parent = DynamicModelChoiceField(queryset=Pool.objects.all(), required=False)
tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False)
device = DynamicModelChoiceField(queryset=Device.objects.all(), required=False)

tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(),
Expand All @@ -92,7 +93,7 @@ class PoolEditForm(NetBoxModelForm):

class Meta:
model = Pool
fields = ('name', 'start', 'end', 'parent', 'tenant', 'site', 'region', 'description', 'provider', 'forward_to',
fields = ('name', 'start', 'end', 'parent', 'tenant', 'site', 'region', 'device', 'description', 'provider', 'forward_to',
'tags')


Expand All @@ -119,6 +120,12 @@ class PoolBulkEditForm(AddRemoveTagsForm, BulkEditForm):
required=False,
null_option='None',
)
device = DynamicModelChoiceField(
queryset=Device.objects.all(),
to_field_name='id',
required=False,
null_option='None',
)

provider = DynamicModelChoiceField(
queryset=Provider.objects.all(),
Expand All @@ -138,7 +145,7 @@ class PoolBulkEditForm(AddRemoveTagsForm, BulkEditForm):
)

class Meta:
nullable_fields = ('region', 'site', 'provider', 'forward_to', 'description')
nullable_fields = ('region', 'site', 'device', 'provider', 'forward_to', 'description')


class PoolCSVForm(CSVModelForm):
Expand Down Expand Up @@ -166,6 +173,12 @@ class PoolCSVForm(CSVModelForm):
to_field_name='name',
help_text='Assigned site'
)
device = CSVModelChoiceField(
queryset=Device.objects.all(),
required=False,
to_field_name='name',
help_text='Assigned device'
)
forward_to = CSVModelChoiceField(
queryset=Pool.objects.all(),
to_field_name="pk",
Expand Down
23 changes: 23 additions & 0 deletions voipbox_plugin/migrations/0002_pool_device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("dcim", "0207_remove_redundant_indexes"),
("voipbox_plugin", "0001_initial"),
]

operations = [
migrations.AddField(
model_name="pool",
name="device",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="voipbox_pools",
to="dcim.device",
),
),
]
9 changes: 8 additions & 1 deletion voipbox_plugin/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ class Pool(NetBoxModel):
null=True,
related_name="site_set"
)
device = models.ForeignKey(
to="dcim.Device",
on_delete=models.SET_NULL,
blank=True,
null=True,
related_name="voipbox_pools"
)
forward_to = models.ForeignKey(
to="self",
on_delete=models.SET_NULL,
Expand All @@ -72,7 +79,7 @@ class Pool(NetBoxModel):

objects = RestrictedQuerySet.as_manager()

csv_headers = ['start', 'end', 'tenant', 'site', 'region', 'description', 'provider', 'forward_to']
csv_headers = ['start', 'end', 'tenant', 'site', 'region', 'device', 'description', 'provider', 'forward_to']

class Meta:
ordering = ['start']
Expand Down
15 changes: 14 additions & 1 deletion voipbox_plugin/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,29 @@ class PoolTable(BaseTable):
region = tables.LinkColumn()

site = tables.LinkColumn()
device = tables.LinkColumn()
provider = tables.LinkColumn()
forward_to = tables.LinkColumn()
tags = columns.TagColumn()

class Meta(BaseTable.Meta):
model = Pool
fields = ('pk', 'name', 'start', 'end', 'parent', 'tenant', 'site', 'region', 'description', 'provider',
fields = ('pk', 'name', 'start', 'end', 'parent', 'tenant', 'site', 'region', 'device', 'description', 'provider',
'forward_to', 'tags')


class DevicePoolTable(BaseTable):
number = tables.Column(accessor='start', linkify=True, verbose_name='Number')
site = tables.LinkColumn()
region = tables.LinkColumn()
provider = tables.LinkColumn()
forward_to = tables.LinkColumn()

class Meta(BaseTable.Meta):
model = Pool
fields = ('number', 'site', 'region', 'description', 'provider', 'forward_to')


class VoiceCircuitTable(BaseTable):
pk = ToggleColumn()
name = tables.LinkColumn()
Expand Down
29 changes: 29 additions & 0 deletions voipbox_plugin/template_content.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from netbox.plugins import PluginTemplateExtension

from .models import Pool

__all__ = (
"template_extensions",
)

class DevicePoolLink(PluginTemplateExtension):
models = ["dcim.device"]

def right_page(self):
device = self.context["object"]
pools = Pool.objects.filter(device=device).select_related(
"provider", "forward_to"
)

if not pools.exists():
return ""

return self.render(
"voipbox_plugin/device_pool_links.html",
extra_context={"pools": pools},
)


template_extensions = (
DevicePoolLink,
)
69 changes: 69 additions & 0 deletions voipbox_plugin/templates/voipbox_plugin/device_pool_links.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<div class="card">
<h2 class="card-header">Voice Pools</h2>
<table class="table table-hover attr-table">
<thead>
<tr>
<th>Name</th>
<th>Start</th>
<th>End</th>
<th>Parent</th>
<th>Tenant</th>
<th>Description</th>
<th>Provider</th>
<th>Forwards To</th>
</tr>
</thead>
<tbody>
{% for pool in pools %}
<tr>
<th scope="row">
<a href="{{ pool.get_absolute_url }}">{{ pool.name }}</a>
</th>
<td>
{% if pool.start %}
<a href="{{ pool.get_absolute_url }}">{{ pool.start }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
<td>
{% if pool.end %}
<a href="{{ pool.get_absolute_url }}">{{ pool.end }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
<td>
{% if pool.parent %}
<a href="{{ pool.parent.get_absolute_url }}">{{ pool.parent }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
<td>
{% if pool.tenant %}
<a href="{{ pool.tenant.get_absolute_url }}">{{ pool.tenant }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
<td>{{ pool.description|default:"-" }}</td>
<td>
{% if pool.provider %}
<a href="{{ pool.provider.get_absolute_url }}">{{ pool.provider }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
<td>
{% if pool.forward_to %}
<a href="{{ pool.forward_to.get_absolute_url }}">{{ pool.forward_to }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
10 changes: 10 additions & 0 deletions voipbox_plugin/templates/voipbox_plugin/pool.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ <h5 class="card-header">
{% endif %}
</td>
</tr>
<tr>
<td>Device</td>
<td>
{% if object.device %}
<a href="{{ object.device.get_absolute_url }}">{{ object.device }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
</tr>
<tr>
<td>Provider</td>
<td>
Expand Down
18 changes: 18 additions & 0 deletions voipbox_plugin/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.utils.translation import gettext_lazy as _
from dcim.models import Device
from netbox.views import generic
from utilities.views import ViewTab, register_model_view

Expand Down Expand Up @@ -64,6 +65,23 @@ class PoolBulkImportView(generic.BulkImportView):
table = tables.PoolTable


@register_model_view(Device, 'voipbox-pools', path='voipbox-pools')
class DevicePoolsView(generic.ObjectChildrenView):
queryset = Device.objects.all()
child_model = Pool
table = tables.DevicePoolTable
tab = ViewTab(
label=_('Voice Pools'),
badge=lambda obj: Pool.objects.filter(device=obj).count(),
permission='voipbox_plugin.view_pool',
weight=2250,
hide_if_empty=True,
)

def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, 'view').filter(device=parent)


@register_model_view(VoiceCircuit, "list", path="", detail=False)
class VoiceCircuitListView(generic.ObjectListView):
queryset = VoiceCircuit.objects.all()
Expand Down