50-cloud-init.yaml

This commit is contained in:
devdatt 2025-12-23 12:06:15 +05:30
parent acb9b19323
commit e1b72df58d
2 changed files with 90 additions and 121 deletions

View File

@ -115,6 +115,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'network_secondary_ipv6_dns2' => $network_secondary_ipv6_dns2
],
];
$json = json_encode($new, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
if (file_put_contents($jsonFile, $json, LOCK_EX) === false) {
$errors[] = "Failed to write {$jsonFile}. Check permissions.";
@ -122,6 +123,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = $new;
$success = 'Saved.';
foreach ($data as $block => &$fields) {
foreach ($fields as $key => $value) {
if (isset($_POST[$key])) {
$fields[$key] = trim($_POST[$key]);
}
}
}
unset($fields);
$netplan = [
'network' => [
'version' => 2,
@ -131,35 +142,34 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
]
];
$primary_vlan = trim($data['primary']['network_primary_vlan'] ?? '');
$secondary_vlan = trim($data['secondary']['network_secondary_vlan'] ?? '');
foreach (['primary', 'secondary'] as $type) {
$uses_vlan = ($primary_vlan !== '' || $secondary_vlan !== '');
if (
$data[$type]['mode'] === 'disabled' &&
$data[$type]['modev6'] === 'disabled'
) {
continue;
}
if (!$uses_vlan) {
$vlan = trim($data[$type]["network_{$type}_vlan"] ?? '');
if ($vlan === '') {
$netplan['network']['ethernets'][$iface] =
build_interface($data['primary'], 'primary');
build_interface($data[$type], $type);
} else {
$netplan['network']['ethernets'][$iface] = new stdClass();
if ($primary_vlan !== '') {
$netplan['network']['vlans']["{$iface}.{$primary_vlan}"] =
$netplan['network']['vlans']["{$iface}.{$vlan}"] =
array_merge(
['id' => (int)$primary_vlan, 'link' => $iface],
build_interface($data['primary'], 'primary')
);
}
if ($secondary_vlan !== '') {
$netplan['network']['vlans']["{$iface}.{$secondary_vlan}"] =
array_merge(
['id' => (int)$secondary_vlan, 'link' => $iface],
build_interface($data['secondary'], 'secondary')
['id' => (int)$vlan, 'link' => $iface],
build_interface($data[$type], $type)
);
}
}
file_put_contents('/var/www/50-cloud-init.yaml', netplan_yaml($netplan));
$yaml = yaml($netplan);
file_put_contents('/var/www/50-cloud-init.yaml', $yaml);
}
}

View File

@ -75,121 +75,80 @@ function find_first_physical_ethernet(): ?string
return null;
}
function build_interface(array $d, string $key): array
function build_interface(array $cfg, string $type): array
{
$cfg = [];
$addresses = [];
$routes = [];
$out = [];
/* IPv4 */
switch ($d['mode'] ?? 'disabled') {
case 'dhcp':
$cfg['dhcp4'] = true;
break;
/* ---------- IPv4 ---------- */
if ($cfg['mode'] === 'dhcp') {
$out['dhcp4'] = true;
} elseif ($cfg['mode'] === 'static') {
$out['dhcp4'] = false;
$out['addresses'][] = $cfg["network_{$type}_ip"];
$out['gateway4'] = $cfg["network_{$type}_gateway"];
case 'static':
if (!empty($d["network_{$key}_ip"]) && !empty($d["network_{$key}_subnet"])) {
$addresses[] = $d["network_{$key}_ip"] . '/' . $d["network_{$key}_subnet"];
}
if (!empty($d["network_{$key}_gateway"])) {
$routes[] = ['to' => 'default', 'via' => $d["network_{$key}_gateway"]];
}
$cfg['dhcp4'] = false;
break;
default:
$cfg['dhcp4'] = false;
}
/* IPv6 */
switch ($d['modev6'] ?? 'disabled') {
case 'auto':
$cfg['accept-ra'] = true;
$cfg['dhcp6'] = false;
break;
case 'dhcp6':
$cfg['dhcp6'] = true;
$cfg['accept-ra'] = false;
break;
case 'static':
if (!empty($d["network_{$key}_ipv6"]) && !empty($d["network_{$key}_ipv6_prefix"])) {
$addresses[] = $d["network_{$key}_ipv6"] . '/' . $d["network_{$key}_ipv6_prefix"];
}
if (!empty($d["network_{$key}_ipv6_gateway"])) {
$routes[] = ['to' => '::/0', 'via' => $d["network_{$key}_ipv6_gateway"]];
}
$cfg['dhcp6'] = false;
$cfg['accept-ra'] = false;
break;
default:
$cfg['dhcp6'] = false;
$cfg['accept-ra'] = false;
}
if ($addresses) {
$cfg['addresses'] = $addresses;
}
if ($routes) {
$cfg['routes'] = $routes;
}
$dns = array_values(array_filter([
$d["network_{$key}_dns1"] ?? '',
$d["network_{$key}_dns2"] ?? '',
$d["network_{$key}_ipv6_dns1"] ?? '',
$d["network_{$key}_ipv6_dns2"] ?? '',
]));
$dns = array_filter([
$cfg["network_{$type}_dns1"],
$cfg["network_{$type}_dns2"]
]);
if ($dns) {
$cfg['nameservers'] = ['addresses' => $dns];
$out['nameservers']['addresses'] = array_values($dns);
}
} else {
$out['dhcp4'] = false;
}
return $cfg;
/* ---------- IPv6 ---------- */
if ($cfg['modev6'] === 'auto') {
$out['dhcp6'] = true;
$out['accept-ra'] = true;
} elseif ($cfg['modev6'] === 'dhcpv6') {
$out['dhcp6'] = true;
$out['accept-ra'] = false;
} elseif ($cfg['modev6'] === 'static') {
$out['dhcp6'] = false;
$out['accept-ra'] = false;
$out['addresses'][] =
$cfg["network_{$type}_ipv6"] . '/' .
$cfg["network_{$type}_ipv6_prefix"];
$out['gateway6'] = $cfg["network_{$type}_ipv6_gateway"];
$dns6 = array_filter([
$cfg["network_{$type}_ipv6_dns1"],
$cfg["network_{$type}_ipv6_dns2"]
]);
if ($dns6) {
$out['nameservers']['addresses'] =
array_merge($out['nameservers']['addresses'] ?? [], $dns6);
}
} else {
$out['dhcp6'] = false;
$out['accept-ra'] = false;
}
return $out;
}
function netplan_yaml(array $data, int $indent = 0): string
function yaml(array $data, int $indent = 0): string
{
$yaml = '';
$out = '';
$pad = str_repeat(' ', $indent);
foreach ($data as $key => $value) {
if ($value instanceof stdClass) {
$yaml .= "{$pad}{$key}: {}\n";
continue;
}
if (is_array($value) && !array_is_list($value)) {
$yaml .= "{$pad}{$key}:\n";
$yaml .= netplan_yaml($value, $indent + 1);
continue;
}
if (is_array($value) && array_is_list($value)) {
foreach ($value as $item) {
if (is_array($item)) {
$yaml .= "{$pad}-\n";
$yaml .= netplan_yaml($item, $indent + 1);
foreach ($data as $k => $v) {
if ($v instanceof stdClass) {
$out .= "{$pad}{$k}: {}\n";
} elseif (is_array($v)) {
$out .= "{$pad}{$k}:\n";
$out .= yaml($v, $indent + 1);
} else {
$yaml .= "{$pad}- {$item}\n";
$out .= "{$pad}{$k}: {$v}\n";
}
}
continue;
}
if (is_bool($value)) {
$value = $value ? 'true' : 'false';
}
$yaml .= "{$pad}{$key}: {$value}\n";
}
return $yaml;
return $out;
}