diff --git a/confluent_server/confluent/core.py b/confluent_server/confluent/core.py index e3c80213..1bb86441 100644 --- a/confluent_server/confluent/core.py +++ b/confluent_server/confluent/core.py @@ -139,6 +139,10 @@ noderesources = { 'pluginattrs': ['hardwaremanagement.method'], 'default': 'ipmi', }), + 'identifier': PluginRoute({ + 'pluginattrs': ['hardwaremanagement.method'], + 'default': 'ipmi', + }), } }, '_console': { diff --git a/confluent_server/confluent/messages.py b/confluent_server/confluent/messages.py index 767d9f8b..609a5928 100644 --- a/confluent_server/confluent/messages.py +++ b/confluent_server/confluent/messages.py @@ -331,6 +331,9 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False): elif (path[:3] == ['configuration', 'management_controller', 'reset'] and operation != 'retrieve'): return InputBMCReset(path, nodes, inputdata) + elif (path[:3] == ['configuration', 'management_controller', 'identifier'] + and operation != 'retrieve'): + return InputMCI(path, nodes, inputdata) elif inputdata: raise exc.InvalidArgumentException() @@ -555,6 +558,23 @@ class InputBMCReset(ConfluentInputMessage): return self.inputbynode[node] +class InputMCI(ConfluentInputMessage): + def __init__(self, path, nodes, inputdata): + self.inputbynode = {} + self.stripped = False + if not inputdata or 'identifier' not in inputdata: + raise exc.InvalidArgumentException('missing input data') + if len(inputdata['identifier']) > 64: + raise exc.InvalidArgumentException( + 'identifier must be less than or = 64 chars') + + if nodes is None: + raise exc.InvalidArgumentException( + 'This only supports per-node input') + for node in nodes: + self.mci[node] = inputdata + + class BootDevice(ConfluentChoiceMessage): valid_values = set([ 'network', @@ -919,6 +939,18 @@ class ListAttributes(ConfluentMessage): self.kvpairs = {name: kv} +class MCI(ConfluentMessage): + def __init__(self, name=None, mci=None): + self.notnode = name is None + self.desc = 'BMC identifier' + + kv = {'identifier': {'value': mci}} + if self.notnode: + self.kvpairs = kv + else: + self.kvpairs = {name: kv} + + class CryptedAttributes(Attributes): defaulttype = 'password' diff --git a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py index 3258f71b..cd739759 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py @@ -369,6 +369,8 @@ class IpmiHandler(object): return self.handle_nets() elif self.element[1:3] == ['management_controller', 'reset']: return self.handle_reset() + elif self.element[1:3] == ['management_controller', 'identifier']: + return self.handle_identifier() raise Exception('Not implemented') def decode_alert(self): @@ -750,6 +752,15 @@ class IpmiHandler(object): self.ipmicmd.reset_bmc() return + def handle_identifier(self): + if 'read' == self.op: + mci = self.ipmicmd.get_mci() + self.output.put(msg.MCI(self.node, mci)) + return + elif 'update' == self.op: + mci = self.inputdata.mci(self.node) + self.ipmicmd.set_mci(mci) + return def _str_health(health): if health == 'unknown':