HPE OneView
1833748 Members
2905 Online
110063 Solutions
New Discussion

correct REST API call to use

 
SOLVED
Go to solution
BradV
Esteemed Contributor

correct REST API call to use

I'm writing some scripts to automate our firmware updates.  I have when the server profile is inconsistent with the server profile template update working pretty well.  However, I have a server which the server profile is consistent with the server profile template, but "The firmware baseline applied on the server hardware is inconsistent with the firmware baseline selected in the server profile."  The GUI interface is displaying that message.  The iLO version is one release behind the current SPP baseline.  I can't seem to find the correct REST API call to see that information.  I pulled the server profile:

curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-profiles/${profUUID}

I get back (in part):

"templateCompliance": "Compliant",
"firmware": {
  "consistencyState": "Consistent",
....

No where do I see anything looking like an inconsistency.  Anyone know the correct REST API call to see this message?

4 REPLIES 4
BradV
Esteemed Contributor

Re: correct REST API call to use

I'm trying to identify when the server profile is compliant with the server profile template, but the hardware is not compliant with the server profile.

ManBha
HPE Pro

Re: correct REST API call to use

Hello,

 

Please verify the SPP version in the template.

 

Also, please do log a case with HPE to work on it.

 

Thanks.

I work for HPE.
[Any personal opinions expressed are mine, and not official statements on behalf of Hewlett Packard Enterprise]

Accept or Kudo

BradV
Esteemed Contributor

Re: correct REST API call to use

The version of SPP is not really important.  I'm trying to be able to detect when the server profile is compliant with the server profile template (no matter what SPP is in the template), but the hardware is not compliant with the profile.  Maybe it is such and edge case no one has thought of it?  I have opened a support case. 

BradV
Esteemed Contributor
Solution

Re: correct REST API call to use

After a discussion with support, we decided that this case would not normally happen in the real world.  So, no real reason to try and detect it.  I was working on a script to automatically run our servers through a server profile update from template.  In order to try and trigger an update for a server that was fully updated, I manually downgraded the iLO version.  That was how the hardware became non-compliant with the profile, but the profile was compliant with the server profile template.  This just would not happen without someone itervening.  In case anyone else is interested, this is my update script.

#!/bin/bash
#
# Script to update a server profile using the HPE OneView REST API.
# This is done mostly to update firmware.
#
# Inputs required:
# SERVER - name of the server.  -s <fqdn of server> (not the iLO interface)
# OneView - variable holding the OneView appliance name with 'https://' pre-pended
# currentVersion - REST API version to use in calls
# sessionID - REST API authorized session ID
#
# The last three are acquired by following the OneView REST API Get Session Credentials page.
#
LOG=$(mktemp)
#
function poweron() {
   DATAON='{"powerState":"On","powerControl":"MomentaryPress"}'
   TASKURI=$(curl --insecure --silent \
     --header "X-API-Version: ${currentVersion}" \
     --header "auth: ${sessionID}" \
     --header "content-type: application/json" \
     --include \
     --data "${DATAON}" \
     --request PUT ${OneView}/rest/server-hardware/${UUID}/powerState | grep '^Location:' | awk '{ print $2 }')
   # A carriage return is added to the end of the variable.  Get rid of it:
   TASKURI=$(echo ${TASKURI} | tr -d '\r')
   echo "The power on task URI is: ${TASKURI}" | tee -a ${LOG}
   #
   # You can check the status of the power on task with: COMPLETED!=0
   while [[ ${COMPLETED} -eq 0 ]]; do
      if [[ $(curl --insecure --silent --header "X-API-Version: ${currentVersion}" \
         --header "auth: ${sessionID}" --request GET ${OneView}${TASKURI} | jq -r '.taskState') == "Completed" ]]; then
         COMPLETED=1
         echo "The server is powering on" | tee -a ${LOG}
      else
         echo -n '.' | tee -a ${LOG}
         sleep 2
      fi
   done
}
#
function mexit() {
   # There was an abnormal termination of the script.  Power the server back on.
   poweron
   echo "${0} is exting with exit value ${1}" >> ${LOG}
   /usr/bin/mailx -s 'abnormal exit from update-from-template' admin@yourplace.com < ${LOG}
   /bin/rm ${LOG}
   exit ${1}
}
#
while getopts 's:' flag; do
   case "${flag}" in
      s) SERVER=${OPTARG};;
   esac
done
#
for VAR in OneView currentVersion sessionID; do
   if [[ -z ${VAR+x} ]]; then echo "${VAR} is not set!" | tee -a ${LOG};mexit 1;fi
done
#
echo "Running against server, ${SERVER}.  Connected to OneView, ${OneView}." | tee -a ${LOG}
#
# Get the server UUID:
ACTV=$(python -c "import urllib, sys; print urllib.quote(sys.argv[1]" "\"'serverName' = '${SERVER}'\"")
UUID=$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-hardware?filter=${ACTV} | jq -r '.members[] | .uuid')
#
# Ge the server profile UUID:
profUUID=$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-hardware/${UUID} | jq -r '.serverProfileUri' | cut -d/ -f 4)
#
echo "Running against server, ${SERVER}, with UUID, ${UUID}, and profile UUID, ${profUUID}" | tee -a ${LOG}
#
# Assuming a shutdown command has already been run.
echo "Running a power check loop" | tee -a ${LOG}
for in in {1..8}; do
   # Get the current power state:
   powerState=$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-hardware/${UUID} | jq -r '.powerState')
   if [[ "${powerState}" == "On" ]]; then
      echo -n '.' | tee -a ${LOG}
      sleep 30
   else
      echo "Power is off, ${powerState}" | tee -a ${LOG}
      break
   fi
   if [[ ${i} -eq 8 ]]; then
      echo "Forcing the server to power off" | tee -a ${LOG}
      DATAOFF='{"powerState":"On","powerControl":"PressAndHold"}'
      TASKURI=$(curl --insecure --silent \
         --header "X-API-Version: ${currentVersion}" \
         --header "auth: ${sessionID}" \
         --header "content-type: application/json" \
         --include \
         --data "${DATAOFF}" \
         --request PUT ${OneView}/rest/server-hardware/${UUID}/powerState | grep '^Location:' | awk '{ print $2 }')
      TASKURI=$(echo ${TASKURI} | tr -d '\r')
      STATUS=$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" \
         --header "auth: ${sessionID}" --request GET ${OneView}${TASKURI} | jq -r '.taskState')
      while [[ "${STATUS}" != "Completed" ]]; do
         sleep 30
         STATUS=$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" \
            --header "auth: ${sessionID}" --request GET ${OneView}${TASKURI} | jq -r '.taskState')
      done
   fi
done
#
# You can then check that the power is off with:
if [[ $(curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-hardware/${UUID} | jq -r '.powerState') == "Off" ]]; then
   echo "The server is off" | tee -a ${LOG}
else
   echo "The server is still on.  Check for a cause." | tee -a ${LOG}
   mexit 2
fi
echo "Checking on the compliance of the server profile with UUID of ${profUUID}" | tee -a ${LOG}
#
MPSTATE=$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-hardware/${UUID} | jq -r '.mpState')
i=0
while [[ ${i} -lt 8 ]]; do
   if [[ "${MPSTATE}" == "Resetting" ]]; then
      echo "iLO is resetting.  Wait a bit." | tee -a ${LOG}
      sleep 30
      ((i++))
      MPSTATE=$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-hardware/${UUID} | jq -r '.mpState')
   elif [[ "${MPSTATE}" == "OK" ]]; then
      echo "iLO is is in a good state." | tee -a ${LOG}
      i=20
   fi
done
# If i is less than 20, the iLO never got to a good state.
if [[ ${i} -lt 20 ]]; then echo "iLO is not in a good state" | tee -a ${LOG};mexit 5;fi
#
# Check if the server is undergoing a refresh.
j=0
CONTINUE=false
RFRSH=$(curl --silent --insecure --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-hardware/${UUID} | jq -r '.refreshState')"
while [[ ${CONTINUE} == false ]]; do
   case ${RFRSH} in
      NotRefreshing)
         echo "The server is not in a refreshing state.  Ready to proceed." | tee -a ${LOG}
         # Check the hardware state.
         STATE="$(curl --silent --insecure --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-hardware/${UUID} | jq -r '.state')"
         case ${STATE} in
            Unknown|Adding|Unmanaged|Removing|RemoveFailed|Removed|RemovingProfile|ProfileError|Unsupported)
               echo "There is a problem with the hardware state: ${STATE}" | tee -a ${LOG}
               mexit 8
               ;;
            NoProfileApplied)
               echo "A profile first needs to be applied to this server." | tee -a ${LOG}
               mexit 9
               ;;
            Monitored)
               echo "The license type for this server is incorrect.  Change it to managed." | tee -a ${LOG}
               mexit 10
               ;;
            ApplyingProfile|UpdatingFirmware)
               echo "A profile operation is currently in process, ${STATE}." | tee -a ${LOG}
               TSKURI=$(curl --silent --insecure --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-profiles/${profUUID} | jq -r '.taskUri')
               curl --silent --insecure --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}${TSKURI} | jq -r '{ "resourceName": .associatedResource.resourceName, "name": .name, "owner": .owner, "percentComplete": .percentComplete, "progressUpdates": [ .progressUpdates[] ], "stateReason": .stateReason, "taskState": .taskState }' | tee -as ${LOG}
               if [[ "$(curl --silent --insecure --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}${TSKURI} | jq -r '.taskState')" == "Completed" ]]; then
                  echo "Whatever task was running has completed.  task uri = ${TSKURI}" | tee -a ${LOG}
               else
                  echo "A profile operation is currently running.  The task uri is: ${TSKURI}." | tee -a ${LOG}
                  sleep 300
                  # If j > 3, then we've done 4 300 second loops and the task is still running.  Exit and continue with the next server.
                  if [[ ${j} -gt 3 ]]; then mexit 13;fi
               fi
               ;;
            ProfileApplied)
               echo "The hardware is in a good state to proceed." | tee -a ${LOG}
               # Check if the profile is in a normal state.
               if [[ "$(curl --silent --insecure --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-profiles/${profUUID} | jq -r '.state')" == "Normal" ]]; then
                  echo "Profile is in a good state" | tee -a ${LOG}
                  # Now check if the template compliance is NonCompliant.  If so, then the server needs updated.
                  if [[ "$(curl --silent --insecure --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}/rest/server-profiles/${profUUID} | jq -r '.templateCompliance')" == "NonCompliant" ]]; then
                     echo "Exiting from this if statement and proceeding with the update." | tee -a ${LOG}
                     CONTINUE=true
                  fi
               else
                  echo "The server profile is not in a normal state." | tee -a ${LOG}
                  mexit 3
               fi
               ;;
         esac
         ;;
      RefreshFailed)
         echo "There is a problem with the refresh state of the server: ${STATE}" | tee -a ${LOG}
         mexit 6
         ;;
      RefreshPending|Refreshing)
         echo "There is either a refresh pending, or in the works." | tee -a ${LOG}
         echo "Wait 60 seconds, then restart from the top." | tee -a ${LOG}
         sleep 60
         if [[ ${j} -gt 3 ]]; then mexit 11;fi
         ;;
   esac
   ((j++))
done
#
# Now we are ready to update the server profile.
echo "Starting to run the firmware update." | tee -a ${LOG}
DATAUP='[{"op": "replace", "path": "/templateCompliance","value": "Compliant"}]'
TASKURI=$(curl --insecure --silent --include --header "content-type: application/json" --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" \
   --data "${DATAUP}" --request PATCH ${OneView}/rest/server-profiles/${profUUID} | grep '^Location:' | awk '{ print $2 }')
TASKURI=$(echo ${TASKURI} | tr -d '\r')
echo "Watching task URI: ${TASKURI}" | tee -a ${LOG}
#
# The above will give a task uri.  Need to watch that task.
# Once it has completed, can then power on the server.
COMPLETED=0
i=1
while [[ ${COMPLETED} -eq 0 ]]; do
   if [[ "$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}${TASKURI} | jq -r '.taskState')" == "Completed" ]]; then
      COMPLETED=1
      echo "The update from template is completed." | tee -a ${LOG}
   elif [[ "$(curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}${TASKURI} | jq -r '.taskState')" == "Error" ]]; then
      echo "The update task is in an error state.  Investigate." | tee -a ${LOG}
      mexit 2
   else
      echo -n '.' | tee -a ${LOG}
      REM=$(( ${i} % 10 ))
      if [[ ${REM} -eq 0 ]]; then
         curl --insecure --silent --header "X-API-Version: ${currentVersion}" --header "auth: ${sessionID}" --request GET ${OneView}${TASKURI} | jq -r '{ "computedPercentComplete": .computedPercentComplete, "stateReason": .stateReason }' | tee -a ${LOG}
      fi
      ((i++))
      sleep 30
   fi
done
#
# The server profile update is completed.  Power the server back on.
poweron
#
# Send an exit log
echo "Sending the success e-mail."
/usr/bin/mailx -s 'Exit from upate-from-template' admin@yourplace.com < ${LOG}
/bin/rm ${LOG}
exit