Source code for saltext.bmc.modules.bmc_redfish
"""
Low-level Redfish HTTP passthrough.
Bypasses the backend abstraction in :mod:`saltext.bmc.modules.bmc` to let
operators read or write any Redfish endpoint directly. Useful for
ad-hoc inspection, vendor-specific OEM extensions, and one-off
operations that the high-level module does not cover.
This module is Redfish-only. If the profile's ``backend`` is set to
``ipmi``, calls raise :class:`~saltext.bmc.utils.redfish.RedfishError`
immediately.
CLI examples (``path`` is the first positional arg; pass the profile via
``name=``)::
salt-call --local bmc_redfish.get /redfish/v1/ name=bmc-host-01
salt-call --local bmc_redfish.get /redfish/v1/Systems name=bmc-host-01
salt-call --local bmc_redfish.patch /redfish/v1/Systems/1 \\
body='{"AssetTag": "rack-7-slot-3"}' name=bmc-host-01
salt-call --local bmc_redfish.post \\
/redfish/v1/Systems/1/Actions/ComputerSystem.Reset \\
body='{"ResetType": "On"}' name=bmc-host-01
"""
from __future__ import annotations
import logging
from saltext.bmc.utils import redfish as rf
log = logging.getLogger(__name__)
__virtualname__ = "bmc_redfish"
def __virtual__():
return __virtualname__
def _require_redfish(name: str | None, conn: dict) -> None:
"""Raise if the resolved profile uses a non-Redfish backend."""
cfg = rf.resolve_conn(__opts__, name=name, **conn)
backend = (cfg.get("backend") or "redfish").lower()
if backend == "ipmi":
raise rf.RedfishError(
f"Profile {name!r} uses backend={backend!r}; bmc_redfish.* requires Redfish."
)
def _client(name: str | None, conn: dict) -> rf.RedfishClient:
_require_redfish(name, conn)
return rf.open_client(__opts__, name=name, **conn)
[docs]
def get(path: str, name: str | None = None, **conn) -> dict:
"""
Raw Redfish GET.
:param str path: Redfish path (must start with ``/redfish/v1/``).
:param str name: Profile name; falls back to top-level config.
CLI Example:
.. code-block:: bash
salt-call --local bmc_redfish.get /redfish/v1/Systems name=bmc-host-01
"""
with _client(name, conn) as client:
return client.get(path)
[docs]
def post(path: str, name: str | None = None, body: dict | None = None, **conn) -> dict | None:
"""
Raw Redfish POST.
:param str path: Redfish action path.
:param dict body: Request body (optional for some Redfish actions).
:param str name: Profile name.
CLI Example:
.. code-block:: bash
salt-call --local bmc_redfish.post \\
/redfish/v1/Systems/1/Actions/ComputerSystem.Reset \\
body='{"ResetType": "On"}' name=bmc-host-01
"""
with _client(name, conn) as client:
return client.post(path, body)
[docs]
def patch(path: str, body: dict, name: str | None = None, **conn) -> dict | None:
"""
Raw Redfish PATCH.
:param str path: Redfish resource path.
:param dict body: Request body (required).
:param str name: Profile name.
CLI Example:
.. code-block:: bash
salt-call --local bmc_redfish.patch /redfish/v1/Systems/1 \\
body='{"AssetTag": "rack-7-slot-3"}' name=bmc-host-01
"""
with _client(name, conn) as client:
return client.patch(path, body)
[docs]
def delete(path: str, name: str | None = None, **conn) -> dict | None:
"""
Raw Redfish DELETE.
:param str path: Redfish resource path.
:param str name: Profile name.
CLI Example:
.. code-block:: bash
salt-call --local bmc_redfish.delete \\
/redfish/v1/SessionService/Sessions/3 name=bmc-host-01
"""
with _client(name, conn) as client:
return client.delete(path)