Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions python/understack-workflows/understack_workflows/ironic_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,38 @@ class NodeInterface:

logger = logging.getLogger(__name__)

# Substrings of patch/update paths whose values must never be logged.
_SENSITIVE_PATH_FRAGMENTS = ("password", "secret", "token")
_REDACTED = "***REDACTED***"


def _is_sensitive(path: str) -> bool:
path = path.lower()
return any(fragment in path for fragment in _SENSITIVE_PATH_FRAGMENTS)


def _redact_patches(patches: Sequence[dict]) -> list[dict]:
"""Return a copy of JSON-patch operations with sensitive values redacted."""
redacted = []
for patch_op in patches:
if isinstance(patch_op, dict) and _is_sensitive(str(patch_op.get("path", ""))):
redacted.append({**patch_op, "value": _REDACTED})
else:
redacted.append(patch_op)
return redacted


def _redact_updates(updates: Sequence[str]) -> list[str]:
"""Return a copy of "path=value" update strings with sensitive values redacted."""
redacted = []
for update in updates:
path, sep, _ = str(update).partition("=")
if sep and _is_sensitive(path):
redacted.append(f"{path}={_REDACTED}")
else:
redacted.append(update)
return redacted


def create_or_update(
bmc: Bmc,
Expand Down Expand Up @@ -127,7 +159,11 @@ def update_ironic_node(
updates.append(f"extra/external_cmdb_id={external_cmdb_id}")

patches = args_array_to_patch("add", updates)
logger.info("Updating Ironic node %s patches=%s", ironic_node.uuid, patches)
logger.info(
"Updating Ironic node %s patches=%s",
ironic_node.uuid,
_redact_patches(patches),
)

client.update_node(ironic_node.uuid, patches)
logger.debug("Ironic node %s Updated.", ironic_node.uuid)
Expand Down Expand Up @@ -213,7 +249,7 @@ def transition(
def patch(node: Node, updates: Sequence[str]) -> None:
if not updates:
return
logger.info("%s updating node %s", node.uuid, list(updates))
logger.info("%s updating node %s", node.uuid, _redact_updates(updates))
IronicClient().update_node(node.uuid, args_array_to_patch("add", list(updates)))


Expand Down
Loading