diff --git a/systemvm/patches/debian/config/opt/cloud/bin/CsDhcp.py b/systemvm/patches/debian/config/opt/cloud/bin/CsDhcp.py new file mode 100644 index 00000000000..a821c332d89 --- /dev/null +++ b/systemvm/patches/debian/config/opt/cloud/bin/CsDhcp.py @@ -0,0 +1,115 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +import CsHelper +from pprint import pprint +import logging + +NO_PRELOAD = False +LEASES = "/var/lib/misc/dnsmasq.leases" +DHCP_HOSTS = "/etc/dhcphosts.txt" + +""" + "172.16.1.102": { + "default_entry": true, + "default_gateway": "172.16.1.1", + "host_name": "VM-58976c22-0832-451e-9ab2-039e9f27e415", + "ipv4_adress": "172.16.1.102", + "ipv6_duid": "00:03:00:01:02:00:26:c3:00:02", + "mac_address": "02:00:26:c3:00:02", + "type": "dhcpentry" + }, +""" +class CsDhcp(object): + """ Manage dhcp entries """ + + def __init__(self, dbag, cl): + dnsmasq = CsDnsMasq() + for item in dbag: + if item == "id": + continue + dnsmasq.add(dbag[item]) + dnsmasq.collect_leases() + dnsmasq.to_str() + dnsmasqb4 = CsDnsMasq(NO_PRELOAD) + dnsmasqb4.parse_hosts() + if not dnsmasq.compare_hosts(dnsmasqb4): + dnsmasq.write_hosts() + else: + logging.debug("Hosts file is up to date") + + +class CsDnsMasq(object): + + def __init__(self, preload = True): + self.list = [] + self.hosts = [] + self.leases = [] + if preload: + self.add_host("127.0.0.1", "localhost") + self.add_host("::1", "localhost ip6-localhost ip6-loopback") + self.add_host("ff02::1", "ip6-allnodes") + self.add_host("ff02::2", "ip6-allrouters") + self.add_host("127.0.0.1", CsHelper.get_hostname()) + + def collect_leases(self): + # Format is + # 0 02:00:56:aa:00:03 10.1.1.18 pup * + try: + for line in open(LEASES): + bits = line.strip().split(' ') + to = { "device" : bits[0], + "mac" : bits[1], + "ip" : bits[2], + "host" : bits[3] + } + self.leases.append(to) + except IOError: + pass + + def parse_hosts(self): + for line in open("/etc/hosts"): + line = line.rstrip().lstrip() + if line == '': + continue + if line.startswith("#"): + continue + bits = ' '.join(line.split()).split(' ', 1) + self.add_host(bits[0], bits[1]) + + def compare_hosts(self, obj): + return set(self.hosts) == set(obj.hosts) + + def write_hosts(self): + logging.debug("Updating hosts file with new entry") + handle = open("/etc/hosts", 'w+') + for line in self.hosts: + handle.write("%s\n" % line) + handle.close() + + def add(self,entry): + self.add_host(entry['ipv4_adress'], entry['host_name']) + self.add_dnsmasq(entry['ipv4_adress'], entry['host_name'], entry['mac_address']) + + def add_dnsmasq(self, ip, host, mac): + self.list.append("%s,%s,%s,infinite" % (mac, ip, host)) + + def add_host(self, ip, host): + self.hosts.append("%s\t%s" % (ip, host)) + + def to_str(self): + pprint(self.hosts) + pprint(self.list) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/CsHelper.py b/systemvm/patches/debian/config/opt/cloud/bin/CsHelper.py index e040c00f73e..e2efc5d0d37 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/CsHelper.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/CsHelper.py @@ -32,6 +32,10 @@ def addifmissing(filename, val): updatefile(filename, val + "\n", "a") logging.debug("Added %s to file %s" % (val, filename)) +def get_hostname(): + for line in open("/etc/hostname"): + return line.strip() + def execute(command): """ Execute command """ p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index e060d944c15..5f8c09e3362 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -25,10 +25,10 @@ import re import time import shutil import os.path -from cs_ip import merge import CsHelper from CsNetfilter import CsNetfilters from fcntl import flock, LOCK_EX, LOCK_UN +from CsDhcp import CsDhcp fw = [] @@ -523,13 +523,52 @@ class CsDataBag(object): self.dbag = db.getDataBag() global fw + def get_bag(self): + return self.dbag + def process(self): pass +class CsCmdLine(CsDataBag): + """ Get cmdline config parameters """ + def is_redundant(self): + if "redundant" in self.dbag['config']: + return self.dbag['config']['redundant'] == "true" + return False + class CsAcl(CsDataBag): + """ + Deal with Network acls + """ + class AclDevice(): + """ A little class for each list of acls per device """ + + def __init__(self, obj): + self.ingess = [] + self.egress = [] + self.device = obj['device'] + self.ip = obj['nic_ip'] + self.netmask= obj['nic_netmask'] + self.cidr = "%s/%s" % (self.ip, self.netmask) + if "ingress_rules" in obj.keys(): + self.ingress = obj['ingress_rules'] + if "egress_rules" in obj.keys(): + self.egress = obj['egress_rules'] + + def create(self): + self.process(self.ingress) + self.process(self.egress) + + def process(self,rule_list): + for i in rule_list: + pprint(i) def process(self): - pass + for item in self.dbag: + if item == "id": + continue + dev_obj = self.AclDevice(self.dbag[item]).create() + class CsPassword(CsDataBag): """ @@ -737,7 +776,9 @@ def main(argv): logging.basicConfig(filename='/var/log/cloud.log', level=logging.DEBUG, format='%(asctime)s %(message)s') - + + cl = CsCmdLine("cmdline") + address = CsAddress("ips") address.compare() address.process() @@ -754,5 +795,8 @@ def main(argv): nf = CsNetfilters() nf.compare(fw) + acls = CsDataBag("dhcpentry") + dhcp = CsDhcp(acls.get_bag(), cl) + if __name__ == "__main__": main(sys.argv) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs_cmdline.py b/systemvm/patches/debian/config/opt/cloud/bin/cs_cmdline.py index f37dacf58fd..86c007f0168 100644 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs_cmdline.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs_cmdline.py @@ -1,5 +1,9 @@ from pprint import pprint def merge(dbag, cmdline): - dbag['config'] = cmdline + if 'redundant' in cmdline['cmd_line']: + cmdline['cmd_line']['redundant'] = "true" + else: + cmdline['cmd_line']['redundant'] = "false" + dbag['config'] = cmdline['cmd_line'] return dbag diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs_dhcp.py b/systemvm/patches/debian/config/opt/cloud/bin/cs_dhcp.py new file mode 100644 index 00000000000..ebbaa1cb753 --- /dev/null +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs_dhcp.py @@ -0,0 +1,9 @@ +from pprint import pprint +from netaddr import * + +def merge(dbag, data): + + # A duplicate ip address wil clobber the old value + # This seems desirable .... + dbag[data['ipv4_adress']] = data + return dbag diff --git a/systemvm/patches/debian/config/opt/cloud/bin/merge.py b/systemvm/patches/debian/config/opt/cloud/bin/merge.py index 65957d128ba..57a57b7eba9 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/merge.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/merge.py @@ -10,6 +10,7 @@ import cs_cmdline import cs_vmp import cs_network_acl import cs_vmdata +import cs_dhcp from pprint import pprint @@ -81,6 +82,8 @@ class updateDataBag: dbag = self.process_network_acl(self.db.getDataBag()) elif self.qFile.type == 'vmdata': dbag = self.processVmData(self.db.getDataBag()) + elif self.qFile.type == 'dhcpentry': + dbag = self.process_dhcp_entry(self.db.getDataBag()) else: logging.error("Error I do not know what to do with file of type %s", self.qFile.type) return @@ -103,6 +106,9 @@ class updateDataBag: d['domain_name'] = "cloudnine.internal" return cs_guestnetwork.merge(dbag, self.qFile.data) + def process_dhcp_entry(self, dbag): + return cs_dhcp.merge(dbag, self.qFile.data) + def process_network_acl(self, dbag): return cs_network_acl.merge(dbag, self.qFile.data) diff --git a/systemvm/patches/debian/config/opt/cloud/testdata/dhcp0001.json b/systemvm/patches/debian/config/opt/cloud/testdata/dhcp0001.json new file mode 100644 index 00000000000..9f7d3aaf859 --- /dev/null +++ b/systemvm/patches/debian/config/opt/cloud/testdata/dhcp0001.json @@ -0,0 +1,9 @@ +{ + "host_name":"VM-58976c22-0832-451e-9ab2-039e9f27e415", + "mac_address":"02:00:26:c3:00:02", + "ipv4_adress":"172.16.1.102", + "ipv6_duid":"00:03:00:01:02:00:26:c3:00:02", + "default_gateway":"172.16.1.1", + "default_entry":true, + "type":"dhcpentry" +}