diff --git a/confluent_client/bin/nodelicense b/confluent_client/bin/nodelicense index 173e8149..e4137e01 100755 --- a/confluent_client/bin/nodelicense +++ b/confluent_client/bin/nodelicense @@ -36,14 +36,17 @@ exitcode = 0 argparser = optparse.OptionParser( usage="Usage: " - "%prog [list][install ]") + "%prog [list][install |save ]") (options, args) = argparser.parse_args() upfile = None +downdir = None try: noderange = args[0] if len(args) > 1: if args[1] == 'install': upfile = args[2] + elif args[1] == 'save': + downdir = args[2] else: components = ['all'] except IndexError: @@ -51,6 +54,7 @@ except IndexError: sys.exit(1) client.check_globbing(noderange) + def install_license(session, filename): global exitcode resource = '/noderange/{0}/configuration/' \ @@ -61,6 +65,22 @@ def install_license(session, filename): pass # print(repr(res)) show_licenses(session) + +def save_licenses(session, dirname): + global exitcode + resource = '/noderange/{0}/configuration/' \ + 'management_controller/save_licenses'.format(noderange) + filename = os.path.abspath(dirname) + instargs = {'dirname': filename} + for res in session.create(resource, instargs): + for node in res.get('databynode', {}): + fname = res['databynode'][node].get('filename', None) + if fname: + print('{0}: Saved license to {1}'.format(node, fname)) + else: + sys.stderr.write('{0}: {1}', node, repr(res['databynode'][node])) + + def show_licenses(session): global exitcode firmware_shown = False @@ -75,10 +95,12 @@ def show_licenses(session): try: session = client.Command() - if upfile is None: - show_licenses(session) - else: + if upfile: install_license(session, upfile) + elif downdir: + save_licenses(session, downdir) + else: + show_licenses(session) except KeyboardInterrupt: print('') sys.exit(exitcode) \ No newline at end of file diff --git a/confluent_client/confluent_env.sh b/confluent_client/confluent_env.sh index 00955c85..b6081a62 100644 --- a/confluent_client/confluent_env.sh +++ b/confluent_client/confluent_env.sh @@ -160,7 +160,7 @@ _confluent_nodelicense_completion() { _confluent_get_args if [ $NUMARGS == 3 ]; then - COMPREPLY=($(compgen -W "install list" -- ${COMP_WORDS[-1]})) + COMPREPLY=($(compgen -W "install list save" -- ${COMP_WORDS[-1]})) return; fi if [ $NUMARGS == 4 ] && [ ${CMPARGS[2]} == 'install' ]; then @@ -168,6 +168,11 @@ _confluent_nodelicense_completion() COMPREPLY=() return fi + if [ $NUMARGS == 4 ] && [ ${CMPARGS[2]} == 'save' ]; then + compopt -o dirnames + COMPREPLY=() + return + fi if [ $NUMARGS -lt 3 ]; then _confluent_nr_completion return diff --git a/confluent_server/confluent/core.py b/confluent_server/confluent/core.py index 96f92941..c1942ec5 100644 --- a/confluent_server/confluent/core.py +++ b/confluent_server/confluent/core.py @@ -171,6 +171,10 @@ def _init_core(): 'pluginattrs': ['hardwaremanagement.method'], 'default': 'ipmi', }), + 'save_licenses': PluginRoute({ + 'pluginattrs': ['hardwaremanagement.method'], + 'default': 'ipmi', + }), 'net_interfaces': PluginCollection({ 'pluginattrs': ['hardwaremanagement.method'], 'default': 'ipmi', diff --git a/confluent_server/confluent/messages.py b/confluent_server/confluent/messages.py index 2b6211eb..23a95625 100644 --- a/confluent_server/confluent/messages.py +++ b/confluent_server/confluent/messages.py @@ -458,6 +458,8 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False, return InputMedia(path, nodes, inputdata, configmanager) elif '/'.join(path).startswith('support/servicedata') and inputdata: return InputMedia(path, nodes, inputdata, configmanager) + elif '/'.join(path).startswith('configuration/management_controller/save_licenses') and inputdata: + return InputMedia(path, nodes, inputdata, configmanager) elif '/'.join(path).startswith( 'configuration/management_controller/licenses') and inputdata: return InputLicense(path, nodes, inputdata, configmanager) @@ -468,7 +470,7 @@ def get_input_message(path, operation, inputdata, nodes=None, multinode=False, class InputFirmwareUpdate(ConfluentMessage): def __init__(self, path, nodes, inputdata, configmanager): - self._filename = inputdata.get('filename', inputdata.get('url', None)) + self._filename = inputdata.get('filename', inputdata.get('url', inputdata.get('dirname', None))) self.bank = inputdata.get('bank', None) self.nodes = nodes self.filebynode = {} @@ -510,6 +512,10 @@ class Media(ConfluentMessage): def __init__(self, node, media): self.kvpairs = {node: {'name': media.name, 'url': media.url}} +class SavedFile(ConfluentMessage): + def __init__(self, node, file): + self.kvpairs = {node: {'filename': file}} + class InputAlertData(ConfluentMessage): def __init__(self, path, inputdata, nodes=None): diff --git a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py index cc42590f..563f6236 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/ipmi.py @@ -626,6 +626,8 @@ class IpmiHandler(object): return self.handle_sysconfigclear() elif self.element[1:3] == ['management_controller', 'licenses']: return self.handle_licenses() + elif self.element[1:3] == ['management_controller', 'save_licenses']: + return self.save_licenses() raise Exception('Not implemented') def decode_alert(self): @@ -1431,6 +1433,11 @@ class IpmiHandler(object): self.output.put(msg.License(self.node, available)) return + def save_licenses(self): + directory = self.inputdata.nodefile(self.node) + for saved in self.ipmicmd.save_licenses(directory): + self.output.put(msg.SavedFile(self.node, saved)) + def handle_licenses(self): if self.element[-1] == '': self.element = self.element[:-1] diff --git a/confluent_server/confluent/plugins/hardwaremanagement/redfish.py b/confluent_server/confluent/plugins/hardwaremanagement/redfish.py index 552e2fb4..e99c79ed 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/redfish.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/redfish.py @@ -496,6 +496,8 @@ class IpmiHandler(object): return self.handle_sysconfigclear() elif self.element[1:3] == ['management_controller', 'licenses']: return self.handle_licenses() + elif self.element[1:3] == ['management_controller', 'save_licenses']: + return self.save_licenses() raise Exception('Not implemented') def decode_alert(self): @@ -1297,6 +1299,11 @@ class IpmiHandler(object): self.output.put(msg.License(self.node, available)) return + def save_licenses(self): + directory = self.inputdata.nodefile(self.node) + for saved in self.ipmicmd.save_licenses(directory): + self.output.put(msg.SavedFile(self.node, saved)) + def handle_licenses(self): if self.element[-1] == '': self.element = self.element[:-1]