Add failover to the XML-RPC client

433506
This commit is contained in:
Rob Crittenden
2008-02-22 14:47:15 -05:00
parent c367b917d7
commit 8f0d4a8ed3
4 changed files with 38 additions and 11 deletions

View File

@@ -23,6 +23,7 @@ from optparse import OptionParser
import krbV import krbV
import socket import socket
import ipa.dnsclient import ipa.dnsclient
import re
class IPAConfigError(Exception): class IPAConfigError(Exception):
def __init__(self, msg=''): def __init__(self, msg=''):
@@ -37,7 +38,7 @@ class IPAConfigError(Exception):
class IPAConfig: class IPAConfig:
def __init__(self): def __init__(self):
self.default_realm = None self.default_realm = None
self.default_server = None self.default_server = []
def get_realm(self): def get_realm(self):
if self.default_realm: if self.default_realm:
@@ -62,7 +63,8 @@ def __parse_config():
if not config.default_realm: if not config.default_realm:
config.default_realm = p.get("defaults", "realm") config.default_realm = p.get("defaults", "realm")
if not config.default_server: if not config.default_server:
config.default_server = p.get("defaults", "server") s = p.get("defaults", "server")
config.default_server = re.sub("\s+", "", s).split(',')
except: except:
pass pass
@@ -95,12 +97,12 @@ def __discover_config():
for r in rs: for r in rs:
if r.dns_type == ipa.dnsclient.DNS_T_SRV: if r.dns_type == ipa.dnsclient.DNS_T_SRV:
rsrv = r.rdata.server.rstrip(".") rsrv = r.rdata.server.rstrip(".")
# we take only the first one returned for now config.default_server.append(rsrv)
config.default_server = rsrv
return True
#if none found if config.default_server:
return False return True
else:
return False
except: except:
return False return False

View File

@@ -20,6 +20,7 @@
import xmlrpclib import xmlrpclib
import socket import socket
import config import config
import errno
from krbtransport import KerbTransport from krbtransport import KerbTransport
from kerberos import GSSError from kerberos import GSSError
from ipa import ipaerror, ipautil from ipa import ipaerror, ipautil
@@ -31,16 +32,34 @@ from ipa import config
class RPCClient: class RPCClient:
def __init__(self): def __init__(self):
self.server = None
config.init_config() config.init_config()
def server_url(self): def server_url(self, server):
"""Build the XML-RPC server URL from our configuration""" """Build the XML-RPC server URL from our configuration"""
return "https://" + config.config.get_server() + "/ipa" return "https://" + server + "/ipa"
def setup_server(self): def setup_server(self):
"""Create our XML-RPC server connection using kerberos """Create our XML-RPC server connection using kerberos
authentication""" authentication"""
return xmlrpclib.ServerProxy(self.server_url(), KerbTransport()) if not self.server:
serverlist = config.config.get_server()
# Try each server until we succeed or run out of servers to try
# Guaranteed by ipa.config to have at least 1 in the list
for s in serverlist:
try:
self.server = s
remote = xmlrpclib.ServerProxy(self.server_url(s), KerbTransport())
result = remote.ping()
break
except socket.error, e:
if (e[0] == errno.ECONNREFUSED) or (e[0] == errno.ECONNREFUSED) or (e[0] == errno.EHOSTDOWN) or (e[0] == errno.EHOSTUNREACH):
continue
else:
raise e
return xmlrpclib.ServerProxy(self.server_url(self.server), KerbTransport())
# Higher-level API # Higher-level API

View File

@@ -91,6 +91,7 @@ class ModXMLRPCRequestHandler(object):
self.funcs = {} self.funcs = {}
self.traceback = False self.traceback = False
#introspection functions #introspection functions
self.register_function(self.ping, name="ping")
self.register_function(self.list_api, name="_listapi") self.register_function(self.list_api, name="_listapi")
self.register_function(self.system_listMethods, name="system.listMethods") self.register_function(self.system_listMethods, name="system.listMethods")
self.register_function(self.system_methodSignature, name="system.methodSignature") self.register_function(self.system_methodSignature, name="system.methodSignature")
@@ -240,6 +241,10 @@ class ModXMLRPCRequestHandler(object):
'args': args}) 'args': args})
return funcs return funcs
def ping(self,opts):
"""Simple test to see if the XML-RPC is up and active."""
return "pong"
def _getFuncArgs(self, func): def _getFuncArgs(self, func):
args = [] args = []
for x in range(0, func.func_code.co_argcount): for x in range(0, func.func_code.co_argcount):

View File

@@ -24,7 +24,8 @@ from ipa import config
ipa.config.init_config() ipa.config.init_config()
url = "http://" + config.config.get_server() + "/ipa" serverlist = config.config.get_server()
url = "http://" + serverlist[0] + "/ipa"
s = xmlrpclib.Server(url, KerbTransport()) s = xmlrpclib.Server(url, KerbTransport())
print "A list of all methods available on the server." print "A list of all methods available on the server."