1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Deprecated the InterfaceConnection model

This commit is contained in:
Jeremy Stretch
2018-10-24 13:59:44 -04:00
parent 2ec8dc8319
commit f30367e094
22 changed files with 219 additions and 884 deletions

View File

@@ -1826,7 +1826,7 @@ class PowerOutlet(ComponentModel):
class Interface(ComponentModel):
"""
A network interface within a Device or VirtualMachine. A physical Interface can connect to exactly one other
Interface via the creation of an InterfaceConnection.
Interface.
"""
device = models.ForeignKey(
to='Device',
@@ -1842,6 +1842,20 @@ class Interface(ComponentModel):
null=True,
blank=True
)
name = models.CharField(
max_length=64
)
connected_endpoint = models.OneToOneField(
to='self',
on_delete=models.SET_NULL,
related_name='+',
blank=True,
null=True
)
connection_status = models.NullBooleanField(
choices=CONNECTION_STATUS_CHOICES,
default=CONNECTION_STATUS_CONNECTED
)
lag = models.ForeignKey(
to='self',
on_delete=models.SET_NULL,
@@ -1850,9 +1864,6 @@ class Interface(ComponentModel):
blank=True,
verbose_name='Parent LAG'
)
name = models.CharField(
max_length=64
)
form_factor = models.PositiveSmallIntegerField(
choices=IFACE_FF_CHOICES,
default=IFACE_FF_10GE_SFP_PLUS
@@ -2002,10 +2013,7 @@ class Interface(ComponentModel):
changed_object=self,
related_object=parent_obj,
action=action,
object_data=serialize_object(self, extra={
'connected_interface': self.connected_interface.pk if self.connection else None,
'connection_status': self.connection.connection_status if self.connection else None,
})
object_data=serialize_object(self)
).save()
@property
@@ -2034,140 +2042,7 @@ class Interface(ComponentModel):
return bool(self.circuit_termination)
except ObjectDoesNotExist:
pass
return bool(self.connection)
@property
def connection(self):
try:
return self.connected_as_a
except ObjectDoesNotExist:
pass
try:
return self.connected_as_b
except ObjectDoesNotExist:
pass
return None
@property
def connected_interface(self):
try:
if self.connected_as_a:
return self.connected_as_a.interface_b
except ObjectDoesNotExist:
pass
try:
if self.connected_as_b:
return self.connected_as_b.interface_a
except ObjectDoesNotExist:
pass
return None
class InterfaceConnection(models.Model):
"""
An InterfaceConnection represents a symmetrical, one-to-one connection between two Interfaces. There is no
significant difference between the interface_a and interface_b fields.
"""
interface_a = models.OneToOneField(
to='dcim.Interface',
on_delete=models.CASCADE,
related_name='connected_as_a'
)
interface_b = models.OneToOneField(
to='dcim.Interface',
on_delete=models.CASCADE,
related_name='connected_as_b'
)
connection_status = models.BooleanField(
choices=CONNECTION_STATUS_CHOICES,
default=CONNECTION_STATUS_CONNECTED,
verbose_name='Status'
)
csv_headers = ['device_a', 'interface_a', 'device_b', 'interface_b', 'connection_status']
def clean(self):
# An interface cannot be connected to itself
if self.interface_a == self.interface_b:
raise ValidationError({
'interface_b': "Cannot connect an interface to itself."
})
# Only connectable interface types are permitted
if self.interface_a.form_factor in NONCONNECTABLE_IFACE_TYPES:
raise ValidationError({
'interface_a': '{} is not a connectable interface type.'.format(
self.interface_a.get_form_factor_display()
)
})
if self.interface_b.form_factor in NONCONNECTABLE_IFACE_TYPES:
raise ValidationError({
'interface_b': '{} is not a connectable interface type.'.format(
self.interface_b.get_form_factor_display()
)
})
# Prevent the A side of one connection from being the B side of another
interface_a_connections = InterfaceConnection.objects.filter(
Q(interface_a=self.interface_a) |
Q(interface_b=self.interface_a)
).exclude(pk=self.pk)
if interface_a_connections.exists():
raise ValidationError({
'interface_a': "This interface is already connected."
})
interface_b_connections = InterfaceConnection.objects.filter(
Q(interface_a=self.interface_b) |
Q(interface_b=self.interface_b)
).exclude(pk=self.pk)
if interface_b_connections.exists():
raise ValidationError({
'interface_b': "This interface is already connected."
})
def to_csv(self):
return (
self.interface_a.device.identifier,
self.interface_a.name,
self.interface_b.device.identifier,
self.interface_b.name,
self.get_connection_status_display(),
)
def log_change(self, user, request_id, action):
"""
Create a new ObjectChange for each of the two affected Interfaces.
"""
interfaces = (
(self.interface_a, self.interface_b),
(self.interface_b, self.interface_a),
)
for interface, peer_interface in interfaces:
if action == OBJECTCHANGE_ACTION_DELETE:
connection_data = {
'connected_interface': None,
}
else:
connection_data = {
'connected_interface': peer_interface.pk,
'connection_status': self.connection_status
}
try:
parent_obj = interface.parent
except ObjectDoesNotExist:
parent_obj = None
ObjectChange(
user=user,
request_id=request_id,
changed_object=interface,
related_object=parent_obj,
action=OBJECTCHANGE_ACTION_UPDATE,
object_data=serialize_object(interface, extra=connection_data)
).save()
return bool(self.connected_endpoint)
#