2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-11-28 20:39:40 +00:00

Refactor plugin api code into its own module

This commit is contained in:
Jarrod Johnson 2013-09-04 15:44:28 -04:00
parent db0596d17b
commit cad7db237c

95
confluent/pluginapi.py Normal file
View File

@ -0,0 +1,95 @@
# concept here that mapping from the resource tree and arguments go to
# specific python class signatures. The intent is to require
# plugin authors to come here if they *really* think they need new 'commands'
# and hopefully curtail deviation by each plugin author
# have to specify a standard place for cfg selection of *which* plugin
# as well a standard to map api requests to python funcitons
# e.g. <nodeelement>/power/state maps to some plugin HardwareManager.get_power/set_power
# selected by hardwaremanagement.method
# plugins can advertise a set of names if there is a desire for readable things
# exceptions to handle os images
# endpoints point to a class... usually, the class should have:
# -create
# -retrieve
# -update
# -delete
# functions. Console is special and just get's passed through
# see API.txt
import os
import sys
pluginmap = {}
def load_plugins():
# To know our plugins directory, we get the parent path of 'bin'
path=os.path.dirname(os.path.realpath(__file__))
plugindir = os.path.realpath(os.path.join(path,'..','plugins'))
sys.path.append(plugindir)
plugins = set()
#two passes, to avoid adding both py and pyc files
for plugin in os.listdir(plugindir):
plugin = os.path.splitext(plugin)[0]
plugins.add(plugin)
for plugin in plugins:
if plugin.startswith('.'):
continue
tmpmod = __import__(plugin)
if 'plugin_names' in tmpmod.__dict__:
for name in tmpmod.plugin_names:
pluginmap[name] = tmpmod
else:
pluginmap[plugin] = tmpmod
nodetree = {
'/': ['power/', 'boot/', 'console/', 'attributes/'],
'/power/': ['state'],
'/boot/': ['device'],
'/console/': ['session', 'logging'],
}
# _ elements are for internal use (e.g. special console scheme)
nodeelements = {
'_console/session': {
'pluginattrs': ['console.method' ,'hardwaremanagement.method'],
},
'console/session': {
'pluginattrs': ['console.method' ,'hardwaremanagement.method'],
},
'power/state': {
'pluginattrs': ['hardwaremanagement.method'],
},
'boot/device': {
'pluginattrs': ['hardwaremanagement.method'],
}
}
def handle_path(path, operation, configmanager):
'''Given a full path request, return an object.
The plugins should generally return some sort of iterator.
An exception is made for console/session, which should return
a class with read(), write(bytes), and close()
'''
if (path.startswith("/node/") or path.startswith("/system/") or
# single node requests
path.startswith("/vm/")):
nodeidx = path.find("/",1) + 1
node = path[nodeidx:]
node, _, element = path.partition("/")
if element not in nodeelements:
raise Exception("Invalid element requested")
plugroute = nodeelements[element]
if 'pluginattrs' in plugroute:
nodeattr = configmanager.get_node_attributes(
[node], plugroute['pluginattrs'])
for attrname in plugroute['pluginattrs']:
if attrname in nodeattr:
return pluginmap[nodeattr[attrname]].__dict__[operation](
node=(node), operation=operation,
configmanager=configmanager)