diff --git a/confluent_server/confluent/core.py b/confluent_server/confluent/core.py index 9a43d16d..b403b68a 100644 --- a/confluent_server/confluent/core.py +++ b/confluent_server/confluent/core.py @@ -175,6 +175,12 @@ noderesources = { 'default': 'ipmi', }), }, + 'firmware': { + 'all': PluginCollection({ + 'pluginattrs': ['hardwaremanagement.method'], + 'default': 'ipmi', + }), + }, }, 'power': { 'state': PluginRoute({ @@ -201,6 +207,12 @@ noderesources = { 'default': 'ipmi', }), }, + 'led': { + 'all': PluginRoute({ + 'pluginattrs': ['hardwaremanagement.method'], + 'default': 'ipmi', + }) + } }, } diff --git a/confluent_server/confluent/messages.py b/confluent_server/confluent/messages.py index c5441efa..bd65be7e 100644 --- a/confluent_server/confluent/messages.py +++ b/confluent_server/confluent/messages.py @@ -799,6 +799,18 @@ class SensorReadings(ConfluentMessage): self.kvpairs = {name: {'sensors': readings}} +class Firmware(ConfluentMessage): + readonly = True + + def __init__(self, data, name): + self.notnode = name is None + self.desc = 'Firmware information' + if self.notnode: + self.kvpairs = {'firmware': data} + else: + self.kvpairs = {name: {'firmware': data}} + + class KeyValueData(ConfluentMessage): readonly = True @@ -810,6 +822,21 @@ class KeyValueData(ConfluentMessage): self.kvpairs = {name: kvdata} +class LEDStatus(ConfluentMessage): + readonly = True + + def __init__(self, data, name): + self.notnode = name is None + self.desc = 'led status' + + self.kvpairs = {} + for led_category in data: + self.kvpairs[led_category] = [data[led_category]] + + if not self.notnode: + self.kvpairs = {name: self.kvpairs} + + class NetworkConfiguration(ConfluentMessage): desc = 'Network configuration' diff --git a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py index 75c2393b..1c5ef0ee 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py @@ -569,13 +569,37 @@ class IpmiHandler(object): for component in components: self.output.put(msg.ChildCollection(simplify_name(component))) + def list_firmware(self): + self.output.put(msg.ChildCollection('all')) + for id, data in self.ipmicmd.get_firmware(): + self.output.put(msg.ChildCollection(simplify_name(id))) + + def read_firmware(self, component): + items = [] + for id, data in self.ipmicmd.get_firmware(): + if component == 'all' or component == simplify_name(id): + items.append({id: data}) + self.output.put(msg.Firmware(items, self.node)) + def handle_inventory(self): - if len(self.element) == 3: # list things in inventory - return self.list_inventory() - elif len(self.element) == 4: # actually read inventory data - return self.read_inventory(self.element[-1]) + if self.element[1] == 'firmware': + if len(self.element) == 3: + return self.list_firmware() + elif len(self.element) == 4: + return self.read_firmware(self.element[-1]) + elif self.element[1] == 'hardware': + if len(self.element) == 3: # list things in inventory + return self.list_inventory() + elif len(self.element) == 4: # actually read inventory data + return self.read_inventory(self.element[-1]) raise Exception('Unsupported scenario...') + def list_leds(self): + led_categories = {} + for category, leds in self.ipmicmd.get_leds(): + led_categories[category] = leds + self.output.put(msg.LEDStatus(led_categories, self.node)) + def read_inventory(self, component): invitems = [] if component == 'all': @@ -610,8 +634,11 @@ class IpmiHandler(object): if len(self.element) < 3: return self.sensorcategory = self.element[2] - if len(self.element) == 3: # list sensors per category + # list sensors per category + if len(self.element) == 3 and self.element[-2] == 'hardware': return self.list_sensors() + elif len(self.element) == 3 and self.element[-2] == 'led': + return self.list_leds() elif len(self.element) == 4: # resource requested return self.read_sensors(self.element[-1])