yamanvmRequest($baseUrl, 'GET', '/api/v1/ping', $token), 'servers' => yamanvmRequest($baseUrl, 'GET', '/api/v1/servers?per_page=5', $token), 'server' => requireServerId($serverId, fn () => yamanvmRequest($baseUrl, 'GET', "/api/v1/servers/{$serverId}", $token)), 'tasks' => requireServerId($serverId, fn () => yamanvmRequest($baseUrl, 'GET', "/api/v1/servers/{$serverId}/tasks", $token)), 'power-off' => requireServerId($serverId, fn () => yamanvmRequest( $baseUrl, 'POST', "/api/v1/servers/{$serverId}/power", $token, ['action' => 'power_off'], "php-client-power-off-{$serverId}-".date('YmdHis') )), default => throw new InvalidArgumentException("Unknown command: {$command}"), }; fwrite(STDOUT, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE).PHP_EOL); exit($result['status'] >= 200 && $result['status'] < 300 ? 0 : 1); } catch (Throwable $exception) { fwrite(STDERR, $exception->getMessage().PHP_EOL); exit(1); } function requireServerId(int $serverId, callable $callback): array { if ($serverId <= 0) { throw new InvalidArgumentException('A numeric server id is required for this command.'); } return $callback(); } function yamanvmRequest( string $baseUrl, string $method, string $path, string $token, ?array $payload = null, ?string $idempotencyKey = null ): array { $headers = [ 'Authorization: Bearer '.$token, 'Accept: application/json', 'X-Request-Id: php-'.bin2hex(random_bytes(8)), ]; if ($idempotencyKey !== null) { $headers[] = 'Idempotency-Key: '.$idempotencyKey; } if ($payload !== null) { $headers[] = 'Content-Type: application/json'; } $responseHeaders = []; $ch = curl_init($baseUrl.$path); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => strtoupper($method), CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => false, CURLOPT_HTTPHEADER => $headers, CURLOPT_TIMEOUT => 30, CURLOPT_HEADERFUNCTION => static function ($curl, string $headerLine) use (&$responseHeaders): int { $trimmed = trim($headerLine); if ($trimmed !== '' && str_contains($trimmed, ':')) { [$name, $value] = explode(':', $trimmed, 2); $responseHeaders[strtolower(trim($name))] = trim($value); } return strlen($headerLine); }, ]); if ($payload !== null) { $json = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); } $raw = curl_exec($ch); if ($raw === false) { $message = curl_error($ch); curl_close($ch); throw new RuntimeException('cURL error: '.$message); } $status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $decoded = json_decode($raw, true); return [ 'status' => $status, 'headers' => $responseHeaders, 'body' => json_last_error() === JSON_ERROR_NONE ? $decoded : null, 'raw' => json_last_error() === JSON_ERROR_NONE ? null : $raw, ]; }