]> git.llucax.com Git - software/pymin.git/commitdiff
Use a plug-in architecture for services (refs #27).
authorLeandro Lucarella <llucax@gmail.com>
Mon, 16 Jun 2008 18:43:45 +0000 (15:43 -0300)
committerLeandro Lucarella <llucax@gmail.com>
Mon, 16 Jun 2008 19:44:47 +0000 (16:44 -0300)
Service modules are loaded dinamically using the imp module. The config.py
file is simplified to avoid the need of defining pymind command handlers
"tree" in the configuration file.

13 files changed:
config.py
pymin/services/__init__.py
pymin/services/dhcp/__init__.py
pymin/services/dns/__init__.py
pymin/services/firewall/__init__.py
pymin/services/ip/__init__.py
pymin/services/nat/__init__.py
pymin/services/ppp/__init__.py
pymin/services/proxy/__init__.py
pymin/services/qos/__init__.py
pymin/services/vpn/__init__.py
pymin/services/vrrp/__init__.py
pymind

index aae79c185fa02ae0783d5e5828de3d46bc29f95c..aa3e5ebc92c472f452c114abc43c119e070838be 100644 (file)
--- a/config.py
+++ b/config.py
@@ -8,7 +8,6 @@ logging.basicConfig(
         datefmt = '%a, %d %b %Y %H:%M:%S',
 )
 
-from pymin.services import *
 from pymin.dispatcher import Handler
 from os.path import join
 
@@ -17,67 +16,64 @@ pickle_path = join(base_path, 'pickle')
 # FIXME, this should be specific for each service
 config_path = join(base_path, 'config')
 
-class Root(Handler):
-
-    def __init__(self):
-        try:
-            f = file("/proc/sys/net/ipv4/ip_forward","w")
-            f.write("1")
-            f.close()
-        except (IOError, OSError), e:
-            print "Can't set ip_forward:", e
-        #self.ip.device_up_hook(self.dns)
-
-    firewall = FirewallHandler(
-        pickle_dir = join(pickle_path, 'firewall'),
-        config_dir = join(config_path, 'firewall'))
-
-    nat = NatHandler(pickle_dir = join(pickle_path, 'nat'))
-
-    ppp = PppHandler(
-        pickle_dir = join(pickle_path, 'ppp'),
-        config_dir = {
-            'pap-secrets':  join(config_path, 'ppp'),
-            'chap-secrets': join(config_path, 'ppp'),
-            'options.X':    join(config_path, 'ppp'),
-            'nameX':        join(config_path, 'ppp', 'peers'),
-        })
-
-    vpn = VpnHandler(
-         pickle_dir = join(pickle_path, 'vpn'),
-         config_dir = join(config_path, 'vpn'))
-
-    ip = IpHandler(
-        pickle_dir = join(pickle_path, 'ip'),
-        config_dir = join(config_path, 'ip'))
-
-    dns = DnsHandler(
-        pickle_dir = join(pickle_path, 'dns'),
-        config_dir = {
-            'named.conf': join(config_path, 'dns'),
-            'zoneX.zone': join(config_path, 'dns', 'zones'),
-        })
-
-    dhcp = DhcpHandler(
-        pickle_dir = join(pickle_path, 'dhcp'),
-        config_dir = join(config_path, 'dhcp'))
-
-    proxy = ProxyHandler(
-        pickle_dir = join(pickle_path, 'proxy'),
-        config_dir = join(config_path, 'proxy'))
-
-    vrrp = VrrpHandler(
-        pickle_dir = join(pickle_path, 'vrrp'),
-        config_dir = join(config_path, 'vrrp'),
-        pid_dir    = join(config_path, 'vrrp', 'run'))
-
-    vpn = VpnHandler(
-        pickle_dir = join(pickle_path, 'vpn'),
-        config_dir = join(config_path, 'vpn'))
-
-    #qos = QoSHandler(
-    #    pickle_dir = join(pickle_path, 'qos'),
-    #    config_dir = join(config_path, 'qos'))
+try:
+    f = file("/proc/sys/net/ipv4/ip_forward","w")
+    f.write("1")
+    f.close()
+except (IOError, OSError), e:
+    print "Can't set ip_forward:", e
+
+class firewall:
+    pickle_dir = join(pickle_path, 'firewall')
+    config_dir = join(config_path, 'firewall')
+
+class nat:
+    pickle_dir = join(pickle_path, 'nat')
+
+class ppp:
+    pickle_dir = join(pickle_path, 'ppp')
+    config_dir = {
+        'pap-secrets':  join(config_path, 'ppp'),
+        'chap-secrets': join(config_path, 'ppp'),
+        'options.X':    join(config_path, 'ppp'),
+        'nameX':        join(config_path, 'ppp', 'peers'),
+    }
+
+class vpn:
+     pickle_dir = join(pickle_path, 'vpn')
+     config_dir = join(config_path, 'vpn')
+
+class ip:
+    pickle_dir = join(pickle_path, 'ip')
+    config_dir = join(config_path, 'ip')
+
+class dns:
+    pickle_dir = join(pickle_path, 'dns')
+    config_dir = {
+        'named.conf': join(config_path, 'dns'),
+        'zoneX.zone': join(config_path, 'dns', 'zones'),
+    }
+
+class dhcp:
+    pickle_dir = join(pickle_path, 'dhcp')
+    config_dir = join(config_path, 'dhcp')
+
+class proxy:
+    pickle_dir = join(pickle_path, 'proxy')
+    config_dir = join(config_path, 'proxy')
+
+class vrrp:
+    pickle_dir = join(pickle_path, 'vrrp')
+    config_dir = join(config_path, 'vrrp')
+    pid_dir    = join(config_path, 'vrrp', 'run')
+
+class vpn:
+    pickle_dir = join(pickle_path, 'vpn')
+    config_dir = join(config_path, 'vpn')
+
+class qos:
+    pickle_dir = join(pickle_path, 'qos')
+    config_dir = join(config_path, 'qos')
 
 bind_addr = \
 (
@@ -85,3 +81,7 @@ bind_addr = \
     9999, # Port
 )
 
+services = 'firewall nat ppp vpn ip dns dhcp proxy vrrp qos'.split()
+
+services_dirs = ['pymin/services']
+
index 7620197e6105f1ee24114fe5efcc2ddae35d9162..1828fb49ea753c977b1e7371add70aa35010018e 100644 (file)
@@ -1,12 +1,19 @@
 # vim: set encoding=utf-8 et sw=4 sts=4 :
 
-from pymin.services.dhcp import DhcpHandler
-from pymin.services.dns import DnsHandler
-from pymin.services.firewall import FirewallHandler
-from pymin.services.nat import NatHandler
-from pymin.services.ip import IpHandler
-from pymin.services.proxy import ProxyHandler
-from pymin.services.vrrp import VrrpHandler
-from pymin.services.ppp import PppHandler
-from pymin.services.qos import QoSHandler
-from pymin.services.vpn import VpnHandler
+import imp
+
+class LoadError(ImportError):
+    pass
+
+def load_service(name, search_paths):
+    try:
+        (fp, path, desc) = imp.find_module(name, search_paths)
+    except ImportError:
+        raise LoadError('module "%s" not found' % name)
+
+    try:
+        return imp.load_module(name, fp, path, desc)
+    finally:
+        if fp:
+            fp.close()
+
index b5bf6f3801ea46bd9ad0c79197921462a5f37c83..1c6a91960a0544c73d339031f0265cb500b33670 100644 (file)
@@ -9,7 +9,12 @@ from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
                                 TransactionalHandler, ParametersHandler, \
                                 DictSubHandler, ReloadHandler
 
-__all__ = ('DhcpHandler',)
+__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.
index 0576cd05721b28f0770e0be88021c09cfceb430f..c3cf03e68632b6a2aa7bd9f1496d139c0c70fe47 100644 (file)
@@ -11,7 +11,12 @@ from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
                                 TransactionalHandler, ParametersHandler, \
                                 DictComposedSubHandler, DictSubHandler, call
 
-__all__ = ('DnsHandler',)
+__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):
index 0ab2b4c9be1f73814fbcb2462edcbffdba73a9b3..7b17c23f0de25c138c667214c345f129369c6342 100644 (file)
@@ -14,7 +14,12 @@ from pymin.dispatcher import Handler, handler, HandlerError
 from pymin.services.util import Restorable, ConfigWriter, ServiceHandler, \
                                 TransactionalHandler, ListSubHandler
 
-__all__ = ('FirewallHandler',)
+__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):
index 86551f4ddefdc6b0b62e54ebf270c8a638eba843..54ee30b020ab0e1b4045adf5772c35837ed205cf 100644 (file)
@@ -12,7 +12,11 @@ from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
                                 DictComposedSubHandler, ListSubHandler, \
                                 Device, Address, ExecutionError
 
-__all__ = ('IpHandler',)
+__all__ = ('IpHandler', 'get_service')
+
+
+def get_service(config):
+    return IpHandler(config.ip.pickle_dir, config.ip.config_dir)
 
 
 class Hop(Sequence):
index 34d5b0dc231e74a825d0c5be2a2260667cc5abe3..3afc997de8830b8939106474bd1d7b22a8a405e1 100644 (file)
@@ -9,7 +9,12 @@ from pymin.services.util import Restorable, ConfigWriter, RestartHandler, \
                                 ReloadHandler, TransactionalHandler, \
                                 ServiceHandler, ListSubHandler, call
 
-__all__ = ('NatHandler',)
+__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.
index 6ee9f5a97218ae0ae5e994c601207968c3fc79e3..7f5a143162d9aee2335b3af44f8815e02c60372d 100644 (file)
@@ -11,7 +11,12 @@ from pymin.dispatcher import Handler, handler, HandlerError
 from pymin.services.util import Restorable, ConfigWriter, ReloadHandler, \
                                 TransactionalHandler, DictSubHandler, call
 
-__all__ = ('PppHandler',)
+__all__ = ('PppHandler', 'get_service')
+
+
+def get_service(config):
+    return PppHandler(config.ppp.pickle_dir, config.ppp.config_dir)
+
 
 class ConnectionError(HandlerError, KeyError):
     r"""
index 5ab624beba4737f26ec3efbd664c6b07505aa989..448f568fec488d9e13dccaa7a4449f0e05274965 100644 (file)
@@ -11,7 +11,13 @@ from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
 
 import crypt
 
-__all__ = ('ProxyHandler',)
+
+__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):
index b583d4d350fbbf6b9b4aaccb5e4539d6967bae86..d021d68e5a7d430bbb91e1501e9a245a91fe33d8 100644 (file)
@@ -10,7 +10,12 @@ from pymin.services.util import Restorable, ConfigWriter, InitdHandler, \
                                 get_network_devices, ListComposedSubHandler, \
                                 DictComposedSubHandler, ExecutionError
 
-__all__ = ('QoSHandler',)
+__all__ = ('QoSHandler', 'get_service')
+
+
+def get_service(config):
+    return QoSHandler(config.qos.pickle_dir, config.qos.config_dir)
+
 
 class DeviceError(HandlerError):
 
index f3b9f95a422f8ffea42df0c4dd64d447f7cdff96..066e8fc42d8f2aeaa34e5752a7578edc9533b114 100644 (file)
@@ -13,6 +13,13 @@ from pymin.services.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
index f957bb4422684dda13598fa7696fe28660fb12b1..9b4c0e6254ad3b22a8f853f6b9160b6df26d26c4 100644 (file)
@@ -8,7 +8,12 @@ from pymin.services.util import Restorable, TransactionalHandler, \
 # Logger
 import logging ; log = logging.getLogger('pymin.services.vrrp')
 
-__all__ = ('VrrpHandler',)
+__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.
diff --git a/pymind b/pymind
index a04307d1920909bbd3a25cce42c0c9d8fbb5dbcf..2f428b52deda71afee4fbf3294dd0099ef973547 100755 (executable)
--- a/pymind
+++ b/pymind
@@ -1,8 +1,29 @@
 #!/usr/bin/env python
 # vim: set encoding=utf-8 et sw=4 sts=4 :
 
+import sys
 from pymin.pymindaemon import PyminDaemon
+from pymin.dispatcher import Handler
+from pymin.services import load_service, LoadError
 import config
 
-PyminDaemon(config.Root(), config.bind_addr).run()
+class Root(Handler):
+    pass
+
+def build_root(config):
+    # TODO check services dependencies
+    services = dict()
+    for service in config.services:
+        try:
+            s = load_service(service, config.services_dirs)
+        except LoadError, e:
+            sys.stderr.write("Can't find service called '%s'\n" % service)
+            sys.exit(1)
+        services[service] = s
+    root = Root()
+    for name, service in services.items():
+        setattr(root, name, service.get_service(config))
+    return root
+
+PyminDaemon(build_root(config), config.bind_addr).run()