#!/usr/bin/python3 import argparse import configparser import os import sys import urllib3 import redfish from datetime import datetime def log(message, is_error=False): """Print message with timestamp""" timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") if is_error: print(f"[{timestamp}] {message}", file=sys.stderr) else: print(f"[{timestamp}] {message}") # Suppress SSL warnings for self-signed iLO certificates urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) parser = argparse.ArgumentParser(description="Power off an HPE server via iLO Redfish") parser.add_argument("hostname", help="iLO hostname or IP address") parser.add_argument("-c", "--credentials", default="/etc/ilo_credentials", help="Path to credentials file (default: /etc/ilo_credentials)") args = parser.parse_args() # Read credentials from file (chmod 600 recommended: sudo chmod 600 /etc/ilo_credentials) # File format: # [ilo] # username = root # password = yourpassword cred_path = args.credentials if not os.path.exists(cred_path): log(f"Error: credentials file not found: {cred_path}", is_error=True) sys.exit(1) config = configparser.ConfigParser() config.read(cred_path) try: LOGIN_ACCOUNT = config.get("ilo_credentials", "username", fallback="root") LOGIN_PASSWORD = config.get("ilo_credentials", "password") except (configparser.NoSectionError, configparser.NoOptionError) as e: log(f"Error reading credentials file: {e}", is_error=True) sys.exit(1) BASE_URL = f"https://{args.hostname}" REDFISHOBJ = redfish.RedfishClient( base_url=BASE_URL, username=LOGIN_ACCOUNT, password=LOGIN_PASSWORD, ) REDFISHOBJ.login(auth="session") # Discover the correct reset action URI from the system resource sys_response = REDFISHOBJ.get("/redfish/v1/Systems/1/") reset_uri = sys_response.dict["Actions"]["#ComputerSystem.Reset"]["target"] body = {"ResetType": "PushPowerButton"} # iLO 4: PushPowerButton = graceful shutdown; use "ForceOff" for hard power cut response = REDFISHOBJ.post(reset_uri, body=body) log(f"Status: {response.status}") if response.status >= 400: log(f"Error: {response.read}", is_error=True) REDFISHOBJ.logout()