changeset 4:85a2bef9574e

Add ensure_floating_formwards for actually communicationg with the switch
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Mon, 11 Feb 2013 11:36:15 +0100
parents cecad00e9d9f
children 286632cf1e03
files srxproxy.py srxtest.py
diffstat 2 files changed, 115 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/srxproxy.py	Fri Feb 08 15:42:15 2013 +0100
+++ b/srxproxy.py	Mon Feb 11 11:36:15 2013 +0100
@@ -1,31 +1,129 @@
 #!/usr/bin/env python
 
+import time
+
 from nova import rpc
 from nova import log
+from nova import flags
+from nova import exception
+
+from ncclient import manager, operations
 
 
-TOPICS = [
-    'srxproxy',
-]
+FLAGS = flags.FLAGS
+LOG = log
+RULESET_XML = """\
+<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+   <configuration><security><nat><static><rule-set>
+        <name>{name}</name>
+        {rules}
+    </rule-set></static></nat></security></configuration>
+</config>"""
+RULE_XML = """\
+<rule>
+    <name>{name}</name>
+    <static-nat-rule-match>
+        <destination-address>
+            <dst-addr>{destination}/32</dst-addr>
+        </destination-address>
+    </static-nat-rule-match>
+    <then>
+        <static-nat>
+            <prefix>
+                <addr-prefix>{prefix}/32</addr-prefix>
+            </prefix>
+        </static-nat>
+    </then>
+</rule>"""
+
+
+
+def ignore_unknown_host_cb(host, fingerprint):
+    return True
 
 
-def _associate_floating_ip(floating_address, fixed_address, interface):
-    print "Associate floating IP %s with static IP %s on interface %s" % (
-        floating_address,
-        fixed_address,
-        interface,
+def ensure_floating_forwards(ips):
+    """Ensure floating IP forwarding rules."""
+
+    netconf_retries = FLAGS.netconf_retries
+    netconf_ip = FLAGS.netconf_server_ip
+    netconf_port = FLAGS.netconf_server_port
+    netconf_user = FLAGS.netconf_server_user
+    netconf_password = FLAGS.netconf_server_password
+    netconf_ruleset = FLAGS.netconf_rule_set
+    with manager.connect_ssh(netconf_ip, port=netconf_port,
+                             unknown_host_cb=ignore_unknown_host_cb,
+                             username=netconf_user,
+                             password=netconf_password,
+                             allow_agent=False,
+                             look_for_keys=False) as m:
+        assert ':url' in m.server_capabilities
+        for retry in xrange(netconf_retries):
+            try:
+                m.private()
+            except operations.rpc.RPCError as e:
+                if (e._message ==
+                    '\nuncommitted changes will be discarded on exit\n'):
+                    break
+            m.privateend()
+            time.sleep(2**retry)
+        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 floating_ip, fixed_ip in ips
+        ]
+        ruleset_xml = RULESET_XML.format(
+            name=netconf_ruleset,
+            rules=''.join(rules_xmls),
+        )
+        m.edit_config(
+            target="candidate",
+            config=ruleset_xml,
+            default_operation="merge",
+        )
+        for retry in xrange(netconf_retries):
+            try:
+                m.commit(confirmed=False)
+            except operations.rpc.RPCError as e:
+                pass
+            else:
+                break
+            time.sleep(2**retry)
+        else:
+            raise exception.FloatingIpNotAssociated()
+
+
+def srx_associate_floating_ip(floating_ip, fixed_ip, host):
+    LOG.info(
+        "Associate floating IP %s with static IP %s on host %s",
+        floating_ip,
+        fixed_ip,
+        host,
     )
+    #ensure_floating_forwards([
+    #    (floating_address, fixed_address)
+    #])
 
 
 def on_message(data):
-    if data.get('method') == '_associate_floating_ip':
-        _associate_floating_ip(**data.get('args', {}))
+    try:
+        assert data.get('method') == 'srx_associate_floating_ip'
+        srx_associate_floating_ip(**data.get('args', {}))
+    except Exception as e:
+        log.exception(e)
 
 
 if __name__ == '__main__':
     log.setup()
     log.root.setLevel(log.DEBUG)
     connection = rpc.create_connection()
-    for topic in TOPICS:
-        connection.declare_topic_consumer(topic, on_message)
-    connection.consume()
+    connection.declare_topic_consumer('srxproxy', on_message)
+    connection.declare_topic_consumer('srxproxy.%s' % flags.FLAGS.host, on_message)
+    for step in connection.iterconsume():
+        print "oink!"
--- a/srxtest.py	Fri Feb 08 15:42:15 2013 +0100
+++ b/srxtest.py	Mon Feb 11 11:36:15 2013 +0100
@@ -9,11 +9,11 @@
     connection.topic_send(
         'srxproxy',
         {
-            'method': '_associate_floating_ip',
+            'method': 'srx_associate_floating_ip',
             'args': {
-                'floating_address': '127.0.0.1',
-                'fixed_address': '127.0.0.1',
-                'interface': 'eth0',
+                'floating_ip': '127.0.0.2',
+                'fixed_ip': '127.0.0.1',
+                'host': 'ziomal',
             },
             '_context_user_id': 'x',
             '_context_project_id': 'x',