changeset 9:09811474d92e

Add disassociate_floating_ip
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Mon, 11 Feb 2013 15:06:05 +0100
parents 4666b92cf626
children 8c94e2bf19a9
files srxproxy.py
diffstat 1 files changed, 72 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/srxproxy.py	Mon Feb 11 14:35:44 2013 +0100
+++ b/srxproxy.py	Mon Feb 11 15:06:05 2013 +0100
@@ -39,11 +39,33 @@
         </static-nat>
     </then>
 </rule>"""
+DELETE_XML = """\
+<rule operation="delete">
+    <name>%s</name>
+</rule>"""
 
 
 def ensure_floating_forwards(ips):
-    """Ensure floating IP forwarding rules."""
+    rules_xml = [
+        RULE_XML.format(
+            name=floating_ip.replace('.', '_'),
+            destination=floating_ip,
+            prefix=fixed_ip,
+        )
+        for context, floating_ip, fixed_ip, host in ips
+    ]
+    apply_ruleset(rules_xml)
 
+
+def remove_floating_forwards(ips):
+    rules_xml = [
+        DELETE_XML.format(name=address.replace('.', '_'))
+        for context, address in ips
+    ]
+    apply_ruleset(rules_xml)
+
+
+def apply_ruleset(rules_xml):
     netconf_retries = FLAGS.netconf_retries
     netconf_ip = FLAGS.netconf_server_ip
     netconf_port = FLAGS.netconf_server_port
@@ -72,17 +94,9 @@
         else:
             LOG.debug('Failed to start private edit %r' % e)
             raise exception.FloatingIpNotAssociated()
-        rules_xmls = [
-            RULE_XML.format(
-                name=floating_ip.replace('.', '_'),
-                destination=floating_ip,
-                prefix=fixed_ip,
-            )
-            for context, floating_ip, fixed_ip, host in ips
-        ]
         ruleset_xml = RULESET_XML.format(
             name=netconf_ruleset,
-            rules=''.join(rules_xmls),
+            rules=''.join(rules_xml),
         )
         m.edit_config(
             target="candidate",
@@ -135,20 +149,58 @@
             LOG.exception(e)
 
 
+def disassociate_floating_ips(ips):
+    if not ips:
+        return
+    try:
+        # Change the device configuration
+        LOG.info("Changing device configuration for %r", ips)
+        remove_floating_forwards(ips)
+    except Exception as e:
+        LOG.exception(e)
+        return
+    nm = NetworkManager()
+    for context, address in ips:
+        # Write the changes to the database
+        LOG.info("Updating database for %s", address)
+        try:
+            fixed_ip_ref = nm.db.fixed_ip_get_by_address(context, address)
+            instance = nm.db.instance_get(context, fixed_ip_ref['instance_id'])
+            nm.db.floating_ip_disassociate(context, address)
+            try:
+                nm.get_instance_nw_info(
+                    context,
+                    instance['id'],
+                    instance['uuid'],
+                    instance['instance_type_id'],
+                    instance['host'],
+                )
+            except exception.InstanceNotFound:
+                pass
+        except Exception as e:
+            LOG.exception(e)
+
+
 def on_message(data):
-    if data.get('method') == 'srx_associate_floating_ip':
-        kwargs = data.get('args', {})
-        context = amqp.unpack_context(data)
-        accumulator.add((
+    method = data.get('method')
+    kwargs = data.get('args', {})
+    context = amqp.unpack_context(data)
+    if method == 'srx_associate_floating_ip':
+        assoc_acc.add((
             context,
             kwargs.get('floating_ip'),
             kwargs.get('fixed_ip'),
             kwargs.get('host'),
         ))
+    elif method == 'srx_disassociate_floating_ip':
+        dis_acc.add((
+            context,
+            kwargs.get('address'),
+        ))
 
 
 class Accumulator(object):
-    """Accumulates entries until the oldest one is old enough."""
+    """Accumulates entries until the oldest one is older than timeout."""
 
     def __init__(self, timeout):
         self.cache = []
@@ -182,12 +234,14 @@
     log.setup()
     log.root.setLevel(log.DEBUG)
     eventlet.monkey_patch()
-    accumulator = Accumulator(DELAY)
+    assoc_acc = Accumulator(DELAY)
+    dis_acc = Accumulator(DELAY)
     connection = rpc.create_connection()
     connection.declare_topic_consumer('srxproxy', on_message)
     connection.declare_topic_consumer('srxproxy.%s' % flags.FLAGS.host, on_message)
     connection.consume_in_thread()
     while True:
-        associate_floating_ips(accumulator.check())
-        delay = DELAY - accumulator.delay()
+        associate_floating_ips(assoc_acc.check())
+        disassociate_floating_ips(dis_acc.check())
+        delay = min(DELAY - assoc_acc.delay(), DELAY - dis_acc.delay())
         eventlet.sleep(delay)