'array', 'log' => 'array', 'instance_created_at' => 'datetime', 'ip_assigned_at' => 'datetime', 'completed_at' => 'datetime', 'failed_at' => 'datetime', ]; protected $hidden = [ 'ssh_private_key', 'generated_mail_db_password', 'completion_token', ]; public function hostingNode(): BelongsTo { return $this->belongsTo(HostingNode::class); } public function emailServer(): BelongsTo { return $this->belongsTo(EmailServer::class); } public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } public function completionUrl(): string { return url('/api/infrastructure/contabo/callback/'.$this->id.'?token='.$this->completion_token); } public function purposeLabel(): string { return match ($this->purpose) { self::PURPOSE_HOSTING_NODE => 'Hosting node', self::PURPOSE_EMAIL_PRIMARY => 'Mail server (primary)', self::PURPOSE_EMAIL_EXTENSION => 'Mail server (extension)', default => $this->purpose, }; } public function addLog(string $message): void { $log = $this->log ?? []; $log[] = ['at' => now()->toIso8601String(), 'message' => $message]; $this->update(['log' => $log]); } public function markFailed(string $message): void { $this->update([ 'status' => self::STATUS_FAILED, 'error_message' => $message, 'failed_at' => now(), ]); $this->addLog('Failed: '.$message); } }