ovs-monitor-ipsec: Detect correctly IPSEC configuration changes
[sliver-openvswitch.git] / debian / ovs-monitor-ipsec
old mode 100644 (file)
new mode 100755 (executable)
index 0c1d6a8..981f0a2
 
 import argparse
 import glob
-import logging
-import logging.handlers
 import os
-import socket
 import subprocess
 import sys
 
@@ -40,21 +37,9 @@ from ovs.db import types
 import ovs.util
 import ovs.daemon
 import ovs.db.idl
+import ovs.vlog
 
-s_log = logging.getLogger("ovs-monitor-ipsec")
-try:
-    # By default log messages as DAEMON into syslog
-    l_handler = logging.handlers.SysLogHandler(
-            "/dev/log",
-            facility=logging.handlers.SysLogHandler.LOG_DAEMON)
-    l_formatter = logging.Formatter('%(filename)s: %(levelname)s: %(message)s')
-    l_handler.setFormatter(l_formatter)
-    s_log.addHandler(l_handler)
-except socket.error, e:
-    logging.basicConfig()
-    s_log.warn("failed to connect to syslog (%s)" % e)
-s_log.addHandler(logging.StreamHandler())
-
+vlog = ovs.vlog.Vlog("ovs-monitor-ipsec")
 root_prefix = ''                # Prefix for absolute file names, for testing.
 setkey = "/usr/sbin/setkey"
 
@@ -134,7 +119,7 @@ path certificate "%s";
             try:
                 os.remove(ovs_cert)
             except OSError:
-                s_log.warning("couldn't remove %s" % ovs_cert)
+                vlog.warn("couldn't remove %s" % ovs_cert)
 
         # Replace racoon's conf file with our template
         self.commit()
@@ -147,11 +132,11 @@ path certificate "%s";
             # refuse to start if it sees something it doesn't like
             # (e.g., a certificate file doesn't exist).  Try restarting
             # the process before giving up.
-            s_log.warning("attempting to restart racoon")
+            vlog.warn("attempting to restart racoon")
             exitcode = subprocess.call([root_prefix + "/etc/init.d/racoon",
                                         "restart"])
             if exitcode != 0:
-                s_log.warning("couldn't reload racoon")
+                vlog.warn("couldn't reload racoon")
 
     def commit(self):
         # Rewrite the Racoon configuration file
@@ -231,13 +216,10 @@ path certificate "%s";
 
         # The peer's certificate comes to us in PEM format as a string.
         # Write that string to a file for Racoon to use.
-        peer_cert_file = "%s/ovs-%s.pem" % (self.cert_dir, host)
-        f = open(root_prefix + peer_cert_file, "w")
+        f = open(root_prefix + vals["peer_cert_file"], "w")
         f.write(vals["peer_cert"])
         f.close()
 
-        vals["peer_cert_file"] = peer_cert_file
-
         self.cert_hosts[host] = vals
         self.commit()
 
@@ -280,7 +262,7 @@ class IPsec:
                                  stdin=subprocess.PIPE,
                                  stdout=subprocess.PIPE)
         except:
-            s_log.error("could not call %s%s" % (root_prefix, setkey))
+            vlog.err("could not call %s%s" % (root_prefix, setkey))
             sys.exit(1)
 
         # xxx It is safer to pass the string into the communicate()
@@ -414,23 +396,26 @@ def update_ipsec(ipsec, interfaces, new_interfaces):
         orig_vals = interfaces.get(name)
         if orig_vals:
             # Configuration for this host already exists.  Check if it's
-            # changed.
-            if vals == orig_vals:
-                continue
-            else:
+            # changed.  We use set difference, since we want to ignore
+            # any local additions to "orig_vals" that we've made
+            # (e.g. the "peer_cert_file" key).
+            if set(vals.items()) - set(orig_vals.items()):
                 ipsec.del_entry(vals["local_ip"], vals["remote_ip"])
+            else:
+                continue
 
         try:
             ipsec.add_entry(vals["local_ip"], vals["remote_ip"], vals)
         except error.Error, msg:
-            s_log.warning("skipping ipsec config for %s: %s" % (name, msg))
+            vlog.warn("skipping ipsec config for %s: %s" % (name, msg))
 
 
 def get_ssl_cert(data):
     for ovs_rec in data["Open_vSwitch"].rows.itervalues():
-        ssl = ovs_rec.ssl
-        if ssl and ssl.certificate and ssl.private_key:
-            return (ssl.certificate, ssl.private_key)
+        if ovs_rec.ssl:
+            ssl = ovs_rec.ssl[0]
+            if ssl.certificate and ssl.private_key:
+                return (ssl.certificate, ssl.private_key)
 
     return None
 
@@ -444,12 +429,15 @@ def main():
                         help="Use DIR as alternate root directory"
                         " (for testing).")
 
+    ovs.vlog.add_args(parser)
     ovs.daemon.add_args(parser)
     args = parser.parse_args()
+    ovs.vlog.handle_args(args)
     ovs.daemon.handle_args(args)
 
     global root_prefix
-    root_prefix = args.root_prefix
+    if args.root_prefix:
+        root_prefix = args.root_prefix
 
     remote = args.database
     schema_file = "%s/vswitch.ovsschema" % ovs.dirs.PKGDATADIR
@@ -476,6 +464,7 @@ def main():
             if rec.type == "ipsec_gre":
                 name = rec.name
                 options = rec.options
+                peer_cert_name = "ovs-%s.pem" % (options.get("remote_ip"))
                 entry = {
                     "remote_ip": options.get("remote_ip"),
                     "local_ip": options.get("local_ip", "0.0.0.0/0"),
@@ -483,22 +472,22 @@ def main():
                     "private_key": options.get("private_key"),
                     "use_ssl_cert": options.get("use_ssl_cert"),
                     "peer_cert": options.get("peer_cert"),
+                    "peer_cert_file": Racoon.cert_dir + "/" + peer_cert_name,
                     "psk": options.get("psk")}
 
                 if entry["peer_cert"] and entry["psk"]:
-                    s_log.warning("both 'peer_cert' and 'psk' defined for %s"
-                            % name)
+                    vlog.warn("both 'peer_cert' and 'psk' defined for %s"
+                              % name)
                     continue
                 elif not entry["peer_cert"] and not entry["psk"]:
-                    s_log.warning("no 'peer_cert' or 'psk' defined for %s"
-                            % name)
+                    vlog.warn("no 'peer_cert' or 'psk' defined for %s" % name)
                     continue
 
                 # The "use_ssl_cert" option is deprecated and will
                 # likely go away in the near future.
                 if entry["use_ssl_cert"] == "true":
                     if not ssl_cert:
-                        s_log.warning("no valid SSL entry for %s" % name)
+                        vlog.warn("no valid SSL entry for %s" % name)
                         continue
 
                     entry["certificate"] = ssl_cert[0]
@@ -518,5 +507,5 @@ if __name__ == '__main__':
         # Let system.exit() calls complete normally
         raise
     except:
-        s_log.exception("traceback")
+        vlog.exception("traceback")
         sys.exit(ovs.daemon.RESTART_EXIT_CODE)