예제 #1
0
파일: xmlrpc.py 프로젝트: tobbakko/NIPAP
class NipapXMLRPC:

    stop = None
    _cfg = None
    _protocol = None
    root_logger = None

    def __init__(self, root_logger = None):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.root_logger = root_logger

        self._cfg = NipapConfig()
        self.cfg_file = None

        # Add dispatch entry for <ex:nil/>
        xmlrpclib.Unmarshaller.dispatch["ex:nil"] = xmlrpclib.Unmarshaller.end_nil

        self.init()


    def init(self):
        """ Non Python init

            This init function should be called after the configuration has
            been read. It is a separate function from __init__ so that it may
            be called if the configuration file is reread when the daemon is
            running.
        """
        # we cannot switch between foreground and background here, so ignoring
        # 'foreground' option

        # syslog
        if self._cfg.getboolean('nipapd', 'syslog'):
            log_syslog = logging.handlers.SysLogHandler(address = '/dev/log')
            log_syslog.setFormatter(logging.Formatter("%(levelname)-8s %(message)s"))
            self.root_logger.addHandler(log_syslog)

        if self._cfg.getboolean('nipapd', 'foreground'):
            # log to stdout
            log_stream = logging.StreamHandler()
            log_stream.setFormatter(logging.Formatter("%(asctime)s: %(levelname)-8s %(message)s"))
            self.root_logger.addHandler(log_stream)
            self.root_logger.setLevel(logging.DEBUG)

        if self._cfg.getboolean('nipapd', 'debug'):
            self.root_logger.setLevel(logging.DEBUG)



    def run(self):
        """ Create the reactor and start it
        """

        # most signals are handled by Twisted by default but for SIGHUP to
        # behave as we want (ie, reload the configuration file) we need to
        # install a custom handler
        import signal
        signal.signal(signal.SIGHUP, self._sigHup)

        # setup twisted logging
        log.defaultObserver.stop()
        log.defaultObserver = None
        observer = log.PythonLoggingObserver()
        observer.start()

        # twist it!
        self._protocol = NipapProtocol()
        # listen on all interface
        if self._cfg.get('nipapd', 'listen') is None or self._cfg.get('nipapd', 'listen') == '':
            self.logger.info("Listening to all addresses on port " + self._cfg.getint('nipapd', 'port'))
            reactor.listenTCP(self._cfg.getint('nipapd', 'port'), server.Site(self._protocol))
        else:
            # If the used has listed specific addresses to listen to, loop
            # through them and start listening to them. It is possible to
            # specify port per IP by separating the address and port with a +
            # character.
            listen = self._cfg.get('nipapd', 'listen')
            for entry in listen.split(','):
                if len(entry.split('+')) > 1:
                    address = entry.split('+')[0]
                    port = int(entry.split('+')[1])
                else:
                    address = entry
                    port = int(self._cfg.get('nipapd', 'port'))
                self.logger.info("Listening to address " + address + " on port " + str(port))
                reactor.listenTCP(port, server.Site(self._protocol), interface=address)

        # finally, start the reactor!
        reactor.run()



    def _sigHup(self, num, frame):
        """ Customer signal handler for SIGHUP
        """
        self.logger.info("Received SIGHUP - reloading configuration")
        self._cfg.read_file()
        self._protocol._auth_fact.reload()
        self.init()