Commit dd6277d7 authored by Sigmund Augdal's avatar Sigmund Augdal

Added rudimentary dhcp config generator.

parent 2a2313ce
#!/usr/bin/env python
import etcd
import os
import os.path
import subprocess
import logging
import logging.handlers
import time
import argparse
import daemon
import socket
try:
from daemon.pidfile import TimeoutPIDLockFile
except ImportError:
from daemon.pidlockfile import TimeoutPIDLockFile
CONF_FILE = "/etc/haproxy/haproxy.cfg"
def etcd_get_dict(etcd_client, prefix):
result = dict()
for key in etcd_client.list(prefix):
if not key.dir:
result[key.key.split('/')[-1]] = key.value
return result
def etcd_get_dirs(etcd_client, prefix):
result = set()
for key in etcd_client.list(prefix):
if key.dir:
result.add(key.key.split('/')[-1])
return result
class Generator(object):
def __init__(self, cert, key, cacert, logfile=None):
self.etcd_client = etcd.Etcd(ssl_key=key, ssl_cert=cert, verify=cacert)
if logfile:
logging.getLogger("").addHandler(logging.handlers.RotatingFileHandler(logfile, maxBytes=10*1024**3, backupCount=5))
self.range = [150, 200]
self.prefix = "158.38.213."
def format_ip(self, i):
return self.prefix + str(i)
def next_free(self, i, hosts):
while self.format_ip(i) in hosts and i <= self.range[1]:
i += 1
if i > self.range[1]:
return None
return i
def next_used(self, i, hosts):
while self.format_ip(i) not in hosts and i <= self.range[1]:
i += 1
if i > self.range[1]:
return None
return i
def format_host(self, ipaddress, mac):
host = mac.replace(":", "")
return """host instance{} {{
hardware ethernet {};
fixed-address {};
}}
""".format(host, mac, ipaddress)
def generate(self, hosts):
result = ""
range_start = self.next_free(self.range[0], hosts)
while range_start:
logging.debug("generating for range from %d", range_start)
next_host = self.next_used(range_start + 1, hosts)
if next_host is None:
range_end = range_start
else:
range_end = next_host - 1
result += "range {} {};\n".format(self.format_ip(range_start),
self.format_ip(range_end))
range_start = self.next_free(range_end + 1, hosts)
for ipaddress, mac in sorted(hosts.items(), key=lambda x: socket.inet_aton(x[0])):
result += self.format_host(ipaddress, mac)
return result
def generate_all(self):
index = None
hosts = {}
for entry in self.etcd_client.list("/nova/iaas/instances"):
if not entry.dir:
next
if not index:
index = entry.index
mac = entry.key.split("/")[-1]
try:
ipaddress = self.etcd_client.get(entry.key + "/ipv4").value
hosts[ipaddress] = mac
except etcd.EtcdError as ex:
if ex.args[0] != 100:
raise ex
print self.generate(hosts)
return index
def main(self):
index = self.generate_all()
while True:
data = self.etcd_client.watch("/nova/iaas/instances", index+1)
logging.debug("new config index %d", data.index)
time.sleep(1)
index = self.generate_all()
def parse_args():
parser = argparse.ArgumentParser(description="Configure haproxy based on data from etcd")
parser.add_argument('-d', '--daemonize', default=False, action='store_true', help="Run as daemon")
parser.add_argument('--pidfile', type=str, default="/var/run/nova_lb_configuration.pid", help="pidfile when run as daemon")
parser.add_argument('--cert', default="client.crt", help="client certificate to use")
parser.add_argument('--key', default="client.key", help="private key to use for client certificate")
parser.add_argument('--cacert', default="etcd_ca.crt", help="ca certificate to use")
return parser.parse_args()
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
logging.getLogger("requests").setLevel(logging.WARNING)
args = parse_args()
if args.daemonize:
logfile='/var/log/nova_loadbalancer_configurator.log'
daemon_context = daemon.DaemonContext(pidfile=TimeoutPIDLockFile(args.pidfile))
with daemon_context:
Generator(args.cert, args.key, args.cacert, logfile=logfile).main()
else:
Generator(args.cert, args.key, args.cacert).main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment