r024: compact Docker inspect output

This commit is contained in:
Mikei386
2026-08-25 16:02:02 +02:00
parent 6876e495d6
commit 8977ced7cf
10 changed files with 84 additions and 31 deletions
+16 -7
View File
@@ -197,7 +197,7 @@ function sanitize_log_output(string $text, int $max_chars = 50000): string {
/**
* Kompakte Container-Inspect-Ausgabe.
*/
function compact_container_inspect(string $raw): string {
function compact_container_inspect(string $raw, string $detail = 'summary'): string {
$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE || !is_array($data)) {
return $raw;
@@ -218,17 +218,26 @@ function compact_container_inspect(string $raw): string {
'Image' => $data['Config']['Image'] ?? '',
'NetworkMode' => $data['HostConfig']['NetworkMode'] ?? '',
'Ports' => $data['NetworkSettings']['Ports'] ?? [],
'Env' => $data['Config']['Env'] ?? [],
'Mounts' => array_map(function ($m) {
'RestartCount' => $data['RestartCount'] ?? 0,
'Created' => $data['Created'] ?? '',
];
if ($detail === 'full') {
$compact['Env'] = array_map(function ($entry) {
if (!is_string($entry) || !str_contains($entry, '=')) return $entry;
[$name, $value] = explode('=', $entry, 2);
if (preg_match('/(KEY|TOKEN|SECRET|PASS|AUTH|COOKIE|ARL)/i', $name)) {
return $name . '=<redacted>';
}
return $name . '=' . $value;
}, $data['Config']['Env'] ?? []);
$compact['Mounts'] = array_map(function ($m) {
return [
'Type' => $m['Type'] ?? '',
'Source' => $m['Source'] ?? '',
'Destination' => $m['Destination'] ?? '',
];
}, $data['Mounts'] ?? []),
'RestartCount' => $data['RestartCount'] ?? 0,
'Created' => $data['Created'] ?? '',
];
}, $data['Mounts'] ?? []);
}
return json_encode($compact, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
+18
View File
@@ -68,6 +68,24 @@ try {
check('container_runtime_summary() funktioniert', false, $e->getMessage());
}
// ── 3b. Kompakte Inspect-Ausgabe ─────────────────────────────────────────
$fixture = json_encode([[
'Id' => str_repeat('a', 64),
'Name' => '/test',
'State' => ['Status' => 'running', 'Running' => true, 'Pid' => 42, 'ExitCode' => 0],
'Config' => ['Image' => 'example:latest', 'Env' => ['SECRET=value']],
'HostConfig' => ['NetworkMode' => 'bridge'],
'NetworkSettings' => ['Ports' => []],
'Mounts' => [['Type' => 'bind', 'Source' => '/secret', 'Destination' => '/data']],
'RestartCount' => 0,
'Created' => 'now',
]]);
$summaryInspect = json_decode(compact_container_inspect($fixture), true);
$fullInspect = json_decode(compact_container_inspect($fixture, 'full'), true);
check('Inspect summary laesst Env aus', !isset($summaryInspect['Env']) && !isset($summaryInspect['Mounts']));
check('Inspect full enthaelt Env und Mounts', isset($fullInspect['Env']) && isset($fullInspect['Mounts']));
check('Inspect full maskiert Secrets', ($fullInspect['Env'][0] ?? '') === 'SECRET=<redacted>');
// ── 4. Netzwerk-Inventur ─────────────────────────────────────────────────
echo "\n[4] Netzwerk-Inventur\n";
try {
+5 -1
View File
@@ -95,8 +95,12 @@ function call_tool(string $name, array $args): string {
case 'unraid_docker_inspect':
$container = validate_name($args['container'] ?? null, 'container');
$detail = $args['detail'] ?? 'summary';
if (!in_array($detail, ['summary', 'full'], true)) {
throw new InvalidArgumentException('detail must be summary or full');
}
$raw = docker_exec("inspect --type container -- $container");
return compact_container_inspect($raw);
return compact_container_inspect($raw, $detail);
case 'unraid_docker_logs':
$container = validate_name($args['container'] ?? null, 'container');
+3 -1
View File
@@ -27,13 +27,15 @@ function mua_tools(): array {
],
[
'name' => 'unraid_docker_inspect',
'description' => 'Inspect a single Docker container in detail (state, image, ports, env, mounts).',
'description' => "Inspect one known Docker container directly. Default summary returns state, image, network mode and ports only; request detail='full' only when environment variables or mounts are required.",
'inputSchema' => [
'type' => 'object',
'properties' => [
'container' => ['type' => 'string', 'description' => 'Container name or ID'],
'detail' => ['type' => 'string', 'enum' => ['summary', 'full'], 'description' => "Use 'summary' by default. 'full' additionally returns redacted environment and mounts."],
],
'required' => ['container'],
'additionalProperties' => false,
],
],
[