From 407d776610d4de9f2d89500cd104396d26c27872 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 23 Sep 2020 09:04:51 +0200 Subject: [PATCH] Support same reset actions on Managers as on Systems (#903) (#947) * bring Manager power cmds to parity with System power commands * add changelog fragment * Update changelogs/fragments/903-enhance-redfish-manager-reset-actions.yml Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit e382044e42b9967c460f408fd364325fe393a573) Co-authored-by: Bill Dodd --- ...-enhance-redfish-manager-reset-actions.yml | 2 + plugins/module_utils/redfish_utils.py | 40 ++++----- .../redfish/redfish_command.py | 87 ++++++++++++++++++- 3 files changed, 101 insertions(+), 28 deletions(-) create mode 100644 changelogs/fragments/903-enhance-redfish-manager-reset-actions.yml diff --git a/changelogs/fragments/903-enhance-redfish-manager-reset-actions.yml b/changelogs/fragments/903-enhance-redfish-manager-reset-actions.yml new file mode 100644 index 0000000000..14109dbe8f --- /dev/null +++ b/changelogs/fragments/903-enhance-redfish-manager-reset-actions.yml @@ -0,0 +1,2 @@ +minor_changes: + - redfish_command - support same reset actions on Managers as on Systems (https://github.com/ansible-collections/community.general/issues/901). diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index e7b3bb1036..4c648de39f 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -710,24 +710,6 @@ class RedfishUtils(object): def get_multi_volume_inventory(self): return self.aggregate_systems(self.get_volume_inventory) - def restart_manager_gracefully(self): - result = {} - key = "Actions" - - # Search for 'key' entry and extract URI from it - response = self.get_request(self.root_uri + self.manager_uri) - if response['ret'] is False: - return response - result['ret'] = True - data = response['data'] - action_uri = data[key]["#Manager.Reset"]["target"] - - payload = {'ResetType': 'GracefulRestart'} - response = self.post_request(self.root_uri + action_uri, payload) - if response['ret'] is False: - return response - return {'ret': True} - def manage_indicator_led(self, command): result = {} key = 'IndicatorLED' @@ -773,6 +755,14 @@ class RedfishUtils(object): return reset_type def manage_system_power(self, command): + return self.manage_power(command, self.systems_uri, + '#ComputerSystem.Reset') + + def manage_manager_power(self, command): + return self.manage_power(command, self.manager_uri, + '#Manager.Reset') + + def manage_power(self, command, resource_uri, action_name): key = "Actions" reset_type_values = ['On', 'ForceOff', 'GracefulShutdown', 'GracefulRestart', 'ForceRestart', 'Nmi', @@ -790,8 +780,8 @@ class RedfishUtils(object): if reset_type not in reset_type_values: return {'ret': False, 'msg': 'Invalid Command (%s)' % command} - # read the system resource and get the current power state - response = self.get_request(self.root_uri + self.systems_uri) + # read the resource and get the current power state + response = self.get_request(self.root_uri + resource_uri) if response['ret'] is False: return response data = response['data'] @@ -803,13 +793,13 @@ class RedfishUtils(object): if power_state == "Off" and reset_type in ['GracefulShutdown', 'ForceOff']: return {'ret': True, 'changed': False} - # get the #ComputerSystem.Reset Action and target URI - if key not in data or '#ComputerSystem.Reset' not in data[key]: - return {'ret': False, 'msg': 'Action #ComputerSystem.Reset not found'} - reset_action = data[key]['#ComputerSystem.Reset'] + # get the reset Action and target URI + if key not in data or action_name not in data[key]: + return {'ret': False, 'msg': 'Action %s not found' % action_name} + reset_action = data[key][action_name] if 'target' not in reset_action: return {'ret': False, - 'msg': 'target URI missing from Action #ComputerSystem.Reset'} + 'msg': 'target URI missing from Action %s' % action_name} action_uri = reset_action['target'] # get AllowableValues diff --git a/plugins/modules/remote_management/redfish/redfish_command.py b/plugins/modules/remote_management/redfish/redfish_command.py index 3e3a61041c..9646f9a3b7 100644 --- a/plugins/modules/remote_management/redfish/redfish_command.py +++ b/plugins/modules/remote_management/redfish/redfish_command.py @@ -206,6 +206,36 @@ EXAMPLES = ''' username: "{{ username }}" password: "{{ password }}" + - name: Turn system power off + community.general.redfish_command: + category: Systems + command: PowerForceOff + resource_id: 437XR1138R2 + + - name: Restart system power forcefully + community.general.redfish_command: + category: Systems + command: PowerForceRestart + resource_id: 437XR1138R2 + + - name: Shutdown system power gracefully + community.general.redfish_command: + category: Systems + command: PowerGracefulShutdown + resource_id: 437XR1138R2 + + - name: Turn system power on + community.general.redfish_command: + category: Systems + command: PowerOn + resource_id: 437XR1138R2 + + - name: Reboot system power + community.general.redfish_command: + category: Systems + command: PowerReboot + resource_id: 437XR1138R2 + - name: Set one-time boot device to {{ bootdevice }} community.general.redfish_command: category: Systems @@ -439,6 +469,51 @@ EXAMPLES = ''' virtual_media: image_url: 'http://example.com/images/SomeLinux-current.iso' resource_id: BMC + + - name: Restart manager power gracefully + community.general.redfish_command: + category: Manager + command: GracefulRestart + resource_id: BMC + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" + + - name: Restart manager power gracefully + community.general.redfish_command: + category: Manager + command: PowerGracefulRestart + resource_id: BMC + + - name: Turn manager power off + community.general.redfish_command: + category: Manager + command: PowerForceOff + resource_id: BMC + + - name: Restart manager power forcefully + community.general.redfish_command: + category: Manager + command: PowerForceRestart + resource_id: BMC + + - name: Shutdown manager power gracefully + community.general.redfish_command: + category: Manager + command: PowerGracefulShutdown + resource_id: BMC + + - name: Turn manager power on + community.general.redfish_command: + category: Manager + command: PowerOn + resource_id: BMC + + - name: Reboot manager power + community.general.redfish_command: + category: Manager + command: PowerReboot + resource_id: BMC ''' RETURN = ''' @@ -464,7 +539,8 @@ CATEGORY_COMMANDS_ALL = { "UpdateAccountServiceProperties"], "Sessions": ["ClearSessions"], "Manager": ["GracefulRestart", "ClearLogs", "VirtualMediaInsert", - "VirtualMediaEject"], + "VirtualMediaEject", "PowerOn", "PowerForceOff", "PowerForceRestart", + "PowerGracefulRestart", "PowerGracefulShutdown", "PowerReboot"], "Update": ["SimpleUpdate"] } @@ -598,7 +674,7 @@ def main(): module.fail_json(msg=to_native(result['msg'])) for command in command_list: - if "Power" in command: + if command.startswith('Power'): result = rf_utils.manage_system_power(command) elif command == "SetOneTimeBoot": boot_opts['override_enabled'] = 'Once' @@ -643,8 +719,13 @@ def main(): module.fail_json(msg=to_native(result['msg'])) for command in command_list: + # standardize on the Power* commands, but allow the the legacy + # GracefulRestart command if command == 'GracefulRestart': - result = rf_utils.restart_manager_gracefully() + command = 'PowerGracefulRestart' + + if command.startswith('Power'): + result = rf_utils.manage_manager_power(command) elif command == 'ClearLogs': result = rf_utils.clear_logs() elif command == 'VirtualMediaInsert':