CluPilotCloud/app/Models/VpnPeer.php

77 lines
2.0 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class VpnPeer extends Model
{
use HasFactory;
use HasUuids;
use SoftDeletes;
/** A tunnel is considered live if the last handshake is recent. WireGuard
* re-handshakes about every two minutes, so three is the first value that
* does not flap for an idle-but-connected peer. */
public const ONLINE_AFTER_MINUTES = 3;
protected $guarded = [];
protected function casts(): array
{
return [
'enabled' => 'boolean',
'present' => 'boolean',
'last_handshake_at' => 'datetime',
'observed_at' => 'datetime',
'rx_bytes' => 'integer',
'tx_bytes' => 'integer',
];
}
public function uniqueIds(): array
{
return ['uuid'];
}
public function host(): BelongsTo
{
return $this->belongsTo(Host::class);
}
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
public function isOnline(): bool
{
return $this->enabled
&& $this->present
&& $this->last_handshake_at !== null
&& $this->last_handshake_at->gt(now()->subMinutes(self::ONLINE_AFTER_MINUTES));
}
/**
* blocked — operator revoked it; it must not be on the hub
* pending — desired and observed state disagree; a job is still applying it
* online — configured and handshaking
* idle — configured, but no recent handshake
*/
public function status(): string
{
if (! $this->enabled) {
return $this->present ? 'pending' : 'blocked';
}
if (! $this->present) {
return 'pending';
}
return $this->isOnline() ? 'online' : 'idle';
}
}