Document the PHP api layer and fix what documenting it exposed
Writing down what each endpoint actually guarantees made the places it didn't obvious — shell arguments reaching a crontab or a bash -c unescaped, master.conf written without tmp+rename, and conf edits that could be saved without ever being parsed.
This commit is contained in:
@@ -1,6 +1,80 @@
|
||||
<?php
|
||||
// Diagnostic endpoint — tests the Unraid GraphQL API and returns raw results.
|
||||
// Hit from browser: /plugins/varaverk/api/api_test.php
|
||||
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
||||
// PURPOSE
|
||||
// Unraid GraphQL API diagnostic. Reports whether this host has a usable API key, what the
|
||||
// PHP environment can do, and what the API actually answers — including live schema
|
||||
// introspection for the types the monitor layer depends on.
|
||||
//
|
||||
// OPERATIONAL MODEL
|
||||
// A hand-run tool, not part of any page. Nothing in the UI links here; it is opened
|
||||
// directly at /plugins/varaverk/api/api_test.php when the monitor page starts showing
|
||||
// degraded detail and the question is whether the API, the key, or the parsing is at fault.
|
||||
//
|
||||
// It exists because that question was expensive to answer. The Unraid API renamed and
|
||||
// removed types between 7.2.5 and 7.3 — ArrayParity and ArrayCache stopped being distinct
|
||||
// types — and the only reliable way to know what the running version exposes is to ask it.
|
||||
//
|
||||
// DESIGN PRINCIPLES
|
||||
// Reports the environment before the result.
|
||||
// Key presence, curl availability and allow_url_fopen are answered first, because a
|
||||
// failed probe means something entirely different depending on those three.
|
||||
//
|
||||
// Two transports, same query.
|
||||
// curl when available, a stream context otherwise. The fallback exists so the
|
||||
// diagnostic still returns something on a PHP build where the probe's failure would
|
||||
// otherwise be indistinguishable from the API being down.
|
||||
//
|
||||
// Returns raw alongside decoded.
|
||||
// probe_raw carries the first 1000 bytes verbatim. When the response is not JSON — an
|
||||
// HTML error page, a proxy interception — the decoded field is null and the raw text is
|
||||
// the only thing that explains why.
|
||||
//
|
||||
// Introspects the specific types the monitor layer reads.
|
||||
// Not a full schema dump. The named type lists are the ones whose field names the
|
||||
// collectors depend on, so a rename shows up here as a missing field rather than as a
|
||||
// quietly empty card on the monitor page.
|
||||
//
|
||||
// Pretty-printed on purpose. The only consumer is a person reading it in a browser tab.
|
||||
//
|
||||
// OPERATIONAL SAFEGUARDS
|
||||
// Read-only. Every query is a read or an introspection; nothing here mutates array, docker,
|
||||
// or VM state through the API.
|
||||
//
|
||||
// Every request is time-boxed.
|
||||
// 5s with a 3s connect timeout on the probe, 8s on each introspection call. A hung or
|
||||
// unreachable API returns a diagnostic rather than becoming one.
|
||||
//
|
||||
// The whole probe is skipped without a key, and reports that as the finding.
|
||||
// key_present is false and probe stays null. The absence of a key is the most common
|
||||
// answer this tool gives, and it is reported as a result rather than as a failure.
|
||||
//
|
||||
// Localhost only. The endpoint is hardcoded to http://localhost/graphql — no part of the
|
||||
// request selects a target, so this cannot be used to probe another host.
|
||||
//
|
||||
// The key is truncated in the response.
|
||||
// Only the first 8 characters are returned, as key_prefix — enough to confirm which key
|
||||
// is in use, not enough to use it.
|
||||
//
|
||||
// Known exposure: this returns more than a normal endpoint should.
|
||||
// A key prefix, the cached API debug log, and the live schema are all visible to anyone
|
||||
// with a WebGUI session. That is acceptable for a diagnostic reachable only by typing
|
||||
// its URL, but it is the reason it is not linked from any page and should not be
|
||||
// wrapped in one. See the CSRF note in README-unraid.md for the session-only guard this
|
||||
// shares with the rest of the api layer.
|
||||
//
|
||||
// REQUEST
|
||||
// GET, no parameters
|
||||
//
|
||||
// RESPONSE
|
||||
// {"host","key_present","key_prefix","curl_available","allow_url_fopen","debug_log",
|
||||
// "probe":{"url","http_code","curl_err","decoded"},"probe_raw",
|
||||
// "schema","pool_drives","schema2"}
|
||||
// The schema, pool_drives and schema2 keys are present only when a key exists.
|
||||
//
|
||||
// DEPENDS ON
|
||||
// include/config.php vv_detect_host(), vv_conf_vars(), VV_CACHE_DIR
|
||||
// Unraid API http://localhost/graphql
|
||||
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
||||
header('Content-Type: application/json');
|
||||
require_once dirname(__DIR__) . '/include/config.php';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user