diff options
Diffstat (limited to 'src/lib/Server/Component.py')
-rw-r--r-- | src/lib/Server/Component.py | 88 |
1 files changed, 34 insertions, 54 deletions
diff --git a/src/lib/Server/Component.py b/src/lib/Server/Component.py index 5c19c3bdd..01b4e1b0a 100644 --- a/src/lib/Server/Component.py +++ b/src/lib/Server/Component.py @@ -1,25 +1,17 @@ '''Cobalt component base classes''' __revision__ = '$Revision$' -from ConfigParser import ConfigParser, NoOptionError -from cPickle import loads, dumps from M2Crypto import SSL -from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler -from socket import gethostname -from sys import exc_info -import sys -from syslog import openlog, syslog, LOG_INFO, LOG_ERR, LOG_LOCAL0 -from traceback import extract_tb -from xmlrpclib import dumps, loads, Fault -from urlparse import urlparse -try: - from SimpleXMLRPCServer import SimpleXMLRPCDispatcher -except ImportError: - SimpleXMLRPCDispatcher = object +import cPickle, logging, socket, urlparse, xmlrpclib, ConfigParser, SimpleXMLRPCServer -class CobaltXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): +class CobaltXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): '''CobaltXMLRPCRequestHandler takes care of ssl xmlrpc requests''' + def __init__(self, request, client_address, server): + SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.__init__(self, + request, client_address, server) + self.logger = logging.getLogger('Bcfg2.Server.Handler') + def finish(self): '''Finish HTTPS connections properly''' self.request.set_shutdown(SSL.SSL_RECEIVED_SHUTDOWN | SSL.SSL_SENT_SHUTDOWN) @@ -33,12 +25,7 @@ class CobaltXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): response = self.server._cobalt_marshalled_dispatch(data, self.client_address) except: # This should only happen if the module is buggy # internal error, report as HTTP server error - (trace, val, trb) = exc_info() - syslog(LOG_ERR, "Unexpected failure in handler") - for line in extract_tb(trb): - syslog(LOG_ERR, ' File "%s", line %i, in %s\n %s\n' % line) - syslog(LOG_ERR, "%s: %s\n"%(trace, val)) - del trace, val, trb + self.logger.error("Unexpected failure in handler", exc_info=1) self.send_response(500) self.end_headers() else: @@ -54,7 +41,7 @@ class CobaltXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): self.connection.shutdown(1) class Component(SSL.SSLServer, - SimpleXMLRPCDispatcher): + SimpleXMLRPCServer.SimpleXMLRPCDispatcher): """Cobalt component providing XML-RPC access""" __name__ = 'Component' __implementation__ = 'Generic' @@ -63,8 +50,8 @@ class Component(SSL.SSLServer, def __init__(self, setup): # need to get addr self.setup = setup - self.cfile = ConfigParser() - openlog(self.__implementation__, 0, LOG_LOCAL0) + self.cfile = ConfigParser.ConfigParser() + self.logger = logging.getLogger('Bcfg2.Server') if setup['configfile']: cfilename = setup['configfile'] else: @@ -80,16 +67,16 @@ class Component(SSL.SSLServer, if self.cfile._sections['components'].has_key(self.__name__): self.static = True - location = urlparse(self.cfile.get('components', self.__name__))[1].split(':') + location = urlparse.urlparse(self.cfile.get('components', self.__name__))[1].split(':') location = (location[0], int(location[1])) else: - location = (gethostname(), 0) + location = (socket.gethostname(), 0) self.password = self.cfile.get('communication', 'password') sslctx = SSL.Context('sslv23') try: keyfile = self.cfile.get('communication', 'key') - except NoOptionError: + except ConfigParser.NoOptionError: print "No key specified in cobalt.conf" raise SystemExit, 1 sslctx.load_cert_chain(keyfile) @@ -102,10 +89,10 @@ class Component(SSL.SSLServer, #sslctx.set_tmp_dh('dh1024.pem') self.logRequests = 0 # setup unhandled request syslog handling - SimpleXMLRPCDispatcher.__init__(self) + SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self) SSL.SSLServer.__init__(self, location, CobaltXMLRPCRequestHandler, sslctx) self.port = self.socket.socket.getsockname()[1] - syslog(LOG_INFO, "Bound to port %s" % self.port) + self.logger.info("Bound to port %s" % self.port) self.funcs.update({'HandleEvents':self.HandleEvents, 'system.listMethods':self.system_listMethods}) @@ -121,41 +108,34 @@ class Component(SSL.SSLServer, """Decode and dispatch XMLRPC requests. Overloaded to pass through client address information """ - rawparams, method = loads(data) + rawparams, method = xmlrpclib.loads(data) if len(rawparams) < 2: - syslog(LOG_ERR, "No authentication included with request from %s" % address[0]) - return dumps(Fault(2, "No Authentication Info")) + self.logger.error("No authentication included with request from %s" % address[0]) + return xmlrpclib.dumps(xmlrpclib.Fault(2, "No Authentication Info")) user = rawparams[0] password = rawparams[1] params = rawparams[2:] # check authentication if not self._authenticate_connection(method, user, password, address): - syslog(LOG_ERR, "Authentication failure from %s" % address[0]) - return dumps(Fault(3, "Authentication Failure")) + self.logger.error("Authentication failure from %s" % address[0]) + return xmlrpclib.dumps(xmlrpclib.Fault(3, "Authentication Failure")) # generate response try: # all handlers must take address as the first argument response = self._dispatch(method, (address, ) + params) # wrap response in a singleton tuple response = (response,) - response = dumps(response, methodresponse=1) - except Fault, fault: - response = dumps(fault) - except TypeError, t: - syslog(LOG_ERR, "Client %s called function %s with wrong argument count" % + response = xmlrpclib.dumps(response, methodresponse=1) + except xmlrpclib.Fault, fault: + response = xmlrpclib.dumps(fault) + except TypeError, terror: + self.logger.error("Client %s called function %s with wrong argument count" % (address[0], method)) - response = dumps(Fault(4, t.args[0])) + response = xmlrpclib.dumps(xmlrpclib.Fault(4, terror.args[0])) except: - (trace, val, trb) = exc_info() - syslog(LOG_ERR, "Unexpected failure in handler") - for line in extract_tb(trb): - syslog(LOG_ERR, ' File "%s", line %i, in %s\n %s\n' % line) - syslog(LOG_ERR, "%s: %s\n"%(trace, val)) - del trace, val, trb + self.logger.error("Unexpected failure in handler", exc_info=1) # report exception back to server - response = dumps(Fault(1, - "%s:%s" % (sys.exc_type, sys.exc_value))) - + response = xmlrpclib.dumps(xmlrpclib.Fault(1, "handler failure")) return response def _authenticate_connection(self, method, user, password, address): @@ -170,22 +150,22 @@ class Component(SSL.SSLServer, try: statefile = open("/var/spool/cobalt/%s" % self.__implementation__, 'w') # need to flock here - statefile.write(dumps(savedata)) + statefile.write(cPickle.dumps(savedata)) except: - syslog(LOG_INFO, "Statefile save failed; data persistence disabled") + self.logger.info("Statefile save failed; data persistence disabled") self.__statefields__ = [] def load_state(self): '''Load fields defined in __statefields__ from /var/spool/cobalt/__implementation__''' if self.__statefields__: try: - loaddata = loads(open("/var/spool/cobalt/%s" % self.__implementation__).read()) + loaddata = cPickle.loads(open("/var/spool/cobalt/%s" % self.__implementation__).read()) except: - syslog(LOG_INFO, "Statefile load failed") + self.logger.info("Statefile load failed") return for field in self.__statefields__: setattr(self, field, loaddata[self.__statefields__.index(field)]) def system_listMethods(self, address): """get rid of the address argument and call the underlying dispatcher method""" - return SimpleXMLRPCDispatcher.system_listMethods(self) + return SimpleXMLRPCServer.SimpleXMLRPCDispatcher.system_listMethods(self) |