services()->where('category', ServiceCategory::GATEWAY)->exists()) { throw new RuntimeException('This server already has a gateway service.'); } $driverName = "{$type->value}.{$version}"; $service = $server->services()->create([ 'organisation_id' => $server->organisation_id, 'name' => $name, 'category' => $category, 'type' => $type, 'version' => $version, 'version_track' => $version, 'driver_name' => $driverName, 'status' => ServiceStatus::NOT_INSTALLED, 'deploy_policy' => $this->defaultDeployPolicy($category, $type), 'process_roles' => [], 'desired_replicas' => 1, 'config' => [], ]); if (method_exists($service->driver(), 'defaultCredentials')) { $service->credentials = $service->driver()->defaultCredentials(); $service->save(); } $service->replicas()->create([ 'server_id' => $server->id, 'container_name' => "keystone-service-{$service->id}-1", 'internal_host' => "keystone-service-{$service->id}", 'internal_port' => $this->defaultInternalPort($type), 'status' => 'pending', 'health_status' => 'unknown', 'config' => [], ]); dispatch(new DeployService($service)); return $service; } private function defaultDeployPolicy(ServiceCategory $category, ServiceType $type): DeployPolicy { return match (true) { $category === ServiceCategory::APPLICATION => DeployPolicy::WITH_ENVIRONMENT, $category === ServiceCategory::DATABASE, $category === ServiceCategory::CACHE, $category === ServiceCategory::STORAGE => DeployPolicy::DEPENDENCY_ONLY, $category === ServiceCategory::GATEWAY => DeployPolicy::MANUAL_OR_ON_ROUTE_CHANGE, default => DeployPolicy::MANUAL, }; } private function defaultInternalPort(ServiceType $type): int { return match ($type) { ServiceType::POSTGRES => 5432, ServiceType::VALKEY => 6379, ServiceType::CADDY, ServiceType::LARAVEL => 80, }; } }