A vSphere 6.x target fails the connect test at the Automation session
step with a generic "HTTP 500" message, because /api on those releases
routes to the JSON-RPC servlet. When /api/session fails with a non-auth
status, probe the legacy /rest CIS session API with the same
credentials; if that login works the target predates the JSON APIs
Pulse uses, so the test now reports the unsupported-version warning
naming the vCenter 8.0U1 floor instead of pointing at credentials. The
probe deletes the session it creates. Also reword the frontend guidance
for that category in plain terms.
Related to #1585.
Update checks against registries without a hardcoded token endpoint
(lscr.io and other spec-compliant registries) failed with a blanket
"Check failed" because the manifest HEAD went out anonymously and the
401 was terminal. Parse the Bearer challenge on the 401, fetch a pull
token from the advertised realm, and retry once. Token endpoints that
answer with access_token instead of token are now accepted too.
Fixes#1583.
Adds branch-coverage unit tests for previously uncovered pure functions in
internal/monitoring and internal/ai/tools. New test files only, with no source
changes.
Covers existing-cluster IP-override and fingerprint lookup, storage-summary
capacity-trend building, nouveau GPU temperature parsing, resolved-resource
control identity, and available-agent-host formatting. 32 TestBranchCov
functions in 2 files, all vet and gofmt clean.
Adds table-driven branch-coverage unit tests for previously uncovered pure
functions across internal/alerts/config, internal/ai/modelresolution,
internal/monitoring, internal/ai, internal/ai/qualification and pkg/licensing.
New test files only, with no source changes.
Covers per-subsystem alert-default normalization, configured model and provider
resolution, fleet-doctor identity and cluster-endpoint helpers, docker-state and
infrastructure-key mapping, investigation and SMART issue helpers, JSON and
autonomy normalization, and licensing feature-tier resolution. 65 TestBranchCov
functions in 7 files, all vet and gofmt clean.
Adds table-driven branch-coverage unit tests for previously uncovered pure
functions across internal/models, internal/config, pkg/securityutil and
pkg/aicontracts. New test files only, with no source changes.
Covers model collection normalizers, reflect-based metric deep-copy,
removed-host agent bookkeeping, report-schedule and entitlement-billing
normalization, effective AI control and Patrol autonomy resolution,
websocket-origin host normalization, and command-safety classifiers. 61
TestBranchCov functions in 8 files, all vet and gofmt clean.
Adds table-driven branch-coverage unit tests for previously untested pure
helper functions across internal/alerts/config, internal/config,
internal/ai/safety, internal/ai/modelresolution, internal/operationreceipt,
internal/models, internal/securityutil and pkg/securityutil. New test files
only, with no source changes.
Covers alert-config normalization and validation, sensitive-path and
redaction classifiers, URL normalizers, provider model resolution,
operation-receipt decoding, credential masking, and account-to-org role
mapping. 57 TestBranchCov functions in 12 files, all vet and gofmt clean.
Every ID token verification failure rendered the issuer-mismatch
advice, sending users with audience or clock problems down the wrong
path and telling users with a genuine issuer mismatch nothing they had
not already checked (#1533). Map the distinct verification failures
(issuer, audience, expiry) to their own error codes and give each
accurate login-page copy pointing at the server log's got/want detail.
A full monitor reload tears the state down and rebuilds it empty, so
agent-reported host rows vanish until each agent's next report lands.
Config fetches in that window 404ed with a perfectly valid token, which
showed up as rare correlated agent_config_fetch failures across
unrelated agents (#1570).
When the live snapshot has no match, resolve the host from the
persisted continuity store with the same semantics as the live path. A
report-scoped token resolves only its bound host and manage-scoped
tokens resolve by host ID. Deliberately removed hosts stay 404 because
removal deletes their continuity entry.
Deleting a host writes a machine-id-keyed removal block that rejected
every future report with HTTP 400, and the error pointed at an Allow
reconnect control that is not wired into the UI, leaving the machine
permanently unable to enroll without changing its machine-id (#1581).
Three holes made the block effectively immortal:
- The 24h TTL sweep only iterated the in-memory removal maps, which
reset on every restart, so persisted blocks never expired. Sweep the
persisted entries by their own RemovedAt for host agents, Docker
hosts, and Kubernetes clusters.
- AllowHostAgentReenroll (and the Docker and Kubernetes equivalents)
bailed out when the ID was missing from the in-memory map, so even
the API escape hatch stopped clearing persisted blocks after a
restart. Check and clear the persisted store independently.
- A report presenting an API token created after the removal is
explicit re-add intent (the user generated a fresh install command),
so clear the block and accept it. A still-running old agent keeps
presenting its pre-removal token and stays blocked.
Also reword the rejection to describe the two working recovery paths
instead of the unwired Settings control.
The recovery store was upsert-only: backups and snapshots deleted at
the source lingered as recovery_points rows until the 90-day retention
prune. ListRollups kept returning a rollup with a frozen LastSuccessAt,
so the backup-age alert for a deleted guest re-raised every poll cycle
and acknowledging or clearing it could never stick (#1580).
Each backup poll already publishes a complete per-instance enumeration
(partial failures early-return or carry previous entries forward), so
attach a reconcile scope to that ingest batch. After the upsert, points
in the scope (provider + id class + instance) that were not part of the
enumeration are deleted, which lets the existing per-cycle alert sweep
resolve the alert. An empty enumeration is meaningful and clears the
scope, covering the delete-all-backups case from the report.
Also make the async ingest queue batches instead of overwriting the
single pending slot, which silently dropped a full poll cycle whenever
two sources coalesced behind an active batch.
Alert start times are stored in UTC and the email templates rendered
them with no zone conversion or label, so the Started line read as a
local clock while showing UTC (#1582). Convert to the server's local
zone and include the zone name.
An availability target's configured poll interval only seeded the
adaptive scheduler: BuildPlan derived every instance's cadence from the
global adaptive bounds, and a failing probe raised the staleness score
and error penalty, collapsing the probe interval toward the global
5-second minimum. With interval 120s and failure threshold 4 the alert
was promised after ~8 minutes of downtime but fired within the first
minute because the four consecutive failures accumulated at the
collapsed cadence (#1582).
Availability checks promise pollInterval x failureThreshold as the
detection window, so the cadence is a user contract, not a scheduling
hint. Add a FixedIntervalPollProvider extension that pins an instance
to its configured interval, implement it for availability targets, and
bypass adaptive selection wherever the next run is computed (plan
building, rescheduling, and the non-adaptive fallback paths).
The Windows installer compared the downloaded agent's --version output
(v6.0.5) against the server's /api/version value (6.0.5) literally, so
every matching install still warned about a version mismatch (#1527).
Strip the leading v from both sides before comparing, matching what
install.sh already does.