mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Did some initial work for Context plugins
This commit is contained in:
parent
e37760a273
commit
ddb5449c7f
@ -25,13 +25,24 @@ This wraps the python-ldap bindings.
|
||||
"""
|
||||
|
||||
import ldap as _ldap
|
||||
from ipalib import api
|
||||
from ipalib import api, Context
|
||||
from ipalib import errors
|
||||
from ipalib.crud import CrudBackend
|
||||
from ipa_server import servercore
|
||||
from ipa_server import ipaldap
|
||||
|
||||
|
||||
class conn(Context):
|
||||
"""
|
||||
Thread-local LDAP connection.
|
||||
"""
|
||||
|
||||
def get_value(self):
|
||||
return 'it worked'
|
||||
|
||||
api.register(conn)
|
||||
|
||||
|
||||
class ldap(CrudBackend):
|
||||
"""
|
||||
LDAP backend plugin.
|
||||
|
@ -30,15 +30,18 @@ To learn about the ``ipalib`` library, you should read the code in this order:
|
||||
"""
|
||||
|
||||
import plugable
|
||||
import frontend
|
||||
import backend
|
||||
import config
|
||||
from backend import Backend, Context
|
||||
from frontend import Command, Object, Method, Property, Application
|
||||
from ipa_types import Bool, Int, Unicode, Enum
|
||||
from frontend import Param, DefaultFrom
|
||||
|
||||
api = plugable.API(
|
||||
frontend.Command,
|
||||
frontend.Object,
|
||||
frontend.Method,
|
||||
frontend.Property,
|
||||
frontend.Application,
|
||||
backend.Backend,
|
||||
)
|
||||
def get_standard_api(unit_test=False):
|
||||
api = plugable.API(
|
||||
Command, Object, Method, Property, Application,
|
||||
Backend, Context,
|
||||
)
|
||||
if unit_test is True:
|
||||
api.env.mode = 'unit_test'
|
||||
return api
|
||||
|
||||
api = get_standard_api()
|
||||
|
@ -23,9 +23,23 @@ Base classes for all backed-end plugins.
|
||||
|
||||
import plugable
|
||||
|
||||
|
||||
class Backend(plugable.Plugin):
|
||||
"""
|
||||
Base class for all backend plugins.
|
||||
"""
|
||||
|
||||
__proxy__ = False # Backend plugins are not wrapped in a PluginProxy
|
||||
|
||||
|
||||
class Context(plugable.Plugin):
|
||||
"""
|
||||
Base class for plugable context components.
|
||||
"""
|
||||
|
||||
__proxy__ = False # Backend plugins are not wrapped in a PluginProxy
|
||||
|
||||
def get_value(self):
|
||||
raise NotImplementedError(
|
||||
'%s.get_value()' % self.__class__.__name__
|
||||
)
|
||||
|
@ -331,7 +331,7 @@ class CLI(object):
|
||||
if len(a) < 2:
|
||||
parser.error('badly specified environment string,'\
|
||||
'use var1=val1[,var2=val2]..')
|
||||
overrides[a[0].strip()] = a[1].strip()
|
||||
overrides[str(a[0].strip())] = a[1].strip()
|
||||
overrides['context'] = 'cli'
|
||||
self.api.bootstrap(**overrides)
|
||||
|
||||
|
@ -27,6 +27,7 @@ http://docs.python.org/ref/sequence-types.html
|
||||
|
||||
import re
|
||||
import inspect
|
||||
import threading
|
||||
import errors
|
||||
from errors import check_type, check_isinstance
|
||||
from config import Environment, Env
|
||||
@ -705,6 +706,25 @@ class Registrar(DictProxy):
|
||||
self.__registered.add(klass)
|
||||
|
||||
|
||||
class LazyContext(object):
|
||||
"""
|
||||
On-demand creation of thread-local context attributes.
|
||||
"""
|
||||
|
||||
def __init__(self, api):
|
||||
self.__api = api
|
||||
self.__context = threading.local()
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name not in self.__context.__dict__:
|
||||
if name not in self.__api.Context:
|
||||
raise AttributeError('no Context plugin for %r' % name)
|
||||
value = self.__api.Context[name].get_value()
|
||||
self.__context.__dict__[name] = value
|
||||
return self.__context.__dict__[name]
|
||||
|
||||
|
||||
|
||||
class API(DictProxy):
|
||||
"""
|
||||
Dynamic API object through which `Plugin` instances are accessed.
|
||||
@ -715,6 +735,7 @@ class API(DictProxy):
|
||||
self.__done = set()
|
||||
self.register = Registrar(*allowed)
|
||||
self.env = Env()
|
||||
self.context = LazyContext(self)
|
||||
super(API, self).__init__(self.__d)
|
||||
|
||||
def __doing(self, name):
|
||||
|
@ -22,12 +22,12 @@ Test the `ipalib.backend` module.
|
||||
"""
|
||||
|
||||
from ipalib import backend, plugable, errors
|
||||
from tests.util import ClassChecker
|
||||
from tests.util import ClassChecker, raises
|
||||
|
||||
|
||||
class test_Backend(ClassChecker):
|
||||
"""
|
||||
Test the `backend.Backend` class.
|
||||
Test the `ipalib.backend.Backend` class.
|
||||
"""
|
||||
|
||||
_cls = backend.Backend
|
||||
@ -35,3 +35,21 @@ class test_Backend(ClassChecker):
|
||||
def test_class(self):
|
||||
assert self.cls.__bases__ == (plugable.Plugin,)
|
||||
assert self.cls.__proxy__ is False
|
||||
|
||||
|
||||
class test_Context(ClassChecker):
|
||||
"""
|
||||
Test the `ipalib.backend.Context` class.
|
||||
"""
|
||||
|
||||
_cls = backend.Context
|
||||
|
||||
def test_get_value(self):
|
||||
"""
|
||||
Test the `ipalib.backend.Context.get_value` method.
|
||||
"""
|
||||
class Subclass(self.cls):
|
||||
pass
|
||||
o = Subclass()
|
||||
e = raises(NotImplementedError, o.get_value)
|
||||
assert str(e) == 'Subclass.get_value()'
|
||||
|
Loading…
Reference in New Issue
Block a user