Decouple resources overview from chorus - #118
pjcdawkins merged 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the legacy CLI metrics flow to obtain the “resources overview” URL via the environment’s /observability/ entrypoint response, rather than relying on the #observability-pipeline link (decoupling the overview lookup from chorus-specific linkage).
Changes:
- Replace
#observability-pipelinelink usage with a GET to{environmentUri}/observability/to discover_links.resources_overview.href. - Adjust return docstring to reflect returning a URL (or
false) when unavailable.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
45ce22e to
908b343
Compare
pjcdawkins
left a comment
There was a problem hiding this comment.
Reviewed. The change itself is sound: I checked the happy path against the live API and the observability/ entrypoint returns an absolute href and responds 200 for inactive and paused environments, so the discovery works. The earlier Copilot points (404-only handling, the is_array() guard) are addressed in 908b343. All four checks pass.
Nothing here is blocking. There is one question that needs a maintainer decision rather than a code fix, and three smaller items.
The decision: host trust
MetricsCommandBase.php:135 follows the returned href verbatim with the OAuth-authenticated client, with no host check. Two pieces of context that make this worth an explicit call rather than a nit:
vendor/platformsh/oauth2/src/GuzzleMiddleware.php:181-185attaches the bearer token to every request made throughApi::getHttpClient(), regardless of host.ApiResourceBase::makeAbsoluteUrl()(vendor/platformsh/client/src/Model/ApiResourceBase.php:568-581) deliberately overrides an absolute link host with the resource's base host, specifically so that link hrefs cannot redirect requests elsewhere.
So the client library has an existing guard for exactly this pattern, and this code path sits outside it: the entrypoint is fetched from the region and the host it returns is then trusted for a token-bearing request. There is precedent for following body-supplied hrefs (TeamListCommand.php:187), so this is hardening rather than a new class of issue — but it is a region-to-central-API hop, so it should be a deliberate choice.
Smaller items
MetricsCommandBase.php:135— the href ismixedwhile the method declaresfalse|string. Underdeclare(strict_types=1)a non-string href raises aTypeErrorinstead of taking the handled "not available" path. PHPStan will not catch this below level 9 (checkExplicitMixedis off, and there is no baseline entry for this file). Foldingis_string(...)into the existing guard covers it.MetricsCommandBase.php:169— the query string is still appended by concatenation, but the URL is now server-controlled. An href carrying its own query would produce...?view=default?range=600. Latent today since the current response has no query part; building the request with Guzzle'squeryoption would remove the class of problem.MetricsCommandBase.php:117— one extra serial, uncached round trip per metrics invocation, and a transient 5xx on the entrypoint now aborts the command even when the metrics endpoint itself is healthy. The URL is stable per environment andApialready has a cache.
Tests
None added. For context rather than criticism: legacy/tests/ has no Command/Metrics/ coverage and no Guzzle MockHandler infrastructure at all, so this matches existing practice rather than regressing it. The new branching is pure logic and would be testable if the discovery were extracted out of the private method.
One thing I did not check: whether the observability entrypoint is present for every region and vendor this binary ships to. The fallback is "metrics not available", so it is worth confirming on the rollout side.
Review by Claude Code.
Resolve conflicts with the --latest fix (#165) and the observability entrypoint lookup (#118): - MetricsCommandBase: keep both STORAGE_MOUNTPOINT and LATEST_SETTLE_TIME. - Move the storage tests to metrics_storage_test.go, next to the --latest tests in metrics_test.go. - Serve the observability entrypoint (_links.resources_overview) in both tests' mocks, as the resources overview URL is now discovered there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since #118, the metrics commands find the resources overview URL via the "resources_overview" link from GET {environment}/observability/, instead of the environment's "#observability-pipeline" link. TestMetricsLatest (#165) was written against the old lookup, so it failed on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#167) Since #118, the metrics commands discover the resources overview URL via GET {environment}/observability/ instead of the #observability-pipeline link. TestMetricsLatest (#165) still mocked the old link, so the CLI got a 404 and failed with "Observability API link not found". Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… plans (#50) * fix: Clarify why certain functions are not available for upsun fixed * Update error message for unsupported API usage * fix(legacy): mention Upsun Fixed only for projects in Fixed organizations The "flexible resources API is not enabled" error is shared by all the resources:* commands, so move it to ResourcesUtil and use it everywhere instead of only in resources:build:get. A disabled sizing API does not by itself mean the project is on Upsun Fixed, so the Fixed note is now only shown when the project's organization has the "fixed" type. If the organization cannot be loaded (e.g. the user has no access to it), the note is skipped. The docs link uses the docs.upsun.com/anchors/fixed/ redirect, like other Fixed links in the CLI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(metrics): mock the observability entrypoint in TestMetricsLatest Since #118, the metrics commands find the resources overview URL via the "resources_overview" link from GET {environment}/observability/, instead of the environment's "#observability-pipeline" link. TestMetricsLatest (#165) was written against the old lookup, so it failed on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(legacy): configure the Fixed docs URL and avoid extra API calls Address review feedback on the sizing API error: - Read the docs link from a new service.fixed_docs_url config key, and drop the "Upsun" brand from the message, so vendor builds without the key show no Fixed note. - Skip the organization lookup when api.organizations is disabled. - Read the project's organization without lazy loading, so a missing property cannot trigger an uncaught API request. - Assert on the note and URL in the test, rather than any "fixed" text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Matthias Van Woensel <3532563+matthiaz@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Migrated from platformsh/legacy-cli#1596.