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

Converted IPAddress.interface to a GenericForeignKey

This commit is contained in:
Jeremy Stretch
2017-08-18 16:57:20 -04:00
parent 97536c4e9b
commit 5930a64203
9 changed files with 106 additions and 32 deletions

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-08-16 21:06
# Generated by Django 1.11.4 on 2017-08-18 19:46
from __future__ import unicode_literals
from django.db import migrations, models

View File

@ -1175,6 +1175,11 @@ class Interface(models.Model):
help_text="This interface is used only for out-of-band management"
)
description = models.CharField(max_length=100, blank=True)
ip_addresses = GenericRelation(
to='ipam.IPAddress',
content_type_field='interface_type',
object_id_field='interface_id'
)
objects = InterfaceQuerySet.as_manager()

View File

@ -134,7 +134,11 @@ class PrefixViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
#
class IPAddressViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant', 'interface__device', 'nat_inside')
queryset = IPAddress.objects.select_related(
'vrf__tenant', 'tenant', 'nat_inside'
).prefetch_related(
'interface__device'
)
serializer_class = serializers.IPAddressSerializer
write_serializer_class = serializers.WritableIPAddressSerializer
filter_class = filters.IPAddressFilter

View File

@ -70,7 +70,7 @@
"family": 4,
"address": "10.0.255.1/32",
"vrf": null,
"interface": 3,
"interface_id": 3,
"nat_inside": null,
"description": ""
}
@ -84,7 +84,7 @@
"family": 4,
"address": "169.254.254.1/31",
"vrf": null,
"interface": 4,
"interface_id": 4,
"nat_inside": null,
"description": ""
}
@ -98,7 +98,7 @@
"family": 4,
"address": "10.0.255.2/32",
"vrf": null,
"interface": 185,
"interface_id": 185,
"nat_inside": null,
"description": ""
}
@ -112,7 +112,7 @@
"family": 4,
"address": "169.254.1.1/31",
"vrf": null,
"interface": 213,
"interface_id": 213,
"nat_inside": null,
"description": ""
}
@ -126,7 +126,7 @@
"family": 4,
"address": "10.0.254.1/24",
"vrf": null,
"interface": 12,
"interface_id": 12,
"nat_inside": null,
"description": ""
}
@ -140,7 +140,7 @@
"family": 4,
"address": "10.15.21.1/31",
"vrf": null,
"interface": 218,
"interface_id": 218,
"nat_inside": null,
"description": ""
}
@ -154,7 +154,7 @@
"family": 4,
"address": "10.15.21.2/31",
"vrf": null,
"interface": 9,
"interface_id": 9,
"nat_inside": null,
"description": ""
}
@ -168,7 +168,7 @@
"family": 4,
"address": "10.15.22.1/31",
"vrf": null,
"interface": 8,
"interface_id": 8,
"nat_inside": null,
"description": ""
}
@ -182,7 +182,7 @@
"family": 4,
"address": "10.15.20.1/31",
"vrf": null,
"interface": 7,
"interface_id": 7,
"nat_inside": null,
"description": ""
}
@ -196,7 +196,7 @@
"family": 4,
"address": "10.16.20.1/31",
"vrf": null,
"interface": 216,
"interface_id": 216,
"nat_inside": null,
"description": ""
}
@ -210,7 +210,7 @@
"family": 4,
"address": "10.15.22.2/31",
"vrf": null,
"interface": 206,
"interface_id": 206,
"nat_inside": null,
"description": ""
}
@ -224,7 +224,7 @@
"family": 4,
"address": "10.16.22.1/31",
"vrf": null,
"interface": 217,
"interface_id": 217,
"nat_inside": null,
"description": ""
}
@ -238,7 +238,7 @@
"family": 4,
"address": "10.16.22.2/31",
"vrf": null,
"interface": 205,
"interface_id": 205,
"nat_inside": null,
"description": ""
}
@ -252,7 +252,7 @@
"family": 4,
"address": "10.16.20.2/31",
"vrf": null,
"interface": 211,
"interface_id": 211,
"nat_inside": null,
"description": ""
}
@ -266,7 +266,7 @@
"family": 4,
"address": "10.15.22.2/31",
"vrf": null,
"interface": 212,
"interface_id": 212,
"nat_inside": null,
"description": ""
}
@ -280,7 +280,7 @@
"family": 4,
"address": "10.0.254.2/32",
"vrf": null,
"interface": 188,
"interface_id": 188,
"nat_inside": null,
"description": ""
}
@ -294,7 +294,7 @@
"family": 4,
"address": "169.254.1.1/31",
"vrf": null,
"interface": 200,
"interface_id": 200,
"nat_inside": null,
"description": ""
}
@ -308,7 +308,7 @@
"family": 4,
"address": "169.254.1.2/31",
"vrf": null,
"interface": 194,
"interface_id": 194,
"nat_inside": null,
"description": ""
}

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-08-18 19:31
from __future__ import unicode_literals
from django.contrib.contenttypes.models import ContentType
from django.db import migrations, models
import django.db.models.deletion
def set_interface_type(apps, schema_editor):
"""
Set the interface_type field to 'Interface' for all IP addresses assigned to an Interface.
"""
Interface = apps.get_model('dcim', 'Interface')
interface_type = ContentType.objects.get_for_model(Interface)
IPAddress = apps.get_model('ipam', 'IPAddress')
IPAddress.objects.filter(interface__isnull=False).update(interface_type=interface_type)
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('ipam', '0018_remove_service_uniqueness_constraint'),
]
operations = [
migrations.AddField(
model_name='ipaddress',
name='interface_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='contenttypes.ContentType'),
),
migrations.RunPython(set_interface_type),
migrations.AlterField(
model_name='IPAddress',
name='interface',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.RenameField(
model_name='IPAddress',
old_name='interface',
new_name='interface_id',
)
]

View File

@ -2,10 +2,12 @@ from __future__ import unicode_literals
import netaddr
from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import Q
from django.db.models.expressions import RawSQL
from django.urls import reverse
from django.utils.encoding import python_2_unicode_compatible
@ -407,8 +409,15 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
role = models.PositiveSmallIntegerField(
'Role', choices=IPADDRESS_ROLE_CHOICES, blank=True, null=True, help_text='The functional role of this IP'
)
interface = models.ForeignKey(Interface, related_name='ip_addresses', on_delete=models.CASCADE, blank=True,
null=True)
interface_type = models.ForeignKey(
to=ContentType,
on_delete=models.PROTECT,
limit_choices_to=Q(app_label='dcim', model='interface') | Q(app_label='virtualization', model='vminterface'),
blank=True,
null=True
)
interface_id = models.PositiveIntegerField(blank=True, null=True)
interface = GenericForeignKey('interface_type', 'interface_id')
nat_inside = models.OneToOneField('self', related_name='nat_outside', on_delete=models.SET_NULL, blank=True,
null=True, verbose_name='NAT (Inside)',
help_text="The IP for which this address is the \"outside\" IP")

View File

@ -594,7 +594,11 @@ class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
#
class IPAddressListView(ObjectListView):
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant', 'interface__device', 'nat_inside')
queryset = IPAddress.objects.select_related(
'vrf__tenant', 'tenant', 'nat_inside'
).prefetch_related(
'interface__device'
)
filter = filters.IPAddressFilter
filter_form = forms.IPAddressFilterForm
table = tables.IPAddressDetailTable
@ -605,7 +609,7 @@ class IPAddressView(View):
def get(self, request, pk):
ipaddress = get_object_or_404(IPAddress.objects.select_related('interface__device'), pk=pk)
ipaddress = get_object_or_404(IPAddress.objects.select_related('vrf__tenant', 'tenant'), pk=pk)
# Parent prefixes table
parent_prefixes = Prefix.objects.filter(
@ -622,12 +626,14 @@ class IPAddressView(View):
).exclude(
pk=ipaddress.pk
).select_related(
'interface__device', 'nat_inside'
'nat_inside'
).prefetch_related(
'interface__device'
)
duplicate_ips_table = tables.IPAddressTable(list(duplicate_ips), orderable=False)
# Related IP table
related_ips = IPAddress.objects.select_related(
related_ips = IPAddress.objects.prefetch_related(
'interface__device'
).exclude(
address=str(ipaddress.address)
@ -681,7 +687,7 @@ class IPAddressBulkImportView(PermissionRequiredMixin, BulkImportView):
class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView):
permission_required = 'ipam.change_ipaddress'
cls = IPAddress
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant', 'interface__device')
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant').prefetch_related('interface__device')
filter = filters.IPAddressFilter
table = tables.IPAddressTable
form = forms.IPAddressBulkEditForm
@ -691,7 +697,7 @@ class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView):
class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
permission_required = 'ipam.delete_ipaddress'
cls = IPAddress
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant', 'interface__device')
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant').prefetch_related('interface__device')
filter = filters.IPAddressFilter
table = tables.IPAddressTable
default_return_url = 'ipam:ipaddress_list'

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-08-16 21:06
# Generated by Django 1.11.4 on 2017-08-18 19:46
from __future__ import unicode_literals
import dcim.fields
@ -13,9 +13,9 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('tenancy', '0003_unicode_literals'),
('dcim', '0041_napalm_integration'),
('ipam', '0018_remove_service_uniqueness_constraint'),
('ipam', '0019_ipaddress_interface_to_gfk'),
('tenancy', '0003_unicode_literals'),
]
operations = [
@ -89,6 +89,7 @@ class Migration(migrations.Migration):
('virtual_machine', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='virtualization.VirtualMachine')),
],
options={
'verbose_name': 'VM interface',
'ordering': ['virtual_machine', 'name'],
},
),

View File

@ -221,6 +221,11 @@ class VMInterface(models.Model):
max_length=100,
blank=True
)
ip_addresses = GenericRelation(
to='ipam.IPAddress',
content_type_field='interface_type',
object_id_field='interface_id'
)
class Meta:
ordering = ['virtual_machine', 'name']