summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/BuiltinCore.py
blob: b433595b9f351a6d641e12f9d3426b833bb90f98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
""" the core of the builtin bcfg2 server """

import os
import sys
import time
import socket
import logging
from Bcfg2.Server.Core import BaseCore
from Bcfg2.Compat import xmlrpclib, urlparse
from Bcfg2.SSLServer import XMLRPCServer

logger = logging.getLogger()

class NoExposedMethod (Exception):
    """There is no method exposed with the given name."""


class Core(BaseCore):
    name = 'bcfg2-server'

    def _resolve_exposed_method(self, method_name):
        """Resolve an exposed method.

        Arguments:
        method_name -- name of the method to resolve

        """
        try:
            func = getattr(self, method_name)
        except AttributeError:
            raise NoExposedMethod(method_name)
        if not getattr(func, "exposed", False):
            raise NoExposedMethod(method_name)
        return func

    def _dispatch(self, method, args, dispatch_dict):
        """Custom XML-RPC dispatcher for components.

        method -- XML-RPC method name
        args -- tuple of paramaters to method

        """
        if method in dispatch_dict:
            method_func = dispatch_dict[method]
        else:
            try:
                method_func = self._resolve_exposed_method(method)
            except NoExposedMethod:
                self.logger.error("Unknown method %s" % (method))
                raise xmlrpclib.Fault(xmlrpclib.METHOD_NOT_FOUND,
                                      "Unknown method %s" % method)

        try:
            method_start = time.time()
            try:
                result = method_func(*args)
            finally:
                self.instance_statistics.add_value(method,
                                                   time.time() - method_start)
        except xmlrpclib.Fault:
            raise
        except Exception:
            e = sys.exc_info()[1]
            if getattr(e, "log", True):
                self.logger.error(e, exc_info=True)
            raise xmlrpclib.Fault(getattr(e, "fault_code", 1), str(e))
        return result

    def run(self):
        if self.setup['daemon']:
            self._daemonize()

        hostname, port = urlparse(self.setup['location'])[1].split(':')
        server_address = socket.getaddrinfo(hostname,
                                            port,
                                            socket.AF_UNSPEC,
                                            socket.SOCK_STREAM)[0][4]
        try:
            server = XMLRPCServer(self.setup['listen_all'],
                                  server_address,
                                  keyfile=self.setup['key'],
                                  certfile=self.setup['cert'],
                                  register=False,
                                  timeout=1,
                                  ca=self.setup['ca'],
                                  protocol=self.setup['protocol'])
        except:
            err = sys.exc_info()[1]
            self.logger.error("Server startup failed: %s" % err)
            os._exit(1)
        server.register_instance(self)

        try:
            server.serve_forever()
        finally:
            server.server_close()
        self.shutdown()

    def methodHelp(self, method_name):
        try:
            func = self._resolve_exposed_method(method_name)
        except NoExposedMethod:
            return ""
        return func.__doc__