initial hpe support - v2 28/228/2
authordavidplunkett <dp7642@att.com>
Tue, 28 Aug 2018 19:00:45 +0000 (19:00 +0000)
committerdavidplunkett <dp7642@att.com>
Fri, 21 Sep 2018 18:48:46 +0000 (18:48 +0000)
Change-Id: I9e83b05aa65b2205f38f71880141b0cf996cefa3
Signed-off-by: davidplunkett <dp7642@att.com>
apply_hpejson.sh [new file with mode: 0755]
buildrc
hpe_dl380_g10_uefi_base.json.template [new file with mode: 0644]
hpe_dl380_g10_uefi_httpboot.json.template [new file with mode: 0644]
install_server_os.sh
set_hpe_config.py [new file with mode: 0644]
setup_tools.sh

diff --git a/apply_hpejson.sh b/apply_hpejson.sh
new file mode 100755 (executable)
index 0000000..1989f53
--- /dev/null
@@ -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 (file)
--- 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 (file)
index 0000000..28b50b5
--- /dev/null
@@ -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 (file)
index 0000000..9ee6191
--- /dev/null
@@ -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"
+            }
+        }
+    }
+]
+
index e23ccbe..e6962ab 100755 (executable)
 # 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 (file)
index 0000000..332e0d9
--- /dev/null
@@ -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()
+
index d8619d3..1238ecf 100755 (executable)
@@ -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]"