From dacdbbf74609dcbecd88b8e0e18694cb430ea015 Mon Sep 17 00:00:00 2001 From: Aymeric Barantal Date: Sun, 29 Jan 2012 13:46:49 +0100 Subject: [PATCH 1/5] node got multiples ips from libcloud driver --- overmind/api/provisioning.py | 2 +- overmind/provisioning/controllers.py | 2 +- overmind/provisioning/models.py | 62 ++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/overmind/api/provisioning.py b/overmind/api/provisioning.py index d982614..3d27bf3 100644 --- a/overmind/api/provisioning.py +++ b/overmind/api/provisioning.py @@ -161,7 +161,7 @@ class SizeHandler(BaseHandler): class NodeHandler(BaseHandler): fields = ('id', 'name', 'node_id', 'provider', 'image', 'location', 'size', - 'public_ip', 'private_ip', 'created_by', 'state', 'environment', + 'public_ips', 'private_ips', 'created_by', 'state', 'environment', 'destroyed_by', 'created_at', 'destroyed_at') model = Node diff --git a/overmind/provisioning/controllers.py b/overmind/provisioning/controllers.py index 928988b..07d62d0 100644 --- a/overmind/provisioning/controllers.py +++ b/overmind/provisioning/controllers.py @@ -97,7 +97,7 @@ def create_node(self, form): return e, None return None, { - 'public_ip': node.public_ip[0], + 'public_ips': node.public_ips, 'node_id': node.id, 'state': node.state, 'extra': node.extra, diff --git a/overmind/provisioning/models.py b/overmind/provisioning/models.py index 73464b9..cf6ce64 100644 --- a/overmind/provisioning/models.py +++ b/overmind/provisioning/models.py @@ -3,6 +3,7 @@ from provisioning.provider_meta import PROVIDERS import logging, datetime import simplejson as json +from IPy import IP provider_meta_keys = PROVIDERS.keys() provider_meta_keys.sort() @@ -96,7 +97,6 @@ def import_nodes(self): if not self.supports('list'): return self.create_connection() nodes = self.conn.get_nodes() - # Import nodes not present in the DB for node in nodes: try: @@ -126,11 +126,13 @@ def import_nodes(self): n.size = Size.objects.get(size_id=size_id, provider=self) except Size.DoesNotExist: n.size = None - + n.save() # Import/Update node info - n.public_ip = node.public_ip[0] - if len(node.private_ip): - n.private_ip = node.private_ip[0] + for i in range(0, len(node.public_ips)): + n.create_ip(ip=node.public_ips[i], position=i, is_public=True) + if len(node.private_ips): + for i in range(0, len(node.private_ips)): + n.create_ip(ip=node.private_ips[i], position=i, is_public=False) n.state = get_state(node.state) n.save_extra_data(node.extra) n.save() @@ -323,6 +325,20 @@ class Meta: unique_together = ('provider', 'size_id') +class NodeIP(models.Model): + INET_FAMILIES = ( + ('inet4', 4), + ('inet6', 6), + ) + node = models.ForeignKey('Node', related_name='ips') + address = models.CharField(max_length=50) # For IPv6 support, not fully supported in django < 1.3.2 (IIRC) + is_public = models.BooleanField(default=True) + version = models.IntegerField(choices=INET_FAMILIES, default=4) + position = models.IntegerField() + + def __unicode__(self): + return "%s" % (self.address) + class Node(models.Model): STATE_CHOICES = ( (u'Begin', u'Begin'), @@ -353,8 +369,6 @@ class Node(models.Model): state = models.CharField( default='Begin', max_length=20, choices=STATE_CHOICES ) - public_ip = models.CharField(max_length=25) - private_ip = models.CharField(max_length=25, blank=True) hostname = models.CharField(max_length=25, blank=True) _extra_data = models.TextField(blank=True) @@ -366,7 +380,39 @@ class Node(models.Model): destroyed_by = models.CharField(max_length=25, blank=True) created_at = models.DateTimeField(auto_now_add=True) destroyed_at = models.DateTimeField(null=True) - + + @property + def public_ips(self): + return self.ips.filter(is_public=True).all() + + + @property + def private_ips(self): + return self.ips.filter(is_public=False).all() + + # Backward compatibility properties + @property + def public_ip(self): + public_ips = self.ips.filter(is_public=True).filter(version=4) + if len(public_ips): + return public_ips[0].address + return '' + + @property + def private_ip(self): + private_ips = self.ips.filter(is_public=False) + if len(private_ips): + return private_ips[0].address + return '' + + # helper for related ips creation + def create_ip(self, ip, position, is_public): + ipaddr = IP(ip) + return NodeIP.objects.create( + address=ipaddr.i.strFullsize(), position=position, version=ipaddr.version(), + is_public=is_public, node=self + ) + class Meta: unique_together = (('provider', 'name'), ('provider', 'node_id')) From b02b4ec2238354a3326180908aa9f068cb302f67 Mon Sep 17 00:00:00 2001 From: Aymeric Barantal Date: Sun, 5 Feb 2012 20:26:19 +0100 Subject: [PATCH 2/5] typo on ipaddr --- overmind/provisioning/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overmind/provisioning/models.py b/overmind/provisioning/models.py index cf6ce64..6385102 100644 --- a/overmind/provisioning/models.py +++ b/overmind/provisioning/models.py @@ -409,7 +409,7 @@ def private_ip(self): def create_ip(self, ip, position, is_public): ipaddr = IP(ip) return NodeIP.objects.create( - address=ipaddr.i.strFullsize(), position=position, version=ipaddr.version(), + address=ipaddr.strFullsize(), position=position, version=ipaddr.version(), is_public=is_public, node=self ) From fb353732b518bc65c9f4400abee634178e1db5af Mon Sep 17 00:00:00 2001 From: Aymeric Barantal Date: Sat, 11 Feb 2012 13:08:17 +0100 Subject: [PATCH 3/5] Change sync strategy for NodeIP --- overmind/provisioning/models.py | 36 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/overmind/provisioning/models.py b/overmind/provisioning/models.py index 6385102..23ab400 100644 --- a/overmind/provisioning/models.py +++ b/overmind/provisioning/models.py @@ -126,13 +126,10 @@ def import_nodes(self): n.size = Size.objects.get(size_id=size_id, provider=self) except Size.DoesNotExist: n.size = None - n.save() + n.save() # Import/Update node info - for i in range(0, len(node.public_ips)): - n.create_ip(ip=node.public_ips[i], position=i, is_public=True) - if len(node.private_ips): - for i in range(0, len(node.private_ips)): - n.create_ip(ip=node.private_ips[i], position=i, is_public=False) + n.sync_ips(node.public_ips, public=True) + n.sync_ips(node.private_ips, public=False) n.state = get_state(node.state) n.save_extra_data(node.extra) n.save() @@ -406,12 +403,27 @@ def private_ip(self): return '' # helper for related ips creation - def create_ip(self, ip, position, is_public): - ipaddr = IP(ip) - return NodeIP.objects.create( - address=ipaddr.strFullsize(), position=position, version=ipaddr.version(), - is_public=is_public, node=self - ) + def sync_ips(self, ips, public=True): + """Sync IP for a node""" + previous = self.ips.filter(is_public=public).order_by('position') + addrs = [] + for i in ips: + addr = IP(i) + addrs.append(addr) + new_ips = [x.strFullsize() for x in addrs] + for p in previous: + if p.address in new_ips: + p.position = new_ips.index(p.address) + else: + p.delete() + for a in addrs: + if a.strFullsize() not in [x.address for x in previous]: + # Create new nodeip object + NodeIP.objects.create( + address=a.strFullsize(), + position=new_ips.index(a.strFullsize()), + version=a.version(), is_public=public, node=self + ) class Meta: unique_together = (('provider', 'name'), ('provider', 'node_id')) From 1e41dad4fa7a826ef2222f73324fb5e6dcf54bcd Mon Sep 17 00:00:00 2001 From: Aymeric Barantal Date: Tue, 14 Feb 2012 10:45:27 +0100 Subject: [PATCH 4/5] use IPAddressField and add an interface_name attribute on NodeIP --- overmind/provisioning/models.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/overmind/provisioning/models.py b/overmind/provisioning/models.py index 23ab400..9a0311b 100644 --- a/overmind/provisioning/models.py +++ b/overmind/provisioning/models.py @@ -328,10 +328,11 @@ class NodeIP(models.Model): ('inet6', 6), ) node = models.ForeignKey('Node', related_name='ips') - address = models.CharField(max_length=50) # For IPv6 support, not fully supported in django < 1.3.2 (IIRC) + address = models.IPAddressField() is_public = models.BooleanField(default=True) version = models.IntegerField(choices=INET_FAMILIES, default=4) position = models.IntegerField() + interface_name = models.CharField(max_length=32, blank=True) def __unicode__(self): return "%s" % (self.address) @@ -380,12 +381,12 @@ class Node(models.Model): @property def public_ips(self): - return self.ips.filter(is_public=True).all() + return self.ips.filter(is_public=True) @property def private_ips(self): - return self.ips.filter(is_public=False).all() + return self.ips.filter(is_public=False) # Backward compatibility properties @property From a9611cc47ad32687b81b13927ccbaa8a0613308e Mon Sep 17 00:00:00 2001 From: Aymeric Barantal Date: Sun, 19 Feb 2012 14:41:16 +0100 Subject: [PATCH 5/5] overview template use node.public_ips first entry --- overmind/templates/overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overmind/templates/overview.html b/overmind/templates/overview.html index 1ca06bd..fa4d6f4 100644 --- a/overmind/templates/overview.html +++ b/overmind/templates/overview.html @@ -27,7 +27,7 @@

Nodesupdate


    - {% for row in nodes %}
  • {{ row.node.provider }} - {{ row.node.name }} - {{ row.node.public_ip }} - {{ row.node.state }}{% for a in row.actions %}{{ a.label }}{% endfor %}
  • + {% for row in nodes %}
  • {{ row.node.provider }} - {{ row.node.name }} - {{ row.node.public_ips.0 }} - {{ row.node.state }}{% for a in row.actions %}{{ a.label }}{% endfor %}
  • {% endfor %}
{% endblock %}