From: Leandro Lucarella Date: Sat, 22 Sep 2007 22:44:14 +0000 (-0300) Subject: Implement DhcpdHandler class. X-Git-Url: https://git.llucax.com/software/pymin.git/commitdiff_plain/c7a9496a78002544cf62358c7d098614c0d0d837?ds=sidebyside Implement DhcpdHandler class. A complete example of a handler class. It uses mako for templates and (c)Pickle for configuration persistence. There is some more work to be done (loading pickled configuration and other details) but the class is pretty functional. --- diff --git a/dhcpd/dhcpd.conf b/dhcpd/dhcpd.conf deleted file mode 100644 index 7fe8d65..0000000 --- a/dhcpd/dhcpd.conf +++ /dev/null @@ -1,23 +0,0 @@ -ddns-update-style none; - -option domain-name baryon.com.ar; -option domain-name-servers my_ns1, my_ns2; - -authoritative; - -log-facility local7; - -subnet 192.168.0.0 netmask 255.255.255.0 { - range 192.168.0.100 192.168.0.200; - option routers 192.168.0.1; -} - -host my_name { - fixed-address 192.168.0.192; - hardware ethernet 00:12:ff:56; -} - -host nico { - fixed-address 192.168.0.188; - hardware ethernet 00:00:00:00; -} diff --git a/dhcpd/dhcpd.py b/dhcpd/dhcpd.py deleted file mode 100644 index 6846703..0000000 --- a/dhcpd/dhcpd.py +++ /dev/null @@ -1,121 +0,0 @@ - -import pickle - -class ParamsError(Exception): - def __init__(self,reason): - self.reason = reason - - def __str__(self): - return repr(reason) - -class dhcpd: - "class that handles dhcpd config" - - def __init__(self): - self.host_list = dict() - self.glob = { 'domain_name' : 'my_domain_name', - 'dns_1' : 'my_ns1', - 'dns_2' : 'my_ns2', - 'net_address' : '192.168.0.0', - 'net_mask' : '255.255.255.0', - 'net_start' : '192.168.0.100', - 'net_end' : '192.168.0.200', - 'net_gateway' : '192.168.0.1'} - - - def to_file_format(self): - #bajo los parametros globales - glob_file = open('dhcpd_global.template','r') - glob_tmp = glob_file.read() - glob_file.close() - conf = glob_tmp % self.glob - #bajo los hosts - host_file = open('dhcpd_host.template','r') - host_tmp = host_file.read() - host_file.close() - for h , v in self.host_list.iteritems(): - conf = conf + '\n' + (host_tmp % v) - return conf - - def add_host(self, args): - #deberia indexar por hostname o por ip? - if len(args) == 3: - self.host_list[args[0]] = {"host_name": args[0], "host_ip": args[1], "host_mac": args[2]} - else: - raise ParamsError('Wrong number of parameters') - - def mod_host(self, args): - #deberia indexar por hostname o por ip? - if len(args) == 3: - self.host_list[args[0]] = {"host_name": args[0], "host_ip": args[1], "host_mac": args[2]} - else: - raise ParamsError('Wrong number of parameters') - - def remove_host(self, hostname): - if hostname in self.host_list: - del(self.host_list[hostname]) - else: - raise ParamsError("No such host") - - def set(self, pair): - if pair[0] in self.glob: - self.glob[pair[0]] = pair[1] - else: - raise ParamsError("Parameter " + pair[0] + " not found") - - def start(self): - #esto seria para poner en una interfaz - #y seria el hook para arrancar el servicio - pass - - def stop(self): - #esto seria para poner en una interfaz - #y seria el hook para arrancar el servicio - pass - - def commit(self): - #esto seria para poner en una interfaz - #y seria que hace el pickle deberia llamarse - #al hacerse un commit - output = open('dhcpd_config.pkl', 'wb') - pickle.dump(config, output) - output.close() - - def show_params(self): - string = '' - for k , v in self.glob.iteritems(): - string = string + k + ' : ' + v + '\n' - return string - - def show_hosts(self): - string = '' - for k , v in self.host_list.iteritems(): - string = string + k + ' : ' + v["host_ip"] + ' : ' + v["host_mac"] + '\n' - return string - - -if __name__ == '__main__': - - config = dhcpd() - - try : - arguments = ('my_name','192.168.0.102','00:12:ff:56') - config.add_host(arguments) - - arguments = ('my_name','192.168.0.192','00:12:ff:56') - config.mod_host(arguments) - - arguments = ('nico','192.168.0.188','00:00:00:00') - config.add_host(arguments) - - config.set(('domain_name','baryon.com.ar')) - config.set(('sarasa','baryon.com.ar')) - - except ParamsError, inst: - print inst.reason - - config.commit() - - conf_file = open('dhcpd.conf','w') - conf_file.write(config.to_file_format()) - conf_file.close() diff --git a/dhcpd/dhcpd_config.pkl b/dhcpd/dhcpd_config.pkl deleted file mode 100644 index 57f614e..0000000 --- a/dhcpd/dhcpd_config.pkl +++ /dev/null @@ -1,68 +0,0 @@ -(i__main__ -dhcpd -p0 -(dp1 -S'glob' -p2 -(dp3 -S'net_end' -p4 -S'192.168.0.200' -p5 -sS'net_mask' -p6 -S'255.255.255.0' -p7 -sS'domain_name' -p8 -S'baryon.com.ar' -p9 -sS'dns_1' -p10 -S'my_ns1' -p11 -sS'dns_2' -p12 -S'my_ns2' -p13 -sS'net_start' -p14 -S'192.168.0.100' -p15 -sS'net_gateway' -p16 -S'192.168.0.1' -p17 -sS'net_address' -p18 -S'192.168.0.0' -p19 -ssS'host_list' -p20 -(dp21 -S'my_name' -p22 -(dp23 -S'host_name' -p24 -g22 -sS'host_mac' -p25 -S'00:12:ff:56' -p26 -sS'host_ip' -p27 -S'192.168.0.192' -p28 -ssS'nico' -p29 -(dp30 -g24 -g29 -sg25 -S'00:00:00:00' -p31 -sg27 -S'192.168.0.188' -p32 -sssb. \ No newline at end of file diff --git a/dhcpd/dhcpd_global.template b/dhcpd/dhcpd_global.template deleted file mode 100644 index 6f1f2fd..0000000 --- a/dhcpd/dhcpd_global.template +++ /dev/null @@ -1,13 +0,0 @@ -ddns-update-style none; - -option domain-name %(domain_name)s; -option domain-name-servers %(dns_1)s, %(dns_2)s; - -authoritative; - -log-facility local7; - -subnet %(net_address)s netmask %(net_mask)s { - range %(net_start)s %(net_end)s; - option routers %(net_gateway)s; -} diff --git a/dhcpd/dhcpd_host.template b/dhcpd/dhcpd_host.template deleted file mode 100644 index edd99d9..0000000 --- a/dhcpd/dhcpd_host.template +++ /dev/null @@ -1,4 +0,0 @@ -host %(host_name)s { - fixed-address %(host_ip)s; - hardware ethernet %(host_mac)s; -} diff --git a/services/dhcp/__init__.py b/services/dhcp/__init__.py new file mode 100644 index 0000000..941bccf --- /dev/null +++ b/services/dhcp/__init__.py @@ -0,0 +1,125 @@ +# vim: set encoding=utf-8 et sw=4 sts=4 : + +try: + import cPickle as pickle +except ImportError: + import pickle + +from mako.template import Template +from mako.runtime import Context + +class Host: + def __init__(self, name, ip, mac): + self.name = name + self.ip = ip + self.mac = mac + def __repr__(self): + return 'Host(name="%s", ip="%s", mac="%s")' % ( + self.name, self.ip, self.mac) + +class HostHandler: + + def __init__(self, hosts): + self.hosts = hosts + + def add(self, name, ip, mac): + #deberia indexar por hostname o por ip? o por mac? :) + # Mejor por nada... + self.hosts[name] = Host(name, ip, mac) + + def update(self, name, ip=None, mac=None): + if ip is not None: + self.hosts[name].ip = ip + if mac is not None: + self.hosts[name].mac = mac + + def delete(self, name): + del self.hosts[name] + + def list(self): + return ','.join(self.hosts) + + def show(self): + hosts = self.hosts.values() + return '\n'.join('%s,%s,%s' % (h.name, h.ip, h.mac) for h in hosts) + +class DhcpHandler: + r"""class that handles DHCP service using dhcpd program""" + + def __init__(self): + self.hosts = dict() + self.vars = dict( + domain_name = 'my_domain_name', + dns_1 = 'my_ns1', + dns_2 = 'my_ns2', + net_address = '192.168.0.0', + net_mask = '255.255.255.0', + net_start = '192.168.0.100', + net_end = '192.168.0.200', + net_gateway = '192.168.0.1', + ) + self.host = HostHandler(self.hosts) + + def set(self, param, value): + if param in self.vars: + self.vars[param] = value + else: + raise KeyError("Parameter " + param + " not found") + + def list(self): + return ','.join(self.vars) + + def show(self): + return '\n'.join(('%s,%s' % (k, v) for (k, v) in self.vars.items())) + + def start(self): + #esto seria para poner en una interfaz + #y seria el hook para arrancar el servicio + pass + + def stop(self): + #esto seria para poner en una interfaz + #y seria el hook para arrancar el servicio + pass + + def commit(self): + #esto seria para poner en una interfaz + #y seria que hace el pickle deberia llamarse + #al hacerse un commit + pickle.dump(self.vars, file('pickled/vars.pkl', 'wb'), 2) + pickle.dump(self.hosts, file('pickled/hosts.pkl', 'wb'), 2) + tpl = Template(filename='templates/dhcpd.conf') + ctx = Context(file('generated/dhcpd.conf', 'w'), + hosts=self.hosts.values(), **self.vars) + tpl.render_context(ctx) + +if __name__ == '__main__': + + config = DhcpHandler() + + config.host.add('my_name','192.168.0.102','00:12:ff:56') + + config.host.update('my_name','192.168.0.192','00:12:ff:56') + + config.host.add('nico','192.168.0.188','00:00:00:00') + + config.set('domain_name','baryon.com.ar') + + try: + config.set('sarasa','baryon.com.ar') + except KeyError, e: + print 'Error:', e + + config.commit() + + print 'Variables:', config.list() + print config.show() + + print 'Hosts:', config.host.list() + print config.host.show() + + vars = pickle.load(file('pickled/vars.pkl')) + hosts = pickle.load(file('pickled/hosts.pkl')) + print 'Pickled vars:', vars + print 'Pickled hosts:', hosts + diff --git a/services/dhcp/templates/dhcpd.conf b/services/dhcp/templates/dhcpd.conf new file mode 100644 index 0000000..19e43ab --- /dev/null +++ b/services/dhcp/templates/dhcpd.conf @@ -0,0 +1,22 @@ + +ddns-update-style none; + +option domain-name ${domain_name}; +option domain-name-servers ${dns_1}, ${dns_2}; + +authoritative; + +log-facility local7; + +subnet ${net_address} netmask ${net_mask} { + range ${net_start} ${net_end}; + option routers ${net_gateway}; +} + +% for host in hosts: +host ${host.name} { + fixed-address ${host.ip}; + hardware ethernet ${host.mac}; +} + +% endfor