From 5f52ee9578bf674710a45ab375771d261f4b4093 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 14 Jan 2019 15:41:17 -0500 Subject: [PATCH] Support unique filenames through attribute expansion Particularly in trying to support license keys, serial number handling is at least required. Easiest and most powerful and most consistent path is to use the same attribute expansion as everywhere else. --- confluent_server/confluent/messages.py | 31 +++++++++++++++---- .../plugins/hardwaremanagement/ipmi.py | 11 ++++--- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/confluent_server/confluent/messages.py b/confluent_server/confluent/messages.py index c5469759..9d146e88 100644 --- a/confluent_server/confluent/messages.py +++ b/confluent_server/confluent/messages.py @@ -431,26 +431,45 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False, operation in ('update', 'create')): return InputVolumes(path, nodes, inputdata) elif 'inventory/firmware/updates/active' in '/'.join(path) and inputdata: - return InputFirmwareUpdate(path, nodes, inputdata) + return InputFirmwareUpdate(path, nodes, inputdata, configmanager) elif '/'.join(path).startswith('media/detach'): return DetachMedia(path, nodes, inputdata) elif '/'.join(path).startswith('media/') and inputdata: - return InputMedia(path, nodes, inputdata) + return InputMedia(path, nodes, inputdata, configmanager) elif '/'.join(path).startswith('support/servicedata') and inputdata: - return InputMedia(path, nodes, inputdata) + return InputMedia(path, nodes, inputdata, configmanager) elif '/'.join(path).startswith( 'configuration/management_controller/licenses') and inputdata: - return InputLicense(path, nodes, inputdata) + return InputLicense(path, nodes, inputdata, configmanager) elif inputdata: raise exc.InvalidArgumentException( 'No known input handler for request') class InputFirmwareUpdate(ConfluentMessage): - def __init__(self, path, nodes, inputdata): - self.filename = inputdata.get('filename', inputdata.get('url', None)) + def __init__(self, path, nodes, inputdata, configmanager): + self._filename = inputdata.get('filename', inputdata.get('url', None)) self.bank = inputdata.get('bank', None) self.nodes = nodes + self.filebynode = {} + self._complexname = False + for expanded in configmanager.expand_attrib_expression( + nodes, self._filename): + node, value = expanded + if value != self._filename: + self._complexname = True + self.filebynode[node] = value + + @property + def filename(self): + if self._complexname: + raise Exception('User requested substitutions, but code is ' + 'written against old api, code must be fixed or ' + 'skip {} expansion') + return self._filename + + def nodefile(self, node): + return self.filebynode[node] class InputMedia(InputFirmwareUpdate): # Use InputFirmwareUpdate diff --git a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py index 70ec4eb5..19506ee5 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py @@ -560,7 +560,7 @@ class IpmiHandler(object): def handle_update(self): u = firmwaremanager.Updater(self.node, self.ipmicmd.update_firmware, - self.inputdata.filename, self.tenant, + self.inputdata.nodefile(self.node), self.tenant, bank=self.inputdata.bank) self.output.put( msg.CreatedResource( @@ -569,7 +569,7 @@ class IpmiHandler(object): def handle_media_upload(self): u = firmwaremanager.Updater(self.node, self.ipmicmd.upload_media, - self.inputdata.filename, self.tenant, + self.inputdata.nodefile(self.node), self.tenant, type='mediaupload') self.output.put(msg.CreatedResource( 'nodes/{0}/media/uploads/{1}'.format(self.node, u.name))) @@ -577,14 +577,15 @@ class IpmiHandler(object): def handle_servicedata_fetch(self): u = firmwaremanager.Updater( self.node, self.ipmicmd.get_diagnostic_data, - self.inputdata.filename, self.tenant, type='ffdc', + self.inputdata.nodefile(self.node), self.tenant, type='ffdc', owner=self.current_user) self.output.put(msg.CreatedResource( 'nodes/{0}/support/servicedata/{1}'.format(self.node, u.name))) def handle_attach_media(self): try: - self.ipmicmd.attach_remote_media(self.inputdata.filename) + self.ipmicmd.attach_remote_media(self.inputdata.nodefile( + self.node)) except pygexc.UnsupportedFunctionality as uf: self.output.put(msg.ConfluentNodeError(self.node, str(uf))) @@ -1403,7 +1404,7 @@ class IpmiHandler(object): if self.element[-1] == '': self.element = self.element[:-1] if self.op in ('create', 'update'): - self.ipmicmd.apply_license(self.inputdata.filename) + self.ipmicmd.apply_license(self.inputdata.nodefile(self.node)) if len(self.element) == 3: self.output.put(msg.ChildCollection('all')) i = 1