def create_profile(module): url = "rest/v1/Oem/eLCM/ProfileManagement/get?PARAM_PATH=Server/{0}".format( module.params['profile']) status, sysdata, msg = irmc_redfish_post(module, url, "") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status == 404: result['msg'] = "Requested profile '{0}' cannot be created.".format( module.params['profile']) module.fail_json(msg=msg, status=status) elif status == 409: result['msg'] = "Requested profile '{0}' already exists.".format( module.params['profile']) result['skipped'] = True module.exit_json(**result) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) if module.params['wait_for_finish'] is True: # check that current session is terminated status, data, msg = waitForSessionToFinish( module, get_irmc_json(sysdata.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status) result['changed'] = True
def set_default_bootorder(module): new_profile = { "Server": { "@Version": "1.01", "SystemConfig": { "BiosConfig": { "@Processing": "execute", "BiosBootOrder": { "BootOrderApply": True, "BootOrderReset": True }, "@Version": "1.03" } } } } if module.params['next_boot_device'] is not None: new_profile['Server']['SystemConfig']['BiosConfig']['BiosBootOrder']['NextBootDevice'] = \ module.params['next_boot_device'] # Set new boot profile status, data, msg = irmc_redfish_post(module, "rest/v1/Oem/eLCM/ProfileManagement/set", json.dumps(new_profile)) if status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) # check that current session is terminated status, data, msg = waitForSessionToFinish(module, get_irmc_json(data.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status)
def elcm_online_update(module): if module.params['command'] == "check": uri = "rest/v1/Oem/eLCM/OnlineUpdate" if module.params['skip_hcl_verify'] is True: uri = uri + "?skipHCLVerification=yes" status, elcmdata, msg = irmc_redfish_post(module, uri, "") else: status, elcmdata, msg = irmc_redfish_put( module, "rest/v1/Oem/eLCM/OnlineUpdate/updateCollection", "") if status < 100: module.fail_json(msg=msg, status=status, exception=elcmdata) elif status == 409: result[ 'msg'] = "Cannot {0} eLCM update, another session is in progress.".format( module.params['command']) result['status'] = status module.fail_json(**result) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) if module.params['wait_for_finish'] is True: # check that current session is terminated status, data, msg = waitForSessionToFinish( module, get_irmc_json(elcmdata.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status) result['changed'] = True
def irmc_fwbios_update(module): # initialize result result['changed'] = False result['status'] = 0 if module.check_mode: result['msg'] = "module was not run" module.exit_json(**result) # preliminary parameter check preliminary_parameter_check(module) # check that all tasks are finished properly check_all_tasks_are_finished(module) # Get iRMC basic data status, sysdata, msg = irmc_redfish_get(module, "redfish/v1/Systems/0/") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status != 200: module.fail_json(msg=msg, status=status) # Get iRMC FW Update data update_url = "redfish/v1/Managers/iRMC/Oem/ts_fujitsu/iRMCConfiguration/FWUpdate/" status, fwdata, msg = irmc_redfish_get(module, update_url) if status < 100: module.fail_json(msg=msg, status=status, exception=fwdata) elif status != 200: module.fail_json(msg=msg, status=status) if module.params['command'] == "get": result['fw_update_configuration'] = setup_resultdata(fwdata, sysdata) module.exit_json(**result) elif module.params['update_type'] == "irmc": patch_update_data(module, update_url, get_irmc_json(fwdata.json(), "@odata.etag")) if module.params['update_source'] == "file": status, udata, msg = irmc_redfish_post_file(module, get_update_url(module), module.params['file_name']) else: status, udata, msg = irmc_redfish_post(module, get_update_url(module), module.params['file_name']) if status < 100: module.fail_json(msg=msg, status=status, exception=udata) elif status not in (200, 202, 204): if status == 104 and module.params['update_type'] == "irmc": msg = "{0} This message might indicate that iRMC needs to reboot before FW update.".format( msg) if status == 400: msg = "{0} This message might be due to the binary file being invalid for the server.".format( msg) module.fail_json(msg=msg, status=status) wait_for_update_to_finish(module, udata.headers['Location'], get_irmc_json(sysdata.json(), "PowerState")) module.exit_json(**result)
def force_new_boot_profile(module): # check whether 'Automatic BiosParameter Backup' is set scci_map = [ # Param, SCCI Name, SCCI Code, value [ "bios_backup_enabled", "ConfPermanentBiosConfigStorageEnabled", 0x1CC0, None ], ["bios_config_active", "ConfPermanentBiosConfigActive", 0x2721, None], ] datadict = dict() datadict['bios_backup_enabled'] = None datadict['bios_config_active'] = None body = scci_body_start for elem in scci_map: body += add_scci_command("GET", scci_map, elem[1], 0, '') body += scci_body_end # send command list to scripting interface status, data, msg = irmc_scci_post(module, body) if status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204, 404): module.fail_json(msg=msg, status=status) # evaluate results list datadict, scciresult, sccicontext = get_scciresultlist( data.content, datadict, scci_map) if scciresult != 0: module.fail_json(msg=sccicontext, status=status) # we only need to generate a new profile if 'Automatic BiosParameter Backup' is not set and active if datadict['bios_backup_enabled'] == "0" or datadict[ 'bios_config_active'] == "0": # Delete current Boot Profile Data (if it exists) status, sysdata, msg = irmc_redfish_delete( module, "rest/v1/Oem/eLCM/ProfileManagement/BiosBootOrder") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status not in (200, 202, 204, 404): module.fail_json(msg=msg, status=status) # Generate new Boot Profile Data url = "/rest/v1/Oem/eLCM/ProfileManagement/get?PARAM_PATH=Server/SystemConfig/BiosConfig/BiosBootOrder" status, sysdata, msg = irmc_redfish_post(module, url, "") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) # check that current session is terminated status, data, msg = waitForSessionToFinish( module, get_irmc_json(sysdata.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status)
def irmc_powerstate(module): result = dict(changed=False, status=0) if module.check_mode: result['msg'] = "module was not run" module.exit_json(**result) # preliminary parameter check if module.params['command'] == "set" and module.params['state'] is None: result['msg'] = "Command 'set' requires 'state' parameter to be set!" result['status'] = 10 module.fail_json(**result) # Get iRMC system data status, sysdata, msg = irmc_redfish_get(module, "redfish/v1/Systems/0/") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status != 200: module.fail_json(msg=msg, status=status) power_state = get_irmc_json(sysdata.json(), "PowerState") if module.params['command'] == "get": result['power_state'] = power_state module.exit_json(**result) # Evaluate function params against iRMC if "Power" + power_state == module.params['state'].replace("Graceful", ""): result['skipped'] = True result['msg'] = "PRIMERGY server is already in state '{0}'".format( power_state) module.exit_json(**result) allowedparams = \ get_irmc_json(sysdata.json(), ["Actions", "Oem", "http://ts.fujitsu.com/redfish-schemas/v1/FTSSchema.v1_0_0#FTSComputerSystem.Reset", "*****@*****.**"]) if module.params['state'] not in allowedparams: result['msg'] = "Invalid parameter '{0}'. Allowed: {1}". \ format(module.params['state'], json.dumps(allowedparams)) result['status'] = 11 module.fail_json(**result) # Set iRMC system data body = {'FTSResetType': module.params['state']} status, sysdata, msg = irmc_redfish_post( module, "redfish/v1/Systems/0/Actions/Oem/FTSComputerSystem.Reset", json.dumps(body)) if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) result['changed'] = True module.exit_json(**result)
def irmc_eventlog(module): # initialize result result['changed'] = False result['status'] = 0 if module.check_mode: result['msg'] = "module was not run" module.exit_json(**result) # preliminary parameter check if module.params['command'] == "get" and module.params['id'] is None: result['msg'] = "Command 'get' requires 'id' parameter to be set!" result['status'] = 10 module.fail_json(**result) if module.params['command'] == "list": status, data, msg = irmc_redfish_get( module, "redfish/v1/Managers/iRMC/LogServices/{0}/Entries".format( module.params['eventlog_type'])) if status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) eventlogs = get_irmc_json(data.json(), ["Members"]) result['eventlog'] = [] for item in eventlogs: result['eventlog'].append(get_irmc_eventlog_info(module, item)) elif module.params['command'] == "clear": url = "redfish/v1/Managers/iRMC/LogServices/{0}/Actions/LogService.ClearLog". \ format(module.params['eventlog_type']) status, data, msg = irmc_redfish_post(module, url, "") if status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) result['changed'] = True else: status, data, msg = irmc_redfish_get( module, "redfish/v1/Managers/iRMC/LogServices/{0}/Entries/{1}".format( module.params['eventlog_type'], module.params['id'])) if status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) result['eventlog_entry'] = get_irmc_eventlog_info(module, data.json()) module.exit_json(**result)
def get_raid_data(module): # make sure RAIDAdapter profile is up-to-date status, sysdata, msg = irmc_redfish_delete( module, "/rest/v1/Oem/eLCM/ProfileManagement/RAIDAdapter") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status not in (200, 202, 204, 404): module.fail_json(msg=msg, status=status) url = "rest/v1/Oem/eLCM/ProfileManagement/get?PARAM_PATH=Server/HWConfigurationIrmc/Adapters/RAIDAdapter" status, sysdata, msg = irmc_redfish_post(module, url, "") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status == 404: result[ 'msg'] = "Requested profile 'HWConfigurationIrmc/Adapters/RAIDAdapter' cannot be created." module.fail_json(msg=msg, status=status) elif status == 409: result[ 'msg'] = "Requested profile 'HWConfigurationIrmc/Adapters/RAIDAdapter' already exists." module.fail_json(msg=msg, status=status) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) if module.params['wait_for_finish'] is True: # check that current session is terminated status, data, msg = waitForSessionToFinish( module, get_irmc_json(sysdata.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status) status, sysdata, msg = irmc_redfish_get( module, "/rest/v1/Oem/eLCM/ProfileManagement/RAIDAdapter") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status == 404: module.fail_json( msg= "Requested profile 'HWConfigurationIrmc/Adapters/RAIDAdapter' does not exist.", status=status) elif status != 200: module.fail_json(msg=msg, status=status) return sysdata.json()
def import_profile(module): if module.params['profile_json'] is None: try: with open(module.params['profile_path']) as infile: irmc_profile = json.load(infile) except Exception: result[ 'msg'] = "Could not read JSON profile data from file '{0}'".format( module.params['profile_path']) result['status'] = 20 module.fail_json(**result) else: try: irmc_profile = json.loads(module.params['profile_json']) except Exception: result['msg'] = "Profile data are not proper JSON '{0}'.".format( module.params['profile_json']) result['status'] = 21 module.fail_json(**result) irmc_profile = checkandupdate_irmc_profile(module, irmc_profile) # Set new profile status, sysdata, msg = irmc_redfish_post( module, "rest/v1/Oem/eLCM/ProfileManagement/set", json.dumps(irmc_profile)) if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status == 404: result['msg'] = "Requested profile '{0}' cannot be imported.".format( module.params['profile']) module.fail_json(msg=msg, status=status) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) if module.params['wait_for_finish'] is True: # check that current session is terminated status, data, msg = waitForSessionToFinish( module, get_irmc_json(sysdata.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status) result['changed'] = True
def apply_raid_configuration(module, body): status, sysdata, msg = irmc_redfish_post(module, "rest/v1/Oem/eLCM/ProfileManagement/set", json.dumps(body)) if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status == 406: result['msg'] = "Raid Configuration cannot be {0}d.".format(module.params['command']) module.fail_json(msg=msg, status=status) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) if module.params['wait_for_finish'] is True: # check that current session is terminated status, data, msg = waitForSessionToFinish(module, get_irmc_json(sysdata.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status) result['changed'] = True
def irmc_biosbootorder(module): # initialize result result['changed'] = False result['status'] = 0 if module.check_mode: result['msg'] = "module was not run" module.exit_json(**result) # preliminary parameter check preliminary_parameter_check(module) # check that all iRMC Profile processing states are terminated waitForIrmcSessionsInactive(module) if module.params['command'] == "default": set_default_bootorder(module) result['changed'] = True module.exit_json(**result) if module.params['force_new'] is True: force_new_boot_profile(module) # Get Boot Profile Data boot_profile_data = get_boot_profile_data(module) devices = get_irmc_json(boot_profile_data, ["Server", "SystemConfig", "BiosConfig", "BiosBootOrder", "Devices"]) if module.params['command'] == "get": for status, devicelist in devices.items(): result['boot_order'] = [] for device in devicelist: bo = {} bo['DeviceIdx'] = device['@DeviceIdx'] bo['DeviceName'] = device['DeviceName'] bo['StructuredBootString'] = device['StructuredBootString'] result['boot_order'].append(bo) module.exit_json(**result) # setup new boot order new_profile = setup_new_boot_profile(module, boot_profile_data) comparison_list = [] comparison_result, comparison_list = compare_irmc_profile(boot_profile_data, new_profile, "", "", comparison_list) if comparison_result is True: result['skipped'] = True result['msg'] = "Bios boot order is already as requested." module.exit_json(**result) # activate the new profile new_profile['Server']['SystemConfig']['BiosConfig']['BiosBootOrder']['BootOrderApply'] = True new_profile['Server']['SystemConfig']['BiosConfig']['@Processing'] = "execute" # Set new boot profile status, sysdata, msg = irmc_redfish_post(module, "rest/v1/Oem/eLCM/ProfileManagement/set", json.dumps(new_profile)) if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) # check that current session is terminated status, data, msg = waitForSessionToFinish(module, get_irmc_json(sysdata.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status) result['changed'] = True module.exit_json(**result)
def irmc_elcm_offline_update(module): # initialize result result['changed'] = False result['status'] = 0 if module.check_mode: result['msg'] = "module was not run" module.exit_json(**result) # check eLCM status status, data, msg = elcm_check_status(module) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status < 30 or status not in (200, 202, 204): module.fail_json(msg=msg, status=status) if module.params['command'] == "execute" and module.params[ 'ignore_power_on'] is False: # Get server power state status, sysdata, msg = irmc_redfish_get(module, "redfish/v1/Systems/0/") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status != 200: module.fail_json(msg=msg, status=status) if get_irmc_json(sysdata.json(), "PowerState") == "On": result['msg'] = "Server is powered on. Cannot continue." result['status'] = 10 module.fail_json(**result) if module.params['command'] == "prepare": uri = "rest/v1/Oem/eLCM/OfflineUpdate" if module.params['skip_hcl_verify'] is True: uri = uri + "?skipHCLVerification=yes" status, elcmdata, msg = irmc_redfish_post(module, uri, "") else: status, elcmdata, msg = irmc_redfish_put( module, "rest/v1/Oem/eLCM/OfflineUpdate", "") if status < 100: module.fail_json(msg=msg, status=status, exception=elcmdata) elif status == 409: result[ 'msg'] = "Cannot {0} eLCM update, another session is in progress.".format( module.params['command']) result['status'] = status module.fail_json(**result) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) if module.params['wait_for_finish'] is True: # check that current session is terminated status, data, msg = waitForSessionToFinish( module, get_irmc_json(elcmdata.json(), ["Session", "Id"])) if status > 30 and status < 100: module.fail_json(msg=msg, status=status, exception=data) elif status not in (200, 202, 204): module.fail_json(msg=msg, log=data, status=status) result['changed'] = True module.exit_json(**result)
def irmc_connectvirtualmedia(module): result = dict(changed=False, status=0) if module.check_mode: result['msg'] = "module was not run" module.exit_json(**result) # Get iRMC system data status, sysdata, msg = irmc_redfish_get(module, "redfish/v1/Systems/0/") if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status != 200: module.fail_json(msg=msg, status=status) # Evaluate function params against iRMC irmctype = get_irmc_json(sysdata.headers, "Server") vmaction_type = "VirtualMediaAction" if "S4" in irmctype else "FTSVirtualMediaAction" vm_type = module.params['command'].replace("Connect", "").replace("Disconnect", "") vm_action = module.params['command'].replace(vm_type, "") vm_other_state = "Connect" + vm_type if vm_action == "Disconnect" else "Disconnect" + vm_type allowedparams = \ get_irmc_json(sysdata.json(), ["Actions", "Oem", "http://ts.fujitsu.com/redfish-schemas/v1/FTSSchema.v1_0_0#FTSComputerSystem.VirtualMedia", vmaction_type + "@Redfish.AllowableValues"]) if module.params['command'] not in allowedparams: if vm_other_state in allowedparams: result['skipped'] = True result[ 'msg'] = "iRMC vitual " + vm_type + " is already in state '" + module.params[ 'command'] + "'" module.exit_json(**result) else: result['warnings'] = "Parameter '" + module.params['command'] + "' cannot be used at this time. " + \ "Allowed: " + json.dumps(allowedparams) module.exit_json(**result) # Get iRMC Virtual Media data status, vmdata, msg = irmc_redfish_get( module, "redfish/v1/Systems/0/Oem/ts_fujitsu/VirtualMedia/") if status < 100: module.fail_json(msg=msg, status=status, xception=vmdata) elif status != 200: module.fail_json(msg=msg, status=status) # Check Virtual Media Data remotemountenabled = get_irmc_json(vmdata.json(), "RemoteMountEnabled") if not remotemountenabled: result['msg'] = "Remote Mount of Virtual Media is not enabled!" result['status'] = 20 module.fail_json(**result) # Set iRMC system data body = {vmaction_type: module.params['command']} status, sysdata, msg = irmc_redfish_post( module, "redfish/v1/Systems/0/Actions/Oem/FTSComputerSystem.VirtualMedia", json.dumps(body)) if status < 100: module.fail_json(msg=msg, status=status, exception=sysdata) elif status not in (200, 202, 204): module.fail_json(msg=msg, status=status) result['changed'] = True module.exit_json(**result)