mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 17:08:41 -06:00
Merge pull request #7297 from netbox-community/7295-tables-cleanup
Closes #7295: General cleanup of table classes
This commit is contained in:
commit
383cdb5340
@ -6,6 +6,14 @@ from utilities.tables import BaseTable, ButtonsColumn, ChoiceFieldColumn, Markdo
|
|||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'CircuitTable',
|
||||||
|
'CircuitTypeTable',
|
||||||
|
'ProviderTable',
|
||||||
|
'ProviderNetworkTable',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
CIRCUITTERMINATION_LINK = """
|
CIRCUITTERMINATION_LINK = """
|
||||||
{% if value.site %}
|
{% if value.site %}
|
||||||
<a href="{{ value.site.get_absolute_url }}">{{ value.site }}</a>
|
<a href="{{ value.site.get_absolute_url }}">{{ value.site }}</a>
|
||||||
|
@ -34,9 +34,7 @@ class ProviderView(generic.ObjectView):
|
|||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'type', 'tenant', 'terminations__site'
|
'type', 'tenant', 'terminations__site'
|
||||||
)
|
)
|
||||||
|
circuits_table = tables.CircuitTable(circuits, exclude=('provider',))
|
||||||
circuits_table = tables.CircuitTable(circuits)
|
|
||||||
circuits_table.columns.hide('provider')
|
|
||||||
paginate_table(circuits_table, request)
|
paginate_table(circuits_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -97,10 +95,7 @@ class ProviderNetworkView(generic.ObjectView):
|
|||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'type', 'tenant', 'terminations__site'
|
'type', 'tenant', 'terminations__site'
|
||||||
)
|
)
|
||||||
|
|
||||||
circuits_table = tables.CircuitTable(circuits)
|
circuits_table = tables.CircuitTable(circuits)
|
||||||
circuits_table.columns.hide('termination_a')
|
|
||||||
circuits_table.columns.hide('termination_z')
|
|
||||||
paginate_table(circuits_table, request)
|
paginate_table(circuits_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -153,12 +148,8 @@ class CircuitTypeView(generic.ObjectView):
|
|||||||
queryset = CircuitType.objects.all()
|
queryset = CircuitType.objects.all()
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
circuits = Circuit.objects.restrict(request.user, 'view').filter(
|
circuits = Circuit.objects.restrict(request.user, 'view').filter(type=instance)
|
||||||
type=instance
|
circuits_table = tables.CircuitTable(circuits, exclude=('type',))
|
||||||
)
|
|
||||||
|
|
||||||
circuits_table = tables.CircuitTable(circuits)
|
|
||||||
circuits_table.columns.hide('type')
|
|
||||||
paginate_table(circuits_table, request)
|
paginate_table(circuits_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -18,6 +18,7 @@ from .template_code import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
|
'BaseInterfaceTable',
|
||||||
'ConsolePortTable',
|
'ConsolePortTable',
|
||||||
'ConsoleServerPortTable',
|
'ConsoleServerPortTable',
|
||||||
'DeviceBayTable',
|
'DeviceBayTable',
|
||||||
|
@ -10,7 +10,6 @@ from utilities.tables import (
|
|||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'RackTable',
|
'RackTable',
|
||||||
'RackDetailTable',
|
|
||||||
'RackReservationTable',
|
'RackReservationTable',
|
||||||
'RackRoleTable',
|
'RackRoleTable',
|
||||||
)
|
)
|
||||||
@ -56,17 +55,6 @@ class RackTable(BaseTable):
|
|||||||
template_code="{{ record.u_height }}U",
|
template_code="{{ record.u_height }}U",
|
||||||
verbose_name='Height'
|
verbose_name='Height'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = Rack
|
|
||||||
fields = (
|
|
||||||
'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type',
|
|
||||||
'width', 'u_height',
|
|
||||||
)
|
|
||||||
default_columns = ('pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'u_height')
|
|
||||||
|
|
||||||
|
|
||||||
class RackDetailTable(RackTable):
|
|
||||||
comments = MarkdownColumn()
|
comments = MarkdownColumn()
|
||||||
device_count = LinkedCountColumn(
|
device_count = LinkedCountColumn(
|
||||||
viewname='dcim:device_list',
|
viewname='dcim:device_list',
|
||||||
@ -85,7 +73,8 @@ class RackDetailTable(RackTable):
|
|||||||
url_name='dcim:rack_list'
|
url_name='dcim:rack_list'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(RackTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
|
model = Rack
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type',
|
'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type',
|
||||||
'width', 'u_height', 'comments', 'device_count', 'get_utilization', 'get_power_utilization', 'tags',
|
'width', 'u_height', 'comments', 'device_count', 'get_utilization', 'get_power_utilization', 'tags',
|
||||||
|
@ -131,8 +131,7 @@ class RegionView(generic.ObjectView):
|
|||||||
sites = Site.objects.restrict(request.user, 'view').filter(
|
sites = Site.objects.restrict(request.user, 'view').filter(
|
||||||
region=instance
|
region=instance
|
||||||
)
|
)
|
||||||
sites_table = tables.SiteTable(sites)
|
sites_table = tables.SiteTable(sites, exclude=('region',))
|
||||||
sites_table.columns.hide('region')
|
|
||||||
paginate_table(sites_table, request)
|
paginate_table(sites_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -216,8 +215,7 @@ class SiteGroupView(generic.ObjectView):
|
|||||||
sites = Site.objects.restrict(request.user, 'view').filter(
|
sites = Site.objects.restrict(request.user, 'view').filter(
|
||||||
group=instance
|
group=instance
|
||||||
)
|
)
|
||||||
sites_table = tables.SiteTable(sites)
|
sites_table = tables.SiteTable(sites, exclude=('group',))
|
||||||
sites_table.columns.hide('group')
|
|
||||||
paginate_table(sites_table, request)
|
paginate_table(sites_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -453,8 +451,7 @@ class RackRoleView(generic.ObjectView):
|
|||||||
role=instance
|
role=instance
|
||||||
)
|
)
|
||||||
|
|
||||||
racks_table = tables.RackTable(racks)
|
racks_table = tables.RackTable(racks, exclude=('role', 'get_utilization', 'get_power_utilization'))
|
||||||
racks_table.columns.hide('role')
|
|
||||||
paginate_table(racks_table, request)
|
paginate_table(racks_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -505,7 +502,7 @@ class RackListView(generic.ObjectListView):
|
|||||||
)
|
)
|
||||||
filterset = filtersets.RackFilterSet
|
filterset = filtersets.RackFilterSet
|
||||||
filterset_form = forms.RackFilterForm
|
filterset_form = forms.RackFilterForm
|
||||||
table = tables.RackDetailTable
|
table = tables.RackTable
|
||||||
|
|
||||||
|
|
||||||
class RackElevationListView(generic.ObjectListView):
|
class RackElevationListView(generic.ObjectListView):
|
||||||
@ -704,8 +701,7 @@ class ManufacturerView(generic.ObjectView):
|
|||||||
manufacturer=instance
|
manufacturer=instance
|
||||||
)
|
)
|
||||||
|
|
||||||
devicetypes_table = tables.DeviceTypeTable(devicetypes)
|
devicetypes_table = tables.DeviceTypeTable(devicetypes, exclude=('manufacturer',))
|
||||||
devicetypes_table.columns.hide('manufacturer')
|
|
||||||
paginate_table(devicetypes_table, request)
|
paginate_table(devicetypes_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -1165,9 +1161,7 @@ class DeviceRoleView(generic.ObjectView):
|
|||||||
devices = Device.objects.restrict(request.user, 'view').filter(
|
devices = Device.objects.restrict(request.user, 'view').filter(
|
||||||
device_role=instance
|
device_role=instance
|
||||||
)
|
)
|
||||||
|
devices_table = tables.DeviceTable(devices, exclude=('device_role',))
|
||||||
devices_table = tables.DeviceTable(devices)
|
|
||||||
devices_table.columns.hide('device_role')
|
|
||||||
paginate_table(devices_table, request)
|
paginate_table(devices_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -1231,9 +1225,7 @@ class PlatformView(generic.ObjectView):
|
|||||||
devices = Device.objects.restrict(request.user, 'view').filter(
|
devices = Device.objects.restrict(request.user, 'view').filter(
|
||||||
platform=instance
|
platform=instance
|
||||||
)
|
)
|
||||||
|
devices_table = tables.DeviceTable(devices, exclude=('platform',))
|
||||||
devices_table = tables.DeviceTable(devices)
|
|
||||||
devices_table.columns.hide('platform')
|
|
||||||
paginate_table(devices_table, request)
|
paginate_table(devices_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -1878,9 +1870,9 @@ class InterfaceView(generic.ObjectView):
|
|||||||
child_interfaces = Interface.objects.restrict(request.user, 'view').filter(parent=instance)
|
child_interfaces = Interface.objects.restrict(request.user, 'view').filter(parent=instance)
|
||||||
child_interfaces_tables = tables.InterfaceTable(
|
child_interfaces_tables = tables.InterfaceTable(
|
||||||
child_interfaces,
|
child_interfaces,
|
||||||
|
exclude=('device', 'parent'),
|
||||||
orderable=False
|
orderable=False
|
||||||
)
|
)
|
||||||
child_interfaces_tables.columns.hide('device')
|
|
||||||
|
|
||||||
# Get assigned VLANs and annotate whether each is tagged or untagged
|
# Get assigned VLANs and annotate whether each is tagged or untagged
|
||||||
vlans = []
|
vlans = []
|
||||||
|
@ -7,6 +7,19 @@ from utilities.tables import (
|
|||||||
)
|
)
|
||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'ConfigContextTable',
|
||||||
|
'CustomFieldTable',
|
||||||
|
'CustomLinkTable',
|
||||||
|
'ExportTemplateTable',
|
||||||
|
'JournalEntryTable',
|
||||||
|
'ObjectChangeTable',
|
||||||
|
'ObjectJournalTable',
|
||||||
|
'TaggedItemTable',
|
||||||
|
'TagTable',
|
||||||
|
'WebhookTable',
|
||||||
|
)
|
||||||
|
|
||||||
CONFIGCONTEXT_ACTIONS = """
|
CONFIGCONTEXT_ACTIONS = """
|
||||||
{% if perms.extras.change_configcontext %}
|
{% if perms.extras.change_configcontext %}
|
||||||
<a href="{% url 'extras:configcontext_edit' pk=record.pk %}" class="btn btn-sm btn-warning"><i class="mdi mdi-pencil" aria-hidden="true"></i></a>
|
<a href="{% url 'extras:configcontext_edit' pk=record.pk %}" class="btn btn-sm btn-warning"><i class="mdi mdi-pencil" aria-hidden="true"></i></a>
|
||||||
|
4
netbox/ipam/tables/__init__.py
Normal file
4
netbox/ipam/tables/__init__.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
from .ip import *
|
||||||
|
from .services import *
|
||||||
|
from .vlans import *
|
||||||
|
from .vrfs import *
|
@ -2,14 +2,23 @@ import django_tables2 as tables
|
|||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django_tables2.utils import Accessor
|
from django_tables2.utils import Accessor
|
||||||
|
|
||||||
from dcim.models import Interface
|
|
||||||
from tenancy.tables import TenantColumn
|
from tenancy.tables import TenantColumn
|
||||||
from utilities.tables import (
|
from utilities.tables import (
|
||||||
BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ContentTypeColumn, LinkedCountColumn, TagColumn,
|
BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, LinkedCountColumn, TagColumn,
|
||||||
ToggleColumn, UtilizationColumn,
|
ToggleColumn, UtilizationColumn,
|
||||||
)
|
)
|
||||||
from virtualization.models import VMInterface
|
from ipam.models import *
|
||||||
from .models import *
|
|
||||||
|
__all__ = (
|
||||||
|
'AggregateTable',
|
||||||
|
'InterfaceIPAddressTable',
|
||||||
|
'IPAddressAssignTable',
|
||||||
|
'IPAddressTable',
|
||||||
|
'IPRangeTable',
|
||||||
|
'PrefixTable',
|
||||||
|
'RIRTable',
|
||||||
|
'RoleTable',
|
||||||
|
)
|
||||||
|
|
||||||
AVAILABLE_LABEL = mark_safe('<span class="badge bg-success">Available</span>')
|
AVAILABLE_LABEL = mark_safe('<span class="badge bg-success">Available</span>')
|
||||||
|
|
||||||
@ -66,114 +75,6 @@ VRF_LINK = """
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VRF_TARGETS = """
|
|
||||||
{% for rt in value.all %}
|
|
||||||
<a href="{{ rt.get_absolute_url }}">{{ rt }}</a>{% if not forloop.last %}<br />{% endif %}
|
|
||||||
{% empty %}
|
|
||||||
—
|
|
||||||
{% endfor %}
|
|
||||||
"""
|
|
||||||
|
|
||||||
VLAN_LINK = """
|
|
||||||
{% if record.pk %}
|
|
||||||
<a href="{{ record.get_absolute_url }}">{{ record.vid }}</a>
|
|
||||||
{% elif perms.ipam.add_vlan %}
|
|
||||||
<a href="{% url 'ipam:vlan_add' %}?vid={{ record.vid }}{% if record.vlan_group %}&group={{ record.vlan_group.pk }}{% endif %}" class="btn btn-sm btn-success">{{ record.available }} VLAN{{ record.available|pluralize }} available</a>
|
|
||||||
{% else %}
|
|
||||||
{{ record.available }} VLAN{{ record.available|pluralize }} available
|
|
||||||
{% endif %}
|
|
||||||
"""
|
|
||||||
|
|
||||||
VLAN_PREFIXES = """
|
|
||||||
{% for prefix in record.prefixes.all %}
|
|
||||||
<a href="{% url 'ipam:prefix' pk=prefix.pk %}">{{ prefix }}</a>{% if not forloop.last %}<br />{% endif %}
|
|
||||||
{% empty %}
|
|
||||||
—
|
|
||||||
{% endfor %}
|
|
||||||
"""
|
|
||||||
|
|
||||||
VLAN_ROLE_LINK = """
|
|
||||||
{% if record.role %}
|
|
||||||
<a href="{% url 'ipam:vlan_list' %}?role={{ record.role.slug }}">{{ record.role }}</a>
|
|
||||||
{% else %}
|
|
||||||
—
|
|
||||||
{% endif %}
|
|
||||||
"""
|
|
||||||
|
|
||||||
VLANGROUP_ADD_VLAN = """
|
|
||||||
{% with next_vid=record.get_next_available_vid %}
|
|
||||||
{% if next_vid and perms.ipam.add_vlan %}
|
|
||||||
<a href="{% url 'ipam:vlan_add' %}?group={{ record.pk }}&vid={{ next_vid }}" title="Add VLAN" class="btn btn-sm btn-success">
|
|
||||||
<i class="mdi mdi-plus-thick" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
"""
|
|
||||||
|
|
||||||
VLAN_MEMBER_TAGGED = """
|
|
||||||
{% if record.untagged_vlan_id == object.pk %}
|
|
||||||
<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>
|
|
||||||
{% else %}
|
|
||||||
<span class="text-success"><i class="mdi mdi-check-bold"></i></span>
|
|
||||||
{% endif %}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# VRFs
|
|
||||||
#
|
|
||||||
|
|
||||||
class VRFTable(BaseTable):
|
|
||||||
pk = ToggleColumn()
|
|
||||||
name = tables.Column(
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
rd = tables.Column(
|
|
||||||
verbose_name='RD'
|
|
||||||
)
|
|
||||||
tenant = TenantColumn()
|
|
||||||
enforce_unique = BooleanColumn(
|
|
||||||
verbose_name='Unique'
|
|
||||||
)
|
|
||||||
import_targets = tables.TemplateColumn(
|
|
||||||
template_code=VRF_TARGETS,
|
|
||||||
orderable=False
|
|
||||||
)
|
|
||||||
export_targets = tables.TemplateColumn(
|
|
||||||
template_code=VRF_TARGETS,
|
|
||||||
orderable=False
|
|
||||||
)
|
|
||||||
tags = TagColumn(
|
|
||||||
url_name='ipam:vrf_list'
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = VRF
|
|
||||||
fields = (
|
|
||||||
'pk', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'import_targets', 'export_targets', 'tags',
|
|
||||||
)
|
|
||||||
default_columns = ('pk', 'name', 'rd', 'tenant', 'description')
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Route targets
|
|
||||||
#
|
|
||||||
|
|
||||||
class RouteTargetTable(BaseTable):
|
|
||||||
pk = ToggleColumn()
|
|
||||||
name = tables.Column(
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
tenant = TenantColumn()
|
|
||||||
tags = TagColumn(
|
|
||||||
url_name='ipam:vrf_list'
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = RouteTarget
|
|
||||||
fields = ('pk', 'name', 'tenant', 'description', 'tags')
|
|
||||||
default_columns = ('pk', 'name', 'tenant', 'description')
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# RIRs
|
# RIRs
|
||||||
@ -215,13 +116,6 @@ class AggregateTable(BaseTable):
|
|||||||
format="Y-m-d",
|
format="Y-m-d",
|
||||||
verbose_name='Added'
|
verbose_name='Added'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = Aggregate
|
|
||||||
fields = ('pk', 'prefix', 'rir', 'tenant', 'date_added', 'description')
|
|
||||||
|
|
||||||
|
|
||||||
class AggregateDetailTable(AggregateTable):
|
|
||||||
child_count = tables.Column(
|
child_count = tables.Column(
|
||||||
verbose_name='Prefixes'
|
verbose_name='Prefixes'
|
||||||
)
|
)
|
||||||
@ -233,7 +127,8 @@ class AggregateDetailTable(AggregateTable):
|
|||||||
url_name='ipam:aggregate_list'
|
url_name='ipam:aggregate_list'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(AggregateTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
|
model = Aggregate
|
||||||
fields = ('pk', 'prefix', 'rir', 'tenant', 'child_count', 'utilization', 'date_added', 'description', 'tags')
|
fields = ('pk', 'prefix', 'rir', 'tenant', 'child_count', 'utilization', 'date_added', 'description', 'tags')
|
||||||
default_columns = ('pk', 'prefix', 'rir', 'tenant', 'child_count', 'utilization', 'date_added', 'description')
|
default_columns = ('pk', 'prefix', 'rir', 'tenant', 'child_count', 'utilization', 'date_added', 'description')
|
||||||
|
|
||||||
@ -332,20 +227,6 @@ class PrefixTable(BaseTable):
|
|||||||
mark_utilized = BooleanColumn(
|
mark_utilized = BooleanColumn(
|
||||||
verbose_name='Marked Utilized'
|
verbose_name='Marked Utilized'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = Prefix
|
|
||||||
fields = (
|
|
||||||
'pk', 'prefix', 'prefix_flat', 'status', 'depth', 'children', 'vrf', 'tenant', 'site', 'vlan', 'role',
|
|
||||||
'is_pool', 'mark_utilized', 'description',
|
|
||||||
)
|
|
||||||
default_columns = ('pk', 'prefix', 'status', 'vrf', 'tenant', 'site', 'vlan', 'role', 'description')
|
|
||||||
row_attrs = {
|
|
||||||
'class': lambda record: 'success' if not record.pk else '',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class PrefixDetailTable(PrefixTable):
|
|
||||||
utilization = PrefixUtilizationColumn(
|
utilization = PrefixUtilizationColumn(
|
||||||
accessor='get_utilization',
|
accessor='get_utilization',
|
||||||
orderable=False
|
orderable=False
|
||||||
@ -354,7 +235,8 @@ class PrefixDetailTable(PrefixTable):
|
|||||||
url_name='ipam:prefix_list'
|
url_name='ipam:prefix_list'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(PrefixTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
|
model = Prefix
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role',
|
'pk', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role',
|
||||||
'is_pool', 'mark_utilized', 'description', 'tags',
|
'is_pool', 'mark_utilized', 'description', 'tags',
|
||||||
@ -362,6 +244,9 @@ class PrefixDetailTable(PrefixTable):
|
|||||||
default_columns = (
|
default_columns = (
|
||||||
'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description',
|
'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description',
|
||||||
)
|
)
|
||||||
|
row_attrs = {
|
||||||
|
'class': lambda record: 'success' if not record.pk else '',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -427,25 +312,11 @@ class IPAddressTable(BaseTable):
|
|||||||
orderable=False,
|
orderable=False,
|
||||||
verbose_name='Device/VM'
|
verbose_name='Device/VM'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = IPAddress
|
|
||||||
fields = (
|
|
||||||
'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned_object', 'assigned_object_parent', 'dns_name',
|
|
||||||
'description',
|
|
||||||
)
|
|
||||||
row_attrs = {
|
|
||||||
'class': lambda record: 'success' if not isinstance(record, IPAddress) else '',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class IPAddressDetailTable(IPAddressTable):
|
|
||||||
nat_inside = tables.Column(
|
nat_inside = tables.Column(
|
||||||
linkify=True,
|
linkify=True,
|
||||||
orderable=False,
|
orderable=False,
|
||||||
verbose_name='NAT (Inside)'
|
verbose_name='NAT (Inside)'
|
||||||
)
|
)
|
||||||
tenant = TenantColumn()
|
|
||||||
assigned = BooleanColumn(
|
assigned = BooleanColumn(
|
||||||
accessor='assigned_object_id',
|
accessor='assigned_object_id',
|
||||||
verbose_name='Assigned'
|
verbose_name='Assigned'
|
||||||
@ -454,14 +325,18 @@ class IPAddressDetailTable(IPAddressTable):
|
|||||||
url_name='ipam:ipaddress_list'
|
url_name='ipam:ipaddress_list'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(IPAddressTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
|
model = IPAddress
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'nat_inside', 'assigned', 'dns_name',
|
'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'nat_inside', 'assigned', 'dns_name', 'description',
|
||||||
'description', 'tags',
|
'tags',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description',
|
'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description',
|
||||||
)
|
)
|
||||||
|
row_attrs = {
|
||||||
|
'class': lambda record: 'success' if not isinstance(record, IPAddress) else '',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class IPAddressAssignTable(BaseTable):
|
class IPAddressAssignTable(BaseTable):
|
||||||
@ -501,173 +376,3 @@ class InterfaceIPAddressTable(BaseTable):
|
|||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = IPAddress
|
model = IPAddress
|
||||||
fields = ('address', 'vrf', 'status', 'role', 'tenant', 'description')
|
fields = ('address', 'vrf', 'status', 'role', 'tenant', 'description')
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# VLAN groups
|
|
||||||
#
|
|
||||||
|
|
||||||
class VLANGroupTable(BaseTable):
|
|
||||||
pk = ToggleColumn()
|
|
||||||
name = tables.Column(linkify=True)
|
|
||||||
scope_type = ContentTypeColumn()
|
|
||||||
scope = tables.Column(
|
|
||||||
linkify=True,
|
|
||||||
orderable=False
|
|
||||||
)
|
|
||||||
vlan_count = LinkedCountColumn(
|
|
||||||
viewname='ipam:vlan_list',
|
|
||||||
url_params={'group_id': 'pk'},
|
|
||||||
verbose_name='VLANs'
|
|
||||||
)
|
|
||||||
actions = ButtonsColumn(
|
|
||||||
model=VLANGroup,
|
|
||||||
prepend_template=VLANGROUP_ADD_VLAN
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = VLANGroup
|
|
||||||
fields = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'slug', 'description', 'actions')
|
|
||||||
default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'description', 'actions')
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# VLANs
|
|
||||||
#
|
|
||||||
|
|
||||||
class VLANTable(BaseTable):
|
|
||||||
pk = ToggleColumn()
|
|
||||||
vid = tables.TemplateColumn(
|
|
||||||
template_code=VLAN_LINK,
|
|
||||||
verbose_name='ID'
|
|
||||||
)
|
|
||||||
site = tables.Column(
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
group = tables.Column(
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
tenant = TenantColumn()
|
|
||||||
status = ChoiceFieldColumn(
|
|
||||||
default=AVAILABLE_LABEL
|
|
||||||
)
|
|
||||||
role = tables.TemplateColumn(
|
|
||||||
template_code=VLAN_ROLE_LINK
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = VLAN
|
|
||||||
fields = ('pk', 'vid', 'name', 'site', 'group', 'tenant', 'status', 'role', 'description')
|
|
||||||
row_attrs = {
|
|
||||||
'class': lambda record: 'success' if not isinstance(record, VLAN) else '',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class VLANDetailTable(VLANTable):
|
|
||||||
prefixes = tables.TemplateColumn(
|
|
||||||
template_code=VLAN_PREFIXES,
|
|
||||||
orderable=False,
|
|
||||||
verbose_name='Prefixes'
|
|
||||||
)
|
|
||||||
tenant = TenantColumn()
|
|
||||||
tags = TagColumn(
|
|
||||||
url_name='ipam:vlan_list'
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(VLANTable.Meta):
|
|
||||||
fields = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description', 'tags')
|
|
||||||
default_columns = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description')
|
|
||||||
|
|
||||||
|
|
||||||
class VLANMembersTable(BaseTable):
|
|
||||||
"""
|
|
||||||
Base table for Interface and VMInterface assignments
|
|
||||||
"""
|
|
||||||
name = tables.Column(
|
|
||||||
linkify=True,
|
|
||||||
verbose_name='Interface'
|
|
||||||
)
|
|
||||||
tagged = tables.TemplateColumn(
|
|
||||||
template_code=VLAN_MEMBER_TAGGED,
|
|
||||||
orderable=False
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class VLANDevicesTable(VLANMembersTable):
|
|
||||||
device = tables.Column(
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
actions = ButtonsColumn(Interface, buttons=['edit'])
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = Interface
|
|
||||||
fields = ('device', 'name', 'tagged', 'actions')
|
|
||||||
|
|
||||||
|
|
||||||
class VLANVirtualMachinesTable(VLANMembersTable):
|
|
||||||
virtual_machine = tables.Column(
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
actions = ButtonsColumn(VMInterface, buttons=['edit'])
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = VMInterface
|
|
||||||
fields = ('virtual_machine', 'name', 'tagged', 'actions')
|
|
||||||
|
|
||||||
|
|
||||||
class InterfaceVLANTable(BaseTable):
|
|
||||||
"""
|
|
||||||
List VLANs assigned to a specific Interface.
|
|
||||||
"""
|
|
||||||
vid = tables.Column(
|
|
||||||
linkify=True,
|
|
||||||
verbose_name='ID'
|
|
||||||
)
|
|
||||||
tagged = BooleanColumn()
|
|
||||||
site = tables.Column(
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
group = tables.Column(
|
|
||||||
accessor=Accessor('group__name'),
|
|
||||||
verbose_name='Group'
|
|
||||||
)
|
|
||||||
tenant = TenantColumn()
|
|
||||||
status = ChoiceFieldColumn()
|
|
||||||
role = tables.TemplateColumn(
|
|
||||||
template_code=VLAN_ROLE_LINK
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = VLAN
|
|
||||||
fields = ('vid', 'tagged', 'site', 'group', 'name', 'tenant', 'status', 'role', 'description')
|
|
||||||
|
|
||||||
def __init__(self, interface, *args, **kwargs):
|
|
||||||
self.interface = interface
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Services
|
|
||||||
#
|
|
||||||
|
|
||||||
class ServiceTable(BaseTable):
|
|
||||||
pk = ToggleColumn()
|
|
||||||
name = tables.Column(
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
parent = tables.Column(
|
|
||||||
linkify=True,
|
|
||||||
order_by=('device', 'virtual_machine')
|
|
||||||
)
|
|
||||||
ports = tables.TemplateColumn(
|
|
||||||
template_code='{{ record.port_list }}',
|
|
||||||
verbose_name='Ports'
|
|
||||||
)
|
|
||||||
tags = TagColumn(
|
|
||||||
url_name='ipam:service_list'
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = Service
|
|
||||||
fields = ('pk', 'name', 'parent', 'protocol', 'ports', 'ipaddresses', 'description', 'tags')
|
|
||||||
default_columns = ('pk', 'name', 'parent', 'protocol', 'ports', 'description')
|
|
35
netbox/ipam/tables/services.py
Normal file
35
netbox/ipam/tables/services.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import django_tables2 as tables
|
||||||
|
|
||||||
|
from utilities.tables import BaseTable, TagColumn, ToggleColumn
|
||||||
|
from ipam.models import *
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'ServiceTable',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Services
|
||||||
|
#
|
||||||
|
|
||||||
|
class ServiceTable(BaseTable):
|
||||||
|
pk = ToggleColumn()
|
||||||
|
name = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
parent = tables.Column(
|
||||||
|
linkify=True,
|
||||||
|
order_by=('device', 'virtual_machine')
|
||||||
|
)
|
||||||
|
ports = tables.TemplateColumn(
|
||||||
|
template_code='{{ record.port_list }}',
|
||||||
|
verbose_name='Ports'
|
||||||
|
)
|
||||||
|
tags = TagColumn(
|
||||||
|
url_name='ipam:service_list'
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = Service
|
||||||
|
fields = ('pk', 'name', 'parent', 'protocol', 'ports', 'ipaddresses', 'description', 'tags')
|
||||||
|
default_columns = ('pk', 'name', 'parent', 'protocol', 'ports', 'description')
|
203
netbox/ipam/tables/vlans.py
Normal file
203
netbox/ipam/tables/vlans.py
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
import django_tables2 as tables
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
from django_tables2.utils import Accessor
|
||||||
|
|
||||||
|
from dcim.models import Interface
|
||||||
|
from tenancy.tables import TenantColumn
|
||||||
|
from utilities.tables import (
|
||||||
|
BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ContentTypeColumn, LinkedCountColumn, TagColumn,
|
||||||
|
ToggleColumn,
|
||||||
|
)
|
||||||
|
from virtualization.models import VMInterface
|
||||||
|
from ipam.models import *
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'InterfaceVLANTable',
|
||||||
|
'VLANDevicesTable',
|
||||||
|
'VLANGroupTable',
|
||||||
|
'VLANMembersTable',
|
||||||
|
'VLANTable',
|
||||||
|
'VLANVirtualMachinesTable',
|
||||||
|
)
|
||||||
|
|
||||||
|
AVAILABLE_LABEL = mark_safe('<span class="badge bg-success">Available</span>')
|
||||||
|
|
||||||
|
VLAN_LINK = """
|
||||||
|
{% if record.pk %}
|
||||||
|
<a href="{{ record.get_absolute_url }}">{{ record.vid }}</a>
|
||||||
|
{% elif perms.ipam.add_vlan %}
|
||||||
|
<a href="{% url 'ipam:vlan_add' %}?vid={{ record.vid }}{% if record.vlan_group %}&group={{ record.vlan_group.pk }}{% endif %}" class="btn btn-sm btn-success">{{ record.available }} VLAN{{ record.available|pluralize }} available</a>
|
||||||
|
{% else %}
|
||||||
|
{{ record.available }} VLAN{{ record.available|pluralize }} available
|
||||||
|
{% endif %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
VLAN_PREFIXES = """
|
||||||
|
{% for prefix in record.prefixes.all %}
|
||||||
|
<a href="{% url 'ipam:prefix' pk=prefix.pk %}">{{ prefix }}</a>{% if not forloop.last %}<br />{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
—
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
VLAN_ROLE_LINK = """
|
||||||
|
{% if record.role %}
|
||||||
|
<a href="{% url 'ipam:vlan_list' %}?role={{ record.role.slug }}">{{ record.role }}</a>
|
||||||
|
{% else %}
|
||||||
|
—
|
||||||
|
{% endif %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
VLANGROUP_ADD_VLAN = """
|
||||||
|
{% with next_vid=record.get_next_available_vid %}
|
||||||
|
{% if next_vid and perms.ipam.add_vlan %}
|
||||||
|
<a href="{% url 'ipam:vlan_add' %}?group={{ record.pk }}&vid={{ next_vid }}" title="Add VLAN" class="btn btn-sm btn-success">
|
||||||
|
<i class="mdi mdi-plus-thick" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
VLAN_MEMBER_TAGGED = """
|
||||||
|
{% if record.untagged_vlan_id == object.pk %}
|
||||||
|
<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>
|
||||||
|
{% else %}
|
||||||
|
<span class="text-success"><i class="mdi mdi-check-bold"></i></span>
|
||||||
|
{% endif %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# VLAN groups
|
||||||
|
#
|
||||||
|
|
||||||
|
class VLANGroupTable(BaseTable):
|
||||||
|
pk = ToggleColumn()
|
||||||
|
name = tables.Column(linkify=True)
|
||||||
|
scope_type = ContentTypeColumn()
|
||||||
|
scope = tables.Column(
|
||||||
|
linkify=True,
|
||||||
|
orderable=False
|
||||||
|
)
|
||||||
|
vlan_count = LinkedCountColumn(
|
||||||
|
viewname='ipam:vlan_list',
|
||||||
|
url_params={'group_id': 'pk'},
|
||||||
|
verbose_name='VLANs'
|
||||||
|
)
|
||||||
|
actions = ButtonsColumn(
|
||||||
|
model=VLANGroup,
|
||||||
|
prepend_template=VLANGROUP_ADD_VLAN
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = VLANGroup
|
||||||
|
fields = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'slug', 'description', 'actions')
|
||||||
|
default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'description', 'actions')
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# VLANs
|
||||||
|
#
|
||||||
|
|
||||||
|
class VLANTable(BaseTable):
|
||||||
|
pk = ToggleColumn()
|
||||||
|
vid = tables.TemplateColumn(
|
||||||
|
template_code=VLAN_LINK,
|
||||||
|
verbose_name='ID'
|
||||||
|
)
|
||||||
|
site = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
group = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
tenant = TenantColumn()
|
||||||
|
status = ChoiceFieldColumn(
|
||||||
|
default=AVAILABLE_LABEL
|
||||||
|
)
|
||||||
|
role = tables.TemplateColumn(
|
||||||
|
template_code=VLAN_ROLE_LINK
|
||||||
|
)
|
||||||
|
prefixes = tables.TemplateColumn(
|
||||||
|
template_code=VLAN_PREFIXES,
|
||||||
|
orderable=False,
|
||||||
|
verbose_name='Prefixes'
|
||||||
|
)
|
||||||
|
tags = TagColumn(
|
||||||
|
url_name='ipam:vlan_list'
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = VLAN
|
||||||
|
fields = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description', 'tags')
|
||||||
|
default_columns = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description')
|
||||||
|
row_attrs = {
|
||||||
|
'class': lambda record: 'success' if not isinstance(record, VLAN) else '',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class VLANMembersTable(BaseTable):
|
||||||
|
"""
|
||||||
|
Base table for Interface and VMInterface assignments
|
||||||
|
"""
|
||||||
|
name = tables.Column(
|
||||||
|
linkify=True,
|
||||||
|
verbose_name='Interface'
|
||||||
|
)
|
||||||
|
tagged = tables.TemplateColumn(
|
||||||
|
template_code=VLAN_MEMBER_TAGGED,
|
||||||
|
orderable=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VLANDevicesTable(VLANMembersTable):
|
||||||
|
device = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
actions = ButtonsColumn(Interface, buttons=['edit'])
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = Interface
|
||||||
|
fields = ('device', 'name', 'tagged', 'actions')
|
||||||
|
|
||||||
|
|
||||||
|
class VLANVirtualMachinesTable(VLANMembersTable):
|
||||||
|
virtual_machine = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
actions = ButtonsColumn(VMInterface, buttons=['edit'])
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = VMInterface
|
||||||
|
fields = ('virtual_machine', 'name', 'tagged', 'actions')
|
||||||
|
|
||||||
|
|
||||||
|
class InterfaceVLANTable(BaseTable):
|
||||||
|
"""
|
||||||
|
List VLANs assigned to a specific Interface.
|
||||||
|
"""
|
||||||
|
vid = tables.Column(
|
||||||
|
linkify=True,
|
||||||
|
verbose_name='ID'
|
||||||
|
)
|
||||||
|
tagged = BooleanColumn()
|
||||||
|
site = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
group = tables.Column(
|
||||||
|
accessor=Accessor('group__name'),
|
||||||
|
verbose_name='Group'
|
||||||
|
)
|
||||||
|
tenant = TenantColumn()
|
||||||
|
status = ChoiceFieldColumn()
|
||||||
|
role = tables.TemplateColumn(
|
||||||
|
template_code=VLAN_ROLE_LINK
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = VLAN
|
||||||
|
fields = ('vid', 'tagged', 'site', 'group', 'name', 'tenant', 'status', 'role', 'description')
|
||||||
|
|
||||||
|
def __init__(self, interface, *args, **kwargs):
|
||||||
|
self.interface = interface
|
||||||
|
super().__init__(*args, **kwargs)
|
74
netbox/ipam/tables/vrfs.py
Normal file
74
netbox/ipam/tables/vrfs.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import django_tables2 as tables
|
||||||
|
|
||||||
|
from tenancy.tables import TenantColumn
|
||||||
|
from utilities.tables import BaseTable, BooleanColumn, TagColumn, ToggleColumn
|
||||||
|
from ipam.models import *
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'RouteTargetTable',
|
||||||
|
'VRFTable',
|
||||||
|
)
|
||||||
|
|
||||||
|
VRF_TARGETS = """
|
||||||
|
{% for rt in value.all %}
|
||||||
|
<a href="{{ rt.get_absolute_url }}">{{ rt }}</a>{% if not forloop.last %}<br />{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
—
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# VRFs
|
||||||
|
#
|
||||||
|
|
||||||
|
class VRFTable(BaseTable):
|
||||||
|
pk = ToggleColumn()
|
||||||
|
name = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
rd = tables.Column(
|
||||||
|
verbose_name='RD'
|
||||||
|
)
|
||||||
|
tenant = TenantColumn()
|
||||||
|
enforce_unique = BooleanColumn(
|
||||||
|
verbose_name='Unique'
|
||||||
|
)
|
||||||
|
import_targets = tables.TemplateColumn(
|
||||||
|
template_code=VRF_TARGETS,
|
||||||
|
orderable=False
|
||||||
|
)
|
||||||
|
export_targets = tables.TemplateColumn(
|
||||||
|
template_code=VRF_TARGETS,
|
||||||
|
orderable=False
|
||||||
|
)
|
||||||
|
tags = TagColumn(
|
||||||
|
url_name='ipam:vrf_list'
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = VRF
|
||||||
|
fields = (
|
||||||
|
'pk', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'import_targets', 'export_targets', 'tags',
|
||||||
|
)
|
||||||
|
default_columns = ('pk', 'name', 'rd', 'tenant', 'description')
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Route targets
|
||||||
|
#
|
||||||
|
|
||||||
|
class RouteTargetTable(BaseTable):
|
||||||
|
pk = ToggleColumn()
|
||||||
|
name = tables.Column(
|
||||||
|
linkify=True
|
||||||
|
)
|
||||||
|
tenant = TenantColumn()
|
||||||
|
tags = TagColumn(
|
||||||
|
url_name='ipam:vrf_list'
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(BaseTable.Meta):
|
||||||
|
model = RouteTarget
|
||||||
|
fields = ('pk', 'name', 'tenant', 'description', 'tags')
|
||||||
|
default_columns = ('pk', 'name', 'tenant', 'description')
|
@ -155,9 +155,7 @@ class RIRView(generic.ObjectView):
|
|||||||
aggregates = Aggregate.objects.restrict(request.user, 'view').filter(
|
aggregates = Aggregate.objects.restrict(request.user, 'view').filter(
|
||||||
rir=instance
|
rir=instance
|
||||||
)
|
)
|
||||||
|
aggregates_table = tables.AggregateTable(aggregates, exclude=('rir', 'utilization'))
|
||||||
aggregates_table = tables.AggregateTable(aggregates)
|
|
||||||
aggregates_table.columns.hide('rir')
|
|
||||||
paginate_table(aggregates_table, request)
|
paginate_table(aggregates_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -207,7 +205,7 @@ class AggregateListView(generic.ObjectListView):
|
|||||||
)
|
)
|
||||||
filterset = filtersets.AggregateFilterSet
|
filterset = filtersets.AggregateFilterSet
|
||||||
filterset_form = forms.AggregateFilterForm
|
filterset_form = forms.AggregateFilterForm
|
||||||
table = tables.AggregateDetailTable
|
table = tables.AggregateTable
|
||||||
|
|
||||||
|
|
||||||
class AggregateView(generic.ObjectView):
|
class AggregateView(generic.ObjectView):
|
||||||
@ -227,7 +225,7 @@ class AggregateView(generic.ObjectView):
|
|||||||
if request.GET.get('show_available', 'true') == 'true':
|
if request.GET.get('show_available', 'true') == 'true':
|
||||||
child_prefixes = add_available_prefixes(instance.prefix, child_prefixes)
|
child_prefixes = add_available_prefixes(instance.prefix, child_prefixes)
|
||||||
|
|
||||||
prefix_table = tables.PrefixDetailTable(child_prefixes)
|
prefix_table = tables.PrefixTable(child_prefixes, exclude=('utilization',))
|
||||||
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
||||||
prefix_table.columns.show('pk')
|
prefix_table.columns.show('pk')
|
||||||
paginate_table(prefix_table, request)
|
paginate_table(prefix_table, request)
|
||||||
@ -296,8 +294,7 @@ class RoleView(generic.ObjectView):
|
|||||||
role=instance
|
role=instance
|
||||||
)
|
)
|
||||||
|
|
||||||
prefixes_table = tables.PrefixTable(prefixes)
|
prefixes_table = tables.PrefixTable(prefixes, exclude=('role', 'utilization'))
|
||||||
prefixes_table.columns.hide('role')
|
|
||||||
paginate_table(prefixes_table, request)
|
paginate_table(prefixes_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -340,7 +337,7 @@ class PrefixListView(generic.ObjectListView):
|
|||||||
queryset = Prefix.objects.all()
|
queryset = Prefix.objects.all()
|
||||||
filterset = filtersets.PrefixFilterSet
|
filterset = filtersets.PrefixFilterSet
|
||||||
filterset_form = forms.PrefixFilterForm
|
filterset_form = forms.PrefixFilterForm
|
||||||
table = tables.PrefixDetailTable
|
table = tables.PrefixTable
|
||||||
template_name = 'ipam/prefix_list.html'
|
template_name = 'ipam/prefix_list.html'
|
||||||
|
|
||||||
|
|
||||||
@ -363,8 +360,11 @@ class PrefixView(generic.ObjectView):
|
|||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'site', 'role'
|
'site', 'role'
|
||||||
)
|
)
|
||||||
parent_prefix_table = tables.PrefixTable(list(parent_prefixes), orderable=False)
|
parent_prefix_table = tables.PrefixTable(
|
||||||
parent_prefix_table.exclude = ('vrf',)
|
list(parent_prefixes),
|
||||||
|
exclude=('vrf', 'utilization'),
|
||||||
|
orderable=False
|
||||||
|
)
|
||||||
|
|
||||||
# Duplicate prefixes table
|
# Duplicate prefixes table
|
||||||
duplicate_prefixes = Prefix.objects.restrict(request.user, 'view').filter(
|
duplicate_prefixes = Prefix.objects.restrict(request.user, 'view').filter(
|
||||||
@ -374,8 +374,11 @@ class PrefixView(generic.ObjectView):
|
|||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'site', 'role'
|
'site', 'role'
|
||||||
)
|
)
|
||||||
duplicate_prefix_table = tables.PrefixTable(list(duplicate_prefixes), orderable=False)
|
duplicate_prefix_table = tables.PrefixTable(
|
||||||
duplicate_prefix_table.exclude = ('vrf',)
|
list(duplicate_prefixes),
|
||||||
|
exclude=('vrf', 'utilization'),
|
||||||
|
orderable=False
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'aggregate': aggregate,
|
'aggregate': aggregate,
|
||||||
@ -398,7 +401,7 @@ class PrefixPrefixesView(generic.ObjectView):
|
|||||||
if child_prefixes and request.GET.get('show_available', 'true') == 'true':
|
if child_prefixes and request.GET.get('show_available', 'true') == 'true':
|
||||||
child_prefixes = add_available_prefixes(instance.prefix, child_prefixes)
|
child_prefixes = add_available_prefixes(instance.prefix, child_prefixes)
|
||||||
|
|
||||||
table = tables.PrefixDetailTable(child_prefixes, user=request.user)
|
table = tables.PrefixTable(child_prefixes, user=request.user, exclude=('utilization',))
|
||||||
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
||||||
table.columns.show('pk')
|
table.columns.show('pk')
|
||||||
paginate_table(table, request)
|
paginate_table(table, request)
|
||||||
@ -601,7 +604,7 @@ class IPAddressListView(generic.ObjectListView):
|
|||||||
queryset = IPAddress.objects.all()
|
queryset = IPAddress.objects.all()
|
||||||
filterset = filtersets.IPAddressFilterSet
|
filterset = filtersets.IPAddressFilterSet
|
||||||
filterset_form = forms.IPAddressFilterForm
|
filterset_form = forms.IPAddressFilterForm
|
||||||
table = tables.IPAddressDetailTable
|
table = tables.IPAddressTable
|
||||||
|
|
||||||
|
|
||||||
class IPAddressView(generic.ObjectView):
|
class IPAddressView(generic.ObjectView):
|
||||||
@ -615,8 +618,11 @@ class IPAddressView(generic.ObjectView):
|
|||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'site', 'role'
|
'site', 'role'
|
||||||
)
|
)
|
||||||
parent_prefixes_table = tables.PrefixTable(list(parent_prefixes), orderable=False)
|
parent_prefixes_table = tables.PrefixTable(
|
||||||
parent_prefixes_table.exclude = ('vrf',)
|
list(parent_prefixes),
|
||||||
|
exclude=('vrf', 'utilization'),
|
||||||
|
orderable=False
|
||||||
|
)
|
||||||
|
|
||||||
# Duplicate IPs table
|
# Duplicate IPs table
|
||||||
duplicate_ips = IPAddress.objects.restrict(request.user, 'view').filter(
|
duplicate_ips = IPAddress.objects.restrict(request.user, 'view').filter(
|
||||||
@ -767,11 +773,9 @@ class VLANGroupView(generic.ObjectView):
|
|||||||
vlans_count = vlans.count()
|
vlans_count = vlans.count()
|
||||||
vlans = add_available_vlans(vlans, vlan_group=instance)
|
vlans = add_available_vlans(vlans, vlan_group=instance)
|
||||||
|
|
||||||
vlans_table = tables.VLANDetailTable(vlans)
|
vlans_table = tables.VLANTable(vlans, exclude=('site', 'group', 'prefixes'))
|
||||||
if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'):
|
if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'):
|
||||||
vlans_table.columns.show('pk')
|
vlans_table.columns.show('pk')
|
||||||
vlans_table.columns.hide('site')
|
|
||||||
vlans_table.columns.hide('group')
|
|
||||||
paginate_table(vlans_table, request)
|
paginate_table(vlans_table, request)
|
||||||
|
|
||||||
# Compile permissions list for rendering the object table
|
# Compile permissions list for rendering the object table
|
||||||
@ -828,7 +832,7 @@ class VLANListView(generic.ObjectListView):
|
|||||||
queryset = VLAN.objects.all()
|
queryset = VLAN.objects.all()
|
||||||
filterset = filtersets.VLANFilterSet
|
filterset = filtersets.VLANFilterSet
|
||||||
filterset_form = forms.VLANFilterForm
|
filterset_form = forms.VLANFilterForm
|
||||||
table = tables.VLANDetailTable
|
table = tables.VLANTable
|
||||||
|
|
||||||
|
|
||||||
class VLANView(generic.ObjectView):
|
class VLANView(generic.ObjectView):
|
||||||
@ -838,8 +842,7 @@ class VLANView(generic.ObjectView):
|
|||||||
prefixes = Prefix.objects.restrict(request.user, 'view').filter(vlan=instance).prefetch_related(
|
prefixes = Prefix.objects.restrict(request.user, 'view').filter(vlan=instance).prefetch_related(
|
||||||
'vrf', 'site', 'role'
|
'vrf', 'site', 'role'
|
||||||
)
|
)
|
||||||
prefix_table = tables.PrefixTable(list(prefixes), orderable=False)
|
prefix_table = tables.PrefixTable(list(prefixes), exclude=('vlan', 'utilization'), orderable=False)
|
||||||
prefix_table.exclude = ('vlan',)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'prefix_table': prefix_table,
|
'prefix_table': prefix_table,
|
||||||
|
@ -21,7 +21,7 @@ from tenancy.tables import TenantTable
|
|||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from virtualization.filtersets import ClusterFilterSet, VirtualMachineFilterSet
|
from virtualization.filtersets import ClusterFilterSet, VirtualMachineFilterSet
|
||||||
from virtualization.models import Cluster, VirtualMachine
|
from virtualization.models import Cluster, VirtualMachine
|
||||||
from virtualization.tables import ClusterTable, VirtualMachineDetailTable
|
from virtualization.tables import ClusterTable, VirtualMachineTable
|
||||||
|
|
||||||
SEARCH_MAX_RESULTS = 15
|
SEARCH_MAX_RESULTS = 15
|
||||||
SEARCH_TYPES = OrderedDict((
|
SEARCH_TYPES = OrderedDict((
|
||||||
@ -130,7 +130,7 @@ SEARCH_TYPES = OrderedDict((
|
|||||||
'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6',
|
'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6',
|
||||||
),
|
),
|
||||||
'filterset': VirtualMachineFilterSet,
|
'filterset': VirtualMachineFilterSet,
|
||||||
'table': VirtualMachineDetailTable,
|
'table': VirtualMachineTable,
|
||||||
'url': 'virtualization:virtualmachine_list',
|
'url': 'virtualization:virtualmachine_list',
|
||||||
}),
|
}),
|
||||||
# IPAM
|
# IPAM
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
{% include 'inc/table_controls.html' with table_modal="PrefixDetailTable_config" %}
|
{% include 'inc/table_controls.html' with table_modal="PrefixTable_config" %}
|
||||||
{% include 'utilities/obj_table.html' with heading='Child Prefixes' bulk_edit_url='ipam:prefix_bulk_edit' bulk_delete_url='ipam:prefix_bulk_delete' parent=prefix %}
|
{% include 'utilities/obj_table.html' with heading='Child Prefixes' bulk_edit_url='ipam:prefix_bulk_edit' bulk_delete_url='ipam:prefix_bulk_delete' parent=prefix %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% table_config_form table table_name="PrefixDetailTable" %}
|
{% table_config_form table table_name="PrefixTable" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -5,6 +5,12 @@ from utilities.tables import (
|
|||||||
)
|
)
|
||||||
from .models import Tenant, TenantGroup
|
from .models import Tenant, TenantGroup
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'TenantColumn',
|
||||||
|
'TenantGroupTable',
|
||||||
|
'TenantTable',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Table columns
|
# Table columns
|
||||||
|
@ -32,9 +32,7 @@ class TenantGroupView(generic.ObjectView):
|
|||||||
tenants = Tenant.objects.restrict(request.user, 'view').filter(
|
tenants = Tenant.objects.restrict(request.user, 'view').filter(
|
||||||
group=instance
|
group=instance
|
||||||
)
|
)
|
||||||
|
tenants_table = tables.TenantTable(tenants, exclude=('group',))
|
||||||
tenants_table = tables.TenantTable(tenants)
|
|
||||||
tenants_table.columns.hide('group')
|
|
||||||
paginate_table(tenants_table, request)
|
paginate_table(tenants_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -12,12 +12,13 @@ __all__ = (
|
|||||||
'ClusterTable',
|
'ClusterTable',
|
||||||
'ClusterGroupTable',
|
'ClusterGroupTable',
|
||||||
'ClusterTypeTable',
|
'ClusterTypeTable',
|
||||||
'VirtualMachineDetailTable',
|
|
||||||
'VirtualMachineTable',
|
'VirtualMachineTable',
|
||||||
'VirtualMachineVMInterfaceTable',
|
'VirtualMachineVMInterfaceTable',
|
||||||
'VMInterfaceTable',
|
'VMInterfaceTable',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
PRIMARY_IP_ORDERING = ('primary_ip4', 'primary_ip6') if settings.PREFER_IPV4 else ('primary_ip6', 'primary_ip4')
|
||||||
|
|
||||||
VMINTERFACE_BUTTONS = """
|
VMINTERFACE_BUTTONS = """
|
||||||
{% if perms.ipam.add_ipaddress %}
|
{% if perms.ipam.add_ipaddress %}
|
||||||
<a href="{% url 'ipam:ipaddress_add' %}?vminterface={{ record.pk }}&return_url={{ virtualmachine.get_absolute_url }}" class="btn btn-sm btn-success" title="Add IP Address">
|
<a href="{% url 'ipam:ipaddress_add' %}?vminterface={{ record.pk }}&return_url={{ virtualmachine.get_absolute_url }}" class="btn btn-sm btn-success" title="Add IP Address">
|
||||||
@ -118,13 +119,7 @@ class VirtualMachineTable(BaseTable):
|
|||||||
)
|
)
|
||||||
role = ColoredLabelColumn()
|
role = ColoredLabelColumn()
|
||||||
tenant = TenantColumn()
|
tenant = TenantColumn()
|
||||||
|
comments = MarkdownColumn()
|
||||||
class Meta(BaseTable.Meta):
|
|
||||||
model = VirtualMachine
|
|
||||||
fields = ('pk', 'name', 'status', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk')
|
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineDetailTable(VirtualMachineTable):
|
|
||||||
primary_ip4 = tables.Column(
|
primary_ip4 = tables.Column(
|
||||||
linkify=True,
|
linkify=True,
|
||||||
verbose_name='IPv4 Address'
|
verbose_name='IPv4 Address'
|
||||||
@ -133,19 +128,11 @@ class VirtualMachineDetailTable(VirtualMachineTable):
|
|||||||
linkify=True,
|
linkify=True,
|
||||||
verbose_name='IPv6 Address'
|
verbose_name='IPv6 Address'
|
||||||
)
|
)
|
||||||
if settings.PREFER_IPV4:
|
primary_ip = tables.Column(
|
||||||
primary_ip = tables.Column(
|
linkify=True,
|
||||||
linkify=True,
|
order_by=PRIMARY_IP_ORDERING,
|
||||||
order_by=('primary_ip4', 'primary_ip6'),
|
verbose_name='IP Address'
|
||||||
verbose_name='IP Address'
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
primary_ip = tables.Column(
|
|
||||||
linkify=True,
|
|
||||||
order_by=('primary_ip6', 'primary_ip4'),
|
|
||||||
verbose_name='IP Address'
|
|
||||||
)
|
|
||||||
comments = MarkdownColumn()
|
|
||||||
tags = TagColumn(
|
tags = TagColumn(
|
||||||
url_name='virtualization:virtualmachine_list'
|
url_name='virtualization:virtualmachine_list'
|
||||||
)
|
)
|
||||||
|
@ -39,9 +39,7 @@ class ClusterTypeView(generic.ObjectView):
|
|||||||
device_count=count_related(Device, 'cluster'),
|
device_count=count_related(Device, 'cluster'),
|
||||||
vm_count=count_related(VirtualMachine, 'cluster')
|
vm_count=count_related(VirtualMachine, 'cluster')
|
||||||
)
|
)
|
||||||
|
clusters_table = tables.ClusterTable(clusters, exclude=('type',))
|
||||||
clusters_table = tables.ClusterTable(clusters)
|
|
||||||
clusters_table.columns.hide('type')
|
|
||||||
paginate_table(clusters_table, request)
|
paginate_table(clusters_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -103,9 +101,7 @@ class ClusterGroupView(generic.ObjectView):
|
|||||||
device_count=count_related(Device, 'cluster'),
|
device_count=count_related(Device, 'cluster'),
|
||||||
vm_count=count_related(VirtualMachine, 'cluster')
|
vm_count=count_related(VirtualMachine, 'cluster')
|
||||||
)
|
)
|
||||||
|
clusters_table = tables.ClusterTable(clusters, exclude=('group',))
|
||||||
clusters_table = tables.ClusterTable(clusters)
|
|
||||||
clusters_table.columns.hide('group')
|
|
||||||
paginate_table(clusters_table, request)
|
paginate_table(clusters_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -171,7 +167,11 @@ class ClusterVirtualMachinesView(generic.ObjectView):
|
|||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
virtualmachines = VirtualMachine.objects.restrict(request.user, 'view').filter(cluster=instance)
|
virtualmachines = VirtualMachine.objects.restrict(request.user, 'view').filter(cluster=instance)
|
||||||
virtualmachines_table = tables.VirtualMachineTable(virtualmachines, orderable=False)
|
virtualmachines_table = tables.VirtualMachineTable(
|
||||||
|
virtualmachines,
|
||||||
|
exclude=('cluster',),
|
||||||
|
orderable=False
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'virtualmachines_table': virtualmachines_table,
|
'virtualmachines_table': virtualmachines_table,
|
||||||
@ -315,7 +315,7 @@ class VirtualMachineListView(generic.ObjectListView):
|
|||||||
queryset = VirtualMachine.objects.all()
|
queryset = VirtualMachine.objects.all()
|
||||||
filterset = filtersets.VirtualMachineFilterSet
|
filterset = filtersets.VirtualMachineFilterSet
|
||||||
filterset_form = forms.VirtualMachineFilterForm
|
filterset_form = forms.VirtualMachineFilterForm
|
||||||
table = tables.VirtualMachineDetailTable
|
table = tables.VirtualMachineTable
|
||||||
template_name = 'virtualization/virtualmachine_list.html'
|
template_name = 'virtualization/virtualmachine_list.html'
|
||||||
|
|
||||||
|
|
||||||
@ -430,9 +430,9 @@ class VMInterfaceView(generic.ObjectView):
|
|||||||
child_interfaces = VMInterface.objects.restrict(request.user, 'view').filter(parent=instance)
|
child_interfaces = VMInterface.objects.restrict(request.user, 'view').filter(parent=instance)
|
||||||
child_interfaces_tables = tables.VMInterfaceTable(
|
child_interfaces_tables = tables.VMInterfaceTable(
|
||||||
child_interfaces,
|
child_interfaces,
|
||||||
|
exclude=('virtual_machine',),
|
||||||
orderable=False
|
orderable=False
|
||||||
)
|
)
|
||||||
child_interfaces_tables.columns.hide('virtual_machine')
|
|
||||||
|
|
||||||
# Get assigned VLANs and annotate whether each is tagged or untagged
|
# Get assigned VLANs and annotate whether each is tagged or untagged
|
||||||
vlans = []
|
vlans = []
|
||||||
|
Loading…
Reference in New Issue
Block a user