From 8316fa66e8a16fb15e16d18fdff001f6617d9ef4 Mon Sep 17 00:00:00 2001 From: panyy3 Date: Thu, 31 Oct 2019 15:57:20 +0800 Subject: [PATCH] add GetManagerServices and SetManagerServices (#62815) * add GetManagerServices in redfish_info module, and add SetManagerServices in redfish_config module * fix incorrect-version-added, fix incorrect Comparison to None, fix continuation line under-indented for visual indent, fix line too long, fix blank line at end of file * update parameter format to allow multi-services update and additional parameter update * fix bad-whitespace and trailing-whitespace detected by ansible-test * change command name from GetManagerServices/SetManagerServices to GetNetworkProtocols/SetNetworkProtocols, and update parameter name to network_protocols with dict type, and enhance set_network_protocols() to follow suggestions * donot need to import ast any more * fix problems caused by code merge --- lib/ansible/module_utils/redfish_utils.py | 96 +++++++++++++++++++ .../redfish/redfish_config.py | 40 +++++++- .../remote_management/redfish/redfish_info.py | 12 ++- 3 files changed, 145 insertions(+), 3 deletions(-) diff --git a/lib/ansible/module_utils/redfish_utils.py b/lib/ansible/module_utils/redfish_utils.py index 0df6be9f922..7d4acf0925a 100644 --- a/lib/ansible/module_utils/redfish_utils.py +++ b/lib/ansible/module_utils/redfish_utils.py @@ -1979,3 +1979,99 @@ class RedfishUtils(object): def get_multi_system_inventory(self): return self.aggregate(self.get_system_inventory) + + def get_network_protocols(self): + result = {} + service_result = {} + # Find NetworkProtocol + response = self.get_request(self.root_uri + self.manager_uri) + if response['ret'] is False: + return response + data = response['data'] + if 'NetworkProtocol' not in data: + return {'ret': False, 'msg': "NetworkProtocol resource not found"} + networkprotocol_uri = data["NetworkProtocol"]["@odata.id"] + + response = self.get_request(self.root_uri + networkprotocol_uri) + if response['ret'] is False: + return response + data = response['data'] + protocol_services = ['SNMP', 'VirtualMedia', 'Telnet', 'SSDP', 'IPMI', 'SSH', + 'KVMIP', 'NTP', 'HTTP', 'HTTPS', 'DHCP', 'DHCPv6', 'RDP', + 'RFB'] + for protocol_service in protocol_services: + if protocol_service in data.keys(): + service_result[protocol_service] = data[protocol_service] + + result['ret'] = True + result["entries"] = service_result + return result + + def set_network_protocols(self, manager_services): + # Check input data validity + protocol_services = ['SNMP', 'VirtualMedia', 'Telnet', 'SSDP', 'IPMI', 'SSH', + 'KVMIP', 'NTP', 'HTTP', 'HTTPS', 'DHCP', 'DHCPv6', 'RDP', + 'RFB'] + protocol_state_onlist = ['true', 'True', True, 'on', 1] + protocol_state_offlist = ['false', 'False', False, 'off', 0] + payload = {} + for service_name in manager_services.keys(): + if service_name not in protocol_services: + return {'ret': False, 'msg': "Service name %s is invalid" % service_name} + payload[service_name] = {} + for service_property in manager_services[service_name].keys(): + value = manager_services[service_name][service_property] + if service_property in ['ProtocolEnabled', 'protocolenabled']: + if value in protocol_state_onlist: + payload[service_name]['ProtocolEnabled'] = True + elif value in protocol_state_offlist: + payload[service_name]['ProtocolEnabled'] = False + else: + return {'ret': False, 'msg': "Value of property %s is invalid" % service_property} + elif service_property in ['port', 'Port']: + if isinstance(value, int): + payload[service_name]['Port'] = value + elif isinstance(value, str) and value.isdigit(): + payload[service_name]['Port'] = int(value) + else: + return {'ret': False, 'msg': "Value of property %s is invalid" % service_property} + else: + payload[service_name][service_property] = value + + # Find NetworkProtocol + response = self.get_request(self.root_uri + self.manager_uri) + if response['ret'] is False: + return response + data = response['data'] + if 'NetworkProtocol' not in data: + return {'ret': False, 'msg': "NetworkProtocol resource not found"} + networkprotocol_uri = data["NetworkProtocol"]["@odata.id"] + + # Check service property support or not + response = self.get_request(self.root_uri + networkprotocol_uri) + if response['ret'] is False: + return response + data = response['data'] + for service_name in payload.keys(): + if service_name not in data: + return {'ret': False, 'msg': "%s service not supported" % service_name} + for service_property in payload[service_name].keys(): + if service_property not in data[service_name]: + return {'ret': False, 'msg': "%s property for %s service not supported" % (service_property, service_name)} + + # if the protocol is already set, nothing to do + need_change = False + for service_name in payload.keys(): + for service_property in payload[service_name].keys(): + value = payload[service_name][service_property] + if value != data[service_name][service_property]: + need_change = True + break + + if not need_change: + return {'ret': True, 'changed': False, 'msg': "Manager NetworkProtocol services already set"} + + response = self.patch_request(self.root_uri + networkprotocol_uri, payload) + if response['ret'] is False: + return response + return {'ret': True, 'changed': True, 'msg': "Modified Manager NetworkProtocol services"} diff --git a/lib/ansible/modules/remote_management/redfish/redfish_config.py b/lib/ansible/modules/remote_management/redfish/redfish_config.py index 69c0febd813..688cc2bb4d3 100644 --- a/lib/ansible/modules/remote_management/redfish/redfish_config.py +++ b/lib/ansible/modules/remote_management/redfish/redfish_config.py @@ -75,6 +75,12 @@ options: default: [] type: list version_added: "2.10" + network_protocols: + required: false + description: + - setting dict of manager services to update + type: dict + version_added: "2.10" author: "Jose Delarosa (@jose-delarosa)" ''' @@ -140,6 +146,21 @@ EXAMPLES = ''' baseuri: "{{ baseuri }}" username: "{{ username }}" password: "{{ password }}" + + - name: Set Manager Network Protocols + redfish_config: + category: Manager + command: SetNetworkProtocols + network_protocols: + SNMP: + ProtocolEnabled: True + Port: 161 + HTTP: + ProtocolEnabled: False + Port: 8080 + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" ''' RETURN = ''' @@ -158,7 +179,8 @@ from ansible.module_utils._text import to_native # More will be added as module features are expanded CATEGORY_COMMANDS_ALL = { "Systems": ["SetBiosDefaultSettings", "SetBiosAttributes", "SetBootOrder", - "SetDefaultBootOrder"] + "SetDefaultBootOrder"], + "Manager": ["SetNetworkProtocols"] } @@ -174,7 +196,11 @@ def main(): bios_attribute_name=dict(default='null'), bios_attribute_value=dict(default='null'), timeout=dict(type='int', default=10), - boot_order=dict(type='list', elements='str', default=[]) + boot_order=dict(type='list', elements='str', default=[]), + network_protocols=dict( + type='dict', + default={} + ) ), supports_check_mode=False ) @@ -227,6 +253,16 @@ def main(): elif command == "SetDefaultBootOrder": result = rf_utils.set_default_boot_order() + elif category == "Manager": + # execute only if we find a Manager service resource + result = rf_utils._find_managers_resource() + if result['ret'] is False: + module.fail_json(msg=to_native(result['msg'])) + + for command in command_list: + if command == "SetNetworkProtocols": + result = rf_utils.set_network_protocols(module.params['network_protocols']) + # Return data back or fail with proper message if result['ret'] is True: module.exit_json(changed=result['changed'], msg=to_native(result['msg'])) diff --git a/lib/ansible/modules/remote_management/redfish/redfish_info.py b/lib/ansible/modules/remote_management/redfish/redfish_info.py index 7395957cac4..1abf5141719 100644 --- a/lib/ansible/modules/remote_management/redfish/redfish_info.py +++ b/lib/ansible/modules/remote_management/redfish/redfish_info.py @@ -222,6 +222,14 @@ EXAMPLES = ''' username: "{{ username }}" password: "{{ password }}" + - name: Get Manager Services + redfish_info: + category: Manager + command: GetNetworkProtocols + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" + - name: Get all information available in all categories redfish_info: category: all @@ -251,7 +259,7 @@ CATEGORY_COMMANDS_ALL = { "Accounts": ["ListUsers"], "Sessions": ["GetSessions"], "Update": ["GetFirmwareInventory", "GetFirmwareUpdateCapabilities", "GetSoftwareInventory"], - "Manager": ["GetManagerNicInventory", "GetVirtualMedia", "GetLogs"], + "Manager": ["GetManagerNicInventory", "GetVirtualMedia", "GetLogs", "GetNetworkProtocols"], } CATEGORY_COMMANDS_DEFAULT = { @@ -418,6 +426,8 @@ def main(): result["virtual_media"] = rf_utils.get_multi_virtualmedia() elif command == "GetLogs": result["log"] = rf_utils.get_logs() + elif command == "GetNetworkProtocols": + result["network_protocols"] = rf_utils.get_network_protocols() # Return data back if is_old_facts: