DevOps with physical servers using Redfish Python api

Using the Redfish ('standard') REST api, you can command and control iDRAC enabled servers just like you would your software. Software continues to eat the world, and is coming for your hardware.
Why do we not treat our physical servers as part of our DevOps / operations processes? I think it's largely because we think its more expensive, more costly, and more complex than it is.
Today, the reality is quite different.
Code for the above:
The humble server(s)
768GB of RAM, 22-Core 44-Threads X 2 (44 total cores, 88 threads) for £66 a month. That's not a typo.

Enter DMTF Redfish - can I treat my boxes as cattle too?
DMTF’s Redfish® is a standard designed to deliver simple and secure management for converged, hybrid IT and the Software Defined Data Center (SDDC). Both human readable and machine capable, Redfish leverages common Internet and web services standards to expose information directly to the modern tool chain. Redfish
When you read Dells implementation of iDRAC-Redfish-Scripting you quickly see the opportunity to build and improve on.
Here's an example, via an REST api call, get the PowerState of your physical server (is it on or off- remember iDRAC is a form of ' Out of band management', meaning you can connect to your hardware even if the server isn't booted).
python GetSetPowerStateREDFISH.py -ip 192.168.0.120 -u root -p calvin --get
- INFO, Current server power state: On
- Supported values to set server power state:
On
ForceOff
ForceRestart
GracefulShutdown
PushPowerButton
Nmi
Today we expect a developer experience to include:
- A 'getting starting' / how to install on the first page
- JSON has won, we expect at least to be able to get an
application/json
response
For some reason the request takes over 8 seconds to complete, despite being on the same network at the physical server:
time python GetSetPowerStateREDFISH.py -ip 192.168.0.120 -u root -p calvin --get
- INFO, Current server power state: On
- Supported values to set server power state:
On
ForceOff
ForceRestart
GracefulShutdown
PushPowerButton
Nmi
real 0m8.126s
user 0m0.218s
sys 0m0.021s
Shutdown Dell server via iDRAC python API
Let's see the examples of what we can do:
python GetSetPowerStateREDFISH.py --script-examples
- GetSetPowerStateREDFISH.py -ip 192.168.0.120 -u root -p calvin --get, this example will return current server power state and possible values supported to set power state.
- GetSetPowerStateREDFISH.py -ip 192.168.0.120 -u root -p calvin --set ForceRestart, this example will set server power state to ForceRestart.
- GetSetPowerStateREDFISH.py -ip 192.168.0.120 -u root -p calvin --set ForceOff --ssl true, this example uses ssl cert validation for Redfish calls to set server power state to Off.
--script-examples
flag you can pass to python GetSetPowerStateREDFISH.py
python GetSetPowerStateREDFISH.py
. Though it does make you wonder why not have a man
page / cli validation and be done with it.Let's gracefully shutdown our Dell server using the python iDRAC api
Thanks to the examples, gracefully shutting down the physical servers is very simple also.
python GetSetPowerStateREDFISH.py -ip 192.168.0.120 -u root -p calvin --set GracefulShutdown
- INFO, setting new server power state to: GracefulShutdown
- PASS, status code 204 returned, server power state successfully set to "GracefulShutdown"
Let's make it web scale
Wrap the above in python + html, what to you get? A web console for your servers!
Naturally, I asked ChatGTP to help me with this: A web interface to turn on/off servers via the out of band management via a web based interface:
import os
import subprocess
from flask import Flask, jsonify, render_template
app = Flask(__name__)
ip_address = os.getenv("IP_ADDRESS", "192.168.0.120")
username = os.getenv("IDRAC_USERNAME", "root")
password = os.getenv("IDRAC_PASSWORD", "calvin")
@app.route("/")
def index():
return render_template("index.html")
def execute_redfish_command(action):
command = [
"python",
"GetSetPowerStateREDFISH.py",
"-ip",
ip_address,
"-u",
username,
"-p",
password,
"--set",
action,
]
result = subprocess.run(command, capture_output=True)
return (
jsonify(
{
"output": result.stdout.decode("utf-8"),
"error": result.stderr.decode("utf-8"),
}
),
result.returncode,
)
@app.route("/api/v1/On", methods=["POST"])
def set_power_on():
return execute_redfish_command("On")
@app.route("/api/v1/GracefulShutdown", methods=["POST"])
def set_power_graceful_shutdown():
return execute_redfish_command("GracefulShutdown")
if __name__ == "__main__":
app.run()
See also
There are many much more substantial projects in the area of open physical server orchestration, Tinkerbell by Equinix looks especially interesting because of it's goal(s) to "Provision and manage bare metal, anywhere" and being inspired by the Kubernetes community approach to development & community.

