Skip to content

Firmware Baseline API

Firmware Baselines

The Firmware Baseline API lets you define a desired firmware state for your servers and then check compliance and remediate drift — all through the REST API. Instead of updating firmware components one at a time, you create a baseline (a named collection of firmware binaries) and apply it to servers or entire pools in a single operation.

This is modeled after enterprise firmware management patterns (like Dell OpenManage Enterprise baselines) and follows a four-step workflow:

Catalog → Baseline → Compliance Check → Remediation
  1. Catalog — Firmware binaries already loaded into MOJO (BIOS, BMC, RAID controller, NIC, etc.)
  2. Baseline — A named collection grouping specific firmware versions for a server model
  3. Compliance — Compare each server's installed firmware against the baseline
  4. Remediation — Automatically update all non-compliant components in one request

When to use baselines vs. individual firmware updates

Use the Firmware Baseline API when you need to manage multiple firmware components across multiple servers — for example, ensuring all Dell R750s in a pool are running the same BIOS, iDRAC, and PERC versions. Use the individual firmware update endpoint when you need to push a single firmware binary to specific servers.


Baseline CRUD Endpoints

Base URL

${MOJOHOST}/api/firmware_baseline/

List All Baselines

curl -s -k \
    -H "Authorization: Bearer ${TOKEN}" \
    ${MOJOHOST}/api/firmware_baseline/

Returns all firmware baselines, ordered by most recently created.

Query Parameters:

Parameter Type Description
name string Filter by exact baseline name
search string Search across name, description

Response: 200 OK

[
    {
        "id": 1,
        "firmware_binaries": [504, 505, 506],
        "created_by": 1,
        "name": "Dell R750 Production Q1 2026",
        "description": "Production firmware baseline for Dell PowerEdge R750. Includes BIOS 1.12.2, iDRAC 6.10.80.00, and PERC H755 25.5.9.0001.",
        "created_at": "2026-01-11T11:13:05.109631Z",
        "updated_at": "2026-01-11T11:13:05.109641Z"
    },
    {
        "id": 2,
        "firmware_binaries": [507, 508],
        "created_by": 1,
        "name": "HPE DL380 Gen10 Plus",
        "description": "Production firmware baseline for HPE ProLiant DL380 Gen10 Plus.",
        "created_at": "2026-01-11T11:13:05.116218Z",
        "updated_at": "2026-01-11T11:13:05.116226Z"
    }
]

Create a Baseline

curl -s -k -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d '{
        "name": "Dell R750 Production Q1 2026",
        "description": "BIOS 1.12.2, iDRAC 6.10.80.00, PERC H755 25.5.9.0001",
        "firmware_binaries": [504, 505, 506]
    }' \
    ${MOJOHOST}/api/firmware_baseline/

Request Fields:

Field Type Required Description
name string yes Unique baseline name (max 256 characters)
description string no Free-text description
firmware_binaries int[] no List of FirmwareBinary IDs to include

The created_by field is automatically set to the authenticated user.

Response: 201 Created

{
    "id": 4,
    "firmware_binaries": [504, 505, 506],
    "created_by": 1,
    "name": "Dell R750 Production Q1 2026",
    "description": "BIOS 1.12.2, iDRAC 6.10.80.00, PERC H755 25.5.9.0001",
    "created_at": "2026-01-11T15:00:00.000000Z",
    "updated_at": "2026-01-11T15:00:00.000000Z"
}

Unique Names

Baseline names must be unique. Attempting to create a baseline with a duplicate name returns 400 Bad Request.

Get a Baseline

curl -s -k \
    -H "Authorization: Bearer ${TOKEN}" \
    ${MOJOHOST}/api/firmware_baseline/1/

Response: 200 OK — Same schema as the list response (single object).

Returns 404 Not Found if the baseline does not exist.

Update a Baseline

Use PATCH to update specific fields without affecting others:

curl -s -k -X PATCH \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d '{"description": "Updated production baseline"}' \
    ${MOJOHOST}/api/firmware_baseline/1/
curl -s -k -X PATCH \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d '{"firmware_binaries": [504, 505, 506, 511]}' \
    ${MOJOHOST}/api/firmware_baseline/1/

Firmware binaries are replaced, not appended

Setting firmware_binaries replaces the entire set. To add a new firmware binary, include all existing IDs plus the new one.

Response: 200 OK

Delete a Baseline

curl -s -k -X DELETE \
    -H "Authorization: Bearer ${TOKEN}" \
    ${MOJOHOST}/api/firmware_baseline/1/

Response: 204 No Content

This does not delete the underlying firmware binary objects — only the baseline grouping.


Compliance Checking

The compliance endpoint compares servers' currently installed firmware against the versions defined in a baseline, returning per-server, per-component status.

Check Compliance

GET ${MOJOHOST}/api/firmware_baseline/{id}/compliance/

Query Parameters:

Parameter Type Required Description
server int no Check a specific server by ID
pool int no Check all servers in a resource pool
(none) If neither is specified, checks all compatible servers

Compatible Servers

When no server or pool filter is specified, MOJO automatically finds all servers whose manufacturer and model match at least one firmware binary in the baseline. This means a "Dell R750" baseline will only check Dell R750 servers.

curl -s -k \
    -H "Authorization: Bearer ${TOKEN}" \
    "${MOJOHOST}/api/firmware_baseline/1/compliance/"
curl -s -k \
    -H "Authorization: Bearer ${TOKEN}" \
    "${MOJOHOST}/api/firmware_baseline/1/compliance/?server=42"
curl -s -k \
    -H "Authorization: Bearer ${TOKEN}" \
    "${MOJOHOST}/api/firmware_baseline/1/compliance/?pool=5"

Response: 200 OK

{
    "baseline_id": 1,
    "baseline_name": "Dell R750 Production Q1 2026",
    "servers": [
        {
            "server_id": 42,
            "server_name": "r750-node01",
            "manufacturer": "Dell",
            "model": "PowerEdge R750",
            "overall_status": "non_compliant",
            "components": [
                {
                    "firmware_binary_id": 504,
                    "firmware_type": "bios",
                    "baseline_version": "1.12.2",
                    "current_version": "1.10.0",
                    "status": "non_compliant"
                },
                {
                    "firmware_binary_id": 505,
                    "firmware_type": "bmc",
                    "baseline_version": "6.10.80.00",
                    "current_version": "6.10.80.00",
                    "status": "compliant"
                },
                {
                    "firmware_binary_id": 506,
                    "firmware_type": "storage_controller",
                    "baseline_version": "25.5.9.0001",
                    "current_version": null,
                    "status": "unknown"
                }
            ]
        }
    ],
    "summary": {
        "total_servers": 1,
        "compliant": 0,
        "non_compliant": 1,
        "unknown": 0,
        "not_applicable": 0
    }
}

Error Responses:

Code Condition
400 Invalid server or pool ID format
404 Server or pool does not exist

Compliance Statuses

Each component in the compliance response has a status field:

Status Meaning
compliant Installed firmware version matches the baseline version
non_compliant Installed firmware version differs from the baseline version
unknown No matching firmware found for this component type on the server
not_applicable The firmware binary is not compatible with this server's manufacturer/model

Overall Status Logic:

The server's overall_status is determined by the most severe component status:

  • If any component is non_compliantnon_compliant
  • If none are non_compliant but some are unknownunknown
  • If all applicable components match → compliant
  • If no components apply to the server → not_applicable

How Compliance Detection Works

The system uses different strategies depending on the firmware component type:

BIOS and BMC — Compared directly against server attributes:

  • BIOS: server.bios_version
  • BMC: server.bmc.firmware_version

Other firmware types (storage controllers, LSI, service packs) — The system searches the server's installed firmware inventory using type-specific keywords matched against the firmware name and software_id fields:

Firmware Type Match Keywords
storage_controller storage, raid, perc, storage controller, hba
lsi_3108 lsi, 3108, megaraid, sas
service_pack service pack, spp, firmware pack

Version Comparison

All version comparisons use exact string equality. For example, "1.2.0" and "1.2" are considered different versions and will be reported as non-compliant.


Remediation

Apply a Firmware Baseline

Submit a request to update all non-compliant firmware components on target servers. This creates a multi-step workflow executed through the MOJO workflow engine.

POST ${MOJOHOST}/api/requests/firmware_baseline_update/

Request Fields:

Field Type Required Description
data.baseline int yes Firmware baseline ID
data.servers int[] no* List of server IDs to remediate
data.pool int no* Resource pool ID — targets all unprotected servers in the pool
data.force_reinstall bool no Reinstall all firmware regardless of compliance. Default: false
data.force_updates bool no Force update even if BMC reports current version. Default: false

*Either servers or pool must be provided. If pool is provided and servers is omitted, all unprotected servers in the pool are targeted.

curl -s -k -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d '{
        "data": {
            "baseline": 1,
            "servers": [42, 43, 44]
        }
    }' \
    ${MOJOHOST}/api/requests/firmware_baseline_update/
curl -s -k -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d '{
        "data": {
            "baseline": 1,
            "pool": 5
        }
    }' \
    ${MOJOHOST}/api/requests/firmware_baseline_update/
curl -s -k -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d '{
        "data": {
            "baseline": 1,
            "pool": 5,
            "force_reinstall": true,
            "force_updates": true
        }
    }' \
    ${MOJOHOST}/api/requests/firmware_baseline_update/

Response: 201 Created — Returns the created request object, which can be tracked through the standard request API.

Error Responses:

Code Condition
400 Baseline has no firmware binaries defined
400 Neither servers nor pool provided
400 No unprotected servers found in the pool
400 Server is not compatible with any firmware in baseline

What Happens During Remediation

For each targeted server, the workflow engine:

  1. Runs a compliance check against the baseline to identify non-compliant components
  2. Logs current firmware versions (for audit trail)
  3. For each non-compliant component:
    • Verifies the firmware binary is downloadable and checksum-valid
    • Runs manufacturer-specific pre-steps (e.g., enter maintenance mode)
    • Flashes the firmware via Redfish and waits for completion
    • Runs manufacturer-specific post-steps (e.g., reboot if required)
  4. Logs new firmware versions (for audit trail)

All steps within a single server execute serially to respect firmware dependency ordering. Multiple servers may be processed in parallel depending on the workflow engine configuration.

If force_reinstall is true, all compatible firmware binaries are applied regardless of compliance status. Otherwise, only non-compliant components are updated.


Individual Firmware Update Endpoint

For cases where you need to update a single firmware component on one or more servers without using a baseline:

curl -s -k -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d '{
        "data": {
            "servers": [42, 43],
            "firmware": 504,
            "force_reinstall": true,
            "force_updates": false
        }
    }' \
    ${MOJOHOST}/api/requests/firmware_update/
Field Type Required Description
data.servers int[] yes List of server IDs
data.firmware int yes Single FirmwareBinary ID
data.force_reinstall bool no Reinstall even if at target version. Default: true
data.force_updates bool no Force update via BMC. Default: false

Note

This endpoint updates one firmware component at a time. To update BIOS + BMC + PERC on a server, you would need 3 separate API calls. For multi-component updates, use the firmware baseline update endpoint instead.


End-to-End Workflow: Pool-Level Firmware Update

This walkthrough demonstrates the recommended automation workflow — the same pattern you would implement in vRealize Orchestrator, Ansible, or any custom automation.

Step 1: Authenticate

export MOJOHOST="https://<your-mojo-ip>"
export TOKEN=$(curl -s -k -X POST \
    -H "Content-Type: application/json" \
    -d '{"username": "your_user", "password": "your_pass"}' \
    ${MOJOHOST}/api/token/ | jq -r '.access')

Step 2: List Available Baselines

curl -s -k \
    -H "Authorization: Bearer ${TOKEN}" \
    ${MOJOHOST}/api/firmware_baseline/ | jq '.[] | {id, name, description}'

Identify which baseline to apply based on the target server hardware.

Step 3: Check Compliance for a Pool

curl -s -k \
    -H "Authorization: Bearer ${TOKEN}" \
    "${MOJOHOST}/api/firmware_baseline/1/compliance/?pool=5" \
    | jq '{summary, non_compliant_servers: [.servers[] | select(.overall_status == "non_compliant") | {server_id, server_name, overall_status}]}'

Review which servers need updates and which components are non-compliant.

Step 4: Remediate Non-Compliant Servers

curl -s -k -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d '{"data": {"baseline": 1, "pool": 5}}' \
    ${MOJOHOST}/api/requests/firmware_baseline_update/

This submits a single request that automatically:

  • Identifies all non-compliant components on each server in the pool
  • Generates the multi-step firmware update workflow
  • Executes updates with proper pre/post steps and dependency ordering

Step 5: Monitor Progress

Track the request status through the standard request API to monitor update progress across all servers.

One API call to update an entire pool

The firmware baseline system replaces what would otherwise require dozens of individual API calls (one per firmware component per server) with a single remediation request. For a pool of 10 servers each needing 3 firmware updates, that's 1 API call instead of 30.


Data Model Reference

FirmwareBaseline

Field Type Description
id int Auto-generated primary key
name string (max 256) Unique baseline name
description string Free-text description (optional)
firmware_binaries many-to-many (FirmwareBinary) Firmware binaries defining the desired state
created_at datetime Auto-set on creation
updated_at datetime Auto-set on update
created_by foreign key (User) User who created the baseline (nullable)

FirmwareBinary (Reference)

Each firmware binary in a baseline represents one firmware component:

Field Type Description
id int Auto-generated primary key
type string bios, bmc, storage_controller, lsi_3108, service_pack
version string Target firmware version string
manufacturer string Server manufacturer (e.g., Dell, HPE, Supermicro)
models list Compatible server models (e.g., ["PowerEdge R750"])
location string URL or path to the firmware binary file

Quick Reference

Method Endpoint Description
GET /api/firmware_baseline/ List all baselines
POST /api/firmware_baseline/ Create a new baseline
GET /api/firmware_baseline/{id}/ Retrieve a specific baseline
PATCH /api/firmware_baseline/{id}/ Update a baseline
DELETE /api/firmware_baseline/{id}/ Delete a baseline
GET /api/firmware_baseline/{id}/compliance/ Check compliance (all compatible servers)
GET /api/firmware_baseline/{id}/compliance/?server={id} Check compliance for a specific server
GET /api/firmware_baseline/{id}/compliance/?pool={id} Check compliance for a pool
POST /api/requests/firmware_baseline_update/ Remediate non-compliant servers
POST /api/requests/firmware_update/ Update a single firmware component
GET /api/firmware/ List firmware binaries (catalog)
GET /api/server/{id}/firmwares/ View server's installed firmware