$template * @return array{id: string} */ public function creerStack(string $nom, array $template): array { $reponse = $this->requete()->post($this->url('/stacks'), [ 'stack_name' => $nom, 'disable_rollback' => true, 'template' => $template, ]); if ($reponse->failed()) { throw new RuntimeException("Heat a refusé la création de la stack {$nom} : ".$reponse->body()); } return ['id' => $reponse->json('stack.id')]; } /** * @return array{statut: string, raison: ?string, sorties: array} */ public function etatStack(string $nom, string $id): array { $reponse = $this->requete()->get($this->url("/stacks/{$nom}/{$id}")); if ($reponse->failed()) { throw new RuntimeException("Impossible de lire l'état de la stack {$nom} : ".$reponse->body()); } $sorties = []; foreach ($reponse->json('stack.outputs') ?? [] as $sortie) { $sorties[$sortie['output_key']] = $sortie['output_value']; } return [ 'statut' => $reponse->json('stack.stack_status'), 'raison' => $reponse->json('stack.stack_status_reason'), 'sorties' => $sorties, ]; } /** * Toutes les stacks du projet (quelques dizaines au plus : pas de pagination). * * @return array */ public function listerStacks(): array { $reponse = $this->requete()->get($this->url('/stacks')); if ($reponse->failed()) { throw new RuntimeException('Impossible de lister les stacks : '.$reponse->body()); } return array_map(fn (array $s) => [ 'nom' => $s['stack_name'], 'id' => $s['id'], 'statut' => $s['stack_status'], 'cree_a' => $s['creation_time'], ], $reponse->json('stacks') ?? []); } public function supprimerStack(string $nom, string $id): void { $reponse = $this->requete()->delete($this->url("/stacks/{$nom}/{$id}")); // 404 : déjà supprimée (idempotent, pas une erreur pour nous). if ($reponse->failed() && $reponse->status() !== 404) { throw new RuntimeException("Heat a refusé la suppression de la stack {$nom} : ".$reponse->body()); } } private function requete(): PendingRequest { return Http::withHeaders(['X-Auth-Token' => $this->auth->jeton()]); } private function url(string $chemin): string { return config('openstack.heat_url').'/'.$this->auth->projetId().$chemin; } }