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:
parent
7baec5a69f
commit
c6d0d87ca9
@ -1 +1 @@
|
||||
1.1
|
||||
1.1.post1
|
||||
|
@ -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'],
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user