feat: add manage:list-backends command with cleanup verdicts - #111
Conversation
There was a problem hiding this comment.
Pull request overview
Adds read-only backend inventory and cleanup verdicts for stack maintenance.
Changes:
- Adds table/CSV backend reporting with filters and summaries.
- Registers the new CLI command.
- Documents usage, verdicts, and output fields.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/Keboola/Console/Command/ListStorageBackends.php |
Implements inventory and cleanup verdicts. |
cli.php |
Registers the command. |
README.md |
Documents command usage and behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| $this->renderTable($output, $visibleRows); | ||
| } | ||
|
|
||
| $this->renderSummary($output, $rows, $format === self::FORMAT_CSV); |
There was a problem hiding this comment.
Bug: renderSummary() receives the unfiltered $rows, so with --verdict/--unsupported the summary counts and the paste-ready "Delete candidates" ID lists ignore the filter — the table above shows filtered rows, but the ID list still covers all backends. Since this output is meant to be pasted into manage:delete-backend, an operator can end up deleting backends outside the scope they filtered for. Total backends: N also contradicts the number of rows shown. Pass $visibleRows to renderSummary() (or apply the same filter inside).
There was a problem hiding this comment.
Opraveno v e9d0fca — summary i paste-ready ID listy se počítají z viditelných (filtrovaných) řádků; při aktivním filtru hlavička říká Backends shown: X of Y (filters active — summary and ID lists cover the shown rows only). Regresní test testSummarizeOnFilteredRowsCoversOnlyThoseRows.
Read-only inventory of a stack's storage backends. Fetches the detail of every backend to include loginType, keyPairLastRotatedAt, SSO and dynamic backend flags, assigns a cleanup verdict per backend and prints ID lists ready for manage:delete-backend. Used for the DMD-1638 prod cleanup. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A failed per-backend detail call previously degraded silently — the detail-added columns (loginType, keyRotated, SSO, dynBackends) rendered empty with no signal to the operator. Now the affected backend IDs are printed as a stderr warning. Counts and verdicts are unaffected: they come from the list response. Also adds timeout/connect_timeout to the Guzzle client so one unresponsive backend cannot hang the whole scan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… bugs - Extract row/verdict/filter/summary logic into StorageBackendInventory (plain class, unit-tested — 24 new tests) so the command does I/O only. - Fix: summary and paste-ready delete ID lists now cover the displayed (filtered) rows only; header shows 'Backends shown: X of Y'. - Fix: --verdict is validated against the known verdicts instead of silently matching nothing. - Fix: CSV output uses fputcsv and OUTPUT_RAW so cell values cannot be mangled by the console formatter. - Skip list entries without a usable numeric id (stderr warning) instead of coercing them to id 0. - Fetch detail only for displayed rows, with retry middleware (3 attempts, 429/5xx/connect) on the Guzzle client; declare guzzlehttp/guzzle as a direct dependency. The raw Guzzle detail call stays for now: Client::getStorageBackend() exists only since manage-api client v9 and this repo locks ^7 — bumping to v10 raises repo-wide phpstan errors from 8 to 236 (typed signatures across ~20 commands), which belongs in a separate PR. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the raw Guzzle detail workaround with the SDK method (added in client v9) — the client brings its own exponential backoff, so the custom retry middleware and HTTP plumbing are gone. The typed v10 signatures surface 234 pre-existing phpstan findings in legacy commands (offset access / casts on now-explicit mixed). Those are captured in phpstan-baseline.neon so new code stays checked at level 9 while cleaning up 22 operator commands stays out of this PR's scope. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
50d8fec to
9497c67
Compare
Changes:
manage:list-backendscommand — read-only inventory of a stack's storage backends with a cleanup verdict per backend (DELETE_UNSUPPORTED_UNUSED/DELETE_UNUSED/REVIEW_UNSUPPORTED_IN_USE/REVIEW_MAINTAINER_ONLY/KEEP). Prints comma-separated ID lists ready to paste intomanage:delete-backend.GET /manage/storage-backend/{id}) to add columns missing from the list response:loginType,keyRotated,dynBackends,useSso,ssoEnabled,ssoConfigured.--format=table|csv(CSV keeps stdout parseable, summary goes to stderr),--verdict=Xand--unsupportedfilters; summary is always computed over the whole stack.cli.php, documented in README.Used for the DMD-1638 prod backend cleanup — drove the inventory and keypair review of all 14 prod stacks.
Additional notes
🤖 Generated with Claude Code