Files
computer-playbook/utils/kcadm_json.py
kevinveenbirkenbachandClaude Fable 5 15a8d26ea4 fix(keycloak): move kcadm module and helper to global library paths
Role-local library/ and module_utils/ resolve only inside the owning
role's task scope, so kcadm update tasks invoked from other contexts
in the swarm flow could not find keycloak_kcadm_update. ansible.cfg
already declares ./library and ./utils as the global paths; the filter
plugin and unit tests follow the move. Helper narrows its parse guard
to ValueError.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00

48 lines
1.3 KiB
Python

from __future__ import annotations
import json
from typing import Any
def json_from_noisy_stdout(text: Any) -> Any:
"""
Parse JSON from output that may contain leading non-JSON noise, including
lines that start with '[' (e.g. JVM warnings like "[0.001s][warning]...").
Deterministic strategy:
- scan for all occurrences of '[' and '{' in the output
- attempt json.loads() starting from each occurrence (in order)
- return the first successfully parsed JSON value
- raise ValueError if none work
"""
if text is None:
raise ValueError("No output (None)")
s = str(text).lstrip()
if not s:
raise ValueError("Empty output")
candidates = []
for ch in ("[", "{"):
start = 0
while True:
idx = s.find(ch, start)
if idx == -1:
break
candidates.append(idx)
start = idx + 1
candidates = sorted(set(candidates))
if not candidates:
raise ValueError("No JSON start delimiter found")
last_err: Exception | None = None
for idx in candidates:
chunk = s[idx:].strip()
try:
return json.loads(chunk)
except ValueError as e:
last_err = e
raise ValueError(f"Failed to parse JSON from noisy stdout: {last_err}")