Paillasse/portail/app/Services/OpenStack/GenerateurTemplateHeat.php

108 lines
3.6 KiB
PHP
Raw Normal View History

<?php
namespace App\Services\OpenStack;
use App\Services\Labs\DefinitionLab;
/**
* Traduit un lab.yaml en modèle Heat (étape 10) : un réseau Neutron par
* réseau du lab, sans DHCP et sans sécurité de port (les élèves configurent
* eux-mêmes leurs adresses), et une VM par machine, avec une interface par
* réseau déclaré, dans l'ordre (= ordre des interfaces ens3, ens4…).
*
* Jamais de routeur vers l'extérieur : les réseaux de lab sont isolés,
* conformément à CLAUDE.md (anti-abus, pas d'accès Internet depuis les VM
* élèves).
*/
class GenerateurTemplateHeat
{
/**
* @return array{template: array, noms_machines: array<int, string>}
*/
public function genererDepuis(DefinitionLab $lab, string $prefixe): array
{
$resources = [];
$outputs = [];
foreach ($lab->reseaux as $reseau) {
$cleReseau = self::cle($reseau['nom']);
$resources["reseau_{$cleReseau}"] = [
'type' => 'OS::Neutron::Net',
'properties' => [
'name' => "{$prefixe}-{$reseau['nom']}",
'port_security_enabled' => false,
],
];
$resources["sousreseau_{$cleReseau}"] = [
'type' => 'OS::Neutron::Subnet',
'properties' => [
'network' => ['get_resource' => "reseau_{$cleReseau}"],
'cidr' => $reseau['cidr'],
'enable_dhcp' => false,
],
];
}
$nomsMachines = [];
foreach ($lab->machines as $machine) {
$cleMachine = self::cle($machine['nom']);
$nomsMachines[] = $machine['nom'];
$ports = [];
foreach ($machine['reseaux'] as $nomReseau) {
$cleReseau = self::cle($nomReseau);
$clePort = "port_{$cleMachine}_{$cleReseau}";
$resources[$clePort] = [
'type' => 'OS::Neutron::Port',
'properties' => [
'network' => ['get_resource' => "reseau_{$cleReseau}"],
'port_security_enabled' => false,
'fixed_ips' => [],
],
];
$ports[] = ['port' => ['get_resource' => $clePort]];
}
$resources["machine_{$cleMachine}"] = [
'type' => 'OS::Nova::Server',
'properties' => [
'name' => "{$prefixe}-{$machine['nom']}",
'image' => $machine['image'],
'flavor' => $machine['flavor'],
'networks' => $ports,
],
];
$outputs["{$cleMachine}_id"] = [
'description' => "Id de l'instance {$machine['nom']}",
'value' => ['get_resource' => "machine_{$cleMachine}"],
];
}
$template = [
'heat_template_version' => '2021-04-16',
'description' => "Lab {$lab->identifiant} ({$prefixe})",
'resources' => $resources,
'outputs' => $outputs,
];
return ['template' => $template, 'noms_machines' => $nomsMachines];
}
/**
* Les noms de ressources Heat ne peuvent pas contenir les caractères du
* nom du lab (ex: "pc-a" → "pc_a"). Utilisé aussi par CreerStackLab pour
* retrouver, dans les sorties de la stack, quelle clé correspond à
* quelle machine.
*/
public static function cle(string $nom): string
{
return str_replace('-', '_', $nom);
}
}