Let console connections use the same flexible framework

This commit is contained in:
Sander Steffann 2019-10-20 21:30:01 +02:00
parent 4e37175c3c
commit 45aa9de22a
7 changed files with 88 additions and 13 deletions

View File

@ -513,7 +513,7 @@ class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet):
queryset = ConsolePort.objects.prefetch_related(
'device', 'connected_endpoint__device'
).filter(
connected_endpoint__isnull=False
connected_endpoint_type=ContentType.objects.get_for_model(ConsoleServerPort)
)
serializer_class = serializers.ConsolePortSerializer
filterset_class = filters.ConsoleConnectionFilter

View File

@ -30,4 +30,45 @@ class Migration(migrations.Migration):
name='_trace',
field=django.contrib.postgres.fields.jsonb.JSONField(default=list),
),
migrations.RenameField(
model_name='consoleport',
old_name='connected_endpoint',
new_name='old_connected_endpoint',
),
migrations.AddField(
model_name='consoleport',
name='connected_endpoint_id',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name='consoleport',
name='connected_endpoint_type',
field=models.ForeignKey(blank=True, limit_choices_to={
'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport',
'rearport', 'circuittermination']
}, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType'),
),
migrations.AddField(
model_name='consoleport',
name='_trace',
field=django.contrib.postgres.fields.jsonb.JSONField(default=list),
),
migrations.AddField(
model_name='consoleserverport',
name='connected_endpoint_id',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name='consoleserverport',
name='connected_endpoint_type',
field=models.ForeignKey(blank=True, limit_choices_to={
'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport',
'rearport', 'circuittermination']
}, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType'),
),
migrations.AddField(
model_name='consoleserverport',
name='_trace',
field=django.contrib.postgres.fields.jsonb.JSONField(default=list),
),
]

View File

@ -91,13 +91,17 @@ def to_generic_connected_endpoint(apps, schema_editor):
print("\nReconstructing all endpoints...", end='')
interface_model = apps.get_model('dcim', 'Interface')
consoleport_model = apps.get_model('dcim', 'ConsolePort')
consoleserverport_model = apps.get_model('dcim', 'ConsoleServerPort')
circuittermination_model = apps.get_model('circuits', 'CircuitTermination')
contenttype_model = apps.get_model('contenttypes', 'ContentType')
db_alias = schema_editor.connection.alias
interface_endpoints = interface_model.objects.using(db_alias).all()
circuittermination_endpoints = circuittermination_model.objects.using(db_alias).all()
for endpoint in chain(interface_endpoints, circuittermination_endpoints):
consoleport_endpoints = consoleport_model.objects.using(db_alias).all()
consoleserverport_endpoints = consoleserverport_model.objects.using(db_alias).all()
for endpoint in chain(interface_endpoints, circuittermination_endpoints, consoleport_endpoints, consoleserverport_endpoints):
path = migration_trace(apps, endpoint)
# The trace returns left and right, we just want a single list

View File

@ -18,4 +18,8 @@ class Migration(migrations.Migration):
model_name='interface',
name='_connected_interface',
),
migrations.RemoveField(
model_name='consoleport',
name='old_connected_endpoint',
),
]

View File

@ -1888,7 +1888,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
# Console ports
#
class ConsolePort(CableTermination, ComponentModel):
class ConsolePort(CableTermination, ComponentModel, CachedTraceModel):
"""
A physical console port within a Device. ConsolePorts connect to ConsoleServerPorts.
"""
@ -1900,13 +1900,22 @@ class ConsolePort(CableTermination, ComponentModel):
name = models.CharField(
max_length=50
)
connected_endpoint = models.OneToOneField(
to='dcim.ConsoleServerPort',
on_delete=models.SET_NULL,
related_name='connected_endpoint',
connected_endpoint_type = models.ForeignKey(
to=ContentType,
limit_choices_to={'model__in': CABLE_TERMINATION_TYPES},
on_delete=models.PROTECT,
related_name='+',
blank=True,
null=True
)
connected_endpoint_id = models.PositiveIntegerField(
blank=True,
null=True
)
connected_endpoint = GenericForeignKey(
ct_field='connected_endpoint_type',
fk_field='connected_endpoint_id'
)
connection_status = models.NullBooleanField(
choices=CONNECTION_STATUS_CHOICES,
blank=True
@ -1939,7 +1948,7 @@ class ConsolePort(CableTermination, ComponentModel):
# Console server ports
#
class ConsoleServerPort(CableTermination, ComponentModel):
class ConsoleServerPort(CableTermination, ComponentModel, CachedTraceModel):
"""
A physical port within a Device (typically a designated console server) which provides access to ConsolePorts.
"""
@ -1951,6 +1960,22 @@ class ConsoleServerPort(CableTermination, ComponentModel):
name = models.CharField(
max_length=50
)
connected_endpoint_type = models.ForeignKey(
to=ContentType,
limit_choices_to={'model__in': CABLE_TERMINATION_TYPES},
on_delete=models.PROTECT,
related_name='+',
blank=True,
null=True
)
connected_endpoint_id = models.PositiveIntegerField(
blank=True,
null=True
)
connected_endpoint = GenericForeignKey(
ct_field='connected_endpoint_type',
fk_field='connected_endpoint_id'
)
connection_status = models.NullBooleanField(
choices=CONNECTION_STATUS_CHOICES,
blank=True

View File

@ -1879,9 +1879,9 @@ class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
queryset = ConsolePort.objects.prefetch_related(
'device', 'connected_endpoint__device'
).filter(
connected_endpoint__isnull=False
connected_endpoint_type=ContentType.objects.get_for_model(ConsoleServerPort)
).order_by(
'cable', 'connected_endpoint__device__name', 'connected_endpoint__name'
'cable', # 'connected_endpoint__device__name', 'connected_endpoint__name'
)
filter = filters.ConsoleConnectionFilter
filter_form = forms.ConsoleConnectionFilterForm

View File

@ -16,8 +16,9 @@ from dcim.filters import (
VirtualChassisFilter,
)
from dcim.models import (
Cable, ConsolePort, Device, DeviceType, Interface, PowerPanel, PowerFeed, PowerPort, Rack, RackGroup, Site, VirtualChassis
)
Cable, ConsolePort, Device, DeviceType, Interface, PowerPanel, PowerFeed, PowerPort, Rack, RackGroup, Site,
VirtualChassis,
ConsoleServerPort)
from dcim.tables import (
CableTable, DeviceDetailTable, DeviceTypeTable, PowerFeedTable, RackTable, RackGroupTable, SiteTable,
VirtualChassisTable,
@ -195,7 +196,7 @@ class HomeView(View):
def get(self, request):
connected_consoleports = ConsolePort.objects.filter(
connected_endpoint__isnull=False
connected_endpoint_type=ContentType.objects.get_for_model(ConsoleServerPort),
)
connected_powerports = PowerPort.objects.filter(
_connected_poweroutlet__isnull=False