#!/usr/bin/python # -*- coding: utf-8 -*- # # Dell EMC OpenManage Ansible Modules # Version 2.0 # Copyright (C) 2019 Dell Inc. or its subsidiaries. All Rights Reserved. # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # from __future__ import (absolute_import, division, print_function) __metaclass__ = type ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} DOCUMENTATION = r''' --- module: idrac_server_config_profile short_description: Export or Import iDRAC Server Configuration Profile (SCP). description: - Export the Server Configuration Profile (SCP) from the iDRAC or Import from a network share or a local file. options: idrac_ip: description: iDRAC IP Address. type: str required: True idrac_user: description: iDRAC username. type: str required: True idrac_password: description: iDRAC user password. type: str required: True aliases: ['idrac_pwd'] idrac_port: description: iDRAC port. type: int default: 443 command: description: - If C(import), will perform SCP import operations. - If C(export), will perform SCP export operations. choices: ['import', 'export'] default: 'export' job_wait: description: Whether to wait for job completion or not. type: bool required: True share_name: description: CIFS or NFS Network Share or a local path. type: str required: True share_user: description: Network share user in the format 'user@domain' or 'domain\\user' if user is part of a domain else 'user'. This option is mandatory for CIFS Network Share. type: str share_password: description: Network share user password. This option is mandatory for CIFS Network Share. type: str aliases: ['share_pwd'] scp_file: description: Server Configuration Profile file name. This option is mandatory for C(import) command. type: str scp_components: description: - If C(ALL), this module will import all components configurations from SCP file. - If C(IDRAC), this module will import iDRAC configuration from SCP file. - If C(BIOS), this module will import BIOS configuration from SCP file. - If C(NIC), this module will import NIC configuration from SCP file. - If C(RAID), this module will import RAID configuration from SCP file. choices: ['ALL', 'IDRAC', 'BIOS', 'NIC', 'RAID'] default: 'ALL' shutdown_type: description: - This option is applicable for C(import) command. - If C(Graceful), it gracefully shuts down the server. - If C(Forced), it forcefully shuts down the server. - If C(NoReboot), it does not reboot the server. choices: ['Graceful', 'Forced', 'NoReboot'] default: 'Graceful' end_host_power_state: description: - This option is applicable for C(import) command. - If C(On), End host power state is on. - If C(Off), End host power state is off. choices: ['On' ,'Off'] default: 'On' export_format: description: Specify the output file format. This option is applicable for C(export) command. choices: ['JSON', 'XML'] default: 'XML' export_use: description: Specify the type of server configuration profile (SCP) to be exported. This option is applicable for C(export) command. choices: ['Default', 'Clone', 'Replace'] default: 'Default' requirements: - "omsdk" - "python >= 2.7.5" author: "Jagadeesh N V(@jagadeeshnv)" ''' EXAMPLES = r''' --- - name: Import Server Configuration Profile from a network share idrac_server_config_profile: idrac_ip: "192.168.0.1" idrac_user: "user_name" idrac_password: "user_password" command: "import" share_name: "192.168.0.2:/share" share_user: "share_user_name" share_password: "share_user_password" scp_file: "scp_filename.xml" scp_components: "ALL" job_wait: True - name: Import Server Configuration Profile from a local path idrac_server_config_profile: idrac_ip: "192.168.0.1" idrac_user: "user_name" idrac_password: "user_password" command: "import" share_name: "/scp_folder" share_user: "share_user_name" share_password: "share_user_password" scp_file: "scp_filename.xml" scp_components: "ALL" job_wait: True - name: Export Server Configuration Profile to a network share idrac_server_config_profile: idrac_ip: "192.168.0.1" idrac_user: "user_name" idrac_password: "user_password" share_name: "192.168.0.2:/share" share_user: "share_user_name" share_password: "share_user_password" job_wait: False - name: Export Server Configuration Profile to a local path idrac_server_config_profile: idrac_ip: "192.168.0.1" idrac_user: "user_name" idrac_password: "user_password" share_name: "/scp_folder" share_user: "share_user_name" share_password: "share_user_password" job_wait: False ''' RETURN = r''' --- msg: type: str description: Status of the import or export SCP job. returned: always sample: "Successfully imported the Server Configuration Profile" scp_status: type: dict description: SCP operation job and progress details from the iDRAC. returned: success sample: { "Id": "JID_XXXXXXXXX", "JobState": "Completed", "JobType": "ImportConfiguration", "Message": "Successfully imported and applied Server Configuration Profile.", "MessageArgs": [], "MessageId": "XXX123", "Name": "Import Configuration", "PercentComplete": 100, "StartTime": "TIME_NOW", "Status": "Success", "TargetSettingsURI": null, "retval": true } ''' import os from ansible_collections.community.general.plugins.module_utils.remote_management.dellemc.dellemc_idrac import iDRACConnection from ansible.module_utils.basic import AnsibleModule try: from omsdk.sdkfile import file_share_manager from omsdk.sdkcreds import UserCredentials from omdrivers.enums.iDRAC.iDRACEnums import (SCPTargetEnum, EndHostPowerStateEnum, ShutdownTypeEnum, ExportFormatEnum, ExportUseEnum) except ImportError: pass def run_import_server_config_profile(idrac, module): """Import Server Configuration Profile from a network share.""" target = SCPTargetEnum[module.params['scp_components']] job_wait = module.params['job_wait'] end_host_power_state = EndHostPowerStateEnum[module.params['end_host_power_state']] shutdown_type = ShutdownTypeEnum[module.params['shutdown_type']] idrac.use_redfish = True try: myshare = file_share_manager.create_share_obj( share_path="{0}{1}{2}".format(module.params['share_name'], os.sep, module.params['scp_file']), creds=UserCredentials(module.params['share_user'], module.params['share_password']), isFolder=False) import_status = idrac.config_mgr.scp_import(myshare, target=target, shutdown_type=shutdown_type, end_host_power_state=end_host_power_state, job_wait=job_wait) if not import_status or import_status.get('Status') != "Success": module.fail_json(msg='Failed to import scp.', scp_status=import_status) except RuntimeError as e: module.fail_json(msg=str(e)) return import_status def run_export_server_config_profile(idrac, module): """Export Server Configuration Profile to a network share.""" export_format = ExportFormatEnum[module.params['export_format']] scp_file_name_format = "%ip_%Y%m%d_%H%M%S_scp.{0}".format(module.params['export_format'].lower()) target = SCPTargetEnum[module.params['scp_components']] export_use = ExportUseEnum[module.params['export_use']] idrac.use_redfish = True try: myshare = file_share_manager.create_share_obj(share_path=module.params['share_name'], creds=UserCredentials(module.params['share_user'], module.params['share_password']), isFolder=True) scp_file_name = myshare.new_file(scp_file_name_format) export_status = idrac.config_mgr.scp_export(scp_file_name, target=target, export_format=export_format, export_use=export_use, job_wait=module.params['job_wait']) if not export_status or export_status.get('Status') != "Success": module.fail_json(msg='Failed to export scp.', scp_status=export_status) except RuntimeError as e: module.fail_json(msg=str(e)) return export_status def main(): module = AnsibleModule( argument_spec={ "idrac_ip": {"required": True, "type": 'str'}, "idrac_user": {"required": True, "type": 'str'}, "idrac_password": {"required": True, "type": 'str', "aliases": ['idrac_pwd'], "no_log": True}, "idrac_port": {"required": False, "default": 443, "type": 'int'}, "command": {"required": False, "type": 'str', "choices": ['export', 'import'], "default": 'export'}, "job_wait": {"required": True, "type": 'bool'}, "share_name": {"required": True, "type": 'str'}, "share_user": {"required": False, "type": 'str'}, "share_password": {"required": False, "type": 'str', "aliases": ['share_pwd'], "no_log": True}, "scp_components": {"required": False, "choices": ['ALL', 'IDRAC', 'BIOS', 'NIC', 'RAID'], "default": 'ALL'}, "scp_file": {"required": False, "type": 'str'}, "shutdown_type": {"required": False, "choices": ['Graceful', 'Forced', 'NoReboot'], "default": 'Graceful'}, "end_host_power_state": {"required": False, "choices": ['On', 'Off'], "default": 'On'}, "export_format": {"required": False, "type": 'str', "choices": ['JSON', 'XML'], "default": 'XML'}, "export_use": {"required": False, "type": 'str', "choices": ['Default', 'Clone', 'Replace'], "default": 'Default'} }, required_if=[ ["command", "import", ["scp_file"]] ], supports_check_mode=False) try: changed = False with iDRACConnection(module.params) as idrac: command = module.params['command'] if command == 'import': scp_status = run_import_server_config_profile(idrac, module) if "No changes were applied" not in scp_status.get('Message', ""): changed = True else: scp_status = run_export_server_config_profile(idrac, module) module.exit_json(changed=changed, msg="Successfully {0}ed the Server Configuration Profile.".format(command), scp_status=scp_status) except (ImportError, ValueError, RuntimeError) as e: module.fail_json(msg=str(e)) if __name__ == '__main__': main()