Started work on a much simplified mod_python server

This commit is contained in:
Jason Gerard DeRose 2009-01-30 20:53:32 -07:00 committed by Rob Crittenden
parent 91ca06f079
commit c2b0c80140
10 changed files with 103 additions and 95 deletions

View File

@ -432,8 +432,9 @@ class Env(object):
self.site_packages = path.dirname(self.ipalib)
self.script = path.abspath(sys.argv[0])
self.bin = path.dirname(self.script)
self.home = path.abspath(os.environ['HOME'])
self.dot_ipa = path.join(self.home, '.ipa')
self.home = os.environ.get('HOME', None)
self.etc = path.join('/', 'etc', 'ipa')
self.dot_ipa = self._join('home', '.ipa')
self._merge(**overrides)
if 'in_tree' not in self:
if self.bin == self.site_packages and \
@ -454,6 +455,10 @@ class Env(object):
if 'conf_dir' not in self:
self.conf_dir = base
def _join(self, key, *parts):
if key in self and self[key] is not None:
return path.join(self[key], *parts)
def _finalize_core(self, **defaults):
"""
Complete initialization of standard IPA environment.

View File

@ -410,9 +410,26 @@ class KerberosError(AuthenticationError):
errno = 1100
class CCacheError(KerberosError):
"""
**1101** Raised when sever does not recieve Kerberose credentials.
For example:
>>> raise CCacheError()
Traceback (most recent call last):
...
CCacheError: did not receive Kerberos credentials
"""
errno = 1101
format = _('did not receive Kerberos credentials')
class ServiceError(KerberosError):
"""
**1101** Raised when service is not found in Kerberos DB.
**1102** Raised when service is not found in Kerberos DB.
For example:
@ -420,10 +437,9 @@ class ServiceError(KerberosError):
Traceback (most recent call last):
...
ServiceError: Service 'HTTP@localhost' not found in Kerberos database
"""
errno = 1101
errno = 1102
format = _('Service %(service)r not found in Kerberos database')

View File

@ -561,6 +561,8 @@ class API(DictProxy):
# Add file handler:
if self.env.mode in ('dummy', 'unit_test'):
return # But not if in unit-test mode
if self.env.log is None:
return
log_dir = path.dirname(self.env.log)
if not path.isdir(log_dir):
try:

View File

@ -41,7 +41,7 @@ class request_certificate(Command):
else:
textui.print_plain('Failed to submit a certificate request.')
api.register(request_certificate)
#api.register(request_certificate)
class get_certificate(Command):
@ -58,7 +58,7 @@ class get_certificate(Command):
else:
textui.print_plain('Failed to obtain a certificate.')
api.register(get_certificate)
#api.register(get_certificate)
class check_request_status(Command):
@ -76,7 +76,7 @@ class check_request_status(Command):
else:
textui.print_plain('Failed to retrieve a request status.')
api.register(check_request_status)
#api.register(check_request_status)
class revoke_certificate(Command):
@ -97,7 +97,7 @@ class revoke_certificate(Command):
else:
textui.print_plain('Failed to revoke a certificate.')
api.register(revoke_certificate)
#api.register(revoke_certificate)
class take_certificate_off_hold(Command):
@ -114,4 +114,4 @@ class take_certificate_off_hold(Command):
else:
textui.print_plain('Failed to take a revoked certificate off hold.')
api.register(take_certificate_off_hold)
#api.register(take_certificate_off_hold)

View File

@ -20,3 +20,31 @@
"""
Package containing server backend.
"""
from xmlrpclib import dumps, Fault
from ipalib import api
try:
from mod_python import apache
api.bootstrap(context='server', log=None, debug=True)
api.finalize()
except ImportError:
pass
def xmlrpc(req):
if req.method != 'POST':
req.allow_methods(['POST'], 1)
return apache.HTTP_METHOD_NOT_ALLOWED
if apache.mpm_query(apache.AP_MPMQ_IS_THREADED):
response = dumps(
Fault(3, 'Apache must use the forked model'), methodresponse=True
)
else:
response = api.Backend.xmlserver.marshaled_dispatch(req.read(), None)
req.content_type = 'text/xml'
req.set_content_length(len(response))
req.write(response)
return apache.OK

View File

@ -29,29 +29,21 @@ Production XML-RPC server using mod_python.
import sys
import os
import time
import traceback
import pprint
from xmlrpclib import Marshaller,loads,dumps,Fault
import logging
import string
from ipalib import api
# We only initialize api when actually running under mod_python:
try:
from mod_python import apache
api.bootstrap(context='server', in_server=True, log=None)
api.finalize()
except ImportError:
pass
import logging
import ldap
from ipalib import api
from ipalib import config
from ipaserver import conn
from ipaserver.servercore import context
from ipaserver.servercore import ipautil
from ipalib.util import xmlrpc_unmarshal
import string
api.load_plugins()
# Global list of available functions
gfunctions = {}
@ -116,57 +108,14 @@ class ModXMLRPCRequestHandler(object):
context.opts['remoteuser'] = req.user
if req.subprocess_env.get("KRB5CCNAME") is not None:
krbccache = req.subprocess_env.get("KRB5CCNAME")
else:
response = dumps(Fault(5, "Did not receive Kerberos credentials."))
return response
debuglevel = logging.INFO
if pythonopts.get("IPADebug"):
context.opts['ipadebug'] = pythonopts.get("IPADebug").lower()
if context.opts['ipadebug'] == "on":
debuglevel = logging.DEBUG
if not context.opts.get('ipadebug'):
context.opts['ipadebug'] = "off"
logging.basicConfig(level=debuglevel,
format='[%(asctime)s] [%(levelname)s] %(message)s',
datefmt='%a %b %d %H:%M:%S %Y',
stream=sys.stderr)
logging.info("Interpreter: %s" % req.interpreter)
# if opts['ipadebug'] == "on":
# for o in opts:
# logging.debug("IPA: setting option %s: %s" % (o, opts[o]))
# for e in req.subprocess_env:
# logging.debug("IPA: environment %s: %s" % (e, req.subprocess_env[e]))
context.conn = conn.IPAConn(api.env.ldaphost, api.env.ldapport, krbccache, context.opts.get('ipadebug'))
start = time.time()
# generate response
try:
response = self._dispatch(method, params)
# wrap response in a singleton tuple
response = (response,)
response = dumps(response, methodresponse=1, allow_none=1)
except Fault, e:
response = dumps(Fault(e.faultCode, e.faultString))
except:
self.traceback = True
# report exception back to server
e_class, e = sys.exc_info()[:2]
faultCode = getattr(e_class,'faultCode',1)
tb_str = ''.join(traceback.format_exception(*sys.exc_info()))
faultString = tb_str
response = dumps(Fault(faultCode, faultString))
return response
ccache = req.subprocess_env.get('KRB5CCNAME')
return api.Backend.xmlserver.marshaled_dispatch(data, ccache)
except Exception, e:
api.log.exception(
'mod_python_xmlrpc: caught error in _marshaled_dispatch()'
)
raise e
def _dispatch(self,method,params):
func = self.funcs.get(method,None)
@ -347,22 +296,7 @@ def load_modules():
PythonHandler ipaxmlrpc
"""
# setup up the logger with a DEBUG level. It may get reset to INFO
# once we start processing requests. We don't have access to the
# Apache configuration yet.
setup_logger(logging.DEBUG)
api.finalize()
# Initialize our environment
config.set_default_env(api.env)
env_dict = config.read_config()
env_dict['server_context'] = True
api.env.update(env_dict)
# Get and register all the methods
for cmd in api.Command:
logging.debug("registering XML-RPC call %s" % cmd)
register_function(api.Command[cmd], cmd)
return

View File

@ -42,6 +42,8 @@ class ldap(CrudBackend):
super(ldap, self).__init__()
def create_connection(self, ccache):
if ccache is None:
raise errors2.CCacheError()
conn = ipaldap.IPAdmin(self.env.ldap_host, self.env.ldap_port)
principle = krbV.CCache(
name=ccache, context=krbV.default_context()

View File

@ -67,6 +67,7 @@ class ra(Backend):
self.__create_nss_db()
self.__import_ca_chain()
self.__request_ipa_certificate(self.__generate_ipa_request())
assert False
super(ra, self).__init__()
@ -404,4 +405,4 @@ class ra(Backend):
# api.log.debug("IPA-RA: stderr: '%s'" % stderr)
return (p.returncode, stdout, stderr)
api.register(ra)
#api.register(ra)

View File

@ -46,15 +46,35 @@ class xmlserver(Executioner):
Also see the `ipalib.rpc.xmlclient` plugin.
"""
def finalize(self):
self.__system = {
'system.listMethods': self.listMethods,
'system.methodSignature': self.methodSignature,
'system.methodHelp': self.methodHelp,
}
super(xmlserver, self).finalize()
def listMethods(self, *params):
return tuple(name.encode('UTF-8') for name in self.Command)
def methodSignature(self, *params):
return 'methodSignature not supported'
def methodHelp(self, *params):
return 'methodHelp not supported'
def marshaled_dispatch(self, data, ccache):
"""
Execute the XML-RPC request in contained in ``data``.
"""
try:
self.create_context(ccache=ccache)
#self.create_context(ccache=ccache)
(params, name) = xml_loads(data)
(args, options) = params_2_args_options(params)
response = (self.execute(name, *args, **options),)
if name in self.__system:
response = (self.__system[name](*params),)
else:
(args, options) = params_2_args_options(params)
response = (self.execute(name, *args, **options),)
except PublicError, e:
self.info('response: %s: %s', e.__class__.__name__, str(e))
response = Fault(e.errno, e.strerror)

View File

@ -27,7 +27,7 @@ from distutils.core import setup
setup(
name='freeipa',
version='1.99.0',
version='1.99.1',
license='GPLv2+',
url='http://freeipa.org/',
packages=[