2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-11-26 11:30:23 +00:00

Add event log to interface

Add a draft event log interface along with an ipmi implementation.
This requires current git master of pyghmi.  Release of pyghmi will
be done before this commit lands in a confluent release.
This commit is contained in:
Jarrod Johnson 2015-05-15 16:49:52 -04:00
parent 7baec5a69f
commit c6d0d87ca9
4 changed files with 75 additions and 12 deletions

View File

@ -1 +1 @@
1.1
1.1.post1

View File

@ -117,6 +117,14 @@ noderesources = {
# this is a dummy value, http or socket must handle special
'session': PluginRoute({}),
},
'events': {
'hardware': {
'log': PluginRoute({
'pluginattrs': ['hardwaremanagement.method'],
'default': 'ipmi',
})
}
},
'power': {
'state': PluginRoute({
'pluginattrs': ['hardwaremanagement.method'],

View File

@ -21,6 +21,13 @@
import confluent.exceptions as exc
import json
valid_health_values = set([
'ok',
'warning',
'critical',
'failed',
'unknown',
])
def _htmlify_structure(indict):
ret = "<ul>"
@ -527,6 +534,44 @@ class PowerState(ConfluentChoiceMessage):
keyname = 'state'
class EventCollection(ConfluentMessage):
"""A collection of events
This conveys a representation of an iterable of events. The following
fields are supported:
id (some data giving the class of event without the specific data of the
event. For example, 'overtemp (1000 degrees celsius)' would have
the same 'id' as 'overtemp (200 degrees celsius)
component (specific name of the component this event references if any)
component_type (A description of the sort of device component is)
event (A text description of the event that occurred)
severity (The text 'ok', 'warning', 'critical', 'failed', or 'unknown')
timestamp (ISO 8601 compliant timestamp if available)
"""
readonly = True
def __init__(self, events=(), name=None):
eventdata = []
self.notnode = name is None
for event in events:
entry = {
'id': event.get('id', None),
'component': event.get('component', None),
'component_type': event.get('component_type', None),
'event': event.get('event', None),
'severity': event['severity'],
'timestamp': event.get('timestamp', None),
}
if event['severity'] not in valid_health_values:
raise exc.NotImplementedException(
'Invalid severity - ' + repr(event['severity']))
eventdata.append(entry)
if self.notnode:
self.kvpairs = {'events': eventdata}
else:
self.kvpairs = {name: {'events': eventdata}}
class SensorReadings(ConfluentMessage):
readonly = True
@ -562,12 +607,7 @@ class KeyValueData(ConfluentMessage):
class HealthSummary(ConfluentMessage):
readonly = True
valid_values = set([
'ok',
'warning',
'critical',
'failed',
])
valid_values = valid_health_values
def __init__(self, health, name=None):
self.stripped = False

View File

@ -79,8 +79,6 @@ def sanitize_invdata(indata):
format(x, '02x') for x in indata[k][idx])
class IpmiCommandWrapper(ipmicommand.Command):
def __init__(self, node, cfm, **kwargs):
self._attribwatcher = cfm.watch_attributes(
@ -262,7 +260,8 @@ def perform_request(operator, node, element,
results.put(msg.ConfluentTargetTimeout(node, str(tu)))
except Exception as e:
results.put(msg.ConfluentNodeError(
node, 'IPMI PluginException: ' + str(e)))
node, 'IPMI PluginException (see stderr log): ' + str(e)))
raise
finally:
results.put('Done')
@ -327,8 +326,8 @@ class IpmiHandler(object):
self._logevt = None
if self.broken:
if (self.error == 'timeout' or
'Insufficient resources' in self.error):
self.error = self.error.replace(' reported in RAKP4','')
'Insufficient resources' in self.error):
self.error = self.error.replace(' reported in RAKP4', '')
self.output.put(msg.ConfluentTargetTimeout(
self.node, self.error))
return
@ -351,6 +350,22 @@ class IpmiHandler(object):
self.handle_sensors()
elif self.element[0] == 'inventory':
self.handle_inventory()
elif self.element == ['events', 'hardware', 'log']:
self.do_eventlog()
else:
raise Exception('Not Implemented')
def do_eventlog(self):
eventout = []
for event in self.ipmicmd.get_event_log():
event['severity'] = _str_health(event['severity'])
if 'event_data' in event:
event['event'] = '{0} - {1}'.format(
event['event'], event['event_data'])
event['id'] = '{0}.{1}'.format(event['event_id'],
event['component_type_id'])
eventout.append(event)
self.output.put(msg.EventCollection(eventout, name=self.node))
def make_inventory_map(self):
invnames = self.ipmicmd.get_inventory_descriptions()