Changeset - 079e7f2b0680
[Not reviewed]
default
0 2 1
Branko Majic (branko) - 11 years ago 2013-07-15 22:39:31
branko@majic.rs
Noticket: Added uniqueness enforcement for IP/address across same entity (i.e. prevent the entity from having multiple interfaces with same IP address.)
3 files changed with 78 insertions and 2 deletions:
0 comments (0 inline, 0 general)
conntrackt/migrations/0004_auto__add_unique_interface_netmask_address_entity.py
Show inline comments
 
new file 100644
 
# -*- coding: utf-8 -*-
 
import datetime
 
from south.db import db
 
from south.v2 import SchemaMigration
 
from django.db import models
 

	
 

	
 
class Migration(SchemaMigration):
 

	
 
    def forwards(self, orm):
 
        # Adding unique constraint on 'Interface', fields ['netmask', 'address', 'entity']
 
        db.create_unique(u'conntrackt_interface', ['netmask', 'address', 'entity_id'])
 

	
 

	
 
    def backwards(self, orm):
 
        # Removing unique constraint on 'Interface', fields ['netmask', 'address', 'entity']
 
        db.delete_unique(u'conntrackt_interface', ['netmask', 'address', 'entity_id'])
 

	
 

	
 
    models = {
 
        u'conntrackt.communication': {
 
            'Meta': {'unique_together': "(('source', 'destination', 'protocol', 'port'),)", 'object_name': 'Communication'},
 
            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
 
            'destination': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'destination_set'", 'to': u"orm['conntrackt.Interface']"}),
 
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 
            'port': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
 
            'protocol': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
 
            'source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'source_set'", 'to': u"orm['conntrackt.Interface']"})
 
        },
 
        u'conntrackt.entity': {
 
            'Meta': {'unique_together': "(('name', 'project'),)", 'object_name': 'Entity'},
 
            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
 
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 
            'location': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['conntrackt.Location']"}),
 
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
 
            'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['conntrackt.Project']"})
 
        },
 
        u'conntrackt.interface': {
 
            'Meta': {'unique_together': "(('name', 'entity'), ('entity', 'address', 'netmask'))", 'object_name': 'Interface'},
 
            'address': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
 
            'description': ('django.db.models.fields.TextField', [], {'default': "'Main network interface.'", 'blank': 'True'}),
 
            'entity': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['conntrackt.Entity']"}),
 
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 
            'name': ('django.db.models.fields.CharField', [], {'default': "'eth0'", 'max_length': '100'}),
 
            'netmask': ('django.db.models.fields.IPAddressField', [], {'default': "'255.255.255.255'", 'max_length': '15'})
 
        },
 
        u'conntrackt.location': {
 
            'Meta': {'object_name': 'Location'},
 
            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
 
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
 
        },
 
        u'conntrackt.project': {
 
            'Meta': {'object_name': 'Project'},
 
            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
 
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
 
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'})
 
        }
 
    }
 

	
 
    complete_apps = ['conntrackt']
 
\ No newline at end of file
conntrackt/models.py
Show inline comments
 
@@ -188,26 +188,28 @@ class Interface(models.Model):
 
      netmask - Netmask of the interface. By default this is /32
 
      (255.255.255.255), but in case of subnet entities this can be used for
 
      denoting the network netmask.
 
    """
 

	
 
    name = models.CharField(max_length=100, default='eth0')
 
    description = models.TextField(blank=True, default='Main network interface.')
 
    entity = models.ForeignKey(Entity)
 
    address = models.IPAddressField()
 
    netmask = models.IPAddressField(default='255.255.255.255')
 

	
 
    class Meta:
 
        # Enforce uniqueness of interface name in an entity.
 
        unique_together = ("name", "entity")
 
        # Enforce uniqueness of interface name in an entity. Enforce uniqueness
 
        # of IP address in a subnet for an entity.
 
        unique_together = (("name", "entity"),
 
                           ("entity", "address", "netmask"),)
 

	
 
    def __unicode__(self):
 
        """
 
        Returns:
 
          String representation of an interface. In case of single IP this will
 
          simply be the interface name and IP address. In case of subnet it will
 
          include the netmask as well.
 
        """
 

	
 
        if self.netmask == '255.255.255.255':
 
            return '%s (%s)' % (self.entity.name, self.address)
 
        else:
conntrackt/tests/test_models.py
Show inline comments
 
@@ -137,24 +137,37 @@ class InterfaceTest(TestCase):
 
        """
 
        Test if unique interface name is enforced across same entity.
 
        """
 

	
 
        entity = Entity.objects.get(pk=1)
 

	
 
        interface = entity.interface_set.get(pk=1)
 

	
 
        duplicate = Interface(name=interface.name, description="Duplicate interface.", entity=entity, address="10.10.10.10", netmask="255.255.255.255")
 

	
 
        self.assertRaises(IntegrityError, duplicate.save)
 

	
 
    def test_unique_address(self):
 
        """
 
        Test if unique address/netmask is enforced across same entity.
 
        """
 

	
 
        entity = Entity.objects.get(pk=1)
 

	
 
        interface = entity.interface_set.get(pk=1)
 

	
 
        duplicate = Interface(name="eth1", description="Duplicate address", entity=entity, address=interface.address, netmask=interface.netmask)
 

	
 
        self.assertRaises(IntegrityError, duplicate.save)
 

	
 
    def test_representation_single(self):
 
        """
 
        Test representation of single IP address.
 
        """
 

	
 
        interface = Entity.objects.get(name="Test Entity 1").interface_set.get(name="eth0")
 
        representation = "Test Entity 1 (192.168.1.1)"
 

	
 
        self.assertEqual(str(interface), representation)
 

	
 
    def test_representation_subnet(self):
 
        """
0 comments (0 inline, 0 general)