Fixes #43: Introduce toggle to enforce unique IP space per VRF

This commit is contained in:
Jeremy Stretch
2016-07-14 16:13:02 -04:00
parent bf44e512ff
commit 4a00971d44
9 changed files with 71 additions and 5 deletions

View File

@@ -12,7 +12,7 @@ class VRFSerializer(serializers.ModelSerializer):
class Meta:
model = VRF
fields = ['id', 'name', 'rd', 'description']
fields = ['id', 'name', 'rd', 'enforce_unique', 'description']
class VRFNestedSerializer(VRFSerializer):

View File

@@ -25,7 +25,7 @@ class VRFForm(forms.ModelForm, BootstrapMixin):
class Meta:
model = VRF
fields = ['name', 'rd', 'description']
fields = ['name', 'rd', 'enforce_unique', 'description']
labels = {
'rd': "RD",
}
@@ -38,7 +38,7 @@ class VRFFromCSVForm(forms.ModelForm):
class Meta:
model = VRF
fields = ['name', 'rd', 'description']
fields = ['name', 'rd', 'enforce_unique', 'description']
class VRFImportForm(BulkImportForm, BootstrapMixin):

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-14 19:34
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ipam', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='vrf',
name='enforce_unique',
field=models.BooleanField(default=True, help_text=b'Prevent duplicate prefixes/IP addresses within this VRF', verbose_name=b'Enforce unique space'),
),
]

View File

@@ -1,5 +1,6 @@
from netaddr import IPNetwork, cidr_merge
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse
from django.core.validators import MaxValueValidator, MinValueValidator
@@ -45,6 +46,8 @@ class VRF(CreatedUpdatedModel):
"""
name = models.CharField(max_length=50)
rd = models.CharField(max_length=21, unique=True, verbose_name='Route distinguisher')
enforce_unique = models.BooleanField(default=True, verbose_name='Enforce unique space',
help_text="Prevent duplicate prefixes/IP addresses within this VRF")
description = models.CharField(max_length=100, blank=True)
class Meta:
@@ -309,6 +312,21 @@ class IPAddress(CreatedUpdatedModel):
def get_absolute_url(self):
return reverse('ipam:ipaddress', args=[self.pk])
def clean(self):
# Enforce unique IP space if applicable
if self.vrf and self.vrf.enforce_unique:
duplicate_ips = IPAddress.objects.filter(vrf=self.vrf, address__net_host=str(self.address.ip))\
.exclude(pk=self.pk)
if duplicate_ips:
raise ValidationError("Duplicate IP address found in VRF {}: {}".format(self.vrf,
duplicate_ips.first()))
elif not self.vrf and settings.ENFORCE_GLOBAL_UNIQUE:
duplicate_ips = IPAddress.objects.filter(vrf=None, address__net_host=str(self.address.ip))\
.exclude(pk=self.pk)
if duplicate_ips:
raise ValidationError("Duplicate IP address found in global table: {}".format(duplicate_ips.first()))
def save(self, *args, **kwargs):
if self.address:
# Infer address family from IPAddress object