57 lines
2.0 KiB
PHP
57 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
/**
|
|
* The SSH login for the "Clusev host" terminal (a singleton — one host). Stored encrypted; only
|
|
* ever read over the internal network by the terminal resolve endpoint, never sent to the browser.
|
|
* When no row exists the host terminal is "not configured" and the tile opens the setup form.
|
|
*/
|
|
class HostCredential extends Model
|
|
{
|
|
/** Explicit allowlist (never $guarded=[]) so request input can't set unintended columns. */
|
|
protected $fillable = ['host', 'port', 'username', 'auth_type', 'secret', 'passphrase'];
|
|
|
|
/** Never serialize the credential fields (mirrors SshCredential). */
|
|
protected $hidden = ['secret', 'passphrase'];
|
|
|
|
protected $casts = [
|
|
'port' => 'integer',
|
|
'secret' => 'encrypted',
|
|
'passphrase' => 'encrypted',
|
|
];
|
|
|
|
/** The single configured host login, or null when the operator hasn't set one up yet. */
|
|
public static function current(): ?self
|
|
{
|
|
return static::query()->orderBy('id')->first();
|
|
}
|
|
|
|
/**
|
|
* A TRANSIENT Server (never persisted) that points SSH tooling — FleetService, DockerService —
|
|
* at the Clusev host itself, reusing the encrypted host login. The SshCredential is likewise
|
|
* transient; its encrypted 'secret' cast round-trips the plaintext back for CredentialVault.
|
|
* verifyHostKey skips pinning a non-persisted server, so this creates no fleet row.
|
|
*/
|
|
public function toServer(): Server
|
|
{
|
|
$cred = new SshCredential(['username' => $this->username, 'auth_type' => $this->auth_type]);
|
|
$cred->secret = $this->secret;
|
|
if ($this->passphrase) {
|
|
$cred->passphrase = $this->passphrase;
|
|
}
|
|
|
|
$server = new Server([
|
|
'name' => 'Clusev Host',
|
|
'ip' => $this->host,
|
|
'ssh_port' => $this->port,
|
|
'status' => 'online',
|
|
]);
|
|
$server->setRelation('credential', $cred);
|
|
|
|
return $server;
|
|
}
|
|
}
|