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, TagColumn, 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 = """ {% if request.GET %} {{ record }} {% else %} {{ record }} {% 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 ) enforce_unique = BooleanColumn( verbose_name='Unique' ) tags = TagColumn( url_name='ipam:vrf_list' ) class Meta(BaseTable.Meta): model = VRF fields = ('pk', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'tags') default_columns = ('pk', 'name', 'rd', 'tenant', 'description') # # RIRs # class RIRTable(BaseTable): pk = ToggleColumn() name = tables.LinkColumn() 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 noprint'}}, verbose_name='' ) class Meta(BaseTable.Meta): model = RIR fields = ('pk', 'name', 'slug', 'is_private', 'aggregate_count', 'description', 'actions') default_columns = ('pk', 'name', 'is_private', 'aggregate_count', 'description', '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', 'slug', 'is_private', 'aggregate_count', 'stats_total', 'stats_active', 'stats_reserved', 'stats_deprecated', 'stats_available', 'utilization', 'actions', ) default_columns = ( '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( template_code=UTILIZATION_GRAPH, orderable=False ) tags = TagColumn( url_name='ipam:aggregate_list' ) class Meta(AggregateTable.Meta): fields = ('pk', 'prefix', 'rir', 'child_count', 'utilization', 'date_added', 'description', 'tags') default_columns = ('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 noprint'}}, verbose_name='' ) class Meta(BaseTable.Meta): model = Role fields = ('pk', 'name', 'slug', 'prefix_count', 'vlan_count', 'description', 'weight', 'actions') default_columns = ('pk', 'name', 'prefix_count', 'vlan_count', 'description', 'actions') # # Prefixes # class PrefixTable(BaseTable): pk = ToggleColumn() prefix = tables.TemplateColumn( template_code=PREFIX_LINK, attrs={'th': {'style': 'padding-left: 17px'}} ) status = tables.TemplateColumn( template_code=STATUS_LABEL ) vrf = tables.TemplateColumn( template_code=VRF_LINK, verbose_name='VRF' ) tenant = tables.TemplateColumn( template_code=TENANT_LINK ) site = tables.LinkColumn( viewname='dcim:site', args=[Accessor('site.slug')] ) vlan = tables.LinkColumn( viewname='ipam:vlan', args=[Accessor('vlan.pk')], verbose_name='VLAN' ) role = tables.TemplateColumn( template_code=PREFIX_ROLE_LINK ) is_pool = BooleanColumn( verbose_name='Pool' ) add_prefetch = False class Meta(BaseTable.Meta): model = Prefix fields = ('pk', 'prefix', 'status', 'vrf', 'tenant', 'site', 'vlan', 'role', 'is_pool', '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 = tables.TemplateColumn( template_code=UTILIZATION_GRAPH, orderable=False ) tenant = tables.TemplateColumn( template_code=COL_TENANT ) tags = TagColumn( url_name='ipam:prefix_list' ) class Meta(PrefixTable.Meta): fields = ( 'pk', 'prefix', 'status', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'is_pool', 'description', 'tags', ) default_columns = ( 'pk', 'prefix', 'status', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description', ) # # IPAddresses # class IPAddressTable(BaseTable): pk = ToggleColumn() address = tables.TemplateColumn( template_code=IPADDRESS_LINK, verbose_name='IP Address' ) vrf = tables.TemplateColumn( template_code=VRF_LINK, verbose_name='VRF' ) status = tables.TemplateColumn( template_code=STATUS_LABEL ) tenant = tables.TemplateColumn( template_code=TENANT_LINK ) assigned = tables.BooleanColumn( accessor='assigned_object_id' ) class Meta(BaseTable.Meta): model = IPAddress fields = ( 'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description', ) row_attrs = { 'class': lambda record: 'success' if not isinstance(record, IPAddress) else '', } class IPAddressDetailTable(IPAddressTable): nat_inside = tables.LinkColumn( viewname='ipam:ipaddress', args=[Accessor('nat_inside.pk')], orderable=False, verbose_name='NAT (Inside)' ) tenant = tables.TemplateColumn( template_code=COL_TENANT ) tags = TagColumn( url_name='ipam:ipaddress_list' ) class Meta(IPAddressTable.Meta): fields = ( 'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'nat_inside', 'assigned', 'dns_name', 'description', 'tags', ) default_columns = ( 'pk', 'address', 'vrf', 'status', 'role', 'tenant', 'assigned', 'dns_name', 'description', ) class IPAddressAssignTable(BaseTable): address = tables.TemplateColumn( template_code=IPADDRESS_ASSIGN_LINK, verbose_name='IP Address' ) status = tables.TemplateColumn( template_code=STATUS_LABEL ) assigned_object = tables.Column( orderable=False ) class Meta(BaseTable.Meta): model = IPAddress fields = ('address', 'dns_name', 'vrf', 'status', 'role', 'tenant', 'assigned_object', 'description') orderable = False class InterfaceIPAddressTable(BaseTable): """ List IP addresses assigned to a specific Interface. """ address = tables.LinkColumn( verbose_name='IP Address' ) vrf = tables.TemplateColumn( template_code=VRF_LINK, verbose_name='VRF' ) status = tables.TemplateColumn( template_code=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() site = tables.LinkColumn( viewname='dcim:site', args=[Accessor('site.slug')] ) vlan_count = tables.Column( verbose_name='VLANs' ) actions = tables.TemplateColumn( template_code=VLANGROUP_ACTIONS, attrs={'td': {'class': 'text-right noprint'}}, verbose_name='' ) class Meta(BaseTable.Meta): model = VLANGroup fields = ('pk', 'name', 'site', 'vlan_count', 'slug', 'description', 'actions') default_columns = ('pk', 'name', 'site', 'vlan_count', 'description', 'actions') # # VLANs # class VLANTable(BaseTable): pk = ToggleColumn() vid = tables.TemplateColumn( template_code=VLAN_LINK, verbose_name='ID' ) site = tables.LinkColumn( viewname='dcim:site', args=[Accessor('site.slug')] ) group = tables.LinkColumn( viewname='ipam:vlangroup_vlans', args=[Accessor('group.pk')] ) tenant = tables.TemplateColumn( template_code=COL_TENANT ) status = tables.TemplateColumn( template_code=STATUS_LABEL ) role = tables.TemplateColumn( template_code=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( template_code=VLAN_PREFIXES, orderable=False, verbose_name='Prefixes' ) tenant = tables.TemplateColumn( template_code=COL_TENANT ) tags = TagColumn( url_name='ipam:vlan_list' ) class Meta(VLANTable.Meta): fields = ('pk', 'vid', 'site', 'group', 'name', 'prefixes', 'tenant', 'status', 'role', 'description', 'tags') default_columns = ('pk', 'vid', 'site', 'group', 'name', 'prefixes', 'tenant', 'status', 'role', 'description') class VLANMemberTable(BaseTable): parent = tables.LinkColumn( order_by=['device', 'virtual_machine'] ) name = tables.LinkColumn( 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 noprint'}}, 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( viewname='ipam:vlan', args=[Accessor('pk')], verbose_name='ID' ) tagged = BooleanColumn() site = tables.LinkColumn( viewname='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( template_code=STATUS_LABEL ) 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.LinkColumn( viewname='ipam:service', args=[Accessor('pk')] ) parent = tables.LinkColumn( order_by=('device', 'virtual_machine') ) tags = TagColumn( url_name='ipam:service_list' ) class Meta(BaseTable.Meta): model = Service fields = ('pk', 'name', 'parent', 'protocol', 'port', 'ipaddresses', 'description', 'tags') default_columns = ('pk', 'name', 'parent', 'protocol', 'port', 'description')