Skip to main content

A collection of tools for interacting with Baseboard Management Controllers (BMCs)

Project description

BMCTools

A Python library and CLI for managing Baseboard Management Controllers (BMCs) across multiple vendors. Supports Redfish, IPMI, and RACADM protocols with automatic manufacturer detection and vendor-specific extensions.

Features

  • Multi-Protocol Support: Redfish API, IPMI (via ipmitool), and RACADM (Dell)
  • Automatic Manufacturer Detection: Connects to the BMC, identifies the vendor, and loads the correct implementation
  • Vendor-Specific Implementations:
    • Dell iDRAC: Full boot management, PXE setup, NIC discovery, user roles, local access control
    • ASUS: Boot order staging via FutureState endpoint, TPM management, firmware updates
    • Supermicro: Boot order and boot option queries
    • Gigabyte (GIGA Computing): Boot management with ETag support, NIC discovery, boot-first-by-MAC
    • Cisco (CIMC/UCS): Boot management, NIC discovery, boot-first-by-MAC
  • Boot Management: Get/set boot order, list boot options, search by MAC address or alias
  • PXE Automation: Enable PXE on a NIC by MAC address, set boot order, and reboot - all in one command
  • Firmware Updates: Upload BIOS and BMC firmware via Redfish
  • Multiple Output Formats: JSON, pretty JSON, table, and plain text
  • Environment Variable Support: Configure connections via env vars for scripting

Installation

From PyPI

pip install bmctools

From Source

git clone https://github.com/jessebutryn/bmctools.git
cd bmctools
pip install -e .

Requirements

  • Python 3.9+
  • requests
  • ipmitool (optional, for IPMI commands)
  • racadm (optional, for Dell RACADM commands)

Quick Start

CLI Usage

# Set connection details via environment variables
export BMC_HOST=10.10.10.10
export BMC_USERNAME=admin
export BMC_PASSWORD=password

# Get boot order
bmctools redfish boot get-order

# Or pass connection details inline
bmctools -i 10.10.10.10 -u admin -p password redfish boot get-order

# Force a specific manufacturer (skip auto-detection)
bmctools -m dell redfish dell get-nics

Python Library Usage

from bmctools.redfish.redfish import Redfish

# Auto-detects manufacturer and loads appropriate implementation
rf = Redfish('10.10.10.10', 'admin', 'password', verify_ssl=False)
print(f"Manufacturer: {rf.manufacturer}")
print(f"System ID: {rf.system_id}")

# Get boot order
boot_order = rf.get_boot_order()

# Find a boot option by MAC address
option = rf.get_boot_option_by_mac('04:32:01:D8:C0:B0')

# Set boot order (must include ALL boot options)
rf.set_boot_order(["Boot0003", "Boot0001", "Boot0000", "Boot0002"])

Global Options

Option Env Variable Description
-i, --ip, --host BMC_HOST BMC IP address or hostname
-u, --username BMC_USERNAME BMC username
-p, --password BMC_PASSWORD BMC password
-m, --manufacturer BMC_MANUFACTURER Force manufacturer: asus, dell, supermicro, gigabyte, cisco
-k, --insecure BMC_INSECURE Disable SSL verification (default: enabled)
--secure Enable SSL verification (overrides -k)
-o, --output Output format: json, json-pretty, table, text
-v, --verbose Enable verbose output
-d, --debug Enable debug mode (show stack traces)
--no-color NO_COLOR Disable colored output
--version Show version

CLI Command Reference

Redfish Boot Management

bmctools redfish boot <command>
Command Description
get-order [--staged] Get current boot order. --staged shows pending order (ASUS).
set-order -o ORDER Set boot order. Comma-separated list (e.g., Boot0003,Boot0001,Boot0000).
set-order --order-file FILE Set boot order from a file (one entry per line).
list-options [--no-cache] List all available boot options.
find-by-mac -m MAC [--type TYPE] Find boot option by MAC address. Optional type filter (e.g., PXE).
find-by-alias -a ALIAS Find boot option by display name or alias.
get-pending Get pending boot order (ASUS FutureState endpoint).

Examples:

# Get current boot order
bmctools redfish boot get-order

# List all boot options with details
bmctools redfish boot list-options -o json-pretty

# Find the PXE boot option for a specific NIC
bmctools redfish boot find-by-mac -m 04:32:01:D8:C0:B0 --type PXE

# Set a new boot order
bmctools redfish boot set-order -o "Boot0003,Boot0001,Boot0000,Boot0002"

Redfish Firmware Management

bmctools redfish firmware <command>
Command Description
inventory Get firmware inventory (BIOS, BMC versions, etc.)
status Get update service status
update-bios -f FILE Update BIOS firmware from a local file
update-bmc -f FILE [--no-preserve-config] Update BMC firmware. Preserves config by default.

Redfish System Management

bmctools redfish system <command>
Command Description
reset [--type TYPE] Reset/reboot the system. Types: GracefulRestart, ForceRestart, ForceOff, On, etc.
reset-types List supported reset types for this system
info Get system information (manufacturer, system ID, IP)

Redfish TPM Management (ASUS)

bmctools redfish tpm <command>
Command Description
set-state --state Enabled|Disabled Set TPM state

Raw Redfish API Access

Explore any Redfish endpoint directly:

bmctools redfish raw <URI>
Command Description
raw /redfish/v1 Get Redfish service root
raw /redfish/v1/Systems List systems
raw /redfish/v1/Systems/{id} Get full system resource
raw /redfish/v1/Managers List BMC managers

Examples:

# Browse the Redfish service root
bmctools redfish raw /redfish/v1 -o json-pretty

# Inspect a specific system
bmctools redfish raw /redfish/v1/Systems/1 -o json-pretty

# Check available Redfish endpoints
bmctools redfish raw /redfish/v1/Chassis

# Explore OEM extensions
bmctools redfish raw /redfish/v1/Managers/1

Dell-Specific Commands

bmctools redfish dell <command>

NIC Discovery

Command Description
get-nics List all NICs with MAC addresses, speed, and status
get-nic-attrs -m MAC Get OEM network attributes for a specific NIC

Example:

# List all NICs and their MAC addresses
bmctools redfish dell get-nics -o json-pretty

# Get detailed attributes for a specific NIC
bmctools redfish dell get-nic-attrs -m 04:32:01:D8:C0:B0

PXE Boot Setup

Command Description
setup-pxe-boot -m MAC [--protocol PROTO] [--no-reboot] Enable PXE on a NIC and set it first in boot order. Handles the full workflow automatically.
enable-pxe -m MAC [--protocol PROTO] Enable PXE on a NIC via BIOS Settings (stages only, requires reboot).
boot-first-by-mac -m MAC [--type TYPE] Move a boot option to the front of the boot order by MAC address.

The setup-pxe-boot command is the recommended way to configure PXE boot. It handles two scenarios automatically:

Scenario 1: PXE already enabled on the NIC

  • Moves the PXE boot option to the front of the boot order
  • No reboot required
  • Returns boot_order_set: true

Scenario 2: PXE not yet enabled

  • Configures a BIOS PxeDev slot for the NIC
  • Sets one-time boot to PXE
  • Reboots the system (unless --no-reboot)
  • Returns boot_order_set: false - run boot-first-by-mac after reboot to make permanent

Example automation workflow:

# Step 1: Enable PXE and reboot if needed
result=$(bmctools redfish dell setup-pxe-boot -m 04:32:01:D8:C0:B0)

# Step 2: Check if boot order still needs to be set
boot_order_set=$(echo "$result" | jq -r '.boot_order_set')
if [ "$boot_order_set" = "false" ]; then
    # Wait for reboot to complete, then set permanent boot order
    sleep 300
    bmctools redfish dell boot-first-by-mac -m 04:32:01:D8:C0:B0 --type PXE
fi

Protocol options: IPv4 (default), IPv6, IPv4andIPv6

Boot Options

Command Description
get-boot-options [--no-cache] Get all Dell boot options
onetime-boot --source SOURCE Set one-time boot source (Pxe, Cd, Hdd, BiosSetup, None)

iDRAC Administration

Command Description
create-role --name NAME --privileges PRIVS Create an iDRAC user role with a privilege bitmask
local-access --enable|--disable Toggle local iDRAC access

IPMI Commands

Requires ipmitool to be installed on the system.

bmctools ipmi <group> <command>

Power Management

Command Description
ipmi power status Get power status
ipmi power on Power on the system
ipmi power off Power off the system
ipmi power reset Hard reset the system

BMC Management

Command Description
ipmi bmc reset-warm Warm reset the BMC
ipmi bmc reset-cold Cold reset the BMC

System Event Log

Command Description
ipmi sel list [--elist] [--raw] [--age AGE] List system event log. --age filters (e.g., 7d, 24h).

Serial Over LAN

Command Description
ipmi sol deactivate Deactivate SOL session
ipmi sol looptest [--loops N] Run SOL loopback test

Raw Commands

Command Description
ipmi raw COMMAND Execute a raw IPMI command

RACADM Commands (Dell)

Requires racadm to be installed on the system.

bmctools racadm <group> <command>
Command Description
get ENDPOINT [--format] Get configuration from an endpoint
set ENDPOINT [--args ARGS] Set configuration on an endpoint
storage get ENDPOINT Get storage configuration
storage check-vdisk [--format] Check virtual disk status
job view -j JOB_ID View job details
job status -j JOB_ID Get job status
job wait -j JOB_ID [--timeout SECS] Wait for job completion (default timeout: 300s)

Shorthand Aliases

These aliases map to the full commands for convenience:

Alias Equivalent Command
bmctools get_boot_order bmctools redfish boot get-order
bmctools set_boot_order bmctools redfish boot set-order
bmctools get_boot_options bmctools redfish boot list-options
bmctools reboot bmctools redfish system reset
bmctools update_bios bmctools redfish firmware update-bios
bmctools update_bmc bmctools redfish firmware update-bmc
bmctools get_nics bmctools redfish dell get-nics
bmctools boot_first_by_mac bmctools redfish dell boot-first-by-mac
bmctools power_on bmctools ipmi power on
bmctools power_off bmctools ipmi power off
bmctools power_status bmctools ipmi power status

Python Library Reference

Redfish Client

from bmctools.redfish.redfish import Redfish

rf = Redfish(ip, username, password, verify_ssl=False, manufacturer=None)

The manufacturer parameter is optional. If not provided, it is auto-detected from the Redfish API. Valid values: asus, dell, supermicro, gigabyte, cisco.

Common Methods (All Manufacturers)

rf.get_boot_order()                                    # -> list of boot option refs
rf.get_boot_options(nocache=False)                     # -> list of boot option dicts
rf.get_boot_option_by_mac(mac, type=None, nocache=False)  # -> boot option dict
rf.get_boot_option_by_alias(alias, nocache=False)      # -> boot option dict
rf.set_boot_order(["Boot0003", "Boot0001", ...])       # must include ALL options
rf.reset_system(reset_type=None)                       # GracefulRestart by default
rf.get_supported_reset_types()                         # -> dict with 'types' list
rf.get_firmware_inventory()                            # -> firmware version dict
rf.get_update_service_info()                           # -> update service status
rf.update_bmc_firmware(path, preserve_config=True)     # -> update status dict
rf.update_bios_firmware(path)                          # -> update status dict

Dell-Specific Methods

Access via rf.manufacturer_class:

dell = rf.manufacturer_class

# NIC discovery
dell.get_network_interfaces()              # -> list of EthernetInterface dicts
dell.get_nic_attributes('04:32:01:D8:C0:B0')  # -> OEM attributes dict

# PXE setup
dell.setup_pxe_boot(mac, protocol='IPv4', reboot=True)  # -> result with boot_order_set flag
dell.enable_nic_pxe(mac, protocol='IPv4')                # -> stages BIOS PxeDev setting
dell.set_boot_first_by_mac(mac, boot_type='PXE')         # -> moves option to front

# Boot management
dell.set_next_onetime_boot('Pxe')          # one-time boot override

# iDRAC administration
dell.create_user_group(name, privileges)   # create iDRAC role
dell.toggle_local_idrac_access(disable)    # toggle local access (inverted semantics)

ASUS-Specific Methods

asus = rf.manufacturer_class

asus.get_pending_boot_order()              # -> pending order from FutureState endpoint
asus.set_trusted_module_state('Enabled')   # TPM management

Gigabyte-Specific Methods

giga = rf.manufacturer_class

giga.get_network_interfaces()                          # -> list of EthernetInterface dicts
giga.set_boot_first_by_mac(mac, boot_type='PXE')      # -> moves option to front of boot order
giga.get_firmware_inventory()                          # -> firmware version dict

Gigabyte BMCs (AMI-based) require ETag headers on PATCH operations. This is handled automatically by the GigaFish implementation.

Cisco-Specific Methods

cisco = rf.manufacturer_class

cisco.get_network_interfaces()                         # -> list of EthernetInterface dicts
cisco.set_boot_first_by_mac(mac, boot_type='PXE')     # -> moves option to front of boot order
cisco.get_firmware_inventory()                         # -> firmware version dict

Cisco CIMC systems use serial-number-based system IDs (e.g., WZP...), which are auto-discovered.

Direct API Access

For operations not covered by the high-level interface:

rf = Redfish('10.10.10.10', 'admin', 'password')

# Raw HTTP methods
response = rf.api.get('/redfish/v1/Systems')
response = rf.api.post('/redfish/v1/...', data={...})
response = rf.api.patch('/redfish/v1/...', data={...}, headers={...})
response = rf.api.delete('/redfish/v1/...')

# File uploads
rf.api.post_file('/redfish/v1/UpdateService/upload', '/path/to/firmware.bin')
rf.api.post_multipart('/redfish/v1/UpdateService/upload', '/path/to/firmware.bin', params)

IPMI Client

from bmctools.ipmi.ipmitool import IpmiTool

ipmi = IpmiTool('10.10.10.10', 'admin', 'password')
ipmi.power_status()       # -> power status string
ipmi.power_on()
ipmi.power_off()
ipmi.power_reset()
ipmi.bmc_reset_warm()
ipmi.bmc_reset_cold()
ipmi.sel_list(elist=False, raw=False, age='7d')
ipmi.sol_deactivate()
ipmi.ipmitool_command('raw 0x06 0x01')  # arbitrary ipmitool command

RACADM Client

from bmctools.racadm.racadm import Racadm

racadm = Racadm('10.10.10.10', 'admin', 'password')
racadm.get('BIOS.SysProfileSettings')
racadm.set('BIOS.SysProfileSettings', arguments=['SysProfile=Custom'])
racadm.check_vdisk()
racadm.jobqueue_view(job_id)
racadm.jobqueue_status(job_id)
racadm.jobqueue_wait(job_id)

Architecture

Manufacturer Detection Flow

Redfish.__init__()
  -> GET /redfish/v1/Systems          (find system ID)
  -> GET /redfish/v1/Systems/{id}     (read Manufacturer field)
  -> instantiate_manufacturer_class() (load DellFish, AsusFish, SMCFish, GigaFish, or CiscoFish)

All high-level Redfish methods delegate to the manufacturer-specific class. You can also access the manufacturer class directly via rf.manufacturer_class for vendor-specific operations.

Vendor Implementation Details

Feature Dell ASUS Supermicro Gigabyte Cisco
Boot order get/set System + Settings endpoint FutureState (SD) with ETag Systems/1 Systems/{id} with ETag Systems/{id}
Boot option search by MAC RelatedItem link traversal UEFI device path parsing Not implemented UEFI device path parsing UEFI device path parsing
Boot-first-by-MAC Yes N/A N/A Yes Yes
Firmware inventory Not yet implemented Multipart upload Not yet implemented FirmwareInventory FirmwareInventory
PXE management BIOS PxeDev attributes N/A N/A N/A N/A
NIC discovery EthernetInterfaces EthernetInterfaces N/A EthernetInterfaces EthernetInterfaces
TPM management N/A OEM endpoint with ETag N/A N/A N/A

Manufacturer Detection Strings

The following strings are matched (case-insensitive) from the Redfish Manufacturer field:

Manufacturer Matched Strings
Dell dell, dell inc.
ASUS asus, asustekcomputerinc., asustek computer inc.
Supermicro supermicro
Gigabyte gigabyte, giga computing
Cisco cisco, cisco systems inc, cisco systems inc.

Caching

Boot options are cached after the first retrieval to minimize API calls. Use nocache=True to force a fresh query:

options = rf.get_boot_options()             # cached
options = rf.get_boot_options(nocache=True)  # fresh query

Exit Codes

Code Meaning
0 Success
1 General error
2 Connection error
3 Feature not implemented for this manufacturer
4 Invalid arguments
5 File not found
6 Operation timeout

Development

Docker Build

make build    # Build the Docker image
make shell    # Launch a shell in the container

The Docker build uses --platform linux/amd64 for compatibility with vendor tools.

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Submit a pull request

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

Author

Jesse Butryn

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bmctools-0.1.9.tar.gz (84.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bmctools-0.1.9-py3-none-any.whl (93.5 kB view details)

Uploaded Python 3

File details

Details for the file bmctools-0.1.9.tar.gz.

File metadata

  • Download URL: bmctools-0.1.9.tar.gz
  • Upload date:
  • Size: 84.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bmctools-0.1.9.tar.gz
Algorithm Hash digest
SHA256 0a60362131c6a445309a8e5f49e241450f5d9f3fd2f44b25ee6fcde2f0872f44
MD5 2d41b6db2abfada3aff64d4eae9f9826
BLAKE2b-256 18662cd1d6606e5a2f6c52f42851209bdbc063abb35b6434c6e57c3400592f46

See more details on using hashes here.

Provenance

The following attestation bundles were made for bmctools-0.1.9.tar.gz:

Publisher: publish.yml on jessebutryn/bmctools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bmctools-0.1.9-py3-none-any.whl.

File metadata

  • Download URL: bmctools-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 93.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bmctools-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 6d08f929af8f5ffc7ebe734aebd32e2b109d5a6ea752ceb6030cedce0450426b
MD5 876ba08d09519b3b136f43256d12f0c3
BLAKE2b-256 53a62b07b00e40e714890f9d86d48b51a72a86135ff20d40df371c1b2f8b837b

See more details on using hashes here.

Provenance

The following attestation bundles were made for bmctools-0.1.9-py3-none-any.whl:

Publisher: publish.yml on jessebutryn/bmctools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page