185 lines
7.1 KiB
Python
185 lines
7.1 KiB
Python
from django.contrib.contenttypes.models import ContentType
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from netbox.ui import actions, attrs, panels
|
|
from utilities.data import resolve_attr_path
|
|
|
|
|
|
class CircuitCircuitTerminationPanel(panels.ObjectPanel):
|
|
"""
|
|
A panel showing the CircuitTermination assigned to the object.
|
|
"""
|
|
|
|
template_name = 'circuits/panels/circuit_circuit_termination.html'
|
|
title = _('Termination')
|
|
termination_ancestor_max_depth = 3
|
|
|
|
def __init__(self, side, accessor=None, **kwargs):
|
|
super().__init__(accessor=accessor, **kwargs)
|
|
self.side = side
|
|
|
|
def _get_termination_nodes(self, termination):
|
|
"""
|
|
Return the termination target's ancestors, including itself, when the
|
|
target is tree-like.
|
|
|
|
Non-tree GFK targets return None, so the template preserves the current
|
|
single-object rendering.
|
|
"""
|
|
target = getattr(termination, 'termination', None)
|
|
if target is None:
|
|
return None
|
|
|
|
get_ancestors = getattr(target, 'get_ancestors', None)
|
|
if not callable(get_ancestors):
|
|
return None
|
|
|
|
nodes = list(get_ancestors(include_self=True))
|
|
|
|
if self.termination_ancestor_max_depth is not None:
|
|
nodes = nodes[-self.termination_ancestor_max_depth:]
|
|
|
|
return nodes
|
|
|
|
def get_context(self, context):
|
|
termination = resolve_attr_path(context, f'{self.accessor}.termination_{self.side.lower()}')
|
|
|
|
return {
|
|
**super().get_context(context),
|
|
'side': self.side,
|
|
'termination': termination,
|
|
'termination_nodes': self._get_termination_nodes(termination),
|
|
}
|
|
|
|
|
|
class CircuitGroupAssignmentsPanel(panels.ObjectsTablePanel):
|
|
"""
|
|
A panel showing all Circuit Groups attached to the object.
|
|
"""
|
|
|
|
title = _('Group Assignments')
|
|
actions = [
|
|
actions.AddObject(
|
|
'circuits.CircuitGroupAssignment',
|
|
url_params={
|
|
'member_content_type': lambda ctx: ContentType.objects.get_for_model(ctx['object']).pk,
|
|
'member_object_id': lambda ctx: ctx['object'].pk,
|
|
'return_url': lambda ctx: ctx['object'].get_absolute_url(),
|
|
},
|
|
label=_('Assign Group'),
|
|
),
|
|
]
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__(
|
|
'circuits.CircuitGroupAssignment',
|
|
filters={
|
|
'member_type_id': lambda ctx: ContentType.objects.get_for_model(ctx['object']).pk,
|
|
'member_id': lambda ctx: ctx['object'].pk,
|
|
},
|
|
**kwargs,
|
|
)
|
|
|
|
|
|
class CircuitTerminationPanel(panels.ObjectAttributesPanel):
|
|
title = _('Circuit Termination')
|
|
circuit = attrs.RelatedObjectAttr('circuit', linkify=True)
|
|
provider = attrs.RelatedObjectAttr('circuit.provider', linkify=True)
|
|
termination = attrs.GenericForeignKeyAttr(
|
|
'termination', linkify=True, nested=True, max_depth=3, label=_('Termination point')
|
|
)
|
|
connection = attrs.TemplatedAttr(
|
|
'pk',
|
|
template_name='circuits/circuit_termination/attrs/connection.html',
|
|
label=_('Connection'),
|
|
)
|
|
speed = attrs.TemplatedAttr(
|
|
'port_speed',
|
|
template_name='circuits/circuit_termination/attrs/speed.html',
|
|
label=_('Speed'),
|
|
)
|
|
xconnect_id = attrs.TextAttr('xconnect_id', label=_('Cross-Connect'), style='font-monospace')
|
|
pp_info = attrs.TextAttr('pp_info', label=_('Patch Panel/Port'))
|
|
description = attrs.TextAttr('description')
|
|
|
|
|
|
class CircuitGroupPanel(panels.OrganizationalObjectPanel):
|
|
tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group')
|
|
|
|
|
|
class CircuitGroupAssignmentPanel(panels.ObjectAttributesPanel):
|
|
group = attrs.RelatedObjectAttr('group', linkify=True)
|
|
provider = attrs.RelatedObjectAttr('member.provider', linkify=True)
|
|
member = attrs.GenericForeignKeyAttr('member', linkify=True)
|
|
priority = attrs.ChoiceAttr('priority')
|
|
|
|
|
|
class CircuitPanel(panels.ObjectAttributesPanel):
|
|
provider = attrs.RelatedObjectAttr('provider', linkify=True)
|
|
provider_account = attrs.RelatedObjectAttr('provider_account', linkify=True)
|
|
cid = attrs.TextAttr('cid', label=_('Circuit ID'), style='font-monospace', copy_button=True)
|
|
type = attrs.RelatedObjectAttr('type', linkify=True, colored=True)
|
|
status = attrs.ChoiceAttr('status')
|
|
distance = attrs.DistanceAttr('distance')
|
|
tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group')
|
|
install_date = attrs.DateTimeAttr('install_date', spec='date')
|
|
termination_date = attrs.DateTimeAttr('termination_date', spec='date')
|
|
commit_rate = attrs.TemplatedAttr('commit_rate', template_name='circuits/circuit/attrs/commit_rate.html')
|
|
description = attrs.TextAttr('description')
|
|
|
|
|
|
class CircuitTypePanel(panels.OrganizationalObjectPanel):
|
|
color = attrs.ColorAttr('color')
|
|
|
|
|
|
class ProviderPanel(panels.ObjectAttributesPanel):
|
|
name = attrs.TextAttr('name')
|
|
asns = attrs.RelatedObjectListAttr('asns', linkify=True, label=_('ASNs'))
|
|
description = attrs.TextAttr('description')
|
|
|
|
|
|
class ProviderAccountPanel(panels.ObjectAttributesPanel):
|
|
provider = attrs.RelatedObjectAttr('provider', linkify=True)
|
|
account = attrs.TextAttr('account', style='font-monospace', copy_button=True)
|
|
name = attrs.TextAttr('name')
|
|
description = attrs.TextAttr('description')
|
|
|
|
|
|
class ProviderNetworkPanel(panels.ObjectAttributesPanel):
|
|
provider = attrs.RelatedObjectAttr('provider', linkify=True)
|
|
name = attrs.TextAttr('name')
|
|
service_id = attrs.TextAttr('service_id', label=_('Service ID'), style='font-monospace', copy_button=True)
|
|
description = attrs.TextAttr('description')
|
|
|
|
|
|
class VirtualCircuitTypePanel(panels.OrganizationalObjectPanel):
|
|
color = attrs.ColorAttr('color')
|
|
|
|
|
|
class VirtualCircuitPanel(panels.ObjectAttributesPanel):
|
|
provider = attrs.RelatedObjectAttr('provider', linkify=True)
|
|
provider_network = attrs.RelatedObjectAttr('provider_network', linkify=True)
|
|
provider_account = attrs.RelatedObjectAttr('provider_account', linkify=True)
|
|
cid = attrs.TextAttr('cid', label=_('Circuit ID'), style='font-monospace', copy_button=True)
|
|
type = attrs.RelatedObjectAttr('type', linkify=True, colored=True)
|
|
status = attrs.ChoiceAttr('status')
|
|
tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group')
|
|
description = attrs.TextAttr('description')
|
|
|
|
|
|
class VirtualCircuitTerminationPanel(panels.ObjectAttributesPanel):
|
|
provider = attrs.RelatedObjectAttr('virtual_circuit.provider', linkify=True)
|
|
provider_network = attrs.RelatedObjectAttr('virtual_circuit.provider_network', linkify=True)
|
|
provider_account = attrs.RelatedObjectAttr('virtual_circuit.provider_account', linkify=True)
|
|
virtual_circuit = attrs.RelatedObjectAttr('virtual_circuit', linkify=True)
|
|
role = attrs.ChoiceAttr('role')
|
|
|
|
|
|
class VirtualCircuitTerminationInterfacePanel(panels.ObjectAttributesPanel):
|
|
title = _('Interface')
|
|
|
|
device = attrs.RelatedObjectAttr('interface.device', linkify=True)
|
|
interface = attrs.RelatedObjectAttr('interface', linkify=True)
|
|
type = attrs.ChoiceAttr('interface.type')
|
|
description = attrs.TextAttr('interface.description')
|