2
0
mirror of https://github.com/xcat2/confluent.git synced 2025-08-23 19:50:23 +00:00

Implement plugin curated collections

A plugin is now allowed to define a collection.  The sensors
hierarchy is added as the first path to allow plugin curated
collections.  ipmi plugin updated to list items in those
collections
This commit is contained in:
Jarrod Johnon
2015-01-15 11:28:22 -05:00
parent c86e1af750
commit 8bc6477700
3 changed files with 81 additions and 3 deletions

View File

@@ -42,11 +42,20 @@ import sys
pluginmap = {}
def seek_element(currplace, currkey):
try:
return currplace[currkey]
except TypeError:
if isinstance(currplace, PluginCollection):
# we hit a plugin curated collection, all children
# are up to the plugin to comprehend
return currplace
raise
def nested_lookup(nestdict, key):
try:
return reduce(dict.__getitem__, key, nestdict)
except TypeError:
return reduce(seek_element, key, nestdict)
except TypeError as e:
raise exc.NotFoundException("Invalid element requested")
@@ -86,6 +95,10 @@ class PluginRoute(object):
def __init__(self, routedict):
self.routeinfo = routedict
class PluginCollection(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 = {
@@ -124,6 +137,26 @@ noderesources = {
'all': PluginRoute({'handler': 'attributes'}),
'current': PluginRoute({'handler': 'attributes'}),
},
'sensors': {
'hardware': {
'all': PluginCollection({
'pluginattrs': ['hardwaremanagement.method'],
'default': 'ipmi',
}),
'temperature': PluginCollection({
'pluginattrs': ['hardwaremanagement.method'],
'default': 'ipmi',
}),
'power': PluginCollection({
'pluginattrs': ['hardwaremanagement.method'],
'default': 'ipmi',
}),
'fans': PluginCollection({
'pluginattrs': ['hardwaremanagement.method'],
'default': 'ipmi',
}),
},
},
}
nodegroupresources = {
@@ -336,6 +369,8 @@ def handle_path(path, operation, configmanager, inputdata=None):
raise exc.NotFoundException("Invalid element requested")
if isinstance(routespec, dict):
iscollection = True
elif isinstance(routespec, PluginCollection):
iscollection = False # it is a collection, but plugin defined
if iscollection:
if operation == "delete":
return delete_node_collection(pathcomponents, configmanager)

View File

@@ -61,7 +61,8 @@ class ConfluentMessage(object):
return self.kvpairs
def strip_node(self, node):
self.kvpairs = self.kvpairs[node]
if self.kvpairs is not None:
self.kvpairs = self.kvpairs[node]
def html(self, extension=''):
#this is used to facilitate the api explorer feature
@@ -199,10 +200,13 @@ class ConfluentChoiceMessage(ConfluentMessage):
class LinkRelation(ConfluentMessage):
kvpairs = None
def __init__(self):
self.href = ''
self.rel = ''
def json(self):
"""Provide json_hal style representation of the relation.

View File

@@ -32,6 +32,15 @@ console.session.threading = eventlet.green.threading
_ipmithread = None
_ipmiwaiters = []
sensor_categories = {
'temperature': frozenset(['Temperature']),
'power': frozenset(['Current', 'Battery']),
'fans': frozenset(['Fan', 'Cooling Device']),
}
def simplify_name(name):
return name.lower().replace(' ', '_')
class IpmiCommandWrapper(ipmicommand.Command):
def __init__(self, node, cfm, **kwargs):
@@ -222,6 +231,7 @@ persistent_ipmicmds = {}
class IpmiHandler(object):
def __init__(self, operation, node, element, cfd, inputdata, cfg):
self.sensormap = {}
self.broken = False
self.error = None
eventlet.sleep(0)
@@ -279,6 +289,35 @@ class IpmiHandler(object):
return self.health()
elif self.element == ['identify']:
return self.identify()
elif self.element[0] == 'sensors':
return self.handle_sensors()
def make_sensor_map(self, sensors=None):
if sensors is None:
sensors = self.ipmicmd.get_sensor_descriptions()
for sensor in sensors:
resourcename = sensor['name']
self.sensormap[simplify_name(resourcename)] = resourcename
def handle_sensors(self):
if self.element[-1] == '':
self.element = self.element[:-1]
if len(self.element) == 3: # list sensors per category
category = self.element[2]
return self.list_sensors(category)
def list_sensors(self, category):
sensors = self.ipmicmd.get_sensor_descriptions()
yield msg.ChildCollection('all')
if category == 'all':
for sensor in sensors:
yield msg.ChildCollection(simplify_name(sensor['name']))
else:
for sensor in sensors:
if sensor['type'] in sensor_categories[category]:
yield msg.ChildCollection(simplify_name(sensor['name']))
@staticmethod
def _str_health(health):