summaryrefslogtreecommitdiffstats
path: root/src/lib/Server/XMLRPC.py
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2009-05-06 01:27:05 +0000
committerNarayan Desai <desai@mcs.anl.gov>2009-05-06 01:27:05 +0000
commitf0e50eac2e890c234ec809f36186a1cd33de4d81 (patch)
tree7c7911c6455febbbe3c84e267c667e838b5f62e0 /src/lib/Server/XMLRPC.py
parent21c48f07db35ed9421307aece62529053a552f09 (diff)
downloadbcfg2-f0e50eac2e890c234ec809f36186a1cd33de4d81.tar.gz
bcfg2-f0e50eac2e890c234ec809f36186a1cd33de4d81.tar.bz2
bcfg2-f0e50eac2e890c234ec809f36186a1cd33de4d81.zip
Get basic auth working again with new ssl framework
git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@5189 ce84e21b-d406-0410-9b95-82705330c041
Diffstat (limited to 'src/lib/Server/XMLRPC.py')
-rw-r--r--src/lib/Server/XMLRPC.py159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/lib/Server/XMLRPC.py b/src/lib/Server/XMLRPC.py
new file mode 100644
index 000000000..5788901cc
--- /dev/null
+++ b/src/lib/Server/XMLRPC.py
@@ -0,0 +1,159 @@
+
+import hashlib
+import logging
+import lxml.etree
+import select
+import socket
+import time
+import xmlrpclib
+
+from Bcfg2.Component import Component, exposed
+import Bcfg2.Server.Core
+
+logger = logging.getLogger('server')
+
+def critical_error(operation):
+ '''Log and err, traceback and return an xmlrpc fault to client'''
+ logger.error(operation, exc_info=1)
+ raise xmlrpclib.Fault(7, "Critical unexpected failure: %s" % (operation))
+
+class SetupError(Exception):
+ '''Used when the server cant be setup'''
+ pass
+
+class bcfg2_server(Component,
+ Bcfg2.Server.Core.Core):
+ '''XML RPC interfaces for the server core'''
+ name = 'bcfg2-server'
+
+ def __init__(self, setup):
+ Component.__init__(self)
+ Bcfg2.Server.Core.Core.__init__(self, setup['repo'], setup['plugins'],
+ setup['password'],
+ setup['encoding'], setup['filemonitor'])
+ self.process_initial_fam_events()
+
+ def process_initial_fam_events(self):
+ events = False
+ while True:
+ try:
+ rsockinfo = select.select([self.fam.fileno()], [], [], 15)[0]
+ if not rsockinfo:
+ if events:
+ break
+ else:
+ logger.error("Hit event timeout without getting "
+ "any events; GAMIN/FAM problem?")
+ continue
+ events = True
+ i = 0
+ while self.fam.Service() or i < 10:
+ i += 1
+ time.sleep(0.1)
+ except socket.error:
+ continue
+
+ @exposed
+ def GetProbes(self, address):
+ '''Fetch probes for a particular client'''
+ resp = lxml.etree.Element('probes')
+ try:
+ name = self.metadata.resolve_client(address)
+ meta = self.build_metadata(name)
+
+ for plugin in [p for p in list(self.plugins.values()) \
+ if isinstance(p, Bcfg2.Server.Plugin.Probing)]:
+ for probe in plugin.GetProbes(meta):
+ resp.append(probe)
+ return lxml.etree.tostring(resp, encoding='UTF-8',
+ xml_declaration=True)
+ except Bcfg2.Server.Plugins.Metadata.MetadataConsistencyError:
+ warning = 'Client metadata resolution error for %s; check server log' % address[0]
+ self.logger.warning(warning)
+ raise xmlrpclib.Fault(6, warning)
+ except:
+ critical_error("error determining client probes")
+
+ @exposed
+ def RecvProbeData(self, address, probedata):
+ '''Receive probe data from clients'''
+ try:
+ name = self.metadata.resolve_client(address)
+ meta = self.build_metadata(name)
+ except Bcfg2.Server.Plugins.Metadata.MetadataConsistencyError:
+ warning = 'metadata consistency error'
+ self.logger.warning(warning)
+ raise xmlrpclib.Fault(6, warning)
+ # clear dynamic groups
+ self.metadata.cgroups[meta.hostname] = []
+ try:
+ xpdata = lxml.etree.XML(probedata)
+ except:
+ self.logger.error("Failed to parse probe data from client %s" % \
+ (address[0]))
+ return False
+
+ sources = []
+ [sources.append(data.get('source')) for data in xpdata
+ if data.get('source') not in sources]
+ for source in sources:
+ if source not in self.plugins:
+ self.logger.warning("Failed to locate plugin %s" % (source))
+ continue
+ dl = [data for data in xpdata if data.get('source') == source]
+ try:
+ self.plugins[source].ReceiveData(meta, dl)
+ except:
+ logger.error("Failed to process probe data from client %s" % \
+ (address[0]), exc_info=1)
+ return True
+
+ @exposed
+ def AssertProfile(self, address, profile):
+ '''Set profile for a client'''
+ try:
+ client = self.metadata.resolve_client(address)
+ self.metadata.set_profile(client, profile, address)
+ except (Bcfg2.Server.Plugins.Metadata.MetadataConsistencyError,
+ Bcfg2.Server.Plugins.Metadata.MetadataRuntimeError):
+ warning = 'metadata consistency error'
+ self.logger.warning(warning)
+ raise xmlrpclib.Fault(6, warning)
+ return True
+
+ @exposed
+ def GetConfig(self, address, checksum=False):
+ '''Build config for a client'''
+ try:
+ client = self.metadata.resolve_client(address)
+ config = self.BuildConfiguration(client)
+ if checksum:
+ for cfile in config.findall('.//ConfigFile'):
+ if cfile.text != None:
+ csum = hashlib.md5()
+ csum.update(cfile.text)
+ cfile.set('checksum', csum.hexdigest())
+ cfile.text = None
+ return lxml.etree.tostring(config, encoding='UTF-8',
+ xml_declaration=True)
+ except Bcfg2.Server.Plugins.Metadata.MetadataConsistencyError:
+ self.logger.warning("Metadata consistency failure for %s" % (address))
+ raise xmlrpclib.Fault(6, "Metadata consistency failure")
+
+ @exposed
+ def RecvStats(self, address, stats):
+ '''Act on statistics upload'''
+ sdata = lxml.etree.XML(stats)
+ client = self.metadata.resolve_client(address)
+ self.process_statistics(client, sdata)
+ return "<ok/>"
+
+ def authenticate(self, cert, user, password, address):
+ print cert, user, password, address
+ return self.metadata.AuthenticateConnection(cert, user, password, address)
+
+ @exposed
+ def GetDecisionList(self, address, mode):
+ client = self.metadata.resolve_client(address)
+ meta = self.build_metadata(client)
+ return self.GetDecisions(meta, mode)