# vim: set encoding=utf-8 et sw=4 sts=4 :
-from os import path
-import logging ; log = logging.getLogger('pymin.services.dhcp')
-
-from pymin.seqtools import Sequence
-from pymin.dispatcher import Handler, handler, HandlerError
-from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
- TransactionalHandler, ParametersHandler, \
- DictSubHandler, ReloadHandler
-
-__all__ = ('DhcpHandler', 'get_service')
-
+from handler import DhcpHandler
def get_service(config):
return DhcpHandler(config.dhcp.pickle_dir, config.dhcp.config_dir)
-
-class Host(Sequence):
- r"""Host(name, ip, mac) -> Host instance :: Class representing a host.
-
- name - Host name, should be a fully qualified name, but no checks are done.
- ip - IP assigned to the hostname.
- mac - MAC address to associate to the hostname.
- """
-
- def __init__(self, name, ip, mac):
- r"Initialize Host object, see class documentation for details."
- self.name = name
- self.ip = ip
- self.mac = mac
-
- def as_tuple(self):
- r"Return a tuple representing the host."
- return (self.name, self.ip, self.mac)
-
- def update(self, ip=None, mac=None):
- if ip is not None:
- self.ip = ip
- if mac is not None:
- self.mac = mac
-
-class HostHandler(DictSubHandler):
- r"""HostHandler(parent) -> HostHandler instance :: Handle a list of hosts.
-
- This class is a helper for DhcpHandler to do all the work related to hosts
- administration.
- """
-
- handler_help = u"Manage DHCP hosts"
-
- _cont_subhandler_attr = 'hosts'
- _cont_subhandler_class = Host
-
-class DhcpHandler(Restorable, ConfigWriter, ReloadHandler, TransactionalHandler,
- ParametersHandler, InitdHandler):
- r"""DhcpHandler([pickle_dir[, config_dir]]) -> DhcpHandler instance.
-
- Handles DHCP service commands for the dhcpd program.
-
- pickle_dir - Directory where to write the persistent configuration data.
-
- config_dir - Directory where to store de generated configuration files.
-
- Both defaults to the current working directory.
- """
-
- handler_help = u"Manage DHCP service"
-
- _initd_name = 'dhcpd'
-
- _persistent_attrs = ('params', 'hosts')
-
- _restorable_defaults = dict(
- hosts = dict(),
- params = dict(
- domain_name = 'example.com',
- dns_1 = 'ns1.example.com',
- dns_2 = 'ns2.example.com',
- 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',
- ),
- )
-
- _config_writer_files = 'dhcpd.conf'
- _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
-
- def __init__(self, pickle_dir='.', config_dir='.'):
- r"Initialize DhcpHandler object, see class documentation for details."
- log.debug(u'DhcpHandler(%r, %r)', pickle_dir, config_dir)
- self._persistent_dir = pickle_dir
- self._config_writer_cfg_dir = config_dir
- self._config_build_templates()
- InitdHandler.__init__(self)
- self.host = HostHandler(self)
-
- def _get_config_vars(self, config_file):
- return dict(hosts=self.hosts.values(), **self.params)
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- import os
-
- h = DhcpHandler()
-
- def dump():
- print '-' * 80
- print 'Variables:', h.list()
- print h.show()
- print
- print 'Hosts:', h.host.list()
- print h.host.show()
- print '-' * 80
-
- dump()
-
- h.host.add('my_name','192.168.0.102','00:12:ff:56')
-
- h.host.update('my_name','192.168.0.192','00:12:ff:56')
-
- h.host.add('nico','192.168.0.188','00:00:00:00')
-
- h.set('domain_name','baryon.com.ar')
-
- try:
- h.set('sarasa','baryon.com.ar')
- except KeyError, e:
- print 'Error:', e
-
- h.commit()
-
- dump()
-
- os.system('rm -f *.pkl ' + ' '.join(h._config_writer_files))
-
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+from os import path
+import logging ; log = logging.getLogger('pymin.services.dhcp')
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import Handler, handler, HandlerError
+from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
+ TransactionalHandler, ParametersHandler, \
+ DictSubHandler, ReloadHandler
+
+__all__ = ('DhcpHandler', 'get_service')
+
+
+def get_service(config):
+ return DhcpHandler(config.dhcp.pickle_dir, config.dhcp.config_dir)
+
+
+class Host(Sequence):
+ r"""Host(name, ip, mac) -> Host instance :: Class representing a host.
+
+ name - Host name, should be a fully qualified name, but no checks are done.
+ ip - IP assigned to the hostname.
+ mac - MAC address to associate to the hostname.
+ """
+
+ def __init__(self, name, ip, mac):
+ r"Initialize Host object, see class documentation for details."
+ self.name = name
+ self.ip = ip
+ self.mac = mac
+
+ def as_tuple(self):
+ r"Return a tuple representing the host."
+ return (self.name, self.ip, self.mac)
+
+ def update(self, ip=None, mac=None):
+ if ip is not None:
+ self.ip = ip
+ if mac is not None:
+ self.mac = mac
+
+class HostHandler(DictSubHandler):
+ r"""HostHandler(parent) -> HostHandler instance :: Handle a list of hosts.
+
+ This class is a helper for DhcpHandler to do all the work related to hosts
+ administration.
+ """
+
+ handler_help = u"Manage DHCP hosts"
+
+ _cont_subhandler_attr = 'hosts'
+ _cont_subhandler_class = Host
+
+class DhcpHandler(Restorable, ConfigWriter, ReloadHandler, TransactionalHandler,
+ ParametersHandler, InitdHandler):
+ r"""DhcpHandler([pickle_dir[, config_dir]]) -> DhcpHandler instance.
+
+ Handles DHCP service commands for the dhcpd program.
+
+ pickle_dir - Directory where to write the persistent configuration data.
+
+ config_dir - Directory where to store de generated configuration files.
+
+ Both defaults to the current working directory.
+ """
+
+ handler_help = u"Manage DHCP service"
+
+ _initd_name = 'dhcpd'
+
+ _persistent_attrs = ('params', 'hosts')
+
+ _restorable_defaults = dict(
+ hosts = dict(),
+ params = dict(
+ domain_name = 'example.com',
+ dns_1 = 'ns1.example.com',
+ dns_2 = 'ns2.example.com',
+ 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',
+ ),
+ )
+
+ _config_writer_files = 'dhcpd.conf'
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='.'):
+ r"Initialize DhcpHandler object, see class documentation for details."
+ log.debug(u'DhcpHandler(%r, %r)', pickle_dir, config_dir)
+ self._persistent_dir = pickle_dir
+ self._config_writer_cfg_dir = config_dir
+ self._config_build_templates()
+ InitdHandler.__init__(self)
+ self.host = HostHandler(self)
+
+ def _get_config_vars(self, config_file):
+ return dict(hosts=self.hosts.values(), **self.params)
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ import os
+
+ h = DhcpHandler()
+
+ def dump():
+ print '-' * 80
+ print 'Variables:', h.list()
+ print h.show()
+ print
+ print 'Hosts:', h.host.list()
+ print h.host.show()
+ print '-' * 80
+
+ dump()
+
+ h.host.add('my_name','192.168.0.102','00:12:ff:56')
+
+ h.host.update('my_name','192.168.0.192','00:12:ff:56')
+
+ h.host.add('nico','192.168.0.188','00:00:00:00')
+
+ h.set('domain_name','baryon.com.ar')
+
+ try:
+ h.set('sarasa','baryon.com.ar')
+ except KeyError, e:
+ print 'Error:', e
+
+ h.commit()
+
+ dump()
+
+ os.system('rm -f *.pkl ' + ' '.join(h._config_writer_files))
+
# vim: set encoding=utf-8 et sw=4 sts=4 :
-# TODO COMMENT
-from os import path
-from os import unlink
-import logging ; log = logging.getLogger('pymin.services.dns')
-
-from pymin.seqtools import Sequence
-from pymin.dispatcher import handler, HandlerError, Handler
-from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
- TransactionalHandler, ParametersHandler, \
- DictComposedSubHandler, DictSubHandler, call
-
-__all__ = ('DnsHandler', 'get_service')
-
+from handler import DnsHandler
def get_service(config):
return DnsHandler(config.dns.pickle_dir, config.dns.config_dir)
-
-class Host(Sequence):
- def __init__(self, name, ip):
- self.name = name
- self.ip = ip
- def update(self, ip=None):
- if ip is not None: self.ip = ip
- def as_tuple(self):
- return (self.name, self.ip)
-
-class HostHandler(DictComposedSubHandler):
- handler_help = u"Manage DNS hosts"
- _comp_subhandler_cont = 'zones'
- _comp_subhandler_attr = 'hosts'
- _comp_subhandler_class = Host
-
-class MailExchange(Sequence):
- def __init__(self, mx, prio):
- self.mx = mx
- self.prio = prio
- def update(self, prio=None):
- if prio is not None: self.prio = prio
- def as_tuple(self):
- return (self.mx, self.prio)
-
-class MailExchangeHandler(DictComposedSubHandler):
- handler_help = u"Manage DNS mail exchangers (MX)"
- _comp_subhandler_cont = 'zones'
- _comp_subhandler_attr = 'mxs'
- _comp_subhandler_class = MailExchange
-
-class NameServer(Sequence):
- def __init__(self, name):
- self.name = name
- def as_tuple(self):
- return (self.name,)
-
-class NameServerHandler(DictComposedSubHandler):
- handler_help = u"Manage DNS name servers (NS)"
- _comp_subhandler_cont = 'zones'
- _comp_subhandler_attr = 'nss'
- _comp_subhandler_class = NameServer
-
-class Zone(Sequence):
- def __init__(self, name):
- self.name = name
- self.hosts = dict()
- self.mxs = dict()
- self.nss = dict()
- self._add = False
- self._update = False
- self._delete = False
- def as_tuple(self):
- return (self.name, self.hosts, self.mxs, self.nss)
-
-class ZoneHandler(DictSubHandler):
- handler_help = u"Manage DNS zones"
- _cont_subhandler_attr = 'zones'
- _cont_subhandler_class = Zone
-
-class DnsHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler,
- ParametersHandler):
- r"""DnsHandler([pickle_dir[, config_dir]]) -> DnsHandler instance.
-
- Handles DNS service commands for the dns program.
-
- pickle_dir - Directory where to write the persistent configuration data.
-
- config_dir - Directory where to store de generated configuration files.
-
- Both defaults to the current working directory.
- """
-
- handler_help = u"Manage DNS service"
-
- _initd_name = 'named'
-
- _persistent_attrs = ('params', 'zones')
-
- _restorable_defaults = dict(
- zones = dict(),
- params = dict(
- isp_dns1 = '',
- isp_dns2 = '',
- bind_addr1 = '',
- bind_addr2 = ''
- ),
- )
-
- _config_writer_files = ('named.conf', 'zoneX.zone')
- _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
-
- def __init__(self, pickle_dir='.', config_dir='.'):
- r"Initialize DnsHandler object, see class documentation for details."
- log.debug(u'DnsHandler(%r, %r)', pickle_dir, config_dir)
- self._persistent_dir = pickle_dir
- self._config_writer_cfg_dir = config_dir
- self._update = False
- self._config_build_templates()
- InitdHandler.__init__(self)
- self.host = HostHandler(self)
- self.zone = ZoneHandler(self)
- self.mx = MailExchangeHandler(self)
- self.ns = NameServerHandler(self)
-
- def _zone_filename(self, zone):
- return zone.name + '.zone'
-
- def _get_config_vars(self, config_file):
- return dict(zones=self.zones.values(), **self.params)
-
- def _write_config(self):
- r"_write_config() -> None :: Generate all the configuration files."
- log.debug(u'DnsHandler._write_config()')
- delete_zones = list()
- for a_zone in self.zones.values():
- log.debug(u'DnsHandler._write_config: processing zone %s', a_zone)
- if a_zone._update or a_zone._add:
- if not a_zone._add and self._service_running:
- log.debug(u'DnsHandler._write_config: zone updated and '
- u'the service is running, freezing zone')
- call(('rndc', 'freeze', a_zone.name))
- vars = dict(
- zone = a_zone,
- hosts = a_zone.hosts.values(),
- mxs = a_zone.mxs.values(),
- nss = a_zone.nss.values()
- )
- self._write_single_config('zoneX.zone',
- self._zone_filename(a_zone), vars)
- a_zone._update = False
- if not a_zone._add and self._service_running:
- log.debug(u'DnsHandler._write_config: unfreezing zone')
- call(('rndc', 'thaw', a_zone.name))
- else :
- self._update = True
- a_zone._add = False
- if a_zone._delete:
- #borro el archivo .zone
- log.debug(u'DnsHandler._write_config: zone deleted, removing '
- u'the file %r', self._zone_filename(a_zone))
- try:
- self._update = True
- unlink(self._zone_filename(a_zone))
- except OSError:
- #la excepcion pude darse en caso que haga un add de una zona y
- #luego el del, como no hice commit, no se crea el archivo
- log.debug(u'DnsHandler._write_config: file not found')
- pass
- delete_zones.append(a_zone.name)
- #borro las zonas
- for z in delete_zones:
- del self.zones[z]
- #archivo general
- if self._update:
- self._write_single_config('named.conf')
- self._update = False
- return False # Do reload
- return True # we don't need to reload
-
- # HACK!!!!
- def handle_timer(self):
- log.debug(u'DnsHandler.handle_timer()')
- import subprocess
- p = subprocess.Popen(('pgrep', '-f', '/usr/sbin/named'),
- stdout=subprocess.PIPE)
- pid = p.communicate()[0]
- if p.returncode == 0 and len(pid) > 0:
- log.debug(u'DnsHandler.handle_timer: pid present, running')
- self._service_running = True
- else:
- log.debug(u'DnsHandler.handle_timer: pid absent, NOT running')
- self._service_running = False
-
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- dns = DnsHandler();
-
- dns.set('isp_dns1','la_garcha.com')
- dns.set('bind_addr1','localhost')
- dns.zone.add('zona_loca.com')
- #dns.zone.update('zona_loca.com','ns1.dominio.com')
-
- dns.host.add('zona_loca.com','hostname_loco','192.168.0.23')
- dns.host.update('zona_loca.com','hostname_loco','192.168.0.66')
-
- dns.host.add('zona_loca.com','hostname_kuak','192.168.0.23')
- dns.host.delete('zona_loca.com','hostname_kuak')
-
- dns.host.add('zona_loca.com','hostname_kuang','192.168.0.24')
- dns.host.add('zona_loca.com','hostname_chan','192.168.0.25')
- dns.host.add('zona_loca.com','hostname_kaine','192.168.0.26')
-
- dns.mx.add('zona_loca.com','mx1.sarasa.com',10)
- dns.mx.update('zona_loca.com','mx1.sarasa.com',20)
- dns.mx.add('zona_loca.com','mx2.sarasa.com',30)
- dns.mx.add('zona_loca.com','mx3.sarasa.com',40)
- dns.mx.delete('zona_loca.com','mx3.sarasa.com')
-
- dns.ns.add('zona_loca.com','ns1.jua.com')
- dns.ns.add('zona_loca.com','ns2.jua.com')
- dns.ns.add('zona_loca.com','ns3.jua.com')
- dns.ns.delete('zona_loca.com','ns3.jua.com')
-
- dns.zone.add('zona_oscura')
-
- dns.host.add('zona_oscura','hostname_a','192.168.0.24')
- dns.host.add('zona_oscura','hostname_b','192.168.0.25')
- dns.host.add('zona_oscura','hostname_c','192.168.0.26')
-
- dns.zone.delete('zona_oscura')
-
- dns.commit()
-
- print 'ZONAS :', dns.zone.show()
- for z in dns.zones:
- print 'HOSTS from', z, ':', dns.host.show(z)
-
- #test zone errors
- #try:
- # dns.zone.update('zone-sarasa','lalal')
- #except ZoneNotFoundError, inst:
- # print 'Error: ', inst
-
- from pymin.services.util import ItemNotFoundError, ItemAlreadyExistsError, \
- ContainerNotFoundError
-
- try:
- dns.zone.delete('zone-sarasa')
- except ItemNotFoundError, inst:
- print 'Error: ', inst
-
- #try:
- # dns.zone.add('zona_loca.com','ns1.dom.com','ns2.dom.com')
- #except ZoneAlreadyExistsError, inst:
- # print 'Error: ', inst
-
-
- #test hosts errors
- try:
- dns.host.update('zone-sarasa','kuak','192.68')
- except ContainerNotFoundError, inst:
- print 'Error: ', inst
-
- try:
- dns.host.update('zona_loca.com','kuak','192.68')
- except ItemNotFoundError, inst:
- print 'Error: ', inst
-
- try:
- dns.host.delete('zone-sarasa','lala')
- except ContainerNotFoundError, inst:
- print 'Error: ', inst
-
- try:
- dns.host.delete('zona_loca.com','lala')
- except ItemNotFoundError, inst:
- print 'Error: ', inst
-
- try:
- dns.host.add('zona','hostname_loco','192.168.0.23')
- except ContainerNotFoundError, inst:
- print 'Error: ', inst
-
- try:
- dns.host.add('zona_loca.com','hostname_loco','192.168.0.23')
- except ItemAlreadyExistsError, inst:
- print 'Error: ', inst
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+# TODO COMMENT
+from os import path
+from os import unlink
+import logging ; log = logging.getLogger('pymin.services.dns')
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import handler, HandlerError, Handler
+from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
+ TransactionalHandler, ParametersHandler, \
+ DictComposedSubHandler, DictSubHandler, call
+
+__all__ = ('DnsHandler', 'get_service')
+
+
+def get_service(config):
+ return DnsHandler(config.dns.pickle_dir, config.dns.config_dir)
+
+
+class Host(Sequence):
+ def __init__(self, name, ip):
+ self.name = name
+ self.ip = ip
+ def update(self, ip=None):
+ if ip is not None: self.ip = ip
+ def as_tuple(self):
+ return (self.name, self.ip)
+
+class HostHandler(DictComposedSubHandler):
+ handler_help = u"Manage DNS hosts"
+ _comp_subhandler_cont = 'zones'
+ _comp_subhandler_attr = 'hosts'
+ _comp_subhandler_class = Host
+
+class MailExchange(Sequence):
+ def __init__(self, mx, prio):
+ self.mx = mx
+ self.prio = prio
+ def update(self, prio=None):
+ if prio is not None: self.prio = prio
+ def as_tuple(self):
+ return (self.mx, self.prio)
+
+class MailExchangeHandler(DictComposedSubHandler):
+ handler_help = u"Manage DNS mail exchangers (MX)"
+ _comp_subhandler_cont = 'zones'
+ _comp_subhandler_attr = 'mxs'
+ _comp_subhandler_class = MailExchange
+
+class NameServer(Sequence):
+ def __init__(self, name):
+ self.name = name
+ def as_tuple(self):
+ return (self.name,)
+
+class NameServerHandler(DictComposedSubHandler):
+ handler_help = u"Manage DNS name servers (NS)"
+ _comp_subhandler_cont = 'zones'
+ _comp_subhandler_attr = 'nss'
+ _comp_subhandler_class = NameServer
+
+class Zone(Sequence):
+ def __init__(self, name):
+ self.name = name
+ self.hosts = dict()
+ self.mxs = dict()
+ self.nss = dict()
+ self._add = False
+ self._update = False
+ self._delete = False
+ def as_tuple(self):
+ return (self.name, self.hosts, self.mxs, self.nss)
+
+class ZoneHandler(DictSubHandler):
+ handler_help = u"Manage DNS zones"
+ _cont_subhandler_attr = 'zones'
+ _cont_subhandler_class = Zone
+
+class DnsHandler(Restorable, ConfigWriter, InitdHandler, TransactionalHandler,
+ ParametersHandler):
+ r"""DnsHandler([pickle_dir[, config_dir]]) -> DnsHandler instance.
+
+ Handles DNS service commands for the dns program.
+
+ pickle_dir - Directory where to write the persistent configuration data.
+
+ config_dir - Directory where to store de generated configuration files.
+
+ Both defaults to the current working directory.
+ """
+
+ handler_help = u"Manage DNS service"
+
+ _initd_name = 'named'
+
+ _persistent_attrs = ('params', 'zones')
+
+ _restorable_defaults = dict(
+ zones = dict(),
+ params = dict(
+ isp_dns1 = '',
+ isp_dns2 = '',
+ bind_addr1 = '',
+ bind_addr2 = ''
+ ),
+ )
+
+ _config_writer_files = ('named.conf', 'zoneX.zone')
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='.'):
+ r"Initialize DnsHandler object, see class documentation for details."
+ log.debug(u'DnsHandler(%r, %r)', pickle_dir, config_dir)
+ self._persistent_dir = pickle_dir
+ self._config_writer_cfg_dir = config_dir
+ self._update = False
+ self._config_build_templates()
+ InitdHandler.__init__(self)
+ self.host = HostHandler(self)
+ self.zone = ZoneHandler(self)
+ self.mx = MailExchangeHandler(self)
+ self.ns = NameServerHandler(self)
+
+ def _zone_filename(self, zone):
+ return zone.name + '.zone'
+
+ def _get_config_vars(self, config_file):
+ return dict(zones=self.zones.values(), **self.params)
+
+ def _write_config(self):
+ r"_write_config() -> None :: Generate all the configuration files."
+ log.debug(u'DnsHandler._write_config()')
+ delete_zones = list()
+ for a_zone in self.zones.values():
+ log.debug(u'DnsHandler._write_config: processing zone %s', a_zone)
+ if a_zone._update or a_zone._add:
+ if not a_zone._add and self._service_running:
+ log.debug(u'DnsHandler._write_config: zone updated and '
+ u'the service is running, freezing zone')
+ call(('rndc', 'freeze', a_zone.name))
+ vars = dict(
+ zone = a_zone,
+ hosts = a_zone.hosts.values(),
+ mxs = a_zone.mxs.values(),
+ nss = a_zone.nss.values()
+ )
+ self._write_single_config('zoneX.zone',
+ self._zone_filename(a_zone), vars)
+ a_zone._update = False
+ if not a_zone._add and self._service_running:
+ log.debug(u'DnsHandler._write_config: unfreezing zone')
+ call(('rndc', 'thaw', a_zone.name))
+ else :
+ self._update = True
+ a_zone._add = False
+ if a_zone._delete:
+ #borro el archivo .zone
+ log.debug(u'DnsHandler._write_config: zone deleted, removing '
+ u'the file %r', self._zone_filename(a_zone))
+ try:
+ self._update = True
+ unlink(self._zone_filename(a_zone))
+ except OSError:
+ #la excepcion pude darse en caso que haga un add de una zona y
+ #luego el del, como no hice commit, no se crea el archivo
+ log.debug(u'DnsHandler._write_config: file not found')
+ pass
+ delete_zones.append(a_zone.name)
+ #borro las zonas
+ for z in delete_zones:
+ del self.zones[z]
+ #archivo general
+ if self._update:
+ self._write_single_config('named.conf')
+ self._update = False
+ return False # Do reload
+ return True # we don't need to reload
+
+ # HACK!!!!
+ def handle_timer(self):
+ log.debug(u'DnsHandler.handle_timer()')
+ import subprocess
+ p = subprocess.Popen(('pgrep', '-f', '/usr/sbin/named'),
+ stdout=subprocess.PIPE)
+ pid = p.communicate()[0]
+ if p.returncode == 0 and len(pid) > 0:
+ log.debug(u'DnsHandler.handle_timer: pid present, running')
+ self._service_running = True
+ else:
+ log.debug(u'DnsHandler.handle_timer: pid absent, NOT running')
+ self._service_running = False
+
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ dns = DnsHandler();
+
+ dns.set('isp_dns1','la_garcha.com')
+ dns.set('bind_addr1','localhost')
+ dns.zone.add('zona_loca.com')
+ #dns.zone.update('zona_loca.com','ns1.dominio.com')
+
+ dns.host.add('zona_loca.com','hostname_loco','192.168.0.23')
+ dns.host.update('zona_loca.com','hostname_loco','192.168.0.66')
+
+ dns.host.add('zona_loca.com','hostname_kuak','192.168.0.23')
+ dns.host.delete('zona_loca.com','hostname_kuak')
+
+ dns.host.add('zona_loca.com','hostname_kuang','192.168.0.24')
+ dns.host.add('zona_loca.com','hostname_chan','192.168.0.25')
+ dns.host.add('zona_loca.com','hostname_kaine','192.168.0.26')
+
+ dns.mx.add('zona_loca.com','mx1.sarasa.com',10)
+ dns.mx.update('zona_loca.com','mx1.sarasa.com',20)
+ dns.mx.add('zona_loca.com','mx2.sarasa.com',30)
+ dns.mx.add('zona_loca.com','mx3.sarasa.com',40)
+ dns.mx.delete('zona_loca.com','mx3.sarasa.com')
+
+ dns.ns.add('zona_loca.com','ns1.jua.com')
+ dns.ns.add('zona_loca.com','ns2.jua.com')
+ dns.ns.add('zona_loca.com','ns3.jua.com')
+ dns.ns.delete('zona_loca.com','ns3.jua.com')
+
+ dns.zone.add('zona_oscura')
+
+ dns.host.add('zona_oscura','hostname_a','192.168.0.24')
+ dns.host.add('zona_oscura','hostname_b','192.168.0.25')
+ dns.host.add('zona_oscura','hostname_c','192.168.0.26')
+
+ dns.zone.delete('zona_oscura')
+
+ dns.commit()
+
+ print 'ZONAS :', dns.zone.show()
+ for z in dns.zones:
+ print 'HOSTS from', z, ':', dns.host.show(z)
+
+ #test zone errors
+ #try:
+ # dns.zone.update('zone-sarasa','lalal')
+ #except ZoneNotFoundError, inst:
+ # print 'Error: ', inst
+
+ from pymin.services.util import ItemNotFoundError, ItemAlreadyExistsError, \
+ ContainerNotFoundError
+
+ try:
+ dns.zone.delete('zone-sarasa')
+ except ItemNotFoundError, inst:
+ print 'Error: ', inst
+
+ #try:
+ # dns.zone.add('zona_loca.com','ns1.dom.com','ns2.dom.com')
+ #except ZoneAlreadyExistsError, inst:
+ # print 'Error: ', inst
+
+
+ #test hosts errors
+ try:
+ dns.host.update('zone-sarasa','kuak','192.68')
+ except ContainerNotFoundError, inst:
+ print 'Error: ', inst
+
+ try:
+ dns.host.update('zona_loca.com','kuak','192.68')
+ except ItemNotFoundError, inst:
+ print 'Error: ', inst
+
+ try:
+ dns.host.delete('zone-sarasa','lala')
+ except ContainerNotFoundError, inst:
+ print 'Error: ', inst
+
+ try:
+ dns.host.delete('zona_loca.com','lala')
+ except ItemNotFoundError, inst:
+ print 'Error: ', inst
+
+ try:
+ dns.host.add('zona','hostname_loco','192.168.0.23')
+ except ContainerNotFoundError, inst:
+ print 'Error: ', inst
+
+ try:
+ dns.host.add('zona_loca.com','hostname_loco','192.168.0.23')
+ except ItemAlreadyExistsError, inst:
+ print 'Error: ', inst
# vim: set encoding=utf-8 et sw=4 sts=4 :
-# TODO See if it's better (more secure) to execute commands via python instead
-# of using script templates.
-
-from os import path
-from formencode import Invalid
-from formencode.validators import OneOf, CIDR, Int
-import logging ; log = logging.getLogger('pymin.services.firewall')
-
-from pymin.item import Item
-from pymin.validatedclass import Field
-from pymin.dispatcher import Handler, handler, HandlerError
-from pymin.service.util import Restorable, ConfigWriter, ServiceHandler, \
- TransactionalHandler, ListSubHandler
-
-__all__ = ('FirewallHandler', 'get_service')
-
+from handler import FirewallHandler
def get_service(config):
return FirewallHandler(config.firewall.pickle_dir, config.firewall.config_dir)
-
-class UpOneOf(OneOf):
- def validate_python(self, value, state):
- value = value.upper()
- return OneOf.validate_python(self, value, state)
-
-class Rule(Item):
- r"""Rule(chain, target[, src[, dst[, ...]]]) -> Rule instance.
-
- chain - INPUT, OUTPUT or FORWARD.
- target - ACCEPT, REJECT or DROP.
- src - Source subnet as IP/mask.
- dst - Destination subnet as IP/mask.
- protocol - ICMP, UDP, TCP or ALL.
- src_port - Source port (only for UDP or TCP protocols).
- dst_port - Destination port (only for UDP or TCP protocols).
- """
- chain = Field(UpOneOf(['INPUT', 'OUTPUT', 'FORWARD'], not_empty=True))
- target = Field(UpOneOf(['ACCEPT', 'REJECT', 'DROP'], not_empty=True))
- src = Field(CIDR(if_empty=None, if_missing=None))
- dst = Field(CIDR(if_empty=None, if_missing=None))
- protocol = Field(UpOneOf(['ICMP', 'UDP', 'TCP', 'ALL'], if_missing=None))
- src_port = Field(Int(min=0, max=65535, if_empty=None, if_missing=None))
- dst_port = Field(Int(min=0, max=65535, if_empty=None, if_missing=None))
- def chained_validator(self, fields, state):
- errors = dict()
- if fields['protocol'] not in ('TCP', 'UDP'):
- for name in ('src_port', 'dst_port'):
- if fields[name] is not None:
- errors[name] = u"Should be None if protocol " \
- "(%(protocol)s) is not TCP or UDP" % fields
- if errors:
- raise Invalid(u"You can't specify any ports if the protocol "
- u'is not TCP or UDP', fields, state, error_dict=errors)
-
-class RuleHandler(ListSubHandler):
- r"""RuleHandler(parent) -> RuleHandler instance :: Handle a list of rules.
-
- This class is a helper for FirewallHandler to do all the work related to rules
- administration.
-
- parent - The parent service handler.
- """
-
- handler_help = u"Manage firewall rules"
-
- _cont_subhandler_attr = 'rules'
- _cont_subhandler_class = Rule
-
-class FirewallHandler(Restorable, ConfigWriter, ServiceHandler,
- TransactionalHandler):
- r"""FirewallHandler([pickle_dir[, config_dir]]) -> FirewallHandler instance.
-
- Handles firewall commands using iptables.
-
- pickle_dir - Directory where to write the persistent configuration data.
-
- config_dir - Directory where to store de generated configuration files.
-
- Both defaults to the current working directory.
- """
-
- handler_help = u"Manage firewall service"
-
- _persistent_attrs = ['rules']
-
- _restorable_defaults = dict(rules=list())
-
- _config_writer_files = 'iptables.sh'
- _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
-
- def __init__(self, pickle_dir='.', config_dir='.'):
- r"Initialize the object, see class documentation for details."
- log.debug(u'FirewallHandler(%r, %r)', pickle_dir, config_dir)
- self._persistent_dir = pickle_dir
- self._config_writer_cfg_dir = config_dir
- self._service_start = ('sh', path.join(self._config_writer_cfg_dir,
- self._config_writer_files))
- self._service_stop = ('iptables', '-t', 'filter', '-F')
- self._service_restart = self._service_start
- self._service_reload = self._service_start
- self._config_build_templates()
- ServiceHandler.__init__(self)
- self.rule = RuleHandler(self)
-
- def _get_config_vars(self, config_file):
- return dict(rules=self.rules)
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- import os
-
- fw_handler = FirewallHandler()
-
- def dump():
- print '-' * 80
- print 'Rules:'
- print fw_handler.rule.show()
- print '-' * 80
-
- dump()
-
- fw_handler.rule.add('input', 'drop', protocol='icmp')
-
- fw_handler.rule.update(0, dst='192.168.0.188/32')
-
- fw_handler.rule.add('output', 'accept', '192.168.1.0/24')
-
- fw_handler.commit()
-
- fw_handler.stop()
-
- dump()
-
- os.system('rm -f *.pkl iptables.sh')
-
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+# TODO See if it's better (more secure) to execute commands via python instead
+# of using script templates.
+
+from os import path
+from formencode import Invalid
+from formencode.validators import OneOf, CIDR, Int
+import logging ; log = logging.getLogger('pymin.services.firewall')
+
+from pymin.item import Item
+from pymin.validatedclass import Field
+from pymin.dispatcher import Handler, handler, HandlerError
+from pymin.service.util import Restorable, ConfigWriter, ServiceHandler, \
+ TransactionalHandler, ListSubHandler
+
+__all__ = ('FirewallHandler', 'get_service')
+
+
+def get_service(config):
+ return FirewallHandler(config.firewall.pickle_dir, config.firewall.config_dir)
+
+
+class UpOneOf(OneOf):
+ def validate_python(self, value, state):
+ value = value.upper()
+ return OneOf.validate_python(self, value, state)
+
+class Rule(Item):
+ r"""Rule(chain, target[, src[, dst[, ...]]]) -> Rule instance.
+
+ chain - INPUT, OUTPUT or FORWARD.
+ target - ACCEPT, REJECT or DROP.
+ src - Source subnet as IP/mask.
+ dst - Destination subnet as IP/mask.
+ protocol - ICMP, UDP, TCP or ALL.
+ src_port - Source port (only for UDP or TCP protocols).
+ dst_port - Destination port (only for UDP or TCP protocols).
+ """
+ chain = Field(UpOneOf(['INPUT', 'OUTPUT', 'FORWARD'], not_empty=True))
+ target = Field(UpOneOf(['ACCEPT', 'REJECT', 'DROP'], not_empty=True))
+ src = Field(CIDR(if_empty=None, if_missing=None))
+ dst = Field(CIDR(if_empty=None, if_missing=None))
+ protocol = Field(UpOneOf(['ICMP', 'UDP', 'TCP', 'ALL'], if_missing=None))
+ src_port = Field(Int(min=0, max=65535, if_empty=None, if_missing=None))
+ dst_port = Field(Int(min=0, max=65535, if_empty=None, if_missing=None))
+ def chained_validator(self, fields, state):
+ errors = dict()
+ if fields['protocol'] not in ('TCP', 'UDP'):
+ for name in ('src_port', 'dst_port'):
+ if fields[name] is not None:
+ errors[name] = u"Should be None if protocol " \
+ "(%(protocol)s) is not TCP or UDP" % fields
+ if errors:
+ raise Invalid(u"You can't specify any ports if the protocol "
+ u'is not TCP or UDP', fields, state, error_dict=errors)
+
+class RuleHandler(ListSubHandler):
+ r"""RuleHandler(parent) -> RuleHandler instance :: Handle a list of rules.
+
+ This class is a helper for FirewallHandler to do all the work related to rules
+ administration.
+
+ parent - The parent service handler.
+ """
+
+ handler_help = u"Manage firewall rules"
+
+ _cont_subhandler_attr = 'rules'
+ _cont_subhandler_class = Rule
+
+class FirewallHandler(Restorable, ConfigWriter, ServiceHandler,
+ TransactionalHandler):
+ r"""FirewallHandler([pickle_dir[, config_dir]]) -> FirewallHandler instance.
+
+ Handles firewall commands using iptables.
+
+ pickle_dir - Directory where to write the persistent configuration data.
+
+ config_dir - Directory where to store de generated configuration files.
+
+ Both defaults to the current working directory.
+ """
+
+ handler_help = u"Manage firewall service"
+
+ _persistent_attrs = ['rules']
+
+ _restorable_defaults = dict(rules=list())
+
+ _config_writer_files = 'iptables.sh'
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='.'):
+ r"Initialize the object, see class documentation for details."
+ log.debug(u'FirewallHandler(%r, %r)', pickle_dir, config_dir)
+ self._persistent_dir = pickle_dir
+ self._config_writer_cfg_dir = config_dir
+ self._service_start = ('sh', path.join(self._config_writer_cfg_dir,
+ self._config_writer_files))
+ self._service_stop = ('iptables', '-t', 'filter', '-F')
+ self._service_restart = self._service_start
+ self._service_reload = self._service_start
+ self._config_build_templates()
+ ServiceHandler.__init__(self)
+ self.rule = RuleHandler(self)
+
+ def _get_config_vars(self, config_file):
+ return dict(rules=self.rules)
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ import os
+
+ fw_handler = FirewallHandler()
+
+ def dump():
+ print '-' * 80
+ print 'Rules:'
+ print fw_handler.rule.show()
+ print '-' * 80
+
+ dump()
+
+ fw_handler.rule.add('input', 'drop', protocol='icmp')
+
+ fw_handler.rule.update(0, dst='192.168.0.188/32')
+
+ fw_handler.rule.add('output', 'accept', '192.168.1.0/24')
+
+ fw_handler.commit()
+
+ fw_handler.stop()
+
+ dump()
+
+ os.system('rm -f *.pkl iptables.sh')
+
# vim: set encoding=utf-8 et sw=4 sts=4 :
-from subprocess import Popen, PIPE
-from os import path
-import logging ; log = logging.getLogger('pymin.services.ip')
-
-from pymin.seqtools import Sequence
-from pymin.dispatcher import handler, HandlerError, Handler
-from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
- TransactionalHandler, SubHandler, call, \
- get_network_devices, ListComposedSubHandler, \
- DictComposedSubHandler, ListSubHandler, \
- Device, Address, ExecutionError
-
-__all__ = ('IpHandler', 'get_service')
-
+from handler import IpHandler
def get_service(config):
return IpHandler(config.ip.pickle_dir, config.ip.config_dir)
-
-class Hop(Sequence):
-
- def __init__(self, gateway, device):
- self.gateway = gateway
- self.device = device
-
- def as_tuple(self):
- return (self.gateway, self.device)
-
- def __cmp__(self, other):
- if self.gateway == other.gateway \
- and self.device == other.device:
- return 0
- return cmp(id(self), id(other))
-
-class HopHandler(ListSubHandler):
- handler_help = u"Manage IP hops"
- _cont_subhandler_attr = 'hops'
- _cont_subhandler_class = Hop
-
- @handler('Add a hop: add <device> <gateway>')
- def add(self, dev, gw):
- if not dev in self.parent.devices:
- raise DeviceNotFoundError(device)
- return ListSubHandler.add(self, dev, gw)
-
-
-class Route(Sequence):
- def __init__(self, net_addr, prefix, gateway):
- self.net_addr = net_addr
- self.prefix = prefix
- self.gateway = gateway
-
- def update(self, net_addr=None, prefix=None, gateway=None):
- if net_addr is not None: self.net_addr = net_addr
- if prefix is not None: self.prefix = prefix
- if gateway is not None: self.gateway = gateway
-
- def as_tuple(self):
- return(self.net_addr, self.prefix, self.gateway)
-
- def __cmp__(self, other):
- if self.net_addr == other.net_addr \
- and self.prefix == other.prefix \
- and self.gateway == other.gateway:
- return 0
- return cmp(id(self), id(other))
-
-class RouteHandler(ListComposedSubHandler):
- handler_help = u"Manage IP routes"
- _comp_subhandler_cont = 'devices'
- _comp_subhandler_attr = 'routes'
- _comp_subhandler_class = Route
-
- @handler(u'Adds a route to : ip route add <net_addr> <prefix> <gateway> [device]')
- def add(self, net_addr, prefix, gateway, dev=None):
- if dev is not None:
- ListComposedSubHandler.add(self, dev, net_addr, prefix, gateway)
- else:
- r = Route(net_addr, prefix, gateway)
- if not r in self.parent.no_device_routes:
- self.parent.no_device_routes.append(r)
-
- @handler("Deletes a route : ip route delete <route_number_in_show> [dev]")
- def delete(self, index, dev=None):
- if dev is not None:
- ListComposedSubHandler.delete(self, dev, index)
- else:
- i = int(index)
- del self.parent.no_device_routes[i]
-
- @handler("Shows routes : ip route show [dev]")
- def show(self, dev=None):
- if dev is not None:
- return ListComposedSubHandler.show(self, dev)
- else:
- return self.parent.no_device_routes
-
-class AddressHandler(DictComposedSubHandler):
- handler_help = u"Manage IP addresses"
- _comp_subhandler_cont = 'devices'
- _comp_subhandler_attr = 'addrs'
- _comp_subhandler_class = Address
-
-
-class DeviceHandler(SubHandler):
-
- handler_help = u"Manage network devices"
-
- def __init__(self, parent):
- log.debug(u'DeviceHandler(%r)', parent)
- # FIXME remove templates to execute commands
- from mako.template import Template
- self.parent = parent
- template_dir = path.join(path.dirname(__file__), 'templates')
- dev_fn = path.join(template_dir, 'device')
- self.device_template = Template(filename=dev_fn)
-
- @handler(u'Bring the device up')
- def up(self, name):
- log.debug(u'DeviceHandler.up(%r)', name)
- if name in self.parent.devices:
- call(self.device_template.render(dev=name, action='up'), shell=True)
- #bring up all the route asocitaed to the device
- for route in self.parent.devices[name].routes:
- try:
- log.debug(u'IpHandler.up: adding %r', route)
- call(self.parent._render_config('route_add', dict(
- dev = name,
- net_addr = route.net_addr,
- prefix = route.prefix,
- gateway = route.gateway,
- )
- ), shell=True)
- except ExecutionError, e:
- log.debug(u'IpHandler.up: error adding %r -> %r', route, e)
- self.parent._bring_up_no_dev_routes()
- self.parent._restart_services()
- else:
- log.debug(u'DeviceHandler.up: device not found')
- raise DeviceNotFoundError(name)
-
- @handler(u'Bring the device down')
- def down(self, name):
- log.debug(u'DeviceHandler.down(%r)', name)
- if name in self.parent.devices:
- call(self.device_template.render(dev=name, action='down'), shell=True)
- self.parent._bring_up_no_dev_routes()
- self.parent._restart_services()
- else:
- log.debug(u'DeviceHandler.up: device not found')
- raise DeviceNotFoundError(name)
-
- @handler(u'List all devices')
- def list(self):
- log.debug(u'DeviceHandler.list()')
- return self.parent.devices.keys()
-
- @handler(u'Get information about a device')
- def show(self):
- log.debug(u'DeviceHandler.show()')
- return self.parent.devices.items()
-
-class IpHandler(Restorable, ConfigWriter, TransactionalHandler):
-
- handler_help = u"Manage IP devices, addresses, routes and hops"
-
- _persistent_attrs = ('devices','hops','no_device_routes')
-
- _restorable_defaults = dict(
- devices=get_network_devices(),
- hops = list(),
- no_device_routes = list(),
- )
-
- _config_writer_files = ('device', 'ip_add', 'ip_del', 'ip_flush',
- 'route_add', 'route_del', 'route_flush', 'hop')
- _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
-
- def __init__(self, pickle_dir='.', config_dir='.'):
- r"Initialize DhcpHandler object, see class documentation for details."
- log.debug(u'IpHandler(%r, %r)', pickle_dir, config_dir)
- self._persistent_dir = pickle_dir
- self._config_writer_cfg_dir = config_dir
- self._config_build_templates()
- self._restore()
- self._write_config()
- self.addr = AddressHandler(self)
- self.route = RouteHandler(self)
- self.dev = DeviceHandler(self)
- self.hop = HopHandler(self)
- self.no_device_routes = list()
- self.services = list()
-
- def _write_config(self):
- r"_write_config() -> None :: Execute all commands."
- log.debug(u'IpHandler._write_config()')
- for device in self.devices.values():
- log.debug(u'IpHandler._write_config: processing device %s', device)
- if device.active:
- self._write_config_for_device(device)
- self._bring_up_no_dev_routes()
- self._write_hops()
-
- def _bring_up_no_dev_routes(self):
- log.debug(u'IpHandler._bring_up_no_dev_routes()')
- for route in self.no_device_routes:
- try:
- log.debug(u'IpHandler._bring_up_no_dev_routes: add %r', route)
- call(self._render_config('route_add', dict(
- dev = None,
- net_addr = route.net_addr,
- prefix = route.prefix,
- gateway = route.gateway,
- )
- ), shell=True)
- except ExecutionError, e:
- log.debug(u'IpHandler._write_config: error flushing -> %r', e)
-
- def _write_hops(self):
- r"_write_hops() -> None :: Execute all hops."
- log.debug(u'IpHandler._write_hops()')
- if self.hops:
- log.debug(u'IpHandler._write_hops: we have hops: %r', self.hops)
- try:
- log.debug(u'IpHandler._write_hops: flushing default hops')
- call('ip route del default', shell=True)
- except ExecutionError, e:
- log.debug(u'IpHandler._write_hops: error adding -> %r', e)
- try:
- log.debug(u'IpHandler._write_hops: configuring hops')
- #get hops for active devices
- active_hops = dict()
- for h in self.hops:
- if h.device in self.devices:
- if self.devices[h.device].active:
- active_hops.append(h)
- call(self._render_config('hop', dict(
- hops = active_hops,
- )
- ), shell=True)
- except ExecutionError, e:
- log.debug(u'IpHandler._write_hops: error adding -> %r', e)
-
- def _write_config_for_device(self, device):
- r"_write_config_for_device(self, device) -> None :: Execute commands."
- log.debug(u'IpHandler._write_config_for_device()')
- try:
- log.debug(u'IpHandler._write_config_for_device: flushing routes...')
- call(self._render_config('route_flush', dict(dev=device.name)),
- shell=True)
- except ExecutionError, e:
- log.debug(u'IpHandler._write_config_for_device: error flushing '
- u'-> %r', e)
- try:
- log.debug(u'IpHandler._write_config_for_device: flushing addrs...')
- call(self._render_config('ip_flush', dict(dev=device.name)),
- shell=True)
- except ExecutionError, e:
- log.debug(u'IpHandler._write_config_for_device: error flushing '
- u'-> %r', e)
- for address in device.addrs.values():
- broadcast = address.broadcast
- if broadcast is None:
- broadcast = '+'
- try:
- log.debug(u'IpHandler._write_config_for_device: adding %r',
- address)
- call(self._render_config('ip_add', dict(
- dev = device.name,
- addr = address.ip,
- netmask = address.netmask,
- peer = address.peer,
- broadcast = broadcast,
- )
- ), shell=True)
- except ExecutionError, e:
- log.debug(u'IpHandler._write_config_for_device: error adding '
- u'-> %r', e)
- for route in device.routes:
- try:
- log.debug(u'IpHandler._write_config_for_device: adding %r',
- route)
- call(self._render_config('route_add', dict(
- dev = device.name,
- net_addr = route.net_addr,
- prefix = route.prefix,
- gateway = route.gateway,
- )
- ), shell=True)
- except ExecutionError, e:
- log.debug(u'IpHandler._write_config_for_device: error adding '
- u'-> %r', e)
-
- def handle_timer(self):
- log.debug(u'IpHandler.handle_timer()')
- self.refresh_devices()
-
- def refresh_devices(self):
- log.debug(u'IpHandler.update_devices()')
- devices = get_network_devices()
- #add not registered and active devices
- go_active = False
- for k,v in devices.items():
- if k not in self.devices:
- log.debug(u'IpHandler.update_devices: adding %r', v)
- self.devices[k] = v
- elif not self.devices[k].active:
- self.active = True
- go_active = True
- self._write_config_for_device(self.devices[k])
- if go_active:
- self._write_hops()
- self._bring_up_no_dev_routes()
- self._restart_services()
-
- #mark inactive devices
- for k in self.devices.keys():
- go_down = False
- if k not in devices:
- log.debug(u'IpHandler.update_devices: removing %s', k)
- self.devices[k].active = False
- go_down = True
- if go_down:
- self._bring_up_no_dev_routes()
-
- def _restart_services(self):
- for s in self.services:
- if s._service_running:
- try:
- s.stop()
- except ExecutionError:
- pass
- try:
- s.start()
- except ExecutionError:
- pass
-
- #hooks a service to the ip handler, so when
- #a device is brought up one can restart the service
- #that need to refresh their device list
- def device_up_hook(self, serv):
- if hasattr(serv, 'stop') and hasattr(serv, 'start'):
- self.services.append(serv)
-
-
-
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- ip = IpHandler()
- print '----------------------'
- ip.hop.add('201.21.32.53','eth0')
- ip.hop.add('205.65.65.25','eth1')
- ip.commit()
- ip.dev.up('eth0')
- ip.addr.add('eth0','192.168.0.23','24','192.168.255.255')
- ip.addr.add('eth0','192.168.0.26','24')
- ip.commit()
- ip.route.add('eth0','192.168.0.0','24','192.168.0.1')
- ip.route.add('eth0','192.168.0.5','24','192.168.0.1')
- ip.commit()
- ip.hop.delete('201.21.32.53','eth0')
- ip.route.clear('eth0')
- ip.commit()
-
-
-
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+from subprocess import Popen, PIPE
+from os import path
+import logging ; log = logging.getLogger('pymin.services.ip')
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import handler, HandlerError, Handler
+from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
+ TransactionalHandler, SubHandler, call, \
+ get_network_devices, ListComposedSubHandler, \
+ DictComposedSubHandler, ListSubHandler, \
+ Device, Address, ExecutionError
+
+__all__ = ('IpHandler', 'get_service')
+
+
+def get_service(config):
+ return IpHandler(config.ip.pickle_dir, config.ip.config_dir)
+
+
+class Hop(Sequence):
+
+ def __init__(self, gateway, device):
+ self.gateway = gateway
+ self.device = device
+
+ def as_tuple(self):
+ return (self.gateway, self.device)
+
+ def __cmp__(self, other):
+ if self.gateway == other.gateway \
+ and self.device == other.device:
+ return 0
+ return cmp(id(self), id(other))
+
+class HopHandler(ListSubHandler):
+ handler_help = u"Manage IP hops"
+ _cont_subhandler_attr = 'hops'
+ _cont_subhandler_class = Hop
+
+ @handler('Add a hop: add <device> <gateway>')
+ def add(self, dev, gw):
+ if not dev in self.parent.devices:
+ raise DeviceNotFoundError(device)
+ return ListSubHandler.add(self, dev, gw)
+
+
+class Route(Sequence):
+ def __init__(self, net_addr, prefix, gateway):
+ self.net_addr = net_addr
+ self.prefix = prefix
+ self.gateway = gateway
+
+ def update(self, net_addr=None, prefix=None, gateway=None):
+ if net_addr is not None: self.net_addr = net_addr
+ if prefix is not None: self.prefix = prefix
+ if gateway is not None: self.gateway = gateway
+
+ def as_tuple(self):
+ return(self.net_addr, self.prefix, self.gateway)
+
+ def __cmp__(self, other):
+ if self.net_addr == other.net_addr \
+ and self.prefix == other.prefix \
+ and self.gateway == other.gateway:
+ return 0
+ return cmp(id(self), id(other))
+
+class RouteHandler(ListComposedSubHandler):
+ handler_help = u"Manage IP routes"
+ _comp_subhandler_cont = 'devices'
+ _comp_subhandler_attr = 'routes'
+ _comp_subhandler_class = Route
+
+ @handler(u'Adds a route to : ip route add <net_addr> <prefix> <gateway> [device]')
+ def add(self, net_addr, prefix, gateway, dev=None):
+ if dev is not None:
+ ListComposedSubHandler.add(self, dev, net_addr, prefix, gateway)
+ else:
+ r = Route(net_addr, prefix, gateway)
+ if not r in self.parent.no_device_routes:
+ self.parent.no_device_routes.append(r)
+
+ @handler("Deletes a route : ip route delete <route_number_in_show> [dev]")
+ def delete(self, index, dev=None):
+ if dev is not None:
+ ListComposedSubHandler.delete(self, dev, index)
+ else:
+ i = int(index)
+ del self.parent.no_device_routes[i]
+
+ @handler("Shows routes : ip route show [dev]")
+ def show(self, dev=None):
+ if dev is not None:
+ return ListComposedSubHandler.show(self, dev)
+ else:
+ return self.parent.no_device_routes
+
+class AddressHandler(DictComposedSubHandler):
+ handler_help = u"Manage IP addresses"
+ _comp_subhandler_cont = 'devices'
+ _comp_subhandler_attr = 'addrs'
+ _comp_subhandler_class = Address
+
+
+class DeviceHandler(SubHandler):
+
+ handler_help = u"Manage network devices"
+
+ def __init__(self, parent):
+ log.debug(u'DeviceHandler(%r)', parent)
+ # FIXME remove templates to execute commands
+ from mako.template import Template
+ self.parent = parent
+ template_dir = path.join(path.dirname(__file__), 'templates')
+ dev_fn = path.join(template_dir, 'device')
+ self.device_template = Template(filename=dev_fn)
+
+ @handler(u'Bring the device up')
+ def up(self, name):
+ log.debug(u'DeviceHandler.up(%r)', name)
+ if name in self.parent.devices:
+ call(self.device_template.render(dev=name, action='up'), shell=True)
+ #bring up all the route asocitaed to the device
+ for route in self.parent.devices[name].routes:
+ try:
+ log.debug(u'IpHandler.up: adding %r', route)
+ call(self.parent._render_config('route_add', dict(
+ dev = name,
+ net_addr = route.net_addr,
+ prefix = route.prefix,
+ gateway = route.gateway,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ log.debug(u'IpHandler.up: error adding %r -> %r', route, e)
+ self.parent._bring_up_no_dev_routes()
+ self.parent._restart_services()
+ else:
+ log.debug(u'DeviceHandler.up: device not found')
+ raise DeviceNotFoundError(name)
+
+ @handler(u'Bring the device down')
+ def down(self, name):
+ log.debug(u'DeviceHandler.down(%r)', name)
+ if name in self.parent.devices:
+ call(self.device_template.render(dev=name, action='down'), shell=True)
+ self.parent._bring_up_no_dev_routes()
+ self.parent._restart_services()
+ else:
+ log.debug(u'DeviceHandler.up: device not found')
+ raise DeviceNotFoundError(name)
+
+ @handler(u'List all devices')
+ def list(self):
+ log.debug(u'DeviceHandler.list()')
+ return self.parent.devices.keys()
+
+ @handler(u'Get information about a device')
+ def show(self):
+ log.debug(u'DeviceHandler.show()')
+ return self.parent.devices.items()
+
+class IpHandler(Restorable, ConfigWriter, TransactionalHandler):
+
+ handler_help = u"Manage IP devices, addresses, routes and hops"
+
+ _persistent_attrs = ('devices','hops','no_device_routes')
+
+ _restorable_defaults = dict(
+ devices=get_network_devices(),
+ hops = list(),
+ no_device_routes = list(),
+ )
+
+ _config_writer_files = ('device', 'ip_add', 'ip_del', 'ip_flush',
+ 'route_add', 'route_del', 'route_flush', 'hop')
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='.'):
+ r"Initialize DhcpHandler object, see class documentation for details."
+ log.debug(u'IpHandler(%r, %r)', pickle_dir, config_dir)
+ self._persistent_dir = pickle_dir
+ self._config_writer_cfg_dir = config_dir
+ self._config_build_templates()
+ self._restore()
+ self._write_config()
+ self.addr = AddressHandler(self)
+ self.route = RouteHandler(self)
+ self.dev = DeviceHandler(self)
+ self.hop = HopHandler(self)
+ self.no_device_routes = list()
+ self.services = list()
+
+ def _write_config(self):
+ r"_write_config() -> None :: Execute all commands."
+ log.debug(u'IpHandler._write_config()')
+ for device in self.devices.values():
+ log.debug(u'IpHandler._write_config: processing device %s', device)
+ if device.active:
+ self._write_config_for_device(device)
+ self._bring_up_no_dev_routes()
+ self._write_hops()
+
+ def _bring_up_no_dev_routes(self):
+ log.debug(u'IpHandler._bring_up_no_dev_routes()')
+ for route in self.no_device_routes:
+ try:
+ log.debug(u'IpHandler._bring_up_no_dev_routes: add %r', route)
+ call(self._render_config('route_add', dict(
+ dev = None,
+ net_addr = route.net_addr,
+ prefix = route.prefix,
+ gateway = route.gateway,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ log.debug(u'IpHandler._write_config: error flushing -> %r', e)
+
+ def _write_hops(self):
+ r"_write_hops() -> None :: Execute all hops."
+ log.debug(u'IpHandler._write_hops()')
+ if self.hops:
+ log.debug(u'IpHandler._write_hops: we have hops: %r', self.hops)
+ try:
+ log.debug(u'IpHandler._write_hops: flushing default hops')
+ call('ip route del default', shell=True)
+ except ExecutionError, e:
+ log.debug(u'IpHandler._write_hops: error adding -> %r', e)
+ try:
+ log.debug(u'IpHandler._write_hops: configuring hops')
+ #get hops for active devices
+ active_hops = dict()
+ for h in self.hops:
+ if h.device in self.devices:
+ if self.devices[h.device].active:
+ active_hops.append(h)
+ call(self._render_config('hop', dict(
+ hops = active_hops,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ log.debug(u'IpHandler._write_hops: error adding -> %r', e)
+
+ def _write_config_for_device(self, device):
+ r"_write_config_for_device(self, device) -> None :: Execute commands."
+ log.debug(u'IpHandler._write_config_for_device()')
+ try:
+ log.debug(u'IpHandler._write_config_for_device: flushing routes...')
+ call(self._render_config('route_flush', dict(dev=device.name)),
+ shell=True)
+ except ExecutionError, e:
+ log.debug(u'IpHandler._write_config_for_device: error flushing '
+ u'-> %r', e)
+ try:
+ log.debug(u'IpHandler._write_config_for_device: flushing addrs...')
+ call(self._render_config('ip_flush', dict(dev=device.name)),
+ shell=True)
+ except ExecutionError, e:
+ log.debug(u'IpHandler._write_config_for_device: error flushing '
+ u'-> %r', e)
+ for address in device.addrs.values():
+ broadcast = address.broadcast
+ if broadcast is None:
+ broadcast = '+'
+ try:
+ log.debug(u'IpHandler._write_config_for_device: adding %r',
+ address)
+ call(self._render_config('ip_add', dict(
+ dev = device.name,
+ addr = address.ip,
+ netmask = address.netmask,
+ peer = address.peer,
+ broadcast = broadcast,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ log.debug(u'IpHandler._write_config_for_device: error adding '
+ u'-> %r', e)
+ for route in device.routes:
+ try:
+ log.debug(u'IpHandler._write_config_for_device: adding %r',
+ route)
+ call(self._render_config('route_add', dict(
+ dev = device.name,
+ net_addr = route.net_addr,
+ prefix = route.prefix,
+ gateway = route.gateway,
+ )
+ ), shell=True)
+ except ExecutionError, e:
+ log.debug(u'IpHandler._write_config_for_device: error adding '
+ u'-> %r', e)
+
+ def handle_timer(self):
+ log.debug(u'IpHandler.handle_timer()')
+ self.refresh_devices()
+
+ def refresh_devices(self):
+ log.debug(u'IpHandler.update_devices()')
+ devices = get_network_devices()
+ #add not registered and active devices
+ go_active = False
+ for k,v in devices.items():
+ if k not in self.devices:
+ log.debug(u'IpHandler.update_devices: adding %r', v)
+ self.devices[k] = v
+ elif not self.devices[k].active:
+ self.active = True
+ go_active = True
+ self._write_config_for_device(self.devices[k])
+ if go_active:
+ self._write_hops()
+ self._bring_up_no_dev_routes()
+ self._restart_services()
+
+ #mark inactive devices
+ for k in self.devices.keys():
+ go_down = False
+ if k not in devices:
+ log.debug(u'IpHandler.update_devices: removing %s', k)
+ self.devices[k].active = False
+ go_down = True
+ if go_down:
+ self._bring_up_no_dev_routes()
+
+ def _restart_services(self):
+ for s in self.services:
+ if s._service_running:
+ try:
+ s.stop()
+ except ExecutionError:
+ pass
+ try:
+ s.start()
+ except ExecutionError:
+ pass
+
+ #hooks a service to the ip handler, so when
+ #a device is brought up one can restart the service
+ #that need to refresh their device list
+ def device_up_hook(self, serv):
+ if hasattr(serv, 'stop') and hasattr(serv, 'start'):
+ self.services.append(serv)
+
+
+
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ ip = IpHandler()
+ print '----------------------'
+ ip.hop.add('201.21.32.53','eth0')
+ ip.hop.add('205.65.65.25','eth1')
+ ip.commit()
+ ip.dev.up('eth0')
+ ip.addr.add('eth0','192.168.0.23','24','192.168.255.255')
+ ip.addr.add('eth0','192.168.0.26','24')
+ ip.commit()
+ ip.route.add('eth0','192.168.0.0','24','192.168.0.1')
+ ip.route.add('eth0','192.168.0.5','24','192.168.0.1')
+ ip.commit()
+ ip.hop.delete('201.21.32.53','eth0')
+ ip.route.clear('eth0')
+ ip.commit()
+
+
+
# vim: set encoding=utf-8 et sw=4 sts=4 :
-from os import path
-import logging ; log = logging.getLogger('pymin.services.nat')
-
-from pymin.seqtools import Sequence
-from pymin.dispatcher import Handler, handler, HandlerError
-from pymin.service.util import Restorable, ConfigWriter, RestartHandler, \
- ReloadHandler, TransactionalHandler, \
- ServiceHandler, ListSubHandler, call
-
-__all__ = ('NatHandler', 'get_service')
-
+from handler import NatHandler
def get_service(config):
return NatHandler(config.nat.pickle_dir)
-
-class PortForward(Sequence):
- r"""PortForward(dev, protocol, port, dst[, dst_port[, ...]]) -> PortForward.
-
- dev - Netword device to use.
- protocol - TCP or UDP.
- port - Port to forward.
- dst - Destination IP address.
- dst_port - Destination port (at dst).
- src_net - Source network to apply the forward (as IP/mask).
- dst_net - Source network to apply the forward (as IP/mask).
- """
-
- def __init__(self, dev, protocol, port, dst, dst_port=None, src_net=None,
- dst_net=None):
- r"Initialize object, see class documentation for details."
- # TODO Validate
- self.dev = dev
- self.protocol = protocol
- self.port = port
- self.dst = dst
- self.dst_port = dst_port
- self.src_net = src_net
- self.dst_net = dst_net
-
- def update(self, dev=None, protocol=None, port=None, dst=None,
- dst_port=None, src_net=None, dst_net=None):
- r"update([dev[, ...]]) -> Update the values of a port (see class doc)."
- # TODO Validate
- if dev is not None: self.dev = dev
- if protocol is not None: self.protocol = protocol
- if port is not None: self.port = port
- if dst is not None: self.dst = dst
- if dst_port is not None: self.dst_port = dst_port
- if src_net is not None: self.src_net = src_net
- if dst_net is not None: self.dst_net = dst_net
-
- def as_tuple(self):
- r"Return a tuple representing the port forward."
- return (self.dev, self.protocol, self.port, self.dst, self.dst_port,
- self.src_net, self.dst_net)
-
- def as_call_list(self, index=None):
- if self.dst_port is not None:
- self.dst = self.dst + ':' + self.dst_port
- cmd = ['-t', 'nat', '-I', 'PREROUTING']
- if index is not None:
- cmd.append(str(index))
- cmd.extend(('-i', self.dev, '-j', 'DNAT', '--to', self.dst,
- '-p', self.protocol, '--dport', self.port))
- if self.src_net is not None:
- cmd.extend(('-s', self.src_net))
- if self.dst_net is not None:
- cmd.extend(('-d', self.dst_net))
- return cmd
-
-class PortForwardHandler(ListSubHandler):
- r"""PortForwardHandler(parent) -> PortForwardHandler instance.
-
- This class is a helper for NatHandler to do all the work related to port
- forwarding.
-
- parent - The parent service handler.
- """
-
- handler_help = u"Manage NAT port forwarding."
-
- _cont_subhandler_attr = 'ports'
- _cont_subhandler_class = PortForward
-
-class SNat(Sequence):
- r"""SNat(dev, src[, src_net]) -> SNat instance.
-
- dev - Netword device to use.
- src - Source IP address.
- src_net - Source network to apply the NAT (as IP/mask).
- """
-
- def __init__(self, dev, src, src_net=None):
- r"Initialize object, see class documentation for details."
- # TODO Validate
- self.dev = dev
- self.src = src
- self.src_net = src_net
-
- def update(self, dev=None, src=None, src_net=None):
- r"update([dev[, ...]]) -> Update the values of a snat (see class doc)."
- # TODO Validate
- if dev is not None: self.dev = dev
- if src is not None: self.src = src
- if src_net is not None: self.src_net = src_net
-
- def __cmp__(self, other):
- r"Compares two SNat objects."
- return cmp(self.as_tuple(), other.as_tuple())
-
- def as_tuple(self):
- r"Return a tuple representing the snat."
- return (self.dev, self.src, self.src_net)
-
- def as_call_list(self, index=None):
- cmd = ['-t', 'nat', '-I', 'POSTROUTING']
- if index is not None:
- cmd.append(str(index))
- cmd.extend(('-o', self.dev, '-j', 'SNAT', '--to', self.src))
- if self.src_net is not None:
- cmd.extend(('-s', self.src_net))
- return cmd
-
-class SNatHandler(ListSubHandler):
- r"""SNatHandler(parent) -> SNatHandler instance.
-
- This class is a helper for NatHandler to do all the work related to
- Source NAT.
-
- parent - The parent service handler.
- """
-
- handler_help = u"Manage source NAT."
-
- _cont_subhandler_attr = 'snats'
- _cont_subhandler_class = SNat
-
-class Masq(Sequence):
- r"""Masq(dev, src_net) -> Masq instance.
-
- dev - Netword device to use.
- src_net - Source network to apply the masquerade (as IP/mask).
- """
-
- def __init__(self, dev, src_net):
- r"Initialize object, see class documentation for details."
- # TODO Validate
- self.dev = dev
- self.src_net = src_net
-
- def update(self, dev=None, src_net=None):
- r"update([dev[, ...]]) -> Update the values of a masq (see class doc)."
- # TODO Validate
- if dev is not None: self.dev = dev
- if src_net is not None: self.src_net = src_net
-
- def __cmp__(self, other):
- r"Compares two Masq objects."
- return cmp(self.as_tuple(), other.as_tuple())
-
- def as_tuple(self):
- r"Return a tuple representing the masquerade."
- return (self.dev, self.src_net)
-
- def as_call_list(self, index=None):
- cmd = ['-t', 'nat', '-I', 'POSTROUTING']
- if index is not None:
- cmd.append(str(index))
- cmd.extend(('-o', self.dev, '-j', 'MASQUERADE', '-s', self.src_net))
- return cmd
-
-class MasqHandler(ListSubHandler):
- r"""MasqHandler(parent) -> MasqHandler instance.
-
- This class is a helper for NatHandler to do all the work related to
- masquerading.
-
- parent - The parent service handler.
- """
-
- handler_help = u"Manage NAT masquerading."
-
- _cont_subhandler_attr = 'masqs'
- _cont_subhandler_class = Masq
-
-class NatHandler(Restorable, ConfigWriter, ReloadHandler, ServiceHandler,
- TransactionalHandler):
- r"""NatHandler([pickle_dir[, config_dir]]) -> NatHandler instance.
-
- Handles NAT commands using iptables.
-
- pickle_dir - Directory where to write the persistent configuration data.
-
- config_dir - Directory where to store de generated configuration files.
-
- Both defaults to the current working directory.
- """
-
- handler_help = u"Manage NAT (Network Address Translation) service."
-
- _persistent_attrs = ('ports', 'snats', 'masqs')
-
- _restorable_defaults = dict(
- ports=list(),
- snats=list(),
- masqs=list(),
- )
-
- def _service_start(self):
- log.debug(u'NatHandler._service_start(): flushing nat table')
- call(('iptables', '-t', 'nat', '-F'))
- for (index, port) in enumerate(self.ports):
- log.debug(u'NatHandler._service_start: adding port %r', port)
- call(['iptables'] + port.as_call_list(index+1))
- for (index, snat) in enumerate(self.snats):
- log.debug(u'NatHandler._service_start: adding snat %r', snat)
- call(['iptables'] + snat.as_call_list(index+1))
- for (index, masq) in enumerate(self.masqs):
- log.debug(u'NatHandler._service_start: adding masq %r', masq)
- call(['iptables'] + masq.as_call_list(index+1))
-
- def _service_stop(self):
- log.debug(u'NatHandler._service_stop(): flushing nat table')
- call(('iptables', '-t', 'nat', '-F'))
-
- _service_restart = _service_start
-
- def __init__(self, pickle_dir='.'):
- r"Initialize the object, see class documentation for details."
- log.debug(u'NatHandler(%r)', pickle_dir)
- self._persistent_dir = pickle_dir
- ServiceHandler.__init__(self)
- self.forward = PortForwardHandler(self)
- self.snat = SNatHandler(self)
- self.masq = MasqHandler(self)
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- import os
-
- handler = NatHandler()
-
- def dump():
- print '-' * 80
- print 'Forwarded ports:'
- print handler.forward.show()
- print '-' * 10
- print 'SNat:'
- print handler.snat.show()
- print '-' * 10
- print 'Masq:'
- print handler.masq.show()
- print '-' * 80
-
- dump()
- handler.forward.add('eth0','tcp','80', '192.168.0.9', '8080')
- handler.forward.update(0, dst_net='192.168.0.188/32')
- handler.forward.add('eth0', 'udp', '53', '192.168.1.0')
- handler.commit()
- handler.stop()
- dump()
- handler.snat.add('eth0', '192.168.0.9')
- handler.snat.update(0, src_net='192.168.0.188/32')
- handler.snat.add('eth0', '192.168.1.0')
- handler.commit()
- dump()
- dump()
- handler.masq.add('eth0', '192.168.0.9/24')
- handler.masq.update(0, src_net='192.168.0.188/30')
- handler.masq.add('eth1', '192.168.1.0/24')
- handler.commit()
- dump()
-
- os.system('rm -f *.pkl')
-
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+from os import path
+import logging ; log = logging.getLogger('pymin.services.nat')
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import Handler, handler, HandlerError
+from pymin.service.util import Restorable, ConfigWriter, RestartHandler, \
+ ReloadHandler, TransactionalHandler, \
+ ServiceHandler, ListSubHandler, call
+
+__all__ = ('NatHandler', 'get_service')
+
+
+def get_service(config):
+ return NatHandler(config.nat.pickle_dir)
+
+
+class PortForward(Sequence):
+ r"""PortForward(dev, protocol, port, dst[, dst_port[, ...]]) -> PortForward.
+
+ dev - Netword device to use.
+ protocol - TCP or UDP.
+ port - Port to forward.
+ dst - Destination IP address.
+ dst_port - Destination port (at dst).
+ src_net - Source network to apply the forward (as IP/mask).
+ dst_net - Source network to apply the forward (as IP/mask).
+ """
+
+ def __init__(self, dev, protocol, port, dst, dst_port=None, src_net=None,
+ dst_net=None):
+ r"Initialize object, see class documentation for details."
+ # TODO Validate
+ self.dev = dev
+ self.protocol = protocol
+ self.port = port
+ self.dst = dst
+ self.dst_port = dst_port
+ self.src_net = src_net
+ self.dst_net = dst_net
+
+ def update(self, dev=None, protocol=None, port=None, dst=None,
+ dst_port=None, src_net=None, dst_net=None):
+ r"update([dev[, ...]]) -> Update the values of a port (see class doc)."
+ # TODO Validate
+ if dev is not None: self.dev = dev
+ if protocol is not None: self.protocol = protocol
+ if port is not None: self.port = port
+ if dst is not None: self.dst = dst
+ if dst_port is not None: self.dst_port = dst_port
+ if src_net is not None: self.src_net = src_net
+ if dst_net is not None: self.dst_net = dst_net
+
+ def as_tuple(self):
+ r"Return a tuple representing the port forward."
+ return (self.dev, self.protocol, self.port, self.dst, self.dst_port,
+ self.src_net, self.dst_net)
+
+ def as_call_list(self, index=None):
+ if self.dst_port is not None:
+ self.dst = self.dst + ':' + self.dst_port
+ cmd = ['-t', 'nat', '-I', 'PREROUTING']
+ if index is not None:
+ cmd.append(str(index))
+ cmd.extend(('-i', self.dev, '-j', 'DNAT', '--to', self.dst,
+ '-p', self.protocol, '--dport', self.port))
+ if self.src_net is not None:
+ cmd.extend(('-s', self.src_net))
+ if self.dst_net is not None:
+ cmd.extend(('-d', self.dst_net))
+ return cmd
+
+class PortForwardHandler(ListSubHandler):
+ r"""PortForwardHandler(parent) -> PortForwardHandler instance.
+
+ This class is a helper for NatHandler to do all the work related to port
+ forwarding.
+
+ parent - The parent service handler.
+ """
+
+ handler_help = u"Manage NAT port forwarding."
+
+ _cont_subhandler_attr = 'ports'
+ _cont_subhandler_class = PortForward
+
+class SNat(Sequence):
+ r"""SNat(dev, src[, src_net]) -> SNat instance.
+
+ dev - Netword device to use.
+ src - Source IP address.
+ src_net - Source network to apply the NAT (as IP/mask).
+ """
+
+ def __init__(self, dev, src, src_net=None):
+ r"Initialize object, see class documentation for details."
+ # TODO Validate
+ self.dev = dev
+ self.src = src
+ self.src_net = src_net
+
+ def update(self, dev=None, src=None, src_net=None):
+ r"update([dev[, ...]]) -> Update the values of a snat (see class doc)."
+ # TODO Validate
+ if dev is not None: self.dev = dev
+ if src is not None: self.src = src
+ if src_net is not None: self.src_net = src_net
+
+ def __cmp__(self, other):
+ r"Compares two SNat objects."
+ return cmp(self.as_tuple(), other.as_tuple())
+
+ def as_tuple(self):
+ r"Return a tuple representing the snat."
+ return (self.dev, self.src, self.src_net)
+
+ def as_call_list(self, index=None):
+ cmd = ['-t', 'nat', '-I', 'POSTROUTING']
+ if index is not None:
+ cmd.append(str(index))
+ cmd.extend(('-o', self.dev, '-j', 'SNAT', '--to', self.src))
+ if self.src_net is not None:
+ cmd.extend(('-s', self.src_net))
+ return cmd
+
+class SNatHandler(ListSubHandler):
+ r"""SNatHandler(parent) -> SNatHandler instance.
+
+ This class is a helper for NatHandler to do all the work related to
+ Source NAT.
+
+ parent - The parent service handler.
+ """
+
+ handler_help = u"Manage source NAT."
+
+ _cont_subhandler_attr = 'snats'
+ _cont_subhandler_class = SNat
+
+class Masq(Sequence):
+ r"""Masq(dev, src_net) -> Masq instance.
+
+ dev - Netword device to use.
+ src_net - Source network to apply the masquerade (as IP/mask).
+ """
+
+ def __init__(self, dev, src_net):
+ r"Initialize object, see class documentation for details."
+ # TODO Validate
+ self.dev = dev
+ self.src_net = src_net
+
+ def update(self, dev=None, src_net=None):
+ r"update([dev[, ...]]) -> Update the values of a masq (see class doc)."
+ # TODO Validate
+ if dev is not None: self.dev = dev
+ if src_net is not None: self.src_net = src_net
+
+ def __cmp__(self, other):
+ r"Compares two Masq objects."
+ return cmp(self.as_tuple(), other.as_tuple())
+
+ def as_tuple(self):
+ r"Return a tuple representing the masquerade."
+ return (self.dev, self.src_net)
+
+ def as_call_list(self, index=None):
+ cmd = ['-t', 'nat', '-I', 'POSTROUTING']
+ if index is not None:
+ cmd.append(str(index))
+ cmd.extend(('-o', self.dev, '-j', 'MASQUERADE', '-s', self.src_net))
+ return cmd
+
+class MasqHandler(ListSubHandler):
+ r"""MasqHandler(parent) -> MasqHandler instance.
+
+ This class is a helper for NatHandler to do all the work related to
+ masquerading.
+
+ parent - The parent service handler.
+ """
+
+ handler_help = u"Manage NAT masquerading."
+
+ _cont_subhandler_attr = 'masqs'
+ _cont_subhandler_class = Masq
+
+class NatHandler(Restorable, ConfigWriter, ReloadHandler, ServiceHandler,
+ TransactionalHandler):
+ r"""NatHandler([pickle_dir[, config_dir]]) -> NatHandler instance.
+
+ Handles NAT commands using iptables.
+
+ pickle_dir - Directory where to write the persistent configuration data.
+
+ config_dir - Directory where to store de generated configuration files.
+
+ Both defaults to the current working directory.
+ """
+
+ handler_help = u"Manage NAT (Network Address Translation) service."
+
+ _persistent_attrs = ('ports', 'snats', 'masqs')
+
+ _restorable_defaults = dict(
+ ports=list(),
+ snats=list(),
+ masqs=list(),
+ )
+
+ def _service_start(self):
+ log.debug(u'NatHandler._service_start(): flushing nat table')
+ call(('iptables', '-t', 'nat', '-F'))
+ for (index, port) in enumerate(self.ports):
+ log.debug(u'NatHandler._service_start: adding port %r', port)
+ call(['iptables'] + port.as_call_list(index+1))
+ for (index, snat) in enumerate(self.snats):
+ log.debug(u'NatHandler._service_start: adding snat %r', snat)
+ call(['iptables'] + snat.as_call_list(index+1))
+ for (index, masq) in enumerate(self.masqs):
+ log.debug(u'NatHandler._service_start: adding masq %r', masq)
+ call(['iptables'] + masq.as_call_list(index+1))
+
+ def _service_stop(self):
+ log.debug(u'NatHandler._service_stop(): flushing nat table')
+ call(('iptables', '-t', 'nat', '-F'))
+
+ _service_restart = _service_start
+
+ def __init__(self, pickle_dir='.'):
+ r"Initialize the object, see class documentation for details."
+ log.debug(u'NatHandler(%r)', pickle_dir)
+ self._persistent_dir = pickle_dir
+ ServiceHandler.__init__(self)
+ self.forward = PortForwardHandler(self)
+ self.snat = SNatHandler(self)
+ self.masq = MasqHandler(self)
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ import os
+
+ handler = NatHandler()
+
+ def dump():
+ print '-' * 80
+ print 'Forwarded ports:'
+ print handler.forward.show()
+ print '-' * 10
+ print 'SNat:'
+ print handler.snat.show()
+ print '-' * 10
+ print 'Masq:'
+ print handler.masq.show()
+ print '-' * 80
+
+ dump()
+ handler.forward.add('eth0','tcp','80', '192.168.0.9', '8080')
+ handler.forward.update(0, dst_net='192.168.0.188/32')
+ handler.forward.add('eth0', 'udp', '53', '192.168.1.0')
+ handler.commit()
+ handler.stop()
+ dump()
+ handler.snat.add('eth0', '192.168.0.9')
+ handler.snat.update(0, src_net='192.168.0.188/32')
+ handler.snat.add('eth0', '192.168.1.0')
+ handler.commit()
+ dump()
+ dump()
+ handler.masq.add('eth0', '192.168.0.9/24')
+ handler.masq.update(0, src_net='192.168.0.188/30')
+ handler.masq.add('eth1', '192.168.1.0/24')
+ handler.commit()
+ dump()
+
+ os.system('rm -f *.pkl')
+
# vim: set encoding=utf-8 et sw=4 sts=4 :
-import os
-import subprocess
-from os import path
-from signal import SIGTERM
-import logging ; log = logging.getLogger('pymin.services.ppp')
-
-from pymin.seqtools import Sequence
-from pymin.dispatcher import Handler, handler, HandlerError
-from pymin.service.util import Restorable, ConfigWriter, ReloadHandler, \
- TransactionalHandler, DictSubHandler, call
-
-__all__ = ('PppHandler', 'get_service')
-
+from handler import PppHandler
def get_service(config):
return PppHandler(config.ppp.pickle_dir, config.ppp.config_dir)
-
-class ConnectionError(HandlerError, KeyError):
- r"""
- ConnectionError(hostname) -> ConnectionError instance
-
- This is the base exception for all connection related errors.
- """
-
- def __init__(self, connection):
- r"Initialize the object. See class documentation for more info."
- self.message = u'Connection error: "%s"' % connection
-
-class ConnectionNotFoundError(ConnectionError):
- def __init__(self, connection):
- r"Initialize the object. See class documentation for more info."
- self.message = u'Connection not found error: "%s"' % connection
-
-class Connection(Sequence):
-
- def __init__(self, name, username, password, type, **kw):
- self.name = name
- self.username = username
- self.password = password
- self.type = type
- self._running = False
- if type == 'OE':
- if not 'device' in kw:
- raise ConnectionError('Bad arguments for type=OE')
- self.device = kw['device']
- elif type == 'TUNNEL':
- if not 'server' in kw:
- raise ConnectionError('Bad arguments for type=TUNNEL')
- self.server = kw['server']
- self.username = self.username.replace('\\','\\\\')
- elif type == 'PPP':
- if not 'device' in kw:
- raise ConnectionError('Bad arguments for type=PPP')
- self.device = kw['device']
- else:
- raise ConnectionError('Bad arguments, unknown or unspecified type')
-
- def as_tuple(self):
- if self.type == 'TUNNEL':
- return (self.name, self.username, self.password, self.type, self.server)
- elif self.type == 'PPP' or self.type == 'OE':
- return (self.name, self.username, self.password, self.type, self.device)
-
- def update(self, device=None, username=None, password=None):
- if device is not None:
- self.device = device
- if username is not None:
- self.username = username
- if password is not None:
- self.password = password
-
-
-class ConnectionHandler(DictSubHandler):
-
- handler_help = u"Manages connections for the ppp service"
-
- _cont_subhandler_attr = 'conns'
- _cont_subhandler_class = Connection
-
-class PppHandler(Restorable, ConfigWriter, ReloadHandler, TransactionalHandler):
-
- handler_help = u"Manage ppp service"
-
- _persistent_attrs = ['conns']
-
- _restorable_defaults = dict(
- conns = dict(),
- )
-
- _config_writer_files = ('options.X','pap-secrets','chap-secrets','nameX')
- _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
-
- def __init__(self, pickle_dir='.', config_dir='.'):
- r"Initialize Ppphandler object, see class documentation for details."
- log.debug(u'PppHandler(%r, %r)', pickle_dir, config_dir)
- self._persistent_dir = pickle_dir
- self._config_writer_cfg_dir = config_dir
- self._config_build_templates()
- self._restore()
- log.debug(u'PppHandler(): restoring connections...')
- for conn in self.conns.values():
- if conn._running:
- log.debug(u'PppHandler(): starting connection %r', conn.name)
- conn._running = False
- self.start(conn.name)
- self.conn = ConnectionHandler(self)
-
- @handler(u'Start one or all the connections.')
- def start(self, name=None):
- log.debug(u'PppHandler.start(%r)', name)
- names = [name]
- if name is None:
- names = self.conns.keys()
- for name in names:
- if name in self.conns:
- if not self.conns[name]._running:
- log.debug(u'PppHandler.start: starting connection %r', name)
- call(('pppd', 'call', name))
- self.conns[name]._running = True
- self._dump_attr('conns')
- else:
- log.debug(u'PppHandler.start: connection not found')
- raise ConnectionNotFoundError(name)
-
- @handler(u'Stop one or all the connections.')
- def stop(self, name=None):
- log.debug(u'PppHandler.stop(%r)', name)
- names = [name]
- names = [name]
- if name is None:
- names = self.conns.keys()
- for name in names:
- if name in self.conns:
- if self.conns[name]._running:
- pid_file = '/var/run/ppp-' + name + '.pid'
- log.debug(u'PppHandler.stop: getting pid from %r', pid_file)
- if path.exists(pid_file):
- pid = file(pid_file).readline()
- pid = int(pid.strip())
- try:
- log.debug(u'PppHandler.stop: killing pid %r', pid)
- os.kill(pid, SIGTERM)
- except OSError, e:
- log.debug(u'PppHandler.stop: error killing: %r', e)
- else:
- log.debug(u'PppHandler.stop: pid file not found')
- self.conns[name]._running = False
- self._dump_attr('conns')
- else:
- log.debug(u'PppHandler.stop: connection not running')
- else:
- log.debug(u'PppHandler.stop: connection not found')
- raise ConnectionNotFoundError(name)
-
- @handler(u'Restart one or all the connections (even disconnected ones).')
- def restart(self, name=None):
- log.debug(u'PppHandler.restart(%r)', name)
- names = [name]
- if name is None:
- names = self.conns.keys()
- for name in names:
- self.stop(name)
- self.start(name)
-
- @handler(u'Restart only one or all the already running connections.')
- def reload(self, name=None):
- r"reload() -> None :: Reload the configuration of the service."
- log.debug(u'PppHandler.reload(%r)', name)
- names = [name]
- if name is None:
- names = self.conns.keys()
- for name in names:
- if self.conns[name]._running:
- self.stop(name)
- self.start(name)
-
- @handler(u'Tell if the service is running.')
- def running(self, name=None):
- r"reload() -> None :: Reload the configuration of the service."
- log.debug(u'PppHandler.running(%r)', name)
- if name is None:
- return [c.name for c in self.conns.values() if c._running]
- if name in self.conns:
- return int(self.conns[name]._running)
- else:
- log.debug(u'PppHandler.running: connection not found')
- raise ConnectionNotFoundError(name)
-
- def handle_timer(self):
- log.debug(u'PppHandler.handle_timer()')
- for c in self.conns.values():
- log.debug(u'PppHandler.handle_timer: processing connection %r', c)
- p = subprocess.Popen(('pgrep', '-f', 'pppd call ' + c.name),
- stdout=subprocess.PIPE)
- pid = p.communicate()[0]
- if p.returncode == 0 and len(pid) > 0:
- log.debug(u'PppHandler.handle_timer: pid present, running')
- c._running = True
- else:
- log.debug(u'PppHandler.handle_timer: pid absent, NOT running')
- c._running = False
-
- def _write_config(self):
- r"_write_config() -> None :: Generate all the configuration files."
- log.debug(u'PppHandler._write_config()')
- #guardo los pass que van el pap-secrets
- vars_pap = dict()
- for conn in self.conns.values():
- if conn.type == 'OE' or conn.type == 'PPP':
- vars_pap[conn.name] = conn
- vars = dict(conns=vars_pap)
- self._write_single_config('pap-secrets','pap-secrets',vars)
- #guardo los pass que van el chap-secrets
- vars_chap = dict()
- for conn in self.conns.values():
- if conn.type == 'TUNNEL' :
- vars_chap[conn.name] = conn
- vars = dict(conns=vars_chap)
- self._write_single_config('chap-secrets','chap-secrets',vars)
- #guard las conns
- for conn in self.conns.values():
- vars = dict(conn=conn)
- self._write_single_config('nameX',conn.name, vars)
- self._write_single_config('options.X','options.' + conn.name, vars)
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- p = PppHandler()
- p.conn.add('ppp_c','nico','nico',type='PPP',device='tty0')
- p.conn.add('pppoe_c','fede','fede',type='OE',device='tty1')
- p.conn.add('ppptunnel_c','dominio\luca','luca',type='TUNNEL',server='192.168.0.23')
- p.commit()
- print p.conn.list()
- print p.conn.show()
-
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+import os
+import subprocess
+from os import path
+from signal import SIGTERM
+import logging ; log = logging.getLogger('pymin.services.ppp')
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import Handler, handler, HandlerError
+from pymin.service.util import Restorable, ConfigWriter, ReloadHandler, \
+ TransactionalHandler, DictSubHandler, call
+
+__all__ = ('PppHandler', 'get_service')
+
+
+def get_service(config):
+ return PppHandler(config.ppp.pickle_dir, config.ppp.config_dir)
+
+
+class ConnectionError(HandlerError, KeyError):
+ r"""
+ ConnectionError(hostname) -> ConnectionError instance
+
+ This is the base exception for all connection related errors.
+ """
+
+ def __init__(self, connection):
+ r"Initialize the object. See class documentation for more info."
+ self.message = u'Connection error: "%s"' % connection
+
+class ConnectionNotFoundError(ConnectionError):
+ def __init__(self, connection):
+ r"Initialize the object. See class documentation for more info."
+ self.message = u'Connection not found error: "%s"' % connection
+
+class Connection(Sequence):
+
+ def __init__(self, name, username, password, type, **kw):
+ self.name = name
+ self.username = username
+ self.password = password
+ self.type = type
+ self._running = False
+ if type == 'OE':
+ if not 'device' in kw:
+ raise ConnectionError('Bad arguments for type=OE')
+ self.device = kw['device']
+ elif type == 'TUNNEL':
+ if not 'server' in kw:
+ raise ConnectionError('Bad arguments for type=TUNNEL')
+ self.server = kw['server']
+ self.username = self.username.replace('\\','\\\\')
+ elif type == 'PPP':
+ if not 'device' in kw:
+ raise ConnectionError('Bad arguments for type=PPP')
+ self.device = kw['device']
+ else:
+ raise ConnectionError('Bad arguments, unknown or unspecified type')
+
+ def as_tuple(self):
+ if self.type == 'TUNNEL':
+ return (self.name, self.username, self.password, self.type, self.server)
+ elif self.type == 'PPP' or self.type == 'OE':
+ return (self.name, self.username, self.password, self.type, self.device)
+
+ def update(self, device=None, username=None, password=None):
+ if device is not None:
+ self.device = device
+ if username is not None:
+ self.username = username
+ if password is not None:
+ self.password = password
+
+
+class ConnectionHandler(DictSubHandler):
+
+ handler_help = u"Manages connections for the ppp service"
+
+ _cont_subhandler_attr = 'conns'
+ _cont_subhandler_class = Connection
+
+class PppHandler(Restorable, ConfigWriter, ReloadHandler, TransactionalHandler):
+
+ handler_help = u"Manage ppp service"
+
+ _persistent_attrs = ['conns']
+
+ _restorable_defaults = dict(
+ conns = dict(),
+ )
+
+ _config_writer_files = ('options.X','pap-secrets','chap-secrets','nameX')
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='.'):
+ r"Initialize Ppphandler object, see class documentation for details."
+ log.debug(u'PppHandler(%r, %r)', pickle_dir, config_dir)
+ self._persistent_dir = pickle_dir
+ self._config_writer_cfg_dir = config_dir
+ self._config_build_templates()
+ self._restore()
+ log.debug(u'PppHandler(): restoring connections...')
+ for conn in self.conns.values():
+ if conn._running:
+ log.debug(u'PppHandler(): starting connection %r', conn.name)
+ conn._running = False
+ self.start(conn.name)
+ self.conn = ConnectionHandler(self)
+
+ @handler(u'Start one or all the connections.')
+ def start(self, name=None):
+ log.debug(u'PppHandler.start(%r)', name)
+ names = [name]
+ if name is None:
+ names = self.conns.keys()
+ for name in names:
+ if name in self.conns:
+ if not self.conns[name]._running:
+ log.debug(u'PppHandler.start: starting connection %r', name)
+ call(('pppd', 'call', name))
+ self.conns[name]._running = True
+ self._dump_attr('conns')
+ else:
+ log.debug(u'PppHandler.start: connection not found')
+ raise ConnectionNotFoundError(name)
+
+ @handler(u'Stop one or all the connections.')
+ def stop(self, name=None):
+ log.debug(u'PppHandler.stop(%r)', name)
+ names = [name]
+ names = [name]
+ if name is None:
+ names = self.conns.keys()
+ for name in names:
+ if name in self.conns:
+ if self.conns[name]._running:
+ pid_file = '/var/run/ppp-' + name + '.pid'
+ log.debug(u'PppHandler.stop: getting pid from %r', pid_file)
+ if path.exists(pid_file):
+ pid = file(pid_file).readline()
+ pid = int(pid.strip())
+ try:
+ log.debug(u'PppHandler.stop: killing pid %r', pid)
+ os.kill(pid, SIGTERM)
+ except OSError, e:
+ log.debug(u'PppHandler.stop: error killing: %r', e)
+ else:
+ log.debug(u'PppHandler.stop: pid file not found')
+ self.conns[name]._running = False
+ self._dump_attr('conns')
+ else:
+ log.debug(u'PppHandler.stop: connection not running')
+ else:
+ log.debug(u'PppHandler.stop: connection not found')
+ raise ConnectionNotFoundError(name)
+
+ @handler(u'Restart one or all the connections (even disconnected ones).')
+ def restart(self, name=None):
+ log.debug(u'PppHandler.restart(%r)', name)
+ names = [name]
+ if name is None:
+ names = self.conns.keys()
+ for name in names:
+ self.stop(name)
+ self.start(name)
+
+ @handler(u'Restart only one or all the already running connections.')
+ def reload(self, name=None):
+ r"reload() -> None :: Reload the configuration of the service."
+ log.debug(u'PppHandler.reload(%r)', name)
+ names = [name]
+ if name is None:
+ names = self.conns.keys()
+ for name in names:
+ if self.conns[name]._running:
+ self.stop(name)
+ self.start(name)
+
+ @handler(u'Tell if the service is running.')
+ def running(self, name=None):
+ r"reload() -> None :: Reload the configuration of the service."
+ log.debug(u'PppHandler.running(%r)', name)
+ if name is None:
+ return [c.name for c in self.conns.values() if c._running]
+ if name in self.conns:
+ return int(self.conns[name]._running)
+ else:
+ log.debug(u'PppHandler.running: connection not found')
+ raise ConnectionNotFoundError(name)
+
+ def handle_timer(self):
+ log.debug(u'PppHandler.handle_timer()')
+ for c in self.conns.values():
+ log.debug(u'PppHandler.handle_timer: processing connection %r', c)
+ p = subprocess.Popen(('pgrep', '-f', 'pppd call ' + c.name),
+ stdout=subprocess.PIPE)
+ pid = p.communicate()[0]
+ if p.returncode == 0 and len(pid) > 0:
+ log.debug(u'PppHandler.handle_timer: pid present, running')
+ c._running = True
+ else:
+ log.debug(u'PppHandler.handle_timer: pid absent, NOT running')
+ c._running = False
+
+ def _write_config(self):
+ r"_write_config() -> None :: Generate all the configuration files."
+ log.debug(u'PppHandler._write_config()')
+ #guardo los pass que van el pap-secrets
+ vars_pap = dict()
+ for conn in self.conns.values():
+ if conn.type == 'OE' or conn.type == 'PPP':
+ vars_pap[conn.name] = conn
+ vars = dict(conns=vars_pap)
+ self._write_single_config('pap-secrets','pap-secrets',vars)
+ #guardo los pass que van el chap-secrets
+ vars_chap = dict()
+ for conn in self.conns.values():
+ if conn.type == 'TUNNEL' :
+ vars_chap[conn.name] = conn
+ vars = dict(conns=vars_chap)
+ self._write_single_config('chap-secrets','chap-secrets',vars)
+ #guard las conns
+ for conn in self.conns.values():
+ vars = dict(conn=conn)
+ self._write_single_config('nameX',conn.name, vars)
+ self._write_single_config('options.X','options.' + conn.name, vars)
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ p = PppHandler()
+ p.conn.add('ppp_c','nico','nico',type='PPP',device='tty0')
+ p.conn.add('pppoe_c','fede','fede',type='OE',device='tty1')
+ p.conn.add('ppptunnel_c','dominio\luca','luca',type='TUNNEL',server='192.168.0.23')
+ p.commit()
+ print p.conn.list()
+ print p.conn.show()
+
# vim: set encoding=utf-8 et sw=4 sts=4 :
-from os import path
-import logging ; log = logging.getLogger('pymin.services.proxy')
-
-from pymin.seqtools import Sequence
-from pymin.dispatcher import Handler, handler, HandlerError
-from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
- TransactionalHandler, ParametersHandler, \
- DictSubHandler
-
-import crypt
-
-
-__all__ = ('ProxyHandler', 'get_service')
-
+from handler import ProxyHandler
def get_service(config):
return ProxyHandler(config.proxy.pickle_dir, config.proxy.config_dir)
-
-class Host(Sequence):
- def __init__(self,ip):
- self.ip = ip
- def as_tuple(self):
- return (self.ip,)
-
-# TODO convert to a SetSubHandler
-
-class HostHandler(DictSubHandler):
-
- handler_help = u"Manage proxy hosts"
-
- _cont_subhandler_attr = 'hosts'
- _cont_subhandler_class = Host
-
-class User(Sequence):
- def __init__(self, name, password):
- self.name = name
- self.password = crypt.crypt(password,'BA')
- def as_tuple(self):
- return (self.name, self.password)
- def update(self, password=None):
- if password is not None:
- self.password = crypt.crypt(password,'BA')
-
-class UserHandler(DictSubHandler):
-
- handler_help = u"Manage proxy users"
-
- _cont_subhandler_attr = 'users'
- _cont_subhandler_class = User
-
-class ProxyHandler(Restorable, ConfigWriter, InitdHandler,
- TransactionalHandler, ParametersHandler):
-
- handler_help = u"Manage proxy service"
-
- _initd_name = 'squid'
-
- _persistent_attrs = ('params', 'hosts', 'users')
-
- _restorable_defaults = dict(
- hosts = dict(),
- params = dict(
- ip = '192.168.0.1',
- port = '8080',
- ),
- users = dict(),
- )
-
- _config_writer_files = ('squid.conf','users.conf')
- _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
-
- def __init__(self, pickle_dir='.', config_dir='.'):
- r"Initialize DhcpHandler object, see class documentation for details."
- log.debug(u'ProxyHandler(%r, %r)', pickle_dir, config_dir)
- self._persistent_dir = pickle_dir
- self._config_writer_cfg_dir = config_dir
- self._config_build_templates()
- InitdHandler.__init__(self)
- self.host = HostHandler(self)
- self.user = UserHandler(self)
-
- def _get_config_vars(self, config_file):
- if config_file == 'squid.conf':
- return dict(hosts=self.hosts.values(), **self.params)
- return dict(users=self.users)
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- px = ProxyHandler()
- px.set('ip','192.66.66.66')
- px.set('port','666')
- px.host.add('192.168.0.25.25')
- px.host.add('192.168.0.25.26')
- px.host.add('192.168.0.25.27')
- px.host.delete('192.168.0.25.27')
- px.user.add('lala','soronga')
- px.user.add('culo','sarasa')
- px.commit()
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+from os import path
+import logging ; log = logging.getLogger('pymin.services.proxy')
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import Handler, handler, HandlerError
+from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
+ TransactionalHandler, ParametersHandler, \
+ DictSubHandler
+
+import crypt
+
+
+__all__ = ('ProxyHandler', 'get_service')
+
+
+def get_service(config):
+ return ProxyHandler(config.proxy.pickle_dir, config.proxy.config_dir)
+
+
+class Host(Sequence):
+ def __init__(self,ip):
+ self.ip = ip
+ def as_tuple(self):
+ return (self.ip,)
+
+# TODO convert to a SetSubHandler
+
+class HostHandler(DictSubHandler):
+
+ handler_help = u"Manage proxy hosts"
+
+ _cont_subhandler_attr = 'hosts'
+ _cont_subhandler_class = Host
+
+class User(Sequence):
+ def __init__(self, name, password):
+ self.name = name
+ self.password = crypt.crypt(password,'BA')
+ def as_tuple(self):
+ return (self.name, self.password)
+ def update(self, password=None):
+ if password is not None:
+ self.password = crypt.crypt(password,'BA')
+
+class UserHandler(DictSubHandler):
+
+ handler_help = u"Manage proxy users"
+
+ _cont_subhandler_attr = 'users'
+ _cont_subhandler_class = User
+
+class ProxyHandler(Restorable, ConfigWriter, InitdHandler,
+ TransactionalHandler, ParametersHandler):
+
+ handler_help = u"Manage proxy service"
+
+ _initd_name = 'squid'
+
+ _persistent_attrs = ('params', 'hosts', 'users')
+
+ _restorable_defaults = dict(
+ hosts = dict(),
+ params = dict(
+ ip = '192.168.0.1',
+ port = '8080',
+ ),
+ users = dict(),
+ )
+
+ _config_writer_files = ('squid.conf','users.conf')
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='.'):
+ r"Initialize DhcpHandler object, see class documentation for details."
+ log.debug(u'ProxyHandler(%r, %r)', pickle_dir, config_dir)
+ self._persistent_dir = pickle_dir
+ self._config_writer_cfg_dir = config_dir
+ self._config_build_templates()
+ InitdHandler.__init__(self)
+ self.host = HostHandler(self)
+ self.user = UserHandler(self)
+
+ def _get_config_vars(self, config_file):
+ if config_file == 'squid.conf':
+ return dict(hosts=self.hosts.values(), **self.params)
+ return dict(users=self.users)
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ px = ProxyHandler()
+ px.set('ip','192.66.66.66')
+ px.set('port','666')
+ px.host.add('192.168.0.25.25')
+ px.host.add('192.168.0.25.26')
+ px.host.add('192.168.0.25.27')
+ px.host.delete('192.168.0.25.27')
+ px.user.add('lala','soronga')
+ px.user.add('culo','sarasa')
+ px.commit()
# vim: set encoding=utf-8 et sw=4 sts=4 :
-from subprocess import Popen, PIPE
-from os import path
-
-from pymin.seqtools import Sequence
-from pymin.dispatcher import handler, HandlerError, Handler
-from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
- TransactionalHandler, SubHandler, call, \
- get_network_devices, ListComposedSubHandler, \
- DictComposedSubHandler, ExecutionError
-
-__all__ = ('QoSHandler', 'get_service')
-
+from handler import QoSHandler
def get_service(config):
return QoSHandler(config.qos.pickle_dir, config.qos.config_dir)
-
-class DeviceError(HandlerError):
-
- def __init__(self, dev):
- self.message = u'Devive error : "%s"' % dev
-
-
-class DeviceNotFoundError(DeviceError):
-
- def __init__(self, dev):
- self.message = u'Device not found : "%s"' % dev
-
-
-class ClassError(HandlerError):
-
- def __init__(self, cls):
- self.message = u'Class error : "%s"' % cls
-
-
-class ClassNotFoundError(ClassError):
-
- def __init__(self, cls):
- self.message = u'Class not found : "%s"' % cls
-
-
-class ClassAlreadyExistsError(ClassError):
-
- def __init__(self, cls):
- self.message = u'Class already exists : "%s"' % cls
-
-
-class HostError(HandlerError):
-
- def __init__(self, host):
- self.message = u'Host error : "%s"' % host
-
-
-class HostNotFoundError(HostError):
-
- def __init__(self, ip):
- self.message = u'Host not found : "%s"' % host
-
-
-class HostAlreadyExistsError(HostError):
-
- def __init__(self, ip):
- self.message = u'Host already exists : "%s"' % host
-
-
-class Class(Sequence):
-
- def __init__(self, cid, rate=None):
- self.cid = cid
- self.rate = rate
- self.hosts = dict()
-
- def as_tuple(self):
- return (self.cid, self.rate)
-
- def __cmp__(self, other):
- if self.cid == other.cid:
- return 0
- return cmp(id(self), id(other))
-
-
-class ClassHandler(Handler):
-
- def __init__(self, parent):
- self.parent = parent
-
- @handler('Adds a class : add <id> <device> <rate>')
- def add(self, dev, cid, rate):
- if not dev in self.parent.devices:
- raise DeviceNotFoundError(dev)
-
- try:
- self.parent.devices[dev].classes[cid] = Class(cid, rate)
- except ValueError:
- raise ClassAlreadyExistsError(cid + ' -> ' + dev)
-
- @handler(u'Deletes a class : delete <id> <device>')
- def delete(self, dev, cid):
- if not dev in self.parent.devices:
- raise DeviceNotFoundError(dev)
-
- try:
- del self.parent.devices[dev].classes[cid]
- except KeyError:
- raise ClassNotFoundError(cid + ' -> ' + dev)
-
- @handler(u'Lists classes : list <dev>')
- def list(self, dev):
- try:
- k = self.parent.devices[dev].classes.items()
- except KeyError:
- k = dict()
- return k
-
-
-class Host(Sequence):
-
- def __init__(self, ip):
- self.ip = ip
-
- def as_tuple(self):
- return (self.ip)
-
- def __cmp__(self, other):
- if self.ip == other.ip:
- return 0
- return cmp(id(self), id(other))
-
-
-class HostHandler(SubHandler):
-
- def __init__(self, parent):
- self.parent = parent
-
- @handler('Adds a host to a class : add <device> <class id> <ip>')
- def add(self, dev, cid, ip):
- if not dev in self.parent.devices:
- raise DeviceNotFoundError(dev)
-
- if not cid in self.parent.devices[dev].classes:
- raise ClassNotFoundError(cid)
-
- try:
- self.parent.devices[dev].classes[cid].hosts[ip] = Host(ip)
- except ValueError:
- raise HostAlreadyExistsError(h + ' -> ' + dev)
-
- @handler(u'Lists hosts : list <dev> <class id>')
- def list(self, dev, cid):
- try:
- k = self.parent.devices[dev].classes[cid].hosts.keys()
- except KeyError:
- k = dict()
- return k
-
-
-class Device(Sequence):
-
- def __init__(self, name, mac):
- self.name = name
- self.mac = mac
- self.classes = dict()
-
- def as_tuple(self):
- return (self.name, self.mac)
-
-
-class DeviceHandler(SubHandler):
-
- handler_help = u"Manage network devices"
-
- def __init__(self, parent):
- # FIXME remove templates to execute commands
- from mako.template import Template
- self.parent = parent
- template_dir = path.join(path.dirname(__file__), 'templates')
- dev_fn = path.join(template_dir, 'device')
- self.device_template = Template(filename=dev_fn)
-
- @handler(u'Bring the device up')
- def up(self, name):
- if name in self.parent.devices:
- try:
- call(self.device_template.render(dev=name, action='add'), shell=True)
- except ExecutionError:
- pass
- else:
- raise DeviceNotFoundError(name)
-
- @handler(u'Bring the device down')
- def down(self, name):
- if name in self.parent.devices:
- try:
- call(self.device_template.render(dev=name, action='del'), shell=True)
- except ExecutionError:
- pass
- else:
- raise DeviceNotFoundError(name)
-
- @handler(u'List all devices')
- def list(self):
- return self.parent.devices.keys()
-
- @handler(u'Get information about a device')
- def show(self):
- return self.parent.devices.items()
-
-
-class QoSHandler(Restorable, ConfigWriter, TransactionalHandler):
-
- handler_help = u"Manage QoS devices, classes and hosts"
-
- _persistent_attrs = ('devices')
-
- _restorable_defaults = dict(
- devices=dict((dev, Device(dev, mac))
- for (dev, mac) in get_network_devices().items())
- )
-
- _config_writer_files = ('device', 'class_add', 'class_del', 'host_add')
-
- _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
-
- def __init__(self, pickle_dir='.', config_dir='.'):
- r"Initialize QoSHandler object, see class documentation for details."
- self._persistent_dir = pickle_dir
- self._config_writer_cfg_dir = config_dir
- self._config_build_templates()
- self._restore()
- self._write_config()
- self.dev = DeviceHandler(self)
- self.cls = ClassHandler(self)
- self.host = HostHandler(self)
-
- def _write_config(self):
- r"_write_config() -> None :: Execute all commands."
- for device in self.devices.values():
- try:
- call(self._render_config('device', dict(dev=device.name, action='del')), shell=True)
- except ExecutionError:
- pass
-
- try:
- call(self._render_config('device', dict(dev=device.name, action='add')), shell=True)
- except ExecutionError:
- pass
-
- for cls in device.classes.values():
- try:
- call(self._render_config('class_add', dict(
- dev = device.name,
- cid = cls.cid,
- rate = cls.rate
- )
- ), shell=True)
- except ExecutionError:
- pass
-
- for host in cls.hosts.values():
- try:
- call(self._render_config('host_add', dict(
- dev = device.name,
- ip = host.ip,
- cid = cls.cid
- )
- ), shell=True)
- except ExecutionError:
- pass
-
- def handle_timer(self):
- self.refresh_devices()
-
- def refresh_devices(self):
- devices = get_network_devices()
- #add not registered devices
- for k, v in devices.items():
- if k not in self.devices:
- self.devices[k] = Device(k, v)
- #delete dead devices
- for k in self.devices.keys():
- if k not in devices:
- del self.devices[k]
-
-
-if __name__ == '__main__':
-
- qos = QoSHandler()
- print '----------------------'
- qos.commit()
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+from subprocess import Popen, PIPE
+from os import path
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import handler, HandlerError, Handler
+from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
+ TransactionalHandler, SubHandler, call, \
+ get_network_devices, ListComposedSubHandler, \
+ DictComposedSubHandler, ExecutionError
+
+__all__ = ('QoSHandler', 'get_service')
+
+
+def get_service(config):
+ return QoSHandler(config.qos.pickle_dir, config.qos.config_dir)
+
+
+class DeviceError(HandlerError):
+
+ def __init__(self, dev):
+ self.message = u'Devive error : "%s"' % dev
+
+
+class DeviceNotFoundError(DeviceError):
+
+ def __init__(self, dev):
+ self.message = u'Device not found : "%s"' % dev
+
+
+class ClassError(HandlerError):
+
+ def __init__(self, cls):
+ self.message = u'Class error : "%s"' % cls
+
+
+class ClassNotFoundError(ClassError):
+
+ def __init__(self, cls):
+ self.message = u'Class not found : "%s"' % cls
+
+
+class ClassAlreadyExistsError(ClassError):
+
+ def __init__(self, cls):
+ self.message = u'Class already exists : "%s"' % cls
+
+
+class HostError(HandlerError):
+
+ def __init__(self, host):
+ self.message = u'Host error : "%s"' % host
+
+
+class HostNotFoundError(HostError):
+
+ def __init__(self, ip):
+ self.message = u'Host not found : "%s"' % host
+
+
+class HostAlreadyExistsError(HostError):
+
+ def __init__(self, ip):
+ self.message = u'Host already exists : "%s"' % host
+
+
+class Class(Sequence):
+
+ def __init__(self, cid, rate=None):
+ self.cid = cid
+ self.rate = rate
+ self.hosts = dict()
+
+ def as_tuple(self):
+ return (self.cid, self.rate)
+
+ def __cmp__(self, other):
+ if self.cid == other.cid:
+ return 0
+ return cmp(id(self), id(other))
+
+
+class ClassHandler(Handler):
+
+ def __init__(self, parent):
+ self.parent = parent
+
+ @handler('Adds a class : add <id> <device> <rate>')
+ def add(self, dev, cid, rate):
+ if not dev in self.parent.devices:
+ raise DeviceNotFoundError(dev)
+
+ try:
+ self.parent.devices[dev].classes[cid] = Class(cid, rate)
+ except ValueError:
+ raise ClassAlreadyExistsError(cid + ' -> ' + dev)
+
+ @handler(u'Deletes a class : delete <id> <device>')
+ def delete(self, dev, cid):
+ if not dev in self.parent.devices:
+ raise DeviceNotFoundError(dev)
+
+ try:
+ del self.parent.devices[dev].classes[cid]
+ except KeyError:
+ raise ClassNotFoundError(cid + ' -> ' + dev)
+
+ @handler(u'Lists classes : list <dev>')
+ def list(self, dev):
+ try:
+ k = self.parent.devices[dev].classes.items()
+ except KeyError:
+ k = dict()
+ return k
+
+
+class Host(Sequence):
+
+ def __init__(self, ip):
+ self.ip = ip
+
+ def as_tuple(self):
+ return (self.ip)
+
+ def __cmp__(self, other):
+ if self.ip == other.ip:
+ return 0
+ return cmp(id(self), id(other))
+
+
+class HostHandler(SubHandler):
+
+ def __init__(self, parent):
+ self.parent = parent
+
+ @handler('Adds a host to a class : add <device> <class id> <ip>')
+ def add(self, dev, cid, ip):
+ if not dev in self.parent.devices:
+ raise DeviceNotFoundError(dev)
+
+ if not cid in self.parent.devices[dev].classes:
+ raise ClassNotFoundError(cid)
+
+ try:
+ self.parent.devices[dev].classes[cid].hosts[ip] = Host(ip)
+ except ValueError:
+ raise HostAlreadyExistsError(h + ' -> ' + dev)
+
+ @handler(u'Lists hosts : list <dev> <class id>')
+ def list(self, dev, cid):
+ try:
+ k = self.parent.devices[dev].classes[cid].hosts.keys()
+ except KeyError:
+ k = dict()
+ return k
+
+
+class Device(Sequence):
+
+ def __init__(self, name, mac):
+ self.name = name
+ self.mac = mac
+ self.classes = dict()
+
+ def as_tuple(self):
+ return (self.name, self.mac)
+
+
+class DeviceHandler(SubHandler):
+
+ handler_help = u"Manage network devices"
+
+ def __init__(self, parent):
+ # FIXME remove templates to execute commands
+ from mako.template import Template
+ self.parent = parent
+ template_dir = path.join(path.dirname(__file__), 'templates')
+ dev_fn = path.join(template_dir, 'device')
+ self.device_template = Template(filename=dev_fn)
+
+ @handler(u'Bring the device up')
+ def up(self, name):
+ if name in self.parent.devices:
+ try:
+ call(self.device_template.render(dev=name, action='add'), shell=True)
+ except ExecutionError:
+ pass
+ else:
+ raise DeviceNotFoundError(name)
+
+ @handler(u'Bring the device down')
+ def down(self, name):
+ if name in self.parent.devices:
+ try:
+ call(self.device_template.render(dev=name, action='del'), shell=True)
+ except ExecutionError:
+ pass
+ else:
+ raise DeviceNotFoundError(name)
+
+ @handler(u'List all devices')
+ def list(self):
+ return self.parent.devices.keys()
+
+ @handler(u'Get information about a device')
+ def show(self):
+ return self.parent.devices.items()
+
+
+class QoSHandler(Restorable, ConfigWriter, TransactionalHandler):
+
+ handler_help = u"Manage QoS devices, classes and hosts"
+
+ _persistent_attrs = ('devices')
+
+ _restorable_defaults = dict(
+ devices=dict((dev, Device(dev, mac))
+ for (dev, mac) in get_network_devices().items())
+ )
+
+ _config_writer_files = ('device', 'class_add', 'class_del', 'host_add')
+
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='.'):
+ r"Initialize QoSHandler object, see class documentation for details."
+ self._persistent_dir = pickle_dir
+ self._config_writer_cfg_dir = config_dir
+ self._config_build_templates()
+ self._restore()
+ self._write_config()
+ self.dev = DeviceHandler(self)
+ self.cls = ClassHandler(self)
+ self.host = HostHandler(self)
+
+ def _write_config(self):
+ r"_write_config() -> None :: Execute all commands."
+ for device in self.devices.values():
+ try:
+ call(self._render_config('device', dict(dev=device.name, action='del')), shell=True)
+ except ExecutionError:
+ pass
+
+ try:
+ call(self._render_config('device', dict(dev=device.name, action='add')), shell=True)
+ except ExecutionError:
+ pass
+
+ for cls in device.classes.values():
+ try:
+ call(self._render_config('class_add', dict(
+ dev = device.name,
+ cid = cls.cid,
+ rate = cls.rate
+ )
+ ), shell=True)
+ except ExecutionError:
+ pass
+
+ for host in cls.hosts.values():
+ try:
+ call(self._render_config('host_add', dict(
+ dev = device.name,
+ ip = host.ip,
+ cid = cls.cid
+ )
+ ), shell=True)
+ except ExecutionError:
+ pass
+
+ def handle_timer(self):
+ self.refresh_devices()
+
+ def refresh_devices(self):
+ devices = get_network_devices()
+ #add not registered devices
+ for k, v in devices.items():
+ if k not in self.devices:
+ self.devices[k] = Device(k, v)
+ #delete dead devices
+ for k in self.devices.keys():
+ if k not in devices:
+ del self.devices[k]
+
+
+if __name__ == '__main__':
+
+ qos = QoSHandler()
+ print '----------------------'
+ qos.commit()
# vim: set encoding=utf-8 et sw=4 sts=4 :
-import os
-import errno
-import signal
-from os import path
-import logging ; log = logging.getLogger('pymin.services.vpn')
-
-
-from pymin.seqtools import Sequence
-from pymin.dispatcher import Handler, handler, HandlerError
-from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
- TransactionalHandler, DictSubHandler, DictComposedSubHandler, call, ExecutionError
-
-__all__ = ('VpnHandler', 'get_service')
-
+from handler import VpnHandler
def get_service(config):
return VpnHandler(config.vpn.pickle_dir, config.vpn.config_dir)
-
-class Host(Sequence):
- def __init__(self, vpn_src, ip, vpn_src_net, key):
- self.name = vpn_src
- self.ip = ip
- self.src_net = vpn_src_net
- self.pub_key = key
- self._delete = False
-
- def as_tuple(self):
- return(self.name, self.ip, self.src_net, self.pub_key)
-
-class HostHandler(DictComposedSubHandler):
-
- handler_help = u"Manage hosts for a vpn"
- _comp_subhandler_cont = 'vpns'
- _comp_subhandler_attr = 'hosts'
- _comp_subhandler_class = Host
-
-
-class Vpn(Sequence):
- def __init__(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask,
- pub_key=None, priv_key=None):
- self.vpn_src = vpn_src
- self.vpn_dst = vpn_dst
- self.vpn_src_ip = vpn_src_ip
- self.vpn_src_mask = vpn_src_mask
- self.pub_key = pub_key
- self.priv_key = priv_key
- self.hosts = dict()
- self._delete = False
-
- def as_tuple(self):
- return(self.vpn_src, self.vpn_dst, self.vpn_src_ip, self.vpn_src_mask, self.pub_key, self.priv_key)
-
- def update(self, vpn_dst=None, vpn_src_ip=None, vpn_src_mask=None):
- if vpn_dst is not None:
- self.vpn_dst = vpn_dst
- if vpn_src_ip is not None:
- self.vpn_src_ip = vpn_src_ip
- if vpn_src_mask is not None:
- self.vpn_src_mask = vpn_src_mask
-
-
-class VpnHandler(Restorable, ConfigWriter,
- TransactionalHandler, DictSubHandler):
-
- handler_help = u"Manage vpn service"
-
- _cont_subhandler_attr = 'vpns'
- _cont_subhandler_class = Vpn
-
- _persistent_attrs = ('vpns','hosts')
-
- _restorable_defaults = dict(
- vpns = dict(),
- hosts = dict(),
- )
-
- _config_writer_files = ('tinc.conf','tinc-up','host')
- _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
-
- def __init__(self, pickle_dir='.', config_dir='/etc/tinc'):
- log.debug(u'VpnHandler(%r, %r)', pickle_dir, config_dir)
- DictSubHandler.__init__(self, self)
- self._config_writer_cfg_dir = config_dir
- self._persistent_dir = pickle_dir
- self._config_build_templates()
- self._restore()
- self.host = HostHandler(self)
-
- @handler('usage: start <vpn_name>')
- def start(self, vpn_src):
- log.debug(u'VpnHandler.start(%r)', vpn_src)
- if vpn_src in self.vpns:
- call(('tincd','--net='+ vpn_src))
-
- @handler('usage: stop <vpn_name>')
- def stop(self, vpn_src):
- log.debug(u'VpnHandler.stop(%r)', vpn_src)
- if vpn_src in self.vpns:
- pid_file = '/var/run/tinc.' + vpn_src + '.pid'
- log.debug(u'VpnHandler.stop: getting pid from %r', pid_file)
- if path.exists(pid_file):
- pid = file(pid_file).readline()
- pid = int(pid.strip())
- try:
- log.debug(u'VpnHandler.stop: killing pid %r', pid)
- os.kill(pid, signal.SIGTERM)
- except OSError:
- log.debug(u'VpnHandler.stop: error killing: %r', e)
- else:
- log.debug(u'VpnHandler.stop: pid file not found')
-
- def _write_config(self):
- log.debug(u'VpnHandler._write_config()')
- for v in self.vpns.values():
- log.debug(u'VpnHandler._write_config: processing %r', v)
- #chek whether it's been created or not.
- if not v._delete:
- if v.pub_key is None:
- log.debug(u'VpnHandler._write_config: new VPN, generating '
- 'key...')
- try:
- log.debug(u'VpnHandler._write_config: creating dir %r',
- path.join(self._config_writer_cfg_dir,
- v.vpn_src ,'hosts'))
- #first create the directory for the vpn
- try:
- os.makedirs(path.join(self._config_writer_cfg_dir,
- v.vpn_src, 'hosts'))
- except (IOError, OSError), e:
- if e.errno != errno.EEXIST:
- raise HandlerError(u"Can't create VPN config "
- "directory '%s' (%s)'"
- % (e.filename, e.strerror))
- #this command should generate 2 files inside the vpn
- #dir, one rsa_key.priv and one rsa_key.pub
- #for some reason debian does not work like this
- # FIXME if the < /dev/null works, is magic!
- log.debug(u'VpnHandler._write_config: creating key...')
- call(('tincd', '-n', v.vpn_src, '-K', '<', '/dev/null'))
- #open the created files and load the keys
- try:
- f = file(path.join(self._config_writer_cfg_dir,
- v.vpn_src, 'rsa_key.pub'),
- 'r')
- pub = f.read()
- f.close()
- except (IOError, OSError), e:
- raise HandlerError(u"Can't read VPN key '%s' (%s)'"
- % (e.filename, e.strerror))
-
- v.pub_key = pub
- v.priv_key = priv
- except ExecutionError, e:
- log.debug(u'VpnHandler._write_config: error executing '
- 'the command: %r', e)
-
- vars = dict(
- vpn = v,
- )
- self._write_single_config('tinc.conf',
- path.join(v.vpn_src, 'tinc.conf'), vars)
- self._write_single_config('tinc-up',
- path.join(v.vpn_src, 'tinc-up'), vars)
- for h in v.hosts.values():
- if not h._delete:
- vars = dict(
- host = h,
- )
- self._write_single_config('host',
- path.join(v.vpn_src, 'hosts', h.name), vars)
- else:
- log.debug(u'VpnHandler._write_config: removing...')
- try:
- # FIXME use os.unlink()
- call(('rm','-f',
- path.join(v.vpn_src, 'hosts', h.name)))
- del v.hosts[h.name]
- except ExecutionError, e:
- log.debug(u'VpnHandler._write_config: error '
- 'removing files: %r', e)
- else:
- #delete the vpn root at tinc dir
- if path.exists('/etc/tinc/' + v.vpn_src):
- self.stop(v.vpn_src)
- call(('rm','-rf','/etc/tinc/' + v.vpn_src))
- del self.vpns[v.vpn_src]
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- v = VpnHandler()
- v.add('prueba','sarasa','192.168.0.188','255.255.255.0')
- v.host.add('prueba', 'azazel' ,'192.168.0.77', '192.168.0.0',
- 'kjdhfkbdskljvkjblkbjeslkjbvkljbselvslberjhbvslbevlhb')
- v.commit()
-
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+import os
+import errno
+import signal
+from os import path
+import logging ; log = logging.getLogger('pymin.services.vpn')
+
+
+from pymin.seqtools import Sequence
+from pymin.dispatcher import Handler, handler, HandlerError
+from pymin.service.util import Restorable, ConfigWriter, InitdHandler, \
+ TransactionalHandler, DictSubHandler, DictComposedSubHandler, call, ExecutionError
+
+__all__ = ('VpnHandler', 'get_service')
+
+
+def get_service(config):
+ return VpnHandler(config.vpn.pickle_dir, config.vpn.config_dir)
+
+
+class Host(Sequence):
+ def __init__(self, vpn_src, ip, vpn_src_net, key):
+ self.name = vpn_src
+ self.ip = ip
+ self.src_net = vpn_src_net
+ self.pub_key = key
+ self._delete = False
+
+ def as_tuple(self):
+ return(self.name, self.ip, self.src_net, self.pub_key)
+
+class HostHandler(DictComposedSubHandler):
+
+ handler_help = u"Manage hosts for a vpn"
+ _comp_subhandler_cont = 'vpns'
+ _comp_subhandler_attr = 'hosts'
+ _comp_subhandler_class = Host
+
+
+class Vpn(Sequence):
+ def __init__(self, vpn_src, vpn_dst, vpn_src_ip, vpn_src_mask,
+ pub_key=None, priv_key=None):
+ self.vpn_src = vpn_src
+ self.vpn_dst = vpn_dst
+ self.vpn_src_ip = vpn_src_ip
+ self.vpn_src_mask = vpn_src_mask
+ self.pub_key = pub_key
+ self.priv_key = priv_key
+ self.hosts = dict()
+ self._delete = False
+
+ def as_tuple(self):
+ return(self.vpn_src, self.vpn_dst, self.vpn_src_ip, self.vpn_src_mask, self.pub_key, self.priv_key)
+
+ def update(self, vpn_dst=None, vpn_src_ip=None, vpn_src_mask=None):
+ if vpn_dst is not None:
+ self.vpn_dst = vpn_dst
+ if vpn_src_ip is not None:
+ self.vpn_src_ip = vpn_src_ip
+ if vpn_src_mask is not None:
+ self.vpn_src_mask = vpn_src_mask
+
+
+class VpnHandler(Restorable, ConfigWriter,
+ TransactionalHandler, DictSubHandler):
+
+ handler_help = u"Manage vpn service"
+
+ _cont_subhandler_attr = 'vpns'
+ _cont_subhandler_class = Vpn
+
+ _persistent_attrs = ('vpns','hosts')
+
+ _restorable_defaults = dict(
+ vpns = dict(),
+ hosts = dict(),
+ )
+
+ _config_writer_files = ('tinc.conf','tinc-up','host')
+ _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
+
+ def __init__(self, pickle_dir='.', config_dir='/etc/tinc'):
+ log.debug(u'VpnHandler(%r, %r)', pickle_dir, config_dir)
+ DictSubHandler.__init__(self, self)
+ self._config_writer_cfg_dir = config_dir
+ self._persistent_dir = pickle_dir
+ self._config_build_templates()
+ self._restore()
+ self.host = HostHandler(self)
+
+ @handler('usage: start <vpn_name>')
+ def start(self, vpn_src):
+ log.debug(u'VpnHandler.start(%r)', vpn_src)
+ if vpn_src in self.vpns:
+ call(('tincd','--net='+ vpn_src))
+
+ @handler('usage: stop <vpn_name>')
+ def stop(self, vpn_src):
+ log.debug(u'VpnHandler.stop(%r)', vpn_src)
+ if vpn_src in self.vpns:
+ pid_file = '/var/run/tinc.' + vpn_src + '.pid'
+ log.debug(u'VpnHandler.stop: getting pid from %r', pid_file)
+ if path.exists(pid_file):
+ pid = file(pid_file).readline()
+ pid = int(pid.strip())
+ try:
+ log.debug(u'VpnHandler.stop: killing pid %r', pid)
+ os.kill(pid, signal.SIGTERM)
+ except OSError:
+ log.debug(u'VpnHandler.stop: error killing: %r', e)
+ else:
+ log.debug(u'VpnHandler.stop: pid file not found')
+
+ def _write_config(self):
+ log.debug(u'VpnHandler._write_config()')
+ for v in self.vpns.values():
+ log.debug(u'VpnHandler._write_config: processing %r', v)
+ #chek whether it's been created or not.
+ if not v._delete:
+ if v.pub_key is None:
+ log.debug(u'VpnHandler._write_config: new VPN, generating '
+ 'key...')
+ try:
+ log.debug(u'VpnHandler._write_config: creating dir %r',
+ path.join(self._config_writer_cfg_dir,
+ v.vpn_src ,'hosts'))
+ #first create the directory for the vpn
+ try:
+ os.makedirs(path.join(self._config_writer_cfg_dir,
+ v.vpn_src, 'hosts'))
+ except (IOError, OSError), e:
+ if e.errno != errno.EEXIST:
+ raise HandlerError(u"Can't create VPN config "
+ "directory '%s' (%s)'"
+ % (e.filename, e.strerror))
+ #this command should generate 2 files inside the vpn
+ #dir, one rsa_key.priv and one rsa_key.pub
+ #for some reason debian does not work like this
+ # FIXME if the < /dev/null works, is magic!
+ log.debug(u'VpnHandler._write_config: creating key...')
+ call(('tincd', '-n', v.vpn_src, '-K', '<', '/dev/null'))
+ #open the created files and load the keys
+ try:
+ f = file(path.join(self._config_writer_cfg_dir,
+ v.vpn_src, 'rsa_key.pub'),
+ 'r')
+ pub = f.read()
+ f.close()
+ except (IOError, OSError), e:
+ raise HandlerError(u"Can't read VPN key '%s' (%s)'"
+ % (e.filename, e.strerror))
+
+ v.pub_key = pub
+ v.priv_key = priv
+ except ExecutionError, e:
+ log.debug(u'VpnHandler._write_config: error executing '
+ 'the command: %r', e)
+
+ vars = dict(
+ vpn = v,
+ )
+ self._write_single_config('tinc.conf',
+ path.join(v.vpn_src, 'tinc.conf'), vars)
+ self._write_single_config('tinc-up',
+ path.join(v.vpn_src, 'tinc-up'), vars)
+ for h in v.hosts.values():
+ if not h._delete:
+ vars = dict(
+ host = h,
+ )
+ self._write_single_config('host',
+ path.join(v.vpn_src, 'hosts', h.name), vars)
+ else:
+ log.debug(u'VpnHandler._write_config: removing...')
+ try:
+ # FIXME use os.unlink()
+ call(('rm','-f',
+ path.join(v.vpn_src, 'hosts', h.name)))
+ del v.hosts[h.name]
+ except ExecutionError, e:
+ log.debug(u'VpnHandler._write_config: error '
+ 'removing files: %r', e)
+ else:
+ #delete the vpn root at tinc dir
+ if path.exists('/etc/tinc/' + v.vpn_src):
+ self.stop(v.vpn_src)
+ call(('rm','-rf','/etc/tinc/' + v.vpn_src))
+ del self.vpns[v.vpn_src]
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ v = VpnHandler()
+ v.add('prueba','sarasa','192.168.0.188','255.255.255.0')
+ v.host.add('prueba', 'azazel' ,'192.168.0.77', '192.168.0.0',
+ 'kjdhfkbdskljvkjblkbjeslkjbvkljbselvslberjhbvslbevlhb')
+ v.commit()
+
# vim: set encoding=utf-8 et sw=4 sts=4 :
-from pymin import procman
-from pymin.service.util import Restorable, TransactionalHandler, \
- ReloadHandler, RestartHandler, \
- ServiceHandler, ParametersHandler
-
-# Logger
-import logging ; log = logging.getLogger('pymin.services.vrrp')
-
-__all__ = ('VrrpHandler', 'get_service')
-
+from handler import VrrpHandler
def get_service(config):
return VrrpHandler(config.vrrp.pickle_dir, config.vrrp.config_dir)
-
-# FIXME the the command should not use new parameters unless commit where called
-# i.e. integrate commit with procman to update internal procman parameters.
-class VrrpHandler(Restorable, ParametersHandler, ReloadHandler, RestartHandler,
- ServiceHandler, TransactionalHandler):
-
- handler_help = u"Manage VRRP service"
-
- _persistent_attrs = ['params']
-
- _restorable_defaults = dict(
- params = dict(
- ipaddress = '192.168.0.1',
- id = '1',
- prio = '',
- dev = 'eth0',
- persist = True,
- ),
- )
-
- @property
- def _command(self):
- command = ['vrrpd', '-i', self.params['dev'], '-v', self.params['id']]
- if self.params['prio']:
- command.extend(('-p', self.params['prio']))
- command.append(self.params['ipaddress'])
- return command
-
- def _service_start(self):
- log.debug(u'VrrpHandler._service_start()')
- procinfo = procman.get('vrrp')
- procinfo.command = self._command
- procinfo.persist = self.params['persist']
- procman.start('vrrp')
-
- def _service_stop(self):
- log.debug(u'VrrpHandler._service_stop()')
- procman.stop('vrrp')
-
- def _service_restart(self):
- procinfo = procman.get('vrrp')
- procinfo.command = self._command
- procinfo.persist = self.params['persist']
- procman.restart('vrrp')
-
- def __init__(self, pickle_dir='.', config_dir='.', pid_dir='.'):
- log.debug(u'VrrpHandler(%r, %r, %r)', pickle_dir, config_dir, pid_dir)
- self._persistent_dir = pickle_dir
- self._pid_dir = pid_dir
- procman.register('vrrp', None)
- ServiceHandler.__init__(self)
-
-
-if __name__ == '__main__':
-
- logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(levelname)-8s %(message)s',
- datefmt = '%H:%M:%S',
- )
-
- v = VrrpHandler()
- v.set('prio', '10')
- v.commit()
-
--- /dev/null
+# vim: set encoding=utf-8 et sw=4 sts=4 :
+
+from pymin import procman
+from pymin.service.util import Restorable, TransactionalHandler, \
+ ReloadHandler, RestartHandler, \
+ ServiceHandler, ParametersHandler
+
+# Logger
+import logging ; log = logging.getLogger('pymin.services.vrrp')
+
+__all__ = ('VrrpHandler', 'get_service')
+
+
+def get_service(config):
+ return VrrpHandler(config.vrrp.pickle_dir, config.vrrp.config_dir)
+
+
+# FIXME the the command should not use new parameters unless commit where called
+# i.e. integrate commit with procman to update internal procman parameters.
+class VrrpHandler(Restorable, ParametersHandler, ReloadHandler, RestartHandler,
+ ServiceHandler, TransactionalHandler):
+
+ handler_help = u"Manage VRRP service"
+
+ _persistent_attrs = ['params']
+
+ _restorable_defaults = dict(
+ params = dict(
+ ipaddress = '192.168.0.1',
+ id = '1',
+ prio = '',
+ dev = 'eth0',
+ persist = True,
+ ),
+ )
+
+ @property
+ def _command(self):
+ command = ['vrrpd', '-i', self.params['dev'], '-v', self.params['id']]
+ if self.params['prio']:
+ command.extend(('-p', self.params['prio']))
+ command.append(self.params['ipaddress'])
+ return command
+
+ def _service_start(self):
+ log.debug(u'VrrpHandler._service_start()')
+ procinfo = procman.get('vrrp')
+ procinfo.command = self._command
+ procinfo.persist = self.params['persist']
+ procman.start('vrrp')
+
+ def _service_stop(self):
+ log.debug(u'VrrpHandler._service_stop()')
+ procman.stop('vrrp')
+
+ def _service_restart(self):
+ procinfo = procman.get('vrrp')
+ procinfo.command = self._command
+ procinfo.persist = self.params['persist']
+ procman.restart('vrrp')
+
+ def __init__(self, pickle_dir='.', config_dir='.', pid_dir='.'):
+ log.debug(u'VrrpHandler(%r, %r, %r)', pickle_dir, config_dir, pid_dir)
+ self._persistent_dir = pickle_dir
+ self._pid_dir = pid_dir
+ procman.register('vrrp', None)
+ ServiceHandler.__init__(self)
+
+
+if __name__ == '__main__':
+
+ logging.basicConfig(
+ level = logging.DEBUG,
+ format = '%(asctime)s %(levelname)-8s %(message)s',
+ datefmt = '%H:%M:%S',
+ )
+
+ v = VrrpHandler()
+ v.set('prio', '10')
+ v.commit()
+