initial commit

This commit is contained in:
TheOnlyMace
2026-05-17 13:26:14 +02:00
commit 75299b723d
176 changed files with 20327 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
<?php
namespace App\Http\Controllers\Web;
use App\Enums\IpPoolType;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\IpPool;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;
class IpPoolController extends Controller
{
public function index(Request $request): View
{
$this->authorize('viewAny', IpPool::class);
$pools = IpPool::query()
->withCount(['vms' => fn ($q) => $q->whereIn('status', ['pending', 'active'])])
->orderBy('type')
->orderBy('name')
->get()
->map(function (IpPool $pool) {
$pool->setAttribute('usage_percent', $pool->totalIps() > 0
? round(($pool->usedIpsCount() / $pool->totalIps()) * 100, 1)
: 0);
return $pool;
});
$assignments = Customer::query()
->forUser($request->user())
->with(['owner', 'ipPool'])
->whereIn('status', ['pending', 'active'])
->where(fn ($q) => $q->whereNotNull('ip_address')->orWhereNotNull('public_ip'))
->orderBy('name')
->get();
return view('ip-pools.index', compact('pools', 'assignments'));
}
public function create(): View
{
$this->authorize('create', IpPool::class);
return view('ip-pools.create', ['types' => IpPoolType::cases()]);
}
public function store(Request $request): RedirectResponse
{
$this->authorize('create', IpPool::class);
$data = $request->validate([
'name' => ['required', 'string', 'max:100'],
'type' => ['required', Rule::enum(IpPoolType::class)],
'start_ip' => ['required', 'ip'],
'end_ip' => ['required', 'ip'],
'gateway' => ['nullable', 'ip'],
'cidr' => ['required', 'integer', 'min:8', 'max:32'],
'description' => ['nullable', 'string', 'max:500'],
'is_active' => ['boolean'],
]);
if (ip2long($data['start_ip']) > ip2long($data['end_ip'])) {
return back()->withErrors(['end_ip' => 'End-IP muss größer als Start-IP sein.'])->withInput();
}
IpPool::query()->create([
...$data,
'is_active' => $request->boolean('is_active', true),
]);
return redirect()->route('ip-pools.index')->with('success', 'IP-Pool erstellt.');
}
public function edit(IpPool $ipPool): View
{
$this->authorize('update', $ipPool);
return view('ip-pools.edit', [
'pool' => $ipPool,
'types' => IpPoolType::cases(),
]);
}
public function update(Request $request, IpPool $ipPool): RedirectResponse
{
$this->authorize('update', $ipPool);
$data = $request->validate([
'name' => ['required', 'string', 'max:100'],
'type' => ['required', Rule::enum(IpPoolType::class)],
'start_ip' => ['required', 'ip'],
'end_ip' => ['required', 'ip'],
'gateway' => ['nullable', 'ip'],
'cidr' => ['required', 'integer', 'min:8', 'max:32'],
'description' => ['nullable', 'string', 'max:500'],
'is_active' => ['boolean'],
]);
$ipPool->update([
...$data,
'is_active' => $request->boolean('is_active'),
]);
return redirect()->route('ip-pools.index')->with('success', 'IP-Pool aktualisiert.');
}
public function destroy(IpPool $ipPool): RedirectResponse
{
$this->authorize('delete', $ipPool);
if ($ipPool->vms()->whereIn('status', ['pending', 'active'])->exists()) {
return back()->withErrors(['pool' => 'Pool wird noch von aktiven VMs verwendet.']);
}
$ipPool->delete();
return redirect()->route('ip-pools.index')->with('success', 'IP-Pool gelöscht.');
}
}