get($vmwareId, 'metrics', 'VM metrics are unavailable'); } public function vmStorage(string $vmwareId): array { return $this->get($vmwareId, 'storage', 'VM storage is unavailable'); } public function vmHistory(string $vmwareId, \DateTimeInterface $from, \DateTimeInterface $to): array { return $this->get($vmwareId, 'history', 'VM metrics are unavailable', [ 'from' => $from->format(DATE_RFC3339), 'to' => $to->format(DATE_RFC3339), 'limit' => 10000, ]); } private function get(string $vmwareId, string $resource, string $notFoundMessage, array $query = []): array { $url = rtrim((string) config('portal-monitor.url'), '/'); $apiKey = (string) config('portal-monitor.api_key'); if ($url === '' || $apiKey === '') { throw new RuntimeException('Portal Monitor is not configured'); } try { $response = Http::acceptJson() ->withHeaders(['X-API-Key' => $apiKey]) ->timeout((int) config('portal-monitor.timeout', 5)) ->get($url . '/api/v1/vsphere/vms/' . rawurlencode($vmwareId) . '/' . $resource, $query); } catch (ConnectionException) { throw new RuntimeException('Portal Monitor is unavailable'); } if ($response->status() === 404) { throw new RuntimeException($notFoundMessage, 404); } if (!$response->successful()) { throw new RuntimeException('Portal Monitor request failed'); } $data = $response->json('data'); if (!is_array($data)) { throw new RuntimeException('Portal Monitor returned an invalid response'); } return $data; } }