schema([ Forms\Components\Select::make('type') ->label('Type') ->options([ 'ipv4' => 'IPv4', 'ipv6' => 'IPv6', ]) ->default('ipv4') ->disabledOn('edit') ->reactive() ->required(), Forms\Components\TextInput::make('ip') ->label('IP Address') ->required() ->maxLength(fn (Get $get) => $get('type') === 'ipv4' ? 15 : 39) // 15 for IPv4, 39 for IPv6 ->disabledOn('edit') ->unique(ignoreRecord: true) ->placeholder('Enter the IP address'), Forms\Components\TextInput::make('gateway') ->label('Gateway') ->required() ->maxLength(fn (Get $get) => $get('type') === 'ipv4' ? 15 : 39) // 15 for IPv4, 39 for IPv6 ->placeholder('Enter the gateway'), Forms\Components\TextInput::make('netmask') ->label('Netmask') ->required() ->maxLength(fn (Get $get) => $get('type') === 'ipv4' ? 15 : 39) // 15 for IPv4, 39 for IPv6 ->placeholder('Enter the netmask'), Forms\Components\TextInput::make('mac_address') ->label('MAC Address') ->maxLength(255) ->placeholder('Enter the MAC address'), Forms\Components\Select::make('server_id') ->label('Server') ->relationship('server', 'hostname') ->searchable() ->preload() ->helperText('Select a server to assign this IP address') ->placeholder('Select a server'), ]); } public function table(Table $table): Table { return $table ->recordTitleAttribute('ip') ->columns([ Tables\Columns\TextColumn::make('ip')->label('IP Address')->searchable(), Tables\Columns\TextColumn::make('server.hostname')->label('Server')->sortable()->searchable(), Tables\Columns\TextColumn::make('gateway'), Tables\Columns\TextColumn::make('mac_address')->label('MAC Address'), ]) ->filters([ // ]) ->headerActions([ Tables\Actions\CreateAction::make(), Tables\Actions\Action::make('bulkaddaddress') ->label('Bulk Add IP Addresses') ->icon('ri-add-line') ->form(function () { return [ Forms\Components\Select::make('type') ->label('Type') ->options([ 'ipv4' => 'IPv4', 'ipv6' => 'IPv6', ]) ->default('ipv4') ->reactive() ->required(), Forms\Components\TextInput::make('start_ip') ->label('Start IP Address') ->required() ->maxLength(fn (Get $get) => $get('type') === 'ipv4' ? 15 : 39) // 15 for IPv4, 39 for IPv6 ->placeholder('Enter the start IP address'), Forms\Components\TextInput::make('end_ip') ->label('End IP Address') ->required() ->maxLength(fn (Get $get) => $get('type') === 'ipv4' ? 15 : 39) // 15 for IPv4, 39 for IPv6 ->placeholder('Enter the end IP address'), Forms\Components\TextInput::make('gateway') ->label('Gateway') ->required() ->maxLength(fn (Get $get) => $get('type') === 'ipv4' ? 15 : 39) // 15 for IPv4, 39 for IPv6 ->placeholder('Enter the gateway'), Forms\Components\TextInput::make('netmask') ->label('Netmask') ->required() ->maxLength(fn (Get $get) => $get('type') === 'ipv4' ? 15 : 39) // 15 for IPv4, 39 for IPv6 ->placeholder('Enter the netmask'), ]; }) ->action(function (array $data, $record) { // Get start IP and end IP if ($data['type'] === 'ipv4') { // Validate and convert IP addresses $startIp = ip2long($data['start_ip']); $endIp = ip2long($data['end_ip']); if ($startIp === false || $endIp === false || $startIp > $endIp) { throw new \InvalidArgumentException('Invalid IP address range.'); } // Generate IP addresses in the range $ipAddresses = []; for ($ip = $startIp; $ip <= $endIp; $ip++) { $ipAddresses[] = long2ip($ip); } } else { $startIp = gmp_import(inet_pton($data['start_ip'])); $endIp = gmp_import(inet_pton($data['end_ip'])); if ($startIp === false || $endIp === false || gmp_cmp($startIp, $endIp) > 0) { throw new \InvalidArgumentException('Invalid IP address range.'); } // Generate IPv6 addresses in the range $ipAddresses = []; for ($ip = $startIp; gmp_cmp($ip, $endIp) <= 0; $ip = gmp_add($ip, 1)) { $ipAddresses[] = inet_ntop(str_pad(gmp_export($ip), 16, "\0", STR_PAD_LEFT)); } // Remove duplicate IP addresses $ipAddresses = array_unique($ipAddresses); sort($ipAddresses); } // Create IP addresses in the pool foreach ($ipAddresses as $ip) { $this->getOwnerRecord()->ipAddresses()->create([ 'type' => $data['type'], 'ip' => $ip, 'gateway' => $data['gateway'], 'netmask' => $data['netmask'], 'mac_address' => $data['mac_address'] ?? null, ]); } $this->dispatch('refresh'); }), ]) ->actions([ Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make()->disabled(fn ($record) => $record->server_id !== null), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make()->before(function (Tables\Actions\DeleteBulkAction $action) { foreach ($action->getRecords() as $record) { if ($record->server_id !== null) { Notification::make() ->title('Cannot delete IP Address') ->body('The IP Address is assigned to a server.') ->duration(5000) ->icon('ri-error-warning-line') ->danger() ->send(); $action->cancel(); } } }), ]), ])->defaultSort('server_id', 'desc'); } }