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:
@@ -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)
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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):
|
||||
|
Reference in New Issue
Block a user