summaryrefslogtreecommitdiffstats
path: root/ipsilon
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-01-24 17:01:35 -0500
committerSimo Sorce <simo@redhat.com>2014-01-24 17:32:21 -0500
commit2b9722213d76306fe6f3b9f2fe157b3459d28e3a (patch)
tree65f19e526cb3fe7b92106e704f60722ca9a4e8b6 /ipsilon
parente34f21377d30704c342abb24a3a84c27fd8cc957 (diff)
downloadipsilon-2b9722213d76306fe6f3b9f2fe157b3459d28e3a.tar.gz
ipsilon-2b9722213d76306fe6f3b9f2fe157b3459d28e3a.tar.xz
ipsilon-2b9722213d76306fe6f3b9f2fe157b3459d28e3a.zip
Better infrastructure to load plugins
Signed-off-by: Simo Sorce <simo@redhat.com>
Diffstat (limited to 'ipsilon')
-rwxr-xr-xipsilon/idpserver.py6
-rwxr-xr-xipsilon/util/data.py103
-rwxr-xr-xipsilon/util/plugin.py93
3 files changed, 165 insertions, 37 deletions
diff --git a/ipsilon/idpserver.py b/ipsilon/idpserver.py
index e260043..41a2cf4 100755
--- a/ipsilon/idpserver.py
+++ b/ipsilon/idpserver.py
@@ -23,7 +23,6 @@ sys.stdout = sys.stderr
import os
import atexit
import cherrypy
-from ipsilon.util.plugin import Plugins
from ipsilon.util.data import Store
from ipsilon.util import page
from ipsilon.root import Root
@@ -31,11 +30,6 @@ from jinja2 import Environment, FileSystemLoader
cherrypy.config.update('ipsilon.conf')
-plugins = Plugins(path=cherrypy.config['base.dir'])
-idp_providers = plugins.get_providers()
-if idp_providers:
- cherrypy.config['idp_providers'] = idp_providers
-
datastore = Store()
admin_config = datastore.get_admin_config()
for option in admin_config:
diff --git a/ipsilon/util/data.py b/ipsilon/util/data.py
index 15bf5b7..251c998 100755
--- a/ipsilon/util/data.py
+++ b/ipsilon/util/data.py
@@ -29,6 +29,24 @@ class Store(object):
self._path = os.getcwd()
else:
self._path = path
+ self._admin_dbname = self._get_admin_dbname()
+ self._user_dbname = self._get_userprefs_dbname()
+
+ def _get_admin_dbname(self):
+ path = None
+ if 'admin.config.db' in cherrypy.config:
+ path = cherrypy.config['admin.config.db']
+ if not path:
+ path = os.path.join(self._path, 'adminconfig.sqlite')
+ return path
+
+ def _get_userprefs_dbname(self):
+ path = None
+ if 'user.prefs.db' in cherrypy.config:
+ path = cherrypy.config['user.prefs.db']
+ if not path:
+ path = os.path.join(self._path, 'userprefs.sqlite')
+ return path
def _load_config(self, dbname):
con = None
@@ -65,13 +83,7 @@ class Store(object):
return conf
def get_admin_config(self):
- path = None
- if 'admin.config.db' in cherrypy.config:
- path = cherrypy.config['admin.config.db']
- if not path:
- path = os.path.join(self._path, 'adminconfig.sqlite')
-
- return self._load_config(path)
+ return self._load_config(self._admin_dbname)
def _load_user_prefs(self, dbname, user):
con = None
@@ -104,10 +116,75 @@ class Store(object):
return conf
def get_user_preferences(self, user):
- path = None
- if 'user.prefs.db' in cherrypy.config:
- path = cherrypy.config['user.prefs.db']
- if not path:
- path = os.path.join(self._path, 'userprefs.sqlite')
+ return self._load_user_prefs(self._user_dbname, user)
- return self._load_user_prefs(path, user)
+ def get_plugins_config(self, facility):
+ con = None
+ rows = []
+ try:
+ con = sqlite3.connect(self._admin_dbname)
+ cur = con.cursor()
+ cur.execute("CREATE TABLE IF NOT EXISTS " +
+ facility + " (name TEXT,option TEXT,value TEXT)")
+ cur.execute("SELECT * FROM " + facility)
+ rows = cur.fetchall()
+ con.commit()
+ except sqlite3.Error, e:
+ if con:
+ con.rollback()
+ cherrypy.log.error("Failed to load %s config: [%s]" % (facility,
+ e))
+ finally:
+ if con:
+ con.close()
+
+ lpo = []
+ plco = dict()
+ for row in rows:
+ if row[0] == 'global':
+ if row[1] == 'order':
+ lpo = row[2].split(',')
+ continue
+ if row[0] not in plco:
+ # one dict per provider
+ plco[row[0]] = dict()
+
+ conf = plco[row[0]]
+ if row[1] in conf:
+ if conf[row[1]] is list:
+ conf[row[1]].append(row[2])
+ else:
+ v = conf[row[1]]
+ conf[row[1]] = [v, row[2]]
+ else:
+ conf[row[1]] = row[2]
+
+ return (lpo, plco)
+
+ def save_plugin_config(self, facility, plugin, options):
+ SELECT = "SELECT option, value FROM %s WHERE name=?" % facility
+ UPDATE = "UPDATE %s SET value=? WHERE name=? AND option=?" % facility
+ INSERT = "INSERT INTO %s VALUES(?,?,?)" % facility
+ con = None
+ try:
+ con = sqlite3.connect(self._admin_dbname)
+ cur = con.cursor()
+ curvals = dict()
+ for row in cur.execute(SELECT, (plugin,)):
+ curvals[row[0]] = row[1]
+
+ for name in options:
+ if name in curvals:
+ cur.execute(UPDATE, (options[name], plugin, name))
+ else:
+ cur.execute(INSERT, (plugin, name, options[name]))
+
+ con.commit()
+ except sqlite3.Error, e:
+ if con:
+ con.rollback()
+ cherrypy.log.error("Failed to store config: [%s]" % e)
+ raise
+ finally:
+ if con:
+ con.close()
diff --git a/ipsilon/util/plugin.py b/ipsilon/util/plugin.py
index 917f28b..2077023 100755
--- a/ipsilon/util/plugin.py
+++ b/ipsilon/util/plugin.py
@@ -20,6 +20,8 @@
import os
import imp
import cherrypy
+import inspect
+from ipsilon.util.data import Store
class Plugins(object):
@@ -38,8 +40,8 @@ class Plugins(object):
try:
if ext.lower() == '.py':
mod = imp.load_source(name, file_name)
- elif ext.lower() == '.pyc':
- mod = imp.load_compiled(name, file_name)
+ #elif ext.lower() == '.pyc':
+ # mod = imp.load_compiled(name, file_name)
else:
return
except Exception, e: # pylint: disable=broad-except
@@ -47,8 +49,10 @@ class Plugins(object):
return
if hasattr(mod, class_type):
- tree[name] = getattr(mod, class_type)()
- cherrypy.log.error('Added module %s' % (name))
+ instance = getattr(mod, class_type)()
+ public_name = getattr(instance, 'name', name)
+ tree[public_name] = instance
+ cherrypy.log.error('Added module %s as %s' % (name, public_name))
def _load_classes(self, tree, path, class_type):
files = None
@@ -62,20 +66,73 @@ class Plugins(object):
filename = os.path.join(path, name)
self._load_class(tree, class_type, filename)
- def get_providers(self):
- if self._providers_tree is None:
- path = None
- if 'providers.dir' in cherrypy.config:
- path = cherrypy.config['providers.dir']
- if not path:
- path = os.path.join(self._path, 'providers')
+ def get_plugins(self, path, class_type):
+ plugins = dict()
+ self._load_classes(plugins, path, class_type)
+ return plugins
- self._providers_tree = []
- self._load_classes(self._providers_tree, path, 'IdpProvider')
- return self._providers_tree
+class PluginLoader(object):
- def get_custom(self, path, class_type):
- tree = []
- self._load_classes(tree, path, class_type)
- return tree
+ def __init__(self, baseobj, facility, plugin_type):
+ (whitelist, config) = Store().get_plugins_config(facility)
+ if cherrypy.config.get('debug', False):
+ cherrypy.log('[%s] %s: %s' % (facility, whitelist, config))
+ if whitelist is None:
+ whitelist = []
+ if config is None:
+ config = dict()
+
+ p = Plugins(path=cherrypy.config['base.dir'])
+ (pathname, dummy) = os.path.split(inspect.getfile(baseobj))
+ self._plugins = {
+ 'config': config,
+ 'available': p.get_plugins(pathname, plugin_type),
+ 'whitelist': whitelist,
+ 'enabled': []
+ }
+
+ def get_plugin_data(self):
+ return self._plugins
+
+
+class PluginObject(object):
+
+ def __init__(self):
+ self.name = None
+ self._config = None
+ self._options = None
+
+ def get_config_desc(self):
+ """ The configuration description is a dictionary that provides
+ A description of the supported configuration options, as well
+ as the default configuration option values.
+ The key is the option name, the value is an array of 3 elements:
+ - description
+ - option type
+ - default value
+ """
+ return self._options
+
+ def set_config(self, config):
+ self._config = config
+
+ def get_config_value(self, name):
+ value = None
+ if self._config:
+ value = self._config.get(name, None)
+ if not value:
+ if self._options:
+ opt = self._options.get(name, None)
+ if opt:
+ value = opt[2]
+
+ if cherrypy.config.get('debug', False):
+ cherrypy.log('[%s] %s: %s' % (self.name, name, value))
+
+ return value
+
+ def set_config_value(self, option, value):
+ if not self._config:
+ self._config = dict()
+ self._config[option] = value