mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-22 09:32:21 +00:00
Have rest explorer actually mostly work as expected
This commit is contained in:
parent
836ea16603
commit
215acdf4a7
@ -257,6 +257,9 @@ def _assemble_html(responses, resource, querydict):
|
||||
yield '<input type="hidden" name="restexplorerop" value="update">'
|
||||
yield '<input type="hidden" name="restexplorerhonorkey" value="">'
|
||||
yield '<a rel="self" href="%s">%s</a><br>' % (resource, resource)
|
||||
print 'got a %s' % resource
|
||||
if resource in ('/', './'):
|
||||
pass
|
||||
if resource[-1] == '/':
|
||||
yield '<a rel="collection" href="../">../</a><br>'
|
||||
else:
|
||||
|
@ -76,9 +76,9 @@ class ChildCollection(LinkRelation):
|
||||
self.href = collname
|
||||
|
||||
def get_input_message(path, operation, inputdata, nodes=None):
|
||||
if 'power/state' in path and operation != 'retrieve':
|
||||
if path[0] == 'power' and path[1] == 'state' and operation != 'retrieve':
|
||||
return InputPowerMessage(path, nodes, inputdata)
|
||||
elif path.startswith('attributes/') and operation != 'retrieve':
|
||||
elif path[0] == 'attributes' and operation != 'retrieve':
|
||||
return InputAttributes(path, nodes, inputdata)
|
||||
elif inputdata:
|
||||
raise exc.InvalidArgumentException()
|
||||
|
@ -25,6 +25,8 @@ import sys
|
||||
|
||||
pluginmap = {}
|
||||
|
||||
def nested_lookup(nestdict, key):
|
||||
return reduce(dict.__getitem__, key, nestdict)
|
||||
|
||||
def load_plugins():
|
||||
# To know our plugins directory, we get the parent path of 'bin'
|
||||
@ -62,7 +64,40 @@ nodecollections = {
|
||||
rootcollections = {
|
||||
'node/': nodecollections
|
||||
}
|
||||
# _ elements are for internal use (e.g. special console scheme)
|
||||
|
||||
class PluginRoute(object):
|
||||
def __init__(self, routedict):
|
||||
self.routeinfo = routedict
|
||||
# _ prefix indicates internal use (e.g. special console scheme) and should not
|
||||
# be enumerated in any collection
|
||||
noderesources = {
|
||||
'_console': {
|
||||
'session': PluginRoute({
|
||||
'pluginattrs': ['console.method' ,'hardwaremanagement.method'],
|
||||
}),
|
||||
},
|
||||
'console': {
|
||||
#this is a dummy value, http or socket must handle special
|
||||
'session': PluginRoute({}),
|
||||
},
|
||||
'power': {
|
||||
'state': PluginRoute({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
},
|
||||
'boot': {
|
||||
'device': PluginRoute({
|
||||
'pluginattrs': ['hardwaremanagement.method'],
|
||||
'default': 'ipmi',
|
||||
}),
|
||||
},
|
||||
'attributes': {
|
||||
'all': PluginRoute({ 'handler': 'attributes' }),
|
||||
'current': PluginRoute({ 'handler': 'attributes' }),
|
||||
},
|
||||
}
|
||||
|
||||
nodeelements = {
|
||||
'_console/session': {
|
||||
'pluginattrs': ['console.method' ,'hardwaremanagement.method'],
|
||||
@ -97,21 +132,21 @@ def iterate_collections(iterable):
|
||||
coll = coll + '/'
|
||||
yield msg.ChildCollection(coll)
|
||||
|
||||
def enumerate_collection(collection, configmanager):
|
||||
if collection.startswith("/"):
|
||||
collection = collection[1:]
|
||||
if collection == 'node/':
|
||||
def iterate_resources(fancydict):
|
||||
for resource in fancydict.iterkeys():
|
||||
if resource.startswith("_"):
|
||||
continue
|
||||
if not isinstance(fancydict[resource], PluginRoute): # a resource
|
||||
resource += '/'
|
||||
yield msg.ChildCollection(resource)
|
||||
|
||||
def enumerate_node_collection(collectionpath, configmanager):
|
||||
print repr(collectionpath)
|
||||
if collectionpath == [ 'node' ]: #it is simple '/node/', need a list of nodes
|
||||
return iterate_collections(configmanager.get_nodes())
|
||||
elif collection.startswith('node/'):
|
||||
nodecoll = collection.replace('node/','')
|
||||
print nodecoll
|
||||
if '/' not in nodecoll[:-1]: # it is supposed to be a node
|
||||
node = nodecoll[:-1]
|
||||
if not configmanager.is_node(node):
|
||||
raise exc.NotFoundException("Invalid node requested")
|
||||
return iterate_collections(nodecollections.iterkeys())
|
||||
else:
|
||||
raise exc.NotFoundException("Invalid path")
|
||||
del collectionpath[0:2]
|
||||
collection = nested_lookup(noderesources, collectionpath)
|
||||
return iterate_resources(collection)
|
||||
|
||||
|
||||
def enumerate_collections(collections):
|
||||
@ -125,23 +160,36 @@ def handle_path(path, operation, configmanager, inputdata=None):
|
||||
An exception is made for console/session, which should return
|
||||
a class with connect(), read(), write(bytes), and close()
|
||||
'''
|
||||
if path == '/':
|
||||
iscollection = False
|
||||
pathcomponents = path.split('/')
|
||||
del pathcomponents[0] # discard the value from leading /
|
||||
print repr(pathcomponents)
|
||||
if pathcomponents[-1] == '':
|
||||
iscollection = True
|
||||
del pathcomponents[-1]
|
||||
if not pathcomponents: #root collection list
|
||||
return enumerate_collections(rootcollections)
|
||||
elif path[-1] == '/':
|
||||
return enumerate_collection(path, configmanager)
|
||||
elif (path.startswith("/node/") or path.startswith("/system/") or
|
||||
# single node requests
|
||||
path.startswith("/vm/")):
|
||||
nodeidx = path.find("/",1) + 1
|
||||
node = path[nodeidx:]
|
||||
node, _, element = node.partition("/")
|
||||
if element not in nodeelements:
|
||||
elif pathcomponents[0] in ('node', 'system', 'vm'):
|
||||
#single node request of some sort
|
||||
try:
|
||||
node = pathcomponents[1]
|
||||
except IndexError: # doesn't actually have a long enough path
|
||||
return iterate_collections(configmanager.get_nodes())
|
||||
if iscollection:
|
||||
print "oh hi there..."
|
||||
print repr(pathcomponents[2:])
|
||||
return enumerate_node_collection(pathcomponents, configmanager)
|
||||
print repr(pathcomponents)
|
||||
del pathcomponents[0:2]
|
||||
print repr(pathcomponents)
|
||||
try:
|
||||
plugroute = nested_lookup(noderesources, pathcomponents).routeinfo
|
||||
except KeyError:
|
||||
raise exc.NotFoundException("Invalid element requested")
|
||||
inputdata = msg.get_input_message(element, operation, inputdata, (node,))
|
||||
plugroute = nodeelements[element]
|
||||
inputdata = msg.get_input_message(pathcomponents, operation, inputdata, (node,))
|
||||
if 'handler' in plugroute: #fixed handler definition
|
||||
passvalue = pluginmap[plugroute['handler']].__dict__[operation](
|
||||
nodes=(node,), element=element,
|
||||
nodes=(node,), element=pathcomponents,
|
||||
configmanager=configmanager,
|
||||
inputdata=inputdata)
|
||||
elif 'pluginattrs' in plugroute:
|
||||
@ -150,12 +198,12 @@ def handle_path(path, operation, configmanager, inputdata=None):
|
||||
for attrname in plugroute['pluginattrs']:
|
||||
if attrname in nodeattr[node]:
|
||||
passvalue = pluginmap[nodeattr[node][attrname]['value']].__dict__[operation](
|
||||
nodes=(node,), element=element,
|
||||
nodes=(node,), element=pathcomponents,
|
||||
configmanager=configmanager,
|
||||
inputdata=inputdata)
|
||||
if 'default' in plugroute:
|
||||
passvalue = pluginmap[plugroute['default']].__dict__[operation](
|
||||
nodes=(node,), element=element, configmanager=configmanager,
|
||||
nodes=(node,), element=pathcomponents, configmanager=configmanager,
|
||||
inputdata=inputdata)
|
||||
if isinstance(passvalue, console.Console):
|
||||
return passvalue
|
||||
|
@ -3,7 +3,7 @@ import confluent.config.attributes as allattributes
|
||||
|
||||
def retrieve(nodes, element, configmanager, inputdata):
|
||||
attributes = configmanager.get_node_attributes(nodes)
|
||||
if element.endswith('/all'):
|
||||
if element[-1] == 'all':
|
||||
for node in nodes:
|
||||
for attribute in sorted(allattributes.node.iterkeys()):
|
||||
if attribute in attributes[node]: #have a setting for it
|
||||
@ -16,7 +16,7 @@ def retrieve(nodes, element, configmanager, inputdata):
|
||||
else:
|
||||
yield msg.Attributes(node,
|
||||
{attribute: val['value']})
|
||||
elif element.endswith('/current'):
|
||||
elif element[-1] == 'current':
|
||||
for node in attributes.iterkeys():
|
||||
for attribute in sorted(attributes[node].iterkeys()):
|
||||
currattr = attributes[node][attribute]
|
||||
|
@ -251,7 +251,7 @@ class IpmiHandler(object):
|
||||
def handle_request(self):
|
||||
while not self.loggedin:
|
||||
wait_on_ipmi()
|
||||
if self.element == 'power/state':
|
||||
if self.element == [ 'power', 'state' ]:
|
||||
if 'read' == self.op:
|
||||
power = self.call_ipmicmd(self.ipmicmd.get_power)
|
||||
return msg.PowerState(node=self.node,
|
||||
@ -266,7 +266,7 @@ class IpmiHandler(object):
|
||||
|
||||
|
||||
def create(nodes, element, configmanager, inputdata):
|
||||
if element == '_console/session':
|
||||
if element == [ '_console', 'session' ]:
|
||||
if len(nodes) > 1:
|
||||
raise Exception("_console/session does not support multiple nodes")
|
||||
return IpmiConsole(nodes[0], configmanager)
|
||||
|
Loading…
Reference in New Issue
Block a user