- ipmi: a failed logout on close is logged at debug level instead of passed over (B110); the session still times out on the BMC. - ipmi: the pyghmi imports are this driver's protocol, the fallback for BMCs without Redfish, documented as insecure in the module and in docs/security.md (nosec B415). - parsers.accounts: the empty password is NAPALM's get_users field; Redfish never returns one (nosec B105).
43 lines
1.5 KiB
Python
43 lines
1.5 KiB
Python
"""AccountService accounts (``AccountService/Accounts/*``)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Iterable, Mapping
|
|
from typing import Any
|
|
|
|
from .common import boolean, text
|
|
|
|
# Privilege level for NAPALM's get_users, from the Redfish standard roles.
|
|
ROLE_LEVELS = {"Administrator": 15, "Operator": 5, "ReadOnly": 1}
|
|
|
|
|
|
def parse_account(account: Mapping[str, Any]) -> dict[str, Any] | None:
|
|
"""One account; ``None`` for an unused slot (no UserName), as iDRAC and Supermicro list."""
|
|
username = text(account.get("UserName"))
|
|
if username is None:
|
|
return None
|
|
types = account.get("AccountTypes")
|
|
return {
|
|
"id": text(account.get("Id")),
|
|
"username": username,
|
|
"role_id": text(account.get("RoleId")),
|
|
"enabled": boolean(account.get("Enabled")),
|
|
"locked": boolean(account.get("Locked")),
|
|
"account_types": [str(t) for t in types] if isinstance(types, list) else [],
|
|
}
|
|
|
|
|
|
def to_napalm_users(accounts: Iterable[Mapping[str, Any] | None]) -> dict[str, dict[str, Any]]:
|
|
"""NAPALM ``get_users`` from parsed accounts. Unknown (OEM) roles get level 0."""
|
|
users = {}
|
|
for acc in accounts:
|
|
if not acc:
|
|
continue
|
|
users[acc["username"]] = {
|
|
"level": ROLE_LEVELS.get(acc.get("role_id") or "", 0),
|
|
# NAPALM's get_users field; Redfish never returns a password, so it stays empty.
|
|
"password": "", # nosec B105
|
|
"sshkeys": [],
|
|
}
|
|
return users
|