From 7c4f3c73b3bf88b52fbbaaae13fe50b127a8bc7d Mon Sep 17 00:00:00 2001 From: davidplunkett Date: Tue, 28 Aug 2018 19:00:45 +0000 Subject: [PATCH] initial hpe support - v2 Change-Id: I9e83b05aa65b2205f38f71880141b0cf996cefa3 Signed-off-by: davidplunkett --- apply_hpejson.sh | 161 ++++++++++++++++ buildrc | 3 +- hpe_dl380_g10_uefi_base.json.template | 125 +++++++++++++ hpe_dl380_g10_uefi_httpboot.json.template | 71 ++++++++ install_server_os.sh | 60 ++++-- set_hpe_config.py | 294 ++++++++++++++++++++++++++++++ setup_tools.sh | 23 ++- 7 files changed, 720 insertions(+), 17 deletions(-) create mode 100755 apply_hpejson.sh create mode 100644 hpe_dl380_g10_uefi_base.json.template create mode 100644 hpe_dl380_g10_uefi_httpboot.json.template create mode 100644 set_hpe_config.py diff --git a/apply_hpejson.sh b/apply_hpejson.sh new file mode 100755 index 0000000..1989f53 --- /dev/null +++ b/apply_hpejson.sh @@ -0,0 +1,161 @@ +#!/bin/bash +# +# Copyright 2018 AT&T Intellectual Property. All other rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Script to apply HPE BIOS and/or RAID settings. +# +# usage: ./apply_hpejson.sh [--rc settingsfile] --template templatefile [--no-confirm] [--no-apply-hw] [--help] +# + +# default behavior will require confirmation before starting +NO_CONFIRM=${NO_CONFIRM:-} +NO_APPLY_HW=${NO_APPLY_HW:-} +RCFILE= +TEMPLATE= + +# PROCESS COMMAND LINE ARGUMENTS +POSITIONAL=() +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + --rc) + RCFILE=$2 + shift # past argument + shift # past value + ;; + --template) + TEMPLATE=$2 + shift # past argument + shift # past value + ;; + --no-confirm|--skip-confirm) + NO_CONFIRM=TRUE + shift # past argument + ;; + --no-apply-hw|--skip-biosraid) + echo "WARNING: This run will only create the xlm file and not apply BIOS and RAID configuration. This is for testing only." + NO_APPLY_HW=TRUE + shift # past argument + ;; + --help) + echo "usage: ./apply_hpejson.sh [--rc settingsfile] --template templatefile [--no-confirm] [--no-apply-hw] [--help]" + exit 0 + ;; + *) # unknown option + POSITIONAL+=("$1") # save it in an array for later + shift # past argument + ;; +esac +done +set -- "${POSITIONAL[@]}" # restore positional parameters + +# SETUP TOOLS AND LOAD DEFAULT BUILD VARIABLES +BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +. $BASEDIR/setup_tools.sh 1>&2 + +# LOAD SERVER VARIABLES IF SERVER RCFILE PROVIDED - OTHERWISE ASSUME THE VARIABLES HAVE BEEN EXPORTED +if [ -n "$RCFILE" ] && [ -f "$RCFILE" ]; then + source $RCFILE +fi + +# CHECK A FEW REQUIRED VARIABLES - BUT NOT ALL +CHECKLIST="SRV_NAME SRV_OOB_IP SRV_OOB_USR SRV_OOB_PWD BUILD_WEBIP BUILD_WEBPORT" +for VAR in $CHECKLIST; do + if [ -z "${!VAR}" ] ; then + echo "ERROR: Invalid or missing variable [$VAR] = [${!VAR}] in rcfile [$RCFILE]" + echo "usage: ./apply_hpejson.sh [--rc settingsfile] --template templatefile [--no-confirm] [--no-apply-hw] [--help]" + exit 1 + fi +done + +# CHECK IF TEMPLATE PASSED AND EXISTS +if [ -z "$TEMPLATE" ] || ! [ -f "$TOOLS_ROOT/$TEMPLATE" ]; then + echo "ERROR: Invalid or missing template file [$TOOLS_ROOT/$TEMPLATE]" + echo "usage: ./apply_hpejson.sh [--rc settingsfile] --template templatefile [--no-confirm] [--no-apply-hw] [--help]" + exit 1 +else + echo "Using template [$TOOLS_ROOT/$TEMPLATE]" +fi + +# SET ADDITIONAL VARIABLES BASED ON RC FILE +SRV_IPXE_URL=http://$BUILD_WEBIP:$BUILD_WEBPORT/ipxe-$SRV_IPXE_INF-$SRV_VLAN.efi +JSONFILE=$SRV_NAME.${TEMPLATE%\.template} + +if [ -z "$NO_CONFIRM" ]; then + echo "" + read -r -p "Preparing to apply json file [$TEMPLATE] to server [$SRV_NAME] using oob ip [$SRV_OOB_IP]. Are you sure? [y/N] " response + case "$response" in + [yY][eE][sS]|[yY]) + ;; + *) + echo "Script aborted!" + exit 1 + ;; + esac + echo "" +else + i="10" + echo -n "WARNING: Preparing to apply json to server [$SRV_NAME] using oob ip [$SRV_OOB_IP]. Beginning in $i seconds " + while [ $i -gt 0 ]; do + echo -n "."; sleep 1; i=$[$i-1] + done + echo "" +fi + +echo "Beginning create and apply json file to server at" `date` +STIME=$(date +%s) + +## CREATE HARDWARE CONFIG JSON FILE FOR USE WITH REDFISH +echo "Creating server BIOS/RAID settings file [$BUILD_ROOT/$JSONFILE] for server [$SRV_NAME]" +mkdir -p $BUILD_ROOT +rm -f $BUILD_ROOT/$JSONFILE +cp -f $TOOLS_ROOT/$TEMPLATE $BUILD_ROOT/$JSONFILE + +for VAR in $(set | grep -P "^SRV_|^BUILD_" | cut -f 1 -d'='); do + sed -i -e "s|@@$VAR@@|${!VAR}|g" $BUILD_ROOT/$JSONFILE +done + +## CHECK THAT ALL VALUES WERE REPLACED +MISSING=$(grep -Po "@@.*?@@" $BUILD_ROOT/$JSONFILE | sort | uniq) +if [ -n "$MISSING" ] ; then + echo "ERROR: Required variable(s) in template [$TEMPLATE] were not located in the resource file [$RCFILE]" + echo ${MISSING//@@/} | xargs -n 1 | sed -e 's/^/ /g' + exit 1 +fi + +if [ -z "$NO_APPLY_HW" ]; then + + ## PUSH HARDWARE CONFIG JSON USING REDFISH - BYPASS PROXY FOR INTERNAL CONNECTION TO IDRAC + echo "Applying server settings file [$BUILD_ROOT/$JSONFILE] to [$SRV_OOB_IP]" + echo "This step could take up to 10 minutes" + HTTPS_PROXY= https_proxy= PYTHONPATH=$HPE_ROOT/examples/Redfish/ python "$TOOLS_ROOT/set_hpe_config.py" \ + -ip $SRV_OOB_IP -u $SRV_OOB_USR -p $SRV_OOB_PWD -f $BUILD_ROOT/$JSONFILE 2>&1 + if [ "$?" -ne 0 ]; then + echo "ERROR: failed applying server BIOS/RAID settings" + exit 1 + fi +else + ## SKIPPING REBOOT + echo "WARNING: Skipping application of hardware settings - normally used for testing only" +fi + +## DONE +ETIME=$(date +%s) +echo "SUCCESS: Completed update of BIOS/RAID settings on [$SRV_NAME] at" `date` +echo "Elapsed time was $(( ($ETIME - $STIME) / 60 )) minutes and $(( ($ETIME - $STIME) % 60 )) seconds" + diff --git a/buildrc b/buildrc index e9fb264..a97445a 100644 --- a/buildrc +++ b/buildrc @@ -22,13 +22,14 @@ export REDFISH_REPO=${REDFISH_REPO:-https://nexus.akraino.org/service/local/arti export IPXE_GIT=${IPXE_GIT:-http://git.ipxe.org/ipxe.git} export DELL_GIT=${DELL_GIT:-https://github.com/dell/iDRAC-Redfish-Scripting.git} -export IPXE_GIT=${IPXE_GIT:-http://git.ipxe.org/ipxe.git} +export HPE_GIT=${HPE_GIT:-https://github.com/HewlettPackard/python-ilorest-library.git} export REDFISH_ROOT=${REDFISH_ROOT:-/opt/akraino} export WEB_ROOT=${WEB_ROOT:-$REDFISH_ROOT/www} export DHCP_ROOT=${DHCP_ROOT:-$REDFISH_ROOT/dhcp} export TOOLS_ROOT=${TOOLS_ROOT:-$REDFISH_ROOT/tools} export DELL_ROOT=${DELL_ROOT:-$REDFISH_ROOT/dell} +export HPE_ROOT=${HPE_ROOT:-$REDFISH_ROOT/hpe} export REGION_ROOT=${REGION_ROOT:-$WEB_ROOT/region} export BUILD_ROOT=${BUILD_ROOT:-$REDFISH_ROOT/server-config} export IPXE_ROOT=${IPXE_ROOT:-$REDFISH_ROOT/ipxe} diff --git a/hpe_dl380_g10_uefi_base.json.template b/hpe_dl380_g10_uefi_base.json.template new file mode 100644 index 0000000..28b50b5 --- /dev/null +++ b/hpe_dl380_g10_uefi_base.json.template @@ -0,0 +1,125 @@ +[ + { + "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/":{ + "POST":{ + "Action":"ComputerSystem.Reset", + "ResetType":"ForceOff" + } + } + }, + { + "/redfish/v1/systems/1/bios/settings/":{ + "PATCH":{ + "Attributes":{ + "RestoreManufacturingDefaults":"Yes" + } + } + } + }, + { + "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/":{ + "POST":{ + "Action":"ComputerSystem.Reset", + "ResetType":"On" + } + } + }, + { + "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/":{ + "POST":{ + "Action":"ComputerSystem.Reset", + "ResetType":"ForceOff" + } + } + }, + { + "/redfish/v1/systems/1/bios/settings/":{ + "PATCH":{ + "Attributes":{ + "BootMode":"Uefi", + "UefiOptimizedBoot":"Enabled", + "Sriov":"Enabled", + "ProcVirtualization":"Enabled", + "IntelProcVtd":"Enabled", + "AutoPowerOn":"AlwaysPowerOn", + "EmbSas1Boot":"TwentyFourTargets", + "HttpSupport":"HttpOnly", + "PreBootNetwork":"Auto", + "PrebootNetworkEnvPolicy":"IPv4", + "UrlBootFile":"", + "Dhcpv4":"Enabled", + "NicBoot1":"NetworkBoot", + "NicBoot2":"Disabled", + "NicBoot3":"Disabled", + "NicBoot4":"Disabled", + "NicBoot5":"Disabled", + "NicBoot6":"Disabled", + "Slot3NicBoot1":"Disabled", + "Slot3NicBoot2":"Disabled", + "Slot6NicBoot1":"Disabled", + "Slot6NicBoot2":"Disabled", + "BootOrderPolicy":"RetryIndefinitely", + "NetworkBootRetry":"Enabled", + "NetworkBootRetryCount":10, + "ConsistentDevNaming":"LomsAndSlots", + "EnergyPerfBias":"BalancedPerf", + "WorkloadProfile":"GeneralPowerEfficientCompute", + "EnergyEfficientTurbo":"Enabled", + "TimeZone":"Utc0", + "DaylightSavingsTime":"Disabled" + } + } + } + }, + { + "/redfish/v1/Systems/1/smartstorageconfig/settings/":{ + "PATCH":[ + { + "CapacityGiB":447, + "Raid":"Raid1", + "StripSizeBytes":262144, + "LogicalDriveName":"root", + "DataDrives":[ + "1I:1:11", + "1I:1:12" + ], + "SpareDrives":[ + ], + "Accelerator":"ControllerCache" + }, + { + "CapacityGiB":1676, + "Raid":"Raid1", + "StripSizeBytes":262144, + "LogicalDriveName":"ceph", + "DataDrives":[ + "1I:1:1", + "1I:1:2" + ], + "SpareDrives":[ + ], + "Accelerator":"ControllerCache" + } + ] + } + }, + { + "/redfish/v1/systems/1/bios/boot/settings/":{ + "PATCH":{ + "PersistentBootConfigOrder":[ + "HD.EmbRAID.1.10", + "NIC.LOM.1.1.IPv4" + ] + } + } + }, + { + "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/":{ + "POST":{ + "Action":"ComputerSystem.Reset", + "ResetType":"On" + } + } + } +] + diff --git a/hpe_dl380_g10_uefi_httpboot.json.template b/hpe_dl380_g10_uefi_httpboot.json.template new file mode 100644 index 0000000..9ee6191 --- /dev/null +++ b/hpe_dl380_g10_uefi_httpboot.json.template @@ -0,0 +1,71 @@ +[ + { + "/redfish/v1/systems/1/bios/settings/":{ + "PATCH":{ + "Attributes":{ + "UrlBootFile":"@@SRV_IPXE_URL@@", + "Dhcpv4":"Enabled", + "VlanControl":"Enabled", + "VlanId":@@SRV_VLAN@@, + "VlanPriority":0, + "NicBoot1":"NetworkBoot", + "NicBoot2":"Disabled", + "NicBoot3":"Disabled", + "NicBoot4":"Disabled", + "NicBoot5":"Disabled", + "NicBoot6":"Disabled", + "Slot3NicBoot1":"NetworkBoot", + "Slot3NicBoot2":"NetworkBoot", + "Slot5NicBoot1":"Disabled", + "Slot5NicBoot2":"Disabled", + "Slot6NicBoot1":"Disabled", + "Slot6NicBoot2":"Disabled", + "BootOrderPolicy":"RetryIndefinitely", + "NetworkBootRetry":"Enabled", + "NetworkBootRetryCount":10 + }, + "Id":"settings" + } + } + }, + { + "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/":{ + "POST":{ + "Action":"ComputerSystem.Reset", + "ResetType":"ForceRestart" + } + } + }, + { + "/redfish/v1/systems/1/bios/boot/settings/":{ + "PATCH":{ + "PersistentBootConfigOrder":[ + "HD.EmbRAID.1.10", + "File.URL.1.1", + "NIC.LOM.1.1.IPv4", + "Generic.USB.1.1", + "HD.EmbRAID.1.2", + "HD.EmbRAID.1.3", + "HD.EmbRAID.1.4", + "HD.EmbRAID.1.5", + "HD.EmbRAID.1.6", + "HD.EmbRAID.1.7", + "HD.EmbRAID.1.8", + "HD.EmbRAID.1.9", + "HD.EmbRAID.1.11", + "NIC.Slot.3.1.IPv4", + "NIC.Slot.3.2.IPv4" + ] + } + } + }, + { + "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/":{ + "POST":{ + "Action":"ComputerSystem.Reset", + "ResetType":"ForceRestart" + } + } + } +] + diff --git a/install_server_os.sh b/install_server_os.sh index e23ccbe..e6962ab 100755 --- a/install_server_os.sh +++ b/install_server_os.sh @@ -27,10 +27,12 @@ # SET DEFAULT VALUES UBUNTU_ISO=${UBUNTU_ISO:-} ## IF NOT SET, UBUNTU_URL WILL BE USED TO DOWNLOAD DEFAULT ISO -# SETUP LOGGING (SAVE ORIGINAL STDIN AND STDOUT AS FD 3 AND 4) +# SETUP LOGGING FOR INTERACTIVE SHELLS (SAVE ORIGINAL STDIN AND STDOUT AS FD 3 AND 4) MYLOGFILE="`basename $0`"; MYLOGFILE="${MYLOGFILE%.*}-`date +%FT%H-%M-%S-%2N`.log" -#exec 3>&1 4>&2 1> >(tee -a "$MYLOGFILE") 2>&1 -#echo "Logging to $PWD/$MYLOGFILE" +if [[ $- = *i* ]]; then + exec 3>&1 4>&2 1> >(tee -a "$MYLOGFILE") 2>&1 + echo "Logging to $PWD/$MYLOGFILE" +fi echo "Beginning $0 as user [$USER] in pwd [$PWD] with home [$HOME]" @@ -145,7 +147,7 @@ else ifconfig | grep --no-group-separator -B1 ":$BUILD_WEBIP " fi -## COLLECT ANY ADDITIONAL SERVER DATA NEEDED - IE LOOKUP MAC FOR DELL NIC +## COLLECT ANY ADDITIONAL SERVER DATA NEEDED - FOR EXAMPLE, LOOKUP MAC FOR DELL NIC case $SRV_OEM in Dell|DELL) if [ -z "$SRV_MAC" ]; then @@ -157,8 +159,10 @@ case $SRV_OEM in fi ;; HP|HPE) - echo "ERROR: HPE SERVER BUILDS ARE NOT SUPPORTED YET!!!" - exit 1; + if [ -z "$SRV_MAC" ]; then + echo "ERROR: HPE required variable SRV_MAC missing from rc file [$RCFILE]" + exit 1; + fi ;; *) # unknown option echo "ERROR: Unknown server oem [$SRV_OEM]" @@ -280,13 +284,36 @@ if ! docker ps | grep akraino-dhcp >/dev/null; then fi ## CREATE CONFIG FILES AND APPLY UNLESS CALLED WITH --no-apply-hw -. $TOOLS_ROOT/apply_dellxml.sh --template $SRV_BIOS_TEMPLATE -echo "Completed update with status [$?]" -sleep 80 +case $SRV_OEM in + Dell|DELL) + if [ -n "$SRV_BIOS_TEMPLATE" ]; then + . $TOOLS_ROOT/apply_dellxml.sh --template $SRV_BIOS_TEMPLATE + echo "Completed update with status [$?]" + sleep 80 + fi -. $TOOLS_ROOT/apply_dellxml.sh --template $SRV_BOOT_TEMPLATE -echo "Completed update with status [$?]" -sleep 20 + if [ -n "$SRV_BOOT_TEMPLATE" ]; then + . $TOOLS_ROOT/apply_dellxml.sh --template $SRV_BOOT_TEMPLATE + echo "Completed update with status [$?]" + sleep 20 + fi + ;; + HP|HPE) + if [ -n "$SRV_BIOS_TEMPLATE" ]; then + . $TOOLS_ROOT/apply_hpejson.sh --template $SRV_BIOS_TEMPLATE + echo "Completed update with status [$?]" + fi + if [ -n "$SRV_BOOT_TEMPLATE" ]; then + . $TOOLS_ROOT/apply_hpejson.sh --template $SRV_BOOT_TEMPLATE + echo "Completed update with status [$?]" + echo "Waiting for server to reboot with new settings." + fi + ;; + *) # unknown option + echo "ERROR: Unknown server oem [$SRV_OEM]" + exit 1; + ;; +esac if [ -z "$NO_APPLY_HW" ]; then @@ -300,6 +327,11 @@ if [ -z "$NO_APPLY_HW" ]; then echo "WARNING: Web server was restarted..." done + if [ $(date +%s) -gt $[$WSTART + 900] ]; then + echo "ERROR: Timeout waiting for server to download firstboot.sh" + exit 1 + fi + ## WAIT FOR SERVER TO START REBOOT echo "Waiting for server [$SRV_IP] to reboot" `date` echo "Waiting for server to shutdown..." @@ -367,6 +399,8 @@ echo "SUCCESS: Try connecting with 'ssh root@$SRV_IP' as user $USER" echo "Elapsed time was $(( ($ENDTIME - $STARTTIME) / 60 )) minutes and $(( ($ENDTIME - $STARTTIME) % 60 )) seconds" ## RESTORE SAVED STDIN AND STDOUT (TERMINATES TEE REDIRECTION) -#exec 1>&3 2>&4 +if [[ $- = *i* ]]; then + exec 1>&3 2>&4 +fi exit 0 diff --git a/set_hpe_config.py b/set_hpe_config.py new file mode 100644 index 0000000..332e0d9 --- /dev/null +++ b/set_hpe_config.py @@ -0,0 +1,294 @@ +#!/usr/bin/python + +# Copyright 2018 AT&T Intellectual Property. All other rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + #Copyright 2016 Hewlett Packard Enterprise Development LP + # + # Licensed under the Apache License, Version 2.0 (the "License"); you may + # not use this file except in compliance with the License. You may obtain + # a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + # License for the specific language governing permissions and limitations + # under the License. + +import sys, os, argparse, json, time +from _redfishobject import RedfishObject +from redfish.rest.v1 import ServerDownOrUnreachableError + +parser = argparse.ArgumentParser(description='Python script using Redfish API to update BIOS attributes') +parser.add_argument('-ip', help='iLO IP address', required=True) +parser.add_argument('-u', help='iLO username', required=True) +parser.add_argument('-p', help='iLO password', required=True) +parser.add_argument('-f', help='Input File', required=True) + +args = vars(parser.parse_args()) + +##### Wait for Server State ##### +def waitfor_server_state (redfishobj, get_state_func, end_state): + timeout = time.time() + 60 * 6; + srv_state = "" + sys.stdout.write("Waiting for server to reach state [{0}]. Current state:".format(end_state)) + while srv_state != end_state and time.time() < timeout: + new_state = get_state_func(redfishobj) + if new_state != srv_state: + sys.stdout.write("\n "+new_state) + srv_state = new_state + else: + sys.stdout.write('.') + sys.stdout.flush() + time.sleep(1) + + sys.stdout.write("\n") + if get_state_func(redfishobj) != end_state: + sys.stdout.write("Timed out waiting for server to reach state [{0}].".format(end_state)) + exit(1) + +##### Get Power State ##### +def get_power_state (redfishobj): + instances = redfishobj.search_for_type("ComputerSystem.") + if len(instances) != 1: + sys.stderr.write("\nERROR: Unable to find ComputerSystem object\n") + exit(1) + + response = redfishobj.redfish_get(instances[0]["@odata.id"]) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + return response.dict["PowerState"] + +##### Get Post State ##### +def get_post_state (redfishobj): + instances = redfishobj.search_for_type("ComputerSystem.") + if len(instances) != 1: + sys.stderr.write("\nERROR: Unable to find ComputerSystem object\n") + exit(1) + + response = redfishobj.redfish_get(instances[0]["@odata.id"]) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + return response.dict["Oem"]["Hpe"]["PostState"] + +##### Get Logical Drives ##### +def get_logical_drives (redfishobj): + instances = redfishobj.search_for_type("smartstorageconfig.") + if not len(instances): + sys.stderr.write("\nERROR: Unable to find SmartStorageConfig object\n") + exit(1) + + for instance in instances: + if instance["@odata.id"][-10:] != "/settings/": + response = redfishobj.redfish_get(instance["@odata.id"]) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + print json.dumps(response.dict,sort_keys=True,indent=4, separators=(',', ': ')) + +##### Get Boot Order ##### +def get_boot_order (redfishobj): + instances = redfishobj.search_for_type("ServerBootSettings.") + if not len(instances) and redfishobj.typepath.defs.isgen9: + sys.stderr.write("\nNOTE: This example will fail on HP Gen9 iLOs"\ + " with the 2.50 firmware or earlier.\n") + + for instance in instances: + if instance["@odata.id"][-10:] != "/settings/": + response = redfishobj.redfish_get(instance["@odata.id"]) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + print json.dumps(response.dict,sort_keys=True,indent=4, separators=(',', ': ')) + +##### Get BIOS settings ##### +def get_bios (redfishobj): + instances = redfishobj.search_for_type("Bios.") + if not len(instances) and redfishobj.typepath.defs.isgen9: + sys.stderr.write("\nNOTE: This example will fail on HP Gen9 iLOs"\ + " with the 2.50 firmware or earlier.\n") + + for instance in instances: + if instance["@odata.id"][-10:] != "/settings/": + response = redfishobj.redfish_get(instance["@odata.id"]) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + print json.dumps(response.dict,sort_keys=True,indent=4, separators=(',', ': ')) + +##### Set Logical Drive(s) ##### +def set_logical_drive (redfishobj, data): + instances = redfishobj.search_for_type("smartstorageconfig.") + if not len(instances) and redfishobj.typepath.defs.isgen9: + sys.stderr.write("\nNOTE: This example will fail on HP Gen9 iLOs"\ + " with the 2.50 firmware or earlier.\n") + + for instance in instances: + if instance["@odata.id"][-10:] == "/settings/": + response = redfishobj.redfish_get(instance["@odata.id"]) + #print json.dumps(response.dict,sort_keys=True,indent=4, separators=(',', ': ')) + #print response + #storage = response.dict["LogicalDrives"] + + body = dict() + body["LogicalDrives"] = data + body["DataGuard"] = "Disabled" + print json.dumps(body,sort_keys=True,indent=4, separators=(',', ': ')) + response = redfishobj.redfish_put(instance["@odata.id"], body) + if response.status != 200: + redfishobj.error_handler(response) + #response = redfishobj.redfish_get(instance["@odata.id"]) + #print response + exit(1) + + +##### Set Boot Order ##### +def set_boot_order(redfishobj, data, bios_password=None): + instances = redfishobj.search_for_type("ServerBootSettings.") + if not len(instances) and redfishobj.typepath.defs.isgen9: + sys.stderr.write("\nNOTE: This example will fail on HP Gen9 iLOs"\ + " with the 2.50 firmware or earlier.\n") + + for instance in instances: + if instance["@odata.id"][-10:] == "/settings/": + response = redfishobj.redfish_get(instance["@odata.id"]) + body = data + response = redfishobj.redfish_patch(instance["@odata.id"], body) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + +##### Set BIOS settings ##### +def set_bios(redfishobj, data, bios_password=None): + instances = redfishobj.search_for_type("Bios.") + if not len(instances) and redfishobj.typepath.defs.isgen9: + sys.stderr.write("\nNOTE: This example will fail on HP Gen9 iLOs"\ + " with the 2.50 firmware or earlier.\n") + + for instance in instances: + if instance["@odata.id"][-10:] == "/settings/": + response = redfishobj.redfish_get(instance["@odata.id"]) + body = data + response = redfishobj.redfish_patch(instance["@odata.id"], body) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + +##### Reset server ##### +def reset_server(redfishobj, data, bios_password=None): + ## common reset types: On, ForceOff, ForceRestart ## + instances = redfishobj.search_for_type("ComputerSystem.") + if len(instances) != 1: + sys.stderr.write("\nERROR: Unable to find ComputerSystem object\n") + exit(1) + + resp = redfishobj.redfish_get(instances[0]["@odata.id"]) + if resp.status==200: + body = data + path = resp.dict["Actions"]["#ComputerSystem.Reset"]["target"] + else: + sys.stderr.write("ERROR: Unable to find the path for reboot.") + exit(1) + if body["ResetType"] == "ForceOff": + if get_power_state(redfishobj) != "Off": + response = redfishobj.redfish_post(path, body) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + waitfor_server_state(redfishobj, get_power_state, "Off") + + elif body["ResetType"] == "On": + if get_power_state(redfishobj) == "Off": + response = redfishobj.redfish_post(path, body) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + waitfor_server_state(redfishobj, get_post_state, "InPostDiscoveryComplete") + + elif body["ResetType"] == "ForceRestart": + if get_power_state(redfishobj) == "Off": + body["ResetType"] = "On" + response = redfishobj.redfish_post(path, body) + if response.status != 200: + redfishobj.error_handler(response) + exit(1) + waitfor_server_state(redfishobj, get_post_state, "InPost") + waitfor_server_state(redfishobj, get_post_state, "InPostDiscoveryComplete") + else: + print "ERROR: Unhandled reset type {0}".format(body["ResetType"]) + +########### This area changes for each server or ilo ########### +if __name__ == "__main__": + + iLO_https_url = "https://"+args['ip'] + iLO_account = args['u'] + iLO_password = args["p"] + inputfile = args["f"] + + ## Create REDFISH object ## + try: + REDFISH_OBJ = RedfishObject(iLO_https_url, iLO_account, iLO_password) + except ServerDownOrUnreachableError as excp: + sys.stderr.write("ERROR: server not reachable or doesn't support RedFish.\n") + sys.exit() + except Exception as excp: + raise excp + + ## Process changes in input file ## + jfile = json.loads(open(inputfile).read()) + print "### Found {0} tasks to be completed in file {1}".format(len(jfile), inputfile) + for i in jfile: + for rf_path, v in i.items(): + for rf_method, rf_data in v.items(): + print "###" + print "### BEGIN TASK" + print "###" + if rf_path == "/redfish/v1/Systems/1/smartstorageconfig/settings/": + print "Creating logical drives" + set_logical_drive(REDFISH_OBJ, rf_data) + elif rf_path == "/redfish/v1/systems/1/bios/settings/": + print "Applying BIOS settings" + set_bios(REDFISH_OBJ, rf_data) + elif rf_path == "/redfish/v1/systems/1/bios/boot/settings/": + print "Updating boot order" + set_boot_order(REDFISH_OBJ, rf_data) + elif rf_path == "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/": + print "Setting server state to {0}".format(rf_data["ResetType"]) + reset_server(REDFISH_OBJ, rf_data) + else: + print "WARNING: Ignoring unknown redfish path {0}.".format(rf_path) + continue + + ## Print final state ## + print "###" + print "### FINAL BIOS SETTINGS" + print "###" + get_bios(REDFISH_OBJ) + print "###" + print "### FINAL BOOT SETTINGS" + print "###" + get_boot_order(REDFISH_OBJ) + print "###" + print "### FINAL SMART ARRAY SETTINGS" + print "###" + get_logical_drives(REDFISH_OBJ) + print "Server power state: {0}".format(get_power_state(REDFISH_OBJ)) + print "Server POST state: {0}".format(get_post_state(REDFISH_OBJ)) + + REDFISH_OBJ.redfish_client.logout() + diff --git a/setup_tools.sh b/setup_tools.sh index d8619d3..1238ecf 100755 --- a/setup_tools.sh +++ b/setup_tools.sh @@ -90,13 +90,30 @@ fi if [ ! -d "$DELL_ROOT" ]; then echo "Cloning Dell redfish source from [$DELL_GIT] to [$DELL_ROOT]" git clone $DELL_GIT $DELL_ROOT + + ## PATCH STATUS REPORTING DELAY TO 15 SECS (INSTEAD OF 3) + sed -i -e 's/time.sleep(3)/time.sleep(15)/g' "$DELL_ROOT/Redfish Python/ImportSystemConfigurationLocalFilenameREDFISH.py" fi if [ ! -f "$DELL_ROOT/Redfish Python/ImportSystemConfigurationLocalFilenameREDFISH.py" ]; then echo "ERROR: failed cloning Dell redfish tools from [$DELL_GIT] to [$DELL_ROOT]" exit 1 -else - ## PATCH STATUS REPORTING DELAY TO 15 SECS (INSTEAD OF 3) - sed -i -e 's/time.sleep(3)/time.sleep(15)/g' "$DELL_ROOT/Redfish Python/ImportSystemConfigurationLocalFilenameREDFISH.py" +fi + +## DOWNLOAD HPE REDFISH TOOLS_ROOT IF HPE FOLDER MISSING +if [ ! -d "$HPE_ROOT" ]; then + echo "Cloning HPE redfish tools from [$HPE_GIT] to [$HPE_ROOT]" + git clone $HPE_GIT $HPE_ROOT + + ## BUILD HPE TOOLS + ( + cd $HPE_ROOT + python setup.py sdist --formats=zip + pip install $HPE_ROOT/dist/python-ilorest-library-*.zip + ) +fi +if [ ! -f "$HPE_ROOT/examples/Redfish/_redfishobject.py" ]; then + echo "ERROR: failed cloning HPE redfish tools from [$HPE_GIT] to [$HPE_ROOT]" + exit 1 fi echo "Tools are ready in [$REDFISH_ROOT]" -- 2.16.6