Add support for environment variables, change tests accordingly

This commit is contained in:
Martin Nagy 2008-09-29 17:41:30 +02:00 committed by Jason Gerard DeRose
parent d77907d2d0
commit afdc721038
9 changed files with 148 additions and 13 deletions

View File

@ -58,8 +58,10 @@ True
import plugable
import frontend
import backend
import config
api = plugable.API(
config.default_environment(),
frontend.Command,
frontend.Object,
frontend.Method,

View File

@ -30,6 +30,7 @@ import errors
import plugable
import ipa_types
from ipalib import config
def exit_error(error):
sys.exit('ipa: ERROR: %s' % error)
@ -256,6 +257,9 @@ class CLI(object):
self.print_commands()
print 'Usage: ipa COMMAND'
sys.exit(2)
# do parsing here, read the conf
conf_dict = config.read_config(self.api.env.conf)
self.api.env.update(conf_dict)
key = sys.argv[1]
if key not in self:
self.print_commands()

84
ipalib/config.py Normal file
View File

@ -0,0 +1,84 @@
# Authors:
# Martin Nagy <mnagy@redhat.com>
#
# Copyright (C) 2008 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
def default_environment():
default = dict(
conf = '/etc/ipa/ipa.conf',
server_context = True,
query_dns = True,
verbose = False,
servers = LazyIter(myservers),
realm = LazyProp(myrealm),
domain = LazyProp(mydomain),
)
return default
class LazyProp(object):
def __init__(self, func, value=None):
self._func = func
self._value = value
def set_value(self, value):
self._value = value
def get_value(self):
if self._value is None:
return self._func()
else:
return self._value
# FIXME: make sure to eliminate duplicates
class LazyIter(LazyProp):
def get_value(self):
if self._value is not None:
if type(self._value) is tuple:
for item in self._value:
yield item
else:
yield self._value
for item in self._func():
yield item
def read_config(file):
assert isinstance(file, basestring)
# open the file and read configuration, return a dict
# for now, these are here just for testing purposes
return dict(servers="server.ipatest.com", realm="IPATEST.COM")
# these functions are here just to "emulate" dns resolving for now
def mydomain():
return "ipatest.com"
def myrealm():
return "IPATEST.COM"
def myservers():
# print is here to demonstrate that the querying will occur only when it is
# really needed
print "Querying DNS"
yield "server.ipatest.com"
yield "backup.ipatest.com"
yield "fake.ipatest.com"

View File

@ -559,7 +559,7 @@ class Command(plugable.Plugin):
return self.run(*args, **kw)
def run(self, *args, **kw):
if self.api.env.in_server_context:
if self.api.env.server_context:
target = self.execute
else:
target = self.forward

View File

@ -692,20 +692,45 @@ class Registrar(DictProxy):
self.__registered.add(klass)
class Environment(dict):
def __getitem__(self, key):
val = super(Environment, self).__getitem__(key)
if hasattr(val, 'get_value'):
return val.get_value()
else:
return val
def __setitem__(self, key, value):
if key in self:
super_value = super(Environment, self).__getitem__(key)
if key in self and hasattr(super_value, 'set_value'):
super_value.set_value(value)
else:
super(Environment, self).__setitem__(key, value)
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, value):
self[name] = value
def update(self, d):
assert isinstance(d, dict)
for key, value in d.iteritems():
self[key] = value
class API(DictProxy):
"""
Dynamic API object through which `Plugin` instances are accessed.
"""
__finalized = False
def __init__(self, *allowed, **kw):
def __init__(self, default_env, *allowed):
self.__d = dict()
self.register = Registrar(*allowed)
default = dict(
in_server_context=True,
)
default.update(kw)
self.env = MagicDict(default)
self.env = Environment(default_env)
super(API, self).__init__(self.__d)
def finalize(self):

View File

@ -57,6 +57,23 @@ class discover(frontend.Command):
'Discover IPA servers on network.'
api.register(discover)
# Command to get the idea how plugins will interact with api.env
class envtest(frontend.Command):
'Show current environment.'
def run(*args, **kw):
print ""
print "Environment variables:"
for var in api.env:
val = api.env[var]
if var is 'servers':
print ""
print " Servers:"
for item in api.env.servers:
print " %s" % item
print ""
else:
print " %s: %s" % (var, val)
api.register(envtest)
# Register some methods for the 'user' object:
class user_add(crud.Add):

View File

@ -22,10 +22,11 @@ Unit tests for `ipalib.crud` module.
"""
from tstutil import read_only, raises, ClassChecker
from ipalib import crud, frontend, plugable
from ipalib import crud, frontend, plugable, config
def get_api():
api = plugable.API(
config.default_environment(),
frontend.Object,
frontend.Method,
frontend.Property,

View File

@ -23,7 +23,7 @@ Unit tests for `ipalib.frontend` module.
from tstutil import raises, getitem, no_set, no_del, read_only, ClassChecker
from tstutil import check_TypeError
from ipalib import frontend, backend, plugable, errors, ipa_types
from ipalib import frontend, backend, plugable, errors, ipa_types, config
def test_RULE_FLAG():
@ -732,7 +732,7 @@ class test_Command(ClassChecker):
kw = dict(how_are='you', on_this='fine day?')
# Test in server context:
api = plugable.API(self.cls, in_server_context=True)
api = plugable.API(dict(server_context=True), self.cls)
api.finalize()
o = my_cmd()
o.set_api(api)
@ -741,7 +741,7 @@ class test_Command(ClassChecker):
assert o.run.im_func is my_cmd.execute.im_func
# Test in non-server context
api = plugable.API(self.cls, in_server_context=False)
api = plugable.API(dict(server_context=False), self.cls)
api.finalize()
o = my_cmd()
o.set_api(api)
@ -868,6 +868,7 @@ class test_Object(ClassChecker):
Test the `frontend.Object.primary_key` attribute.
"""
api = plugable.API(
config.default_environment(),
frontend.Method,
frontend.Property,
)
@ -922,6 +923,7 @@ class test_Object(ClassChecker):
Test the `frontend.Object.backend` attribute.
"""
api = plugable.API(
config.default_environment(),
frontend.Object,
frontend.Method,
frontend.Property,

View File

@ -742,7 +742,7 @@ def test_API():
def method(self, n):
return n + 1
api = plugable.API(base0, base1)
api = plugable.API(dict(), base0, base1)
r = api.register
assert isinstance(r, plugable.Registrar)
assert read_only(api, 'register') is r
@ -800,7 +800,7 @@ def test_API():
# Test with base class that doesn't request a proxy
class NoProxy(plugable.Plugin):
__proxy__ = False
api = plugable.API(NoProxy)
api = plugable.API(dict(), NoProxy)
class plugin0(NoProxy):
pass
api.register(plugin0)