259 lines
11 KiB
PHP
259 lines
11 KiB
PHP
<?php
|
||
|
||
namespace App\Filament\Pages;
|
||
|
||
use App\Services\NetworkService;
|
||
use App\Settings\NetworkSettings;
|
||
use Filament\Forms;
|
||
use Filament\Forms\Form;
|
||
use Filament\Notifications\Notification;
|
||
use Filament\Pages\SettingsPage;
|
||
use Filament\Forms\Components\TextInput;
|
||
use Filament\Forms\Components\Select;
|
||
use Filament\Forms\Components\Fieldset;
|
||
use Filament\Forms\Components\TagsInput;
|
||
|
||
class ManageNetwork extends SettingsPage
|
||
{
|
||
protected static ?string $navigationIcon = 'heroicon-o-cog-6-tooth';
|
||
|
||
protected static string $settings = NetworkSettings::class;
|
||
|
||
protected static ?string $navigationLabel = '网络连接配置管理';
|
||
|
||
protected static ?string $title = '网络连接配置管理';
|
||
|
||
public function form(Form $form): Form
|
||
{
|
||
// 获取当前网络接口
|
||
$interfaces = NetworkService::getNetworkInterfaces();
|
||
|
||
return $form
|
||
->schema([
|
||
// 添加网络接口选择框
|
||
Select::make('network_interface')
|
||
->label('选择网络接口')
|
||
->options(array_combine(array_keys($interfaces), array_keys($interfaces)))
|
||
->reactive()
|
||
->afterStateUpdated(function ($state, callable $set) use ($interfaces) {
|
||
// 调试输出:检查当前选择的接口
|
||
error_log("选择的接口: " . $state);
|
||
|
||
// 当选择框的值更新时,自动填充对应的网络信息
|
||
if (isset($interfaces[$state])) {
|
||
$dhcp_status = NetworkService::getDHCPstatus($state);
|
||
$set('dhcp_enabled', $dhcp_status ? 'true':'false');
|
||
$set('ip', $interfaces[$state]['ip'] ?? '无IP地址');
|
||
$set('mask', $interfaces[$state]['mask'] ?? '无子网掩码');
|
||
$set('gateway', $interfaces[$state]['gateway']);
|
||
// $set('dns_server_1', $interfaces[$state]['dns'][0] ?? null);
|
||
// $set('dns_server_2', $interfaces[$state]['dns'][1] ??
|
||
$set('dns_servers', $interfaces[$state]['dns'] ?? []);
|
||
|
||
error_log('state:' . $state);
|
||
error_log('dhcp_enabled: ' . $dhcp_status);
|
||
error_log("ip " . $interfaces[$state]['ip']);
|
||
error_log("mask " . $interfaces[$state]['mask']);
|
||
error_log("gateway " . $interfaces[$state]['gateway']);
|
||
error_log("dns_servers " . print_r($interfaces[$state]['dns'], true));
|
||
}
|
||
else{
|
||
error_log("未找到接口:" . $state);
|
||
}
|
||
}),
|
||
|
||
// 动态显示端口信息
|
||
Fieldset::make('端口信息')
|
||
->schema([
|
||
Select::make('dhcp_enabled')
|
||
->label('DHCP启用')
|
||
->options([
|
||
'true' => '是',
|
||
'false' => '否',
|
||
])
|
||
->reactive()
|
||
->required(), // 如果需要可以加上这个
|
||
TextInput::make('ip')
|
||
->label("IP地址")
|
||
->disabled(fn($get) => $get('dhcp_enabled') === 'true')
|
||
->required()
|
||
->reactive(),
|
||
Select::make('mask')
|
||
->label('子网掩码')
|
||
->options([
|
||
8 => "255.0.0.0 /8",
|
||
9 => "255.128.0.0 /9",
|
||
10 => "255.192.0.0 /10",
|
||
11 => "255.224.0.0 /11",
|
||
12 => "255.240.0.0 /12",
|
||
13 => "255.248.0.0 /13",
|
||
14 => "255.252.0.0 /14",
|
||
15 => "255.254.0.0 /15",
|
||
16 => "255.255.0.0 /16",
|
||
17 => "255.255.128.0 /17",
|
||
18 => "255.255.192.0 /18",
|
||
19 => "255.255.224.0 /19",
|
||
20 => "255.255.240.0 /20",
|
||
21 => "255.255.248.0 /21",
|
||
22 => "255.255.252.0 /22",
|
||
23 => "255.255.254.0 /23",
|
||
24 => "255.255.255.0 /24",
|
||
25 => "255.255.255.128 /25",
|
||
26 => "255.255.255.192 /26",
|
||
27 => "255.255.255.224 /27",
|
||
28 => "255.255.255.240 /28",
|
||
29 => "255.255.255.248 /29",
|
||
30 => "255.255.255.252 /30",
|
||
31 => "255.255.255.254 /31",
|
||
32 => "255.255.255.255 /32",
|
||
])
|
||
->required()
|
||
->disabled(fn($get) => $get('dhcp_enabled') === 'true')
|
||
->reactive(),
|
||
TextInput::make('gateway')
|
||
->label('网关')
|
||
->disabled(fn($get) => $get('dhcp_enabled') === 'true'),
|
||
TagsInput::make('dns_servers')
|
||
->label('DNS地址')
|
||
->disabled(fn($get) => $get('dhcp_enabled') === 'true')
|
||
->reactive()
|
||
->afterStateUpdated(function ($state, callable $set) {
|
||
// 保留合法的DNS地址
|
||
$validDns = array_filter($state, function ($dns) {
|
||
// 验证是否是合法的IPv4地址
|
||
return filter_var($dns, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
|
||
});
|
||
|
||
// 如果有非法的DNS地址,显示提示并移除它们
|
||
if (count($validDns) !== count($state)) {
|
||
Notification::make()
|
||
->title('无效的DNS地址 已自动移除')
|
||
->warning() // 设置消息类型为警告
|
||
->send();
|
||
}
|
||
|
||
// 限制最多只能有3个合法的DNS地址
|
||
if (count($validDns) > 3) {
|
||
$validDns = array_slice($validDns, 0, 3);
|
||
Notification::make()
|
||
->title('最多只能输入3个DNS地址')
|
||
->warning()
|
||
->send();
|
||
}
|
||
|
||
// 更新字段状态
|
||
$set('dns_servers', $validDns);
|
||
})
|
||
])
|
||
->visible(fn($get) => !is_null($get('network_interface'))) // 检查是否有选择的接口
|
||
->reactive(),
|
||
|
||
|
||
]);
|
||
}
|
||
|
||
public function save(): void
|
||
{
|
||
// 获取用户输入的网络配置
|
||
$ipAddress = $this->form->getState()['ip'] ?? '';
|
||
$gateway = $this->form->getState()['gateway'] ?? '';
|
||
$dhcpEnabled = $this->form->getState()['dhcp_enabled'];
|
||
if ($dhcpEnabled !== 'true'){
|
||
if (!filter_var($ipAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||
Notification::make()
|
||
->title('无效的 IP 地址格式')
|
||
->warning()
|
||
->send();
|
||
|
||
return; // 返回,不执行保存操作
|
||
}
|
||
|
||
// 验证网关地址格式
|
||
if (!filter_var($gateway, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
|
||
Notification::make()
|
||
->title('无效的网关地址格式')
|
||
->warning()
|
||
->send();
|
||
|
||
return; // 返回,不执行保存操作
|
||
}
|
||
}
|
||
// 验证 IP 地址格式
|
||
|
||
|
||
// 调用父类的保存方法以持久化设置
|
||
parent::save();
|
||
|
||
// 保存后执行终端命令
|
||
$this->executeCommands();
|
||
}
|
||
|
||
protected function executeCommands(): void
|
||
{
|
||
// 获取用户输入的网络配置
|
||
$networkInterface = $this->form->getState()['network_interface'] ?? '';
|
||
$dhcpEnabled = $this->form->getState()['dhcp_enabled'];
|
||
|
||
error_log('接口名称:' . $networkInterface);
|
||
error_log('dhcp:' . $dhcpEnabled);
|
||
|
||
$ipAddress = $this->form->getState()['ip'] ?? '';
|
||
$mask = $this->form->getState()['mask'] ?? '';
|
||
$gateway = $this->form->getState()['gateway'] ?? '';
|
||
|
||
$dnsServers = $this->form->getState()['dns_servers'] ?? [];
|
||
$dnsString = implode(',', $dnsServers); // 合并 DNS 地址为字符串
|
||
|
||
if ($dhcpEnabled=='true') {
|
||
|
||
// 如果启用 DHCP,设置为使用 DHCP
|
||
$commands = [
|
||
"nmcli con mod '$networkInterface' ipv4.method auto ipv4.addresses \"\" ipv4.gateway \"\" ipv4.dns \"\"",
|
||
"nmcli con down '$networkInterface'",
|
||
"nmcli con up '$networkInterface'"
|
||
];
|
||
|
||
foreach ($commands as $command) {
|
||
$output = [];
|
||
$returnVar = 0;
|
||
exec($command, $output, $returnVar);
|
||
|
||
// 记录输出和返回状态以便调试
|
||
error_log("命令: $command");
|
||
error_log("输出: " . implode("\n", $output));
|
||
error_log("返回状态: $returnVar");
|
||
|
||
// 如果需要,处理错误
|
||
if ($returnVar !== 0) {
|
||
error_log("执行命令出错: $command");
|
||
}
|
||
}
|
||
} else {
|
||
// 根据接口和用户输入构建命令
|
||
$commands = [
|
||
"nmcli con mod '$networkInterface' ipv4.method manual ipv4.addresses $ipAddress/$mask ipv4.gateway $gateway ipv4.dns $dnsString",
|
||
"nmcli con down '$networkInterface'",
|
||
"nmcli con up '$networkInterface'", // 重新激活连接
|
||
];
|
||
|
||
foreach ($commands as $command) {
|
||
$output = [];
|
||
$returnVar = 0;
|
||
exec($command, $output, $returnVar);
|
||
|
||
// 记录输出和返回状态以便调试
|
||
error_log("命令: $command");
|
||
error_log("输出: " . implode("\n", $output));
|
||
error_log("返回状态: $returnVar");
|
||
|
||
// 如果需要,处理错误
|
||
if ($returnVar !== 0) {
|
||
error_log("执行命令出错: $command");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|