# adding an interface to racoon.conf.
-import getopt
+import argparse
import glob
-import logging
-import logging.handlers
import os
-import socket
import subprocess
import sys
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)
-
+vlog = ovs.vlog.Vlog("ovs-monitor-ipsec")
+root_prefix = '' # Prefix for absolute file names, for testing.
setkey = "/usr/sbin/setkey"
self.psk_hosts = {}
self.cert_hosts = {}
- if not os.path.isdir(self.cert_dir):
+ if not os.path.isdir(root_prefix + self.cert_dir):
os.mkdir(self.cert_dir)
# Clean out stale peer certs from previous runs
- for ovs_cert in glob.glob("%s/ovs-*.pem" % self.cert_dir):
+ for ovs_cert in glob.glob("%s%s/ovs-*.pem"
+ % (root_prefix, self.cert_dir)):
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()
def reload(self):
- exitcode = subprocess.call(["/etc/init.d/racoon", "reload"])
+ exitcode = subprocess.call([root_prefix + "/etc/init.d/racoon",
+ "reload"])
if exitcode != 0:
# Racoon is finicky about its configuration file and will
# 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")
- exitcode = subprocess.call(["/etc/init.d/racoon", "restart"])
+ 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
- conf_file = open(self.conf_file, 'w')
+ conf_file = open(root_prefix + self.conf_file, 'w')
conf_file.write(Racoon.conf_header % (self.psk_file, self.cert_dir))
for host, vals in self.cert_hosts.iteritems():
# Rewrite the pre-shared keys file; it must only be readable by root.
orig_umask = os.umask(0077)
- psk_file = open(Racoon.psk_file, 'w')
+ psk_file = open(root_prefix + Racoon.psk_file, 'w')
os.umask(orig_umask)
psk_file.write("# Generated by Open vSwitch...do not modify by hand!")
def _verify_certs(self, vals):
# Racoon will refuse to start if the certificate files don't
# exist, so verify that they're there.
- if not os.path.isfile(vals["certificate"]):
+ if not os.path.isfile(root_prefix + vals["certificate"]):
raise error.Error("'certificate' file does not exist: %s"
% vals["certificate"])
- elif not os.path.isfile(vals["private_key"]):
+ elif not os.path.isfile(root_prefix + vals["private_key"]):
raise error.Error("'private_key' file does not exist: %s"
% vals["private_key"])
if vals["peer_cert"].find("-----BEGIN CERTIFICATE-----") == -1:
raise error.Error("'peer_cert' is not in valid PEM format")
- cert = open(vals["certificate"]).read()
+ cert = open(root_prefix + vals["certificate"]).read()
if cert.find("-----BEGIN CERTIFICATE-----") == -1:
raise error.Error("'certificate' is not in valid PEM format")
- cert = open(vals["private_key"]).read()
+ cert = open(root_prefix + vals["private_key"]).read()
if cert.find("-----BEGIN RSA PRIVATE KEY-----") == -1:
raise error.Error("'private_key' is not in valid PEM format")
# 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(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()
del self.cert_hosts[host]
self.commit()
try:
- os.remove(peer_cert_file)
+ os.remove(root_prefix + peer_cert_file)
except OSError:
pass
def call_setkey(self, cmds):
try:
- p = subprocess.Popen([setkey, "-c"], stdin=subprocess.PIPE,
- stdout=subprocess.PIPE)
+ p = subprocess.Popen([root_prefix + setkey, "-c"],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
except:
- s_log.error("could not call 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()
# older entry could be in a "dying" state.
spi_list = []
host_line = "%s %s" % (local_ip, remote_ip)
- results = self.call_setkey("dump ;").split("\n")
+ results = self.call_setkey("dump ;\n").split("\n")
for i in range(len(results)):
if results[i].strip() == host_line:
# The SPI is in the line following the host pair
return spi_list
def sad_flush(self):
- self.call_setkey("flush;")
+ self.call_setkey("flush;\n")
def sad_del(self, local_ip, remote_ip):
# To delete all SAD entries, we should be able to use setkey's
self.call_setkey(cmds)
def spd_flush(self):
- self.call_setkey("spdflush;")
+ self.call_setkey("spdflush;\n")
def spd_add(self, local_ip, remote_ip):
cmds = ("spdadd %s %s gre -P out ipsec esp/transport//require;\n" %
(local_ip, remote_ip))
- cmds += ("spdadd %s %s gre -P in ipsec esp/transport//require;" %
+ cmds += ("spdadd %s %s gre -P in ipsec esp/transport//require;\n" %
(remote_ip, local_ip))
self.call_setkey(cmds)
def spd_del(self, local_ip, remote_ip):
cmds = "spddelete %s %s gre -P out;\n" % (local_ip, remote_ip)
- cmds += "spddelete %s %s gre -P in;" % (remote_ip, local_ip)
+ cmds += "spddelete %s %s gre -P in;\n" % (remote_ip, local_ip)
self.call_setkey(cmds)
def add_entry(self, local_ip, remote_ip, vals):
schema.tables = new_tables
-def usage():
- print "usage: %s [OPTIONS] DATABASE" % sys.argv[0]
- print "where DATABASE is a socket on which ovsdb-server is listening."
- ovs.daemon.usage()
- print "Other options:"
- print " -h, --help display this help message"
- sys.exit(0)
-
-
def update_ipsec(ipsec, interfaces, new_interfaces):
for name, vals in interfaces.iteritems():
if name not in new_interfaces:
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
-def main(argv):
- try:
- options, args = getopt.gnu_getopt(
- argv[1:], 'h', ['help'] + ovs.daemon.LONG_OPTIONS)
- except getopt.GetoptError, geo:
- sys.stderr.write("%s: %s\n" % (ovs.util.PROGRAM_NAME, geo.msg))
- sys.exit(1)
-
- for key, value in options:
- if key in ['-h', '--help']:
- usage()
- elif not ovs.daemon.parse_opt(key, value):
- sys.stderr.write("%s: unhandled option %s\n"
- % (ovs.util.PROGRAM_NAME, key))
- sys.exit(1)
+def main():
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument("database", metavar="DATABASE",
+ help="A socket on which ovsdb-server is listening.")
+ parser.add_argument("--root-prefix", metavar="DIR",
+ help="Use DIR as alternate root directory"
+ " (for testing).")
- if len(args) != 1:
- sys.stderr.write("%s: exactly one nonoption argument is required "
- "(use --help for help)\n" % ovs.util.PROGRAM_NAME)
- sys.exit(1)
+ ovs.vlog.add_args(parser)
+ ovs.daemon.add_args(parser)
+ args = parser.parse_args()
+ ovs.vlog.handle_args(args)
+ ovs.daemon.handle_args(args)
- remote = args[0]
+ global root_prefix
+ if args.root_prefix:
+ root_prefix = args.root_prefix
+ remote = args.database
schema_file = "%s/vswitch.ovsschema" % ovs.dirs.PKGDATADIR
schema = ovs.db.schema.DbSchema.from_json(ovs.json.from_file(schema_file))
prune_schema(schema)
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"),
"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]
if __name__ == '__main__':
try:
- main(sys.argv)
+ main()
except SystemExit:
# Let system.exit() calls complete normally
raise
except:
- s_log.exception("traceback")
+ vlog.exception("traceback")
sys.exit(ovs.daemon.RESTART_EXIT_CODE)