from __future__ import unicode_literals import django_tables2 as tables from django_tables2.utils import Accessor from dcim.models import Interface from tenancy.tables import COL_TENANT from utilities.tables import BaseTable, BooleanColumn, ToggleColumn from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF RIR_UTILIZATION = """
{% if record.stats.total %}
{{ record.stats.percentages.active }}%
{{ record.stats.percentages.reserved }}%
{{ record.stats.percentages.deprecated }}%
{{ record.stats.percentages.available }}%
{% endif %}
""" RIR_ACTIONS = """ {% if perms.ipam.change_rir %} {% endif %} """ UTILIZATION_GRAPH = """ {% load helpers %} {% if record.pk %}{% utilization_graph record.get_utilization %}{% else %}—{% endif %} """ ROLE_PREFIX_COUNT = """ {{ value }} """ ROLE_VLAN_COUNT = """ {{ value }} """ ROLE_ACTIONS = """ {% if perms.ipam.change_role %} {% endif %} """ PREFIX_LINK = """ {% if record.has_children %} {% else %} {% endif %} {{ record.prefix }} """ PREFIX_ROLE_LINK = """ {% if record.role %} {{ record.role }} {% else %} — {% endif %} """ IPADDRESS_LINK = """ {% if record.pk %} {{ record.address }} {% elif perms.ipam.add_ipaddress %} {% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available {% else %} {% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available {% endif %} """ IPADDRESS_ASSIGN_LINK = """ {{ record }} """ IPADDRESS_PARENT = """ {% if record.interface %} {{ record.interface.parent }} {% else %} — {% endif %} """ VRF_LINK = """ {% if record.vrf %} {{ record.vrf }} {% elif prefix.vrf %} {{ prefix.vrf }} {% else %} Global {% endif %} """ STATUS_LABEL = """ {% if record.pk %} {{ record.get_status_display }} {% else %} Available {% endif %} """ VLAN_LINK = """ {% if record.pk %} {{ record.vid }} {% elif perms.ipam.add_vlan %} {{ record.available }} VLAN{{ record.available|pluralize }} available {% else %} {{ record.available }} VLAN{{ record.available|pluralize }} available {% endif %} """ VLAN_PREFIXES = """ {% for prefix in record.prefixes.all %} {{ prefix }}{% if not forloop.last %}
{% endif %} {% empty %} — {% endfor %} """ VLAN_ROLE_LINK = """ {% if record.role %} {{ record.role }} {% else %} — {% endif %} """ VLANGROUP_ACTIONS = """ {% with next_vid=record.get_next_available_vid %} {% if next_vid and perms.ipam.add_vlan %} {% endif %} {% endwith %} {% if perms.ipam.change_vlangroup %} {% endif %} """ VLAN_MEMBER_UNTAGGED = """ {% if record.untagged_vlan_id == vlan.pk %} {% endif %} """ VLAN_MEMBER_ACTIONS = """ {% if perms.dcim.change_interface %} {% endif %} """ TENANT_LINK = """ {% if record.tenant %} {{ record.tenant }} {% elif record.vrf.tenant %} {{ record.vrf.tenant }}* {% else %} — {% endif %} """ # # VRFs # class VRFTable(BaseTable): pk = ToggleColumn() name = tables.LinkColumn() rd = tables.Column(verbose_name='RD') tenant = tables.TemplateColumn(template_code=COL_TENANT) class Meta(BaseTable.Meta): model = VRF fields = ('pk', 'name', 'rd', 'tenant', 'description') # # RIRs # class RIRTable(BaseTable): pk = ToggleColumn() name = tables.LinkColumn(verbose_name='Name') is_private = BooleanColumn(verbose_name='Private') aggregate_count = tables.Column(verbose_name='Aggregates') actions = tables.TemplateColumn(template_code=RIR_ACTIONS, attrs={'td': {'class': 'text-right'}}, verbose_name='') class Meta(BaseTable.Meta): model = RIR fields = ('pk', 'name', 'is_private', 'aggregate_count', 'actions') class RIRDetailTable(RIRTable): stats_total = tables.Column( accessor='stats.total', verbose_name='Total', footer=lambda table: sum(r.stats['total'] for r in table.data) ) stats_active = tables.Column( accessor='stats.active', verbose_name='Active', footer=lambda table: sum(r.stats['active'] for r in table.data) ) stats_reserved = tables.Column( accessor='stats.reserved', verbose_name='Reserved', footer=lambda table: sum(r.stats['reserved'] for r in table.data) ) stats_deprecated = tables.Column( accessor='stats.deprecated', verbose_name='Deprecated', footer=lambda table: sum(r.stats['deprecated'] for r in table.data) ) stats_available = tables.Column( accessor='stats.available', verbose_name='Available', footer=lambda table: sum(r.stats['available'] for r in table.data) ) utilization = tables.TemplateColumn( template_code=RIR_UTILIZATION, verbose_name='Utilization' ) class Meta(RIRTable.Meta): fields = ( 'pk', 'name', 'is_private', 'aggregate_count', 'stats_total', 'stats_active', 'stats_reserved', 'stats_deprecated', 'stats_available', 'utilization', 'actions', ) # # Aggregates # class AggregateTable(BaseTable): pk = ToggleColumn() prefix = tables.LinkColumn(verbose_name='Aggregate') date_added = tables.DateColumn(format="Y-m-d", verbose_name='Added') class Meta(BaseTable.Meta): model = Aggregate fields = ('pk', 'prefix', 'rir', 'date_added', 'description') class AggregateDetailTable(AggregateTable): child_count = tables.Column(verbose_name='Prefixes') utilization = tables.TemplateColumn(UTILIZATION_GRAPH, orderable=False, verbose_name='Utilization') class Meta(AggregateTable.Meta): fields = ('pk', 'prefix', 'rir', 'child_count', 'utilization', 'date_added', 'description') # # Roles # class RoleTable(BaseTable): pk = ToggleColumn() prefix_count = tables.TemplateColumn( accessor=Accessor('prefixes.count'), template_code=ROLE_PREFIX_COUNT, orderable=False, verbose_name='Prefixes' ) vlan_count = tables.TemplateColumn( accessor=Accessor('vlans.count'), template_code=ROLE_VLAN_COUNT, orderable=False, verbose_name='VLANs' ) actions = tables.TemplateColumn(template_code=ROLE_ACTIONS, attrs={'td': {'class': 'text-right'}}, verbose_name='') class Meta(BaseTable.Meta): model = Role fields = ('pk', 'name', 'prefix_count', 'vlan_count', 'slug', 'actions') # # Prefixes # class PrefixTable(BaseTable): pk = ToggleColumn() prefix = tables.TemplateColumn(PREFIX_LINK, attrs={'th': {'style': 'padding-left: 17px'}}) status = tables.TemplateColumn(STATUS_LABEL) vrf = tables.TemplateColumn(VRF_LINK, verbose_name='VRF') tenant = tables.TemplateColumn(template_code=TENANT_LINK) site = tables.LinkColumn('dcim:site', args=[Accessor('site.slug')]) vlan = tables.LinkColumn('ipam:vlan', args=[Accessor('vlan.pk')], verbose_name='VLAN') role = tables.TemplateColumn(PREFIX_ROLE_LINK) class Meta(BaseTable.Meta): model = Prefix fields = ('pk', 'prefix', 'status', 'vrf', 'tenant', 'site', 'vlan', 'role', 'description') row_attrs = { 'class': lambda record: 'success' if not record.pk else '', } class PrefixDetailTable(PrefixTable): utilization = tables.TemplateColumn(UTILIZATION_GRAPH, orderable=False) class Meta(PrefixTable.Meta): fields = ('pk', 'prefix', 'status', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description') # # IPAddresses # class IPAddressTable(BaseTable): pk = ToggleColumn() address = tables.TemplateColumn(IPADDRESS_LINK, verbose_name='IP Address') vrf = tables.TemplateColumn(VRF_LINK, verbose_name='VRF') status = tables.TemplateColumn(STATUS_LABEL) tenant = tables.TemplateColumn(template_code=TENANT_LINK) parent = tables.TemplateColumn(IPADDRESS_PARENT, orderable=False) interface = tables.Column(orderable=False) class Meta(BaseTable.Meta): model = IPAddress fields = ('pk', 'address', 'vrf', 'status', 'role', 'tenant', 'parent', 'interface', 'description') row_attrs = { 'class': lambda record: 'success' if not isinstance(record, IPAddress) else '', } class IPAddressDetailTable(IPAddressTable): nat_inside = tables.LinkColumn( 'ipam:ipaddress', args=[Accessor('nat_inside.pk')], orderable=False, verbose_name='NAT (Inside)' ) class Meta(IPAddressTable.Meta): fields = ( 'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'nat_inside', 'parent', 'interface', 'description', ) class IPAddressAssignTable(BaseTable): address = tables.TemplateColumn(IPADDRESS_ASSIGN_LINK, verbose_name='IP Address') status = tables.TemplateColumn(STATUS_LABEL) parent = tables.TemplateColumn(IPADDRESS_PARENT, orderable=False) interface = tables.Column(orderable=False) class Meta(BaseTable.Meta): model = IPAddress fields = ('address', 'vrf', 'status', 'role', 'tenant', 'parent', 'interface', 'description') orderable = False class InterfaceIPAddressTable(BaseTable): """ List IP addresses assigned to a specific Interface. """ address = tables.TemplateColumn(IPADDRESS_ASSIGN_LINK, verbose_name='IP Address') vrf = tables.TemplateColumn(VRF_LINK, verbose_name='VRF') status = tables.TemplateColumn(STATUS_LABEL) tenant = tables.TemplateColumn(template_code=TENANT_LINK) class Meta(BaseTable.Meta): model = IPAddress fields = ('address', 'vrf', 'status', 'role', 'tenant', 'description') # # VLAN groups # class VLANGroupTable(BaseTable): pk = ToggleColumn() name = tables.LinkColumn(verbose_name='Name') site = tables.LinkColumn('dcim:site', args=[Accessor('site.slug')], verbose_name='Site') vlan_count = tables.Column(verbose_name='VLANs') slug = tables.Column(verbose_name='Slug') actions = tables.TemplateColumn(template_code=VLANGROUP_ACTIONS, attrs={'td': {'class': 'text-right'}}, verbose_name='') class Meta(BaseTable.Meta): model = VLANGroup fields = ('pk', 'name', 'site', 'vlan_count', 'slug', 'actions') # # VLANs # class VLANTable(BaseTable): pk = ToggleColumn() vid = tables.TemplateColumn(VLAN_LINK, verbose_name='ID') site = tables.LinkColumn('dcim:site', args=[Accessor('site.slug')]) group = tables.LinkColumn('ipam:vlangroup_vlans', args=[Accessor('group.pk')], verbose_name='Group') tenant = tables.TemplateColumn(template_code=COL_TENANT) status = tables.TemplateColumn(STATUS_LABEL) role = tables.TemplateColumn(VLAN_ROLE_LINK) class Meta(BaseTable.Meta): model = VLAN fields = ('pk', 'vid', 'site', 'group', 'name', 'tenant', 'status', 'role', 'description') row_attrs = { 'class': lambda record: 'success' if not isinstance(record, VLAN) else '', } class VLANDetailTable(VLANTable): prefixes = tables.TemplateColumn(VLAN_PREFIXES, orderable=False, verbose_name='Prefixes') class Meta(VLANTable.Meta): fields = ('pk', 'vid', 'site', 'group', 'name', 'prefixes', 'tenant', 'status', 'role', 'description') class VLANMemberTable(BaseTable): parent = tables.LinkColumn(order_by=['device', 'virtual_machine']) name = tables.Column(verbose_name='Interface') untagged = tables.TemplateColumn( template_code=VLAN_MEMBER_UNTAGGED, orderable=False ) actions = tables.TemplateColumn( template_code=VLAN_MEMBER_ACTIONS, attrs={'td': {'class': 'text-right'}}, verbose_name='' ) class Meta(BaseTable.Meta): model = Interface fields = ('parent', 'name', 'untagged', 'actions') class InterfaceVLANTable(BaseTable): """ List VLANs assigned to a specific Interface. """ vid = tables.LinkColumn('ipam:vlan', args=[Accessor('pk')], verbose_name='ID') tagged = BooleanColumn() site = tables.LinkColumn('dcim:site', args=[Accessor('site.slug')]) group = tables.Column(accessor=Accessor('group.name'), verbose_name='Group') tenant = tables.TemplateColumn(template_code=COL_TENANT) status = tables.TemplateColumn(STATUS_LABEL) role = tables.TemplateColumn(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(InterfaceVLANTable, self).__init__(*args, **kwargs) # # Services # class ServiceTable(BaseTable): pk = ToggleColumn() name = tables.LinkColumn( viewname='ipam:service', args=[Accessor('pk')] ) class Meta(BaseTable.Meta): model = Service fields = ('pk', 'name', 'parent', 'protocol', 'port', 'description')