From a020bc872d74f54cc0461fbb6c020f792f5f6ee9 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 7 Aug 2023 18:46:40 +0200 Subject: [PATCH] feat: init postgresql database --- app/Actions/Database/StartPostgresql.php | 25 +++++++ .../Controllers/ApplicationController.php | 2 +- app/Http/Controllers/Controller.php | 2 + app/Http/Controllers/DatabaseController.php | 30 +++++++++ app/Http/Livewire/ActivityMonitor.php | 2 +- app/Http/Livewire/{ => Dev}/S3Test.php | 3 +- .../Livewire/Project/Application/General.php | 2 + .../{ => Project}/Application/Heading.php | 2 +- .../Livewire/Project/Database/Heading.php | 23 +++++++ .../Project/Database/Postgresql/General.php | 39 +++++++++++ app/Models/Environment.php | 12 +++- app/Models/Postgresql.php | 25 +++++++ app/Models/Project.php | 6 +- app/Models/S3Storage.php | 4 ++ app/Models/StandaloneDocker.php | 6 +- app/View/Components/Modal.php | 4 +- ..._08_07_073651_create_s3_storages_table.php | 2 +- ..._08_07_142950_create_postgresqls_table.php | 42 ++++++++++++ ...scription_field_to_applications_table.php} | 17 ++--- database/seeders/ApplicationSeeder.php | 10 ++- database/seeders/DatabaseSeeder.php | 1 + database/seeders/PostgresqlSeeder.php | 26 ++++++++ .../components/databases/navbar.blade.php | 41 ++++++++++++ resources/views/components/modal.blade.php | 11 +++- .../breadcrumbs.blade.php | 8 +-- resources/views/dashboard.blade.php | 2 +- .../livewire/{ => dev}/s3-test.blade.php | 0 .../project/application/general.blade.php | 29 +++++---- .../application/heading.blade.php | 2 +- .../project/database/heading.blade.php | 4 ++ .../database/postgresql/general.blade.php | 18 +++++ .../application/configuration.blade.php | 2 +- .../project/application/deployment.blade.php | 2 +- .../project/application/deployments.blade.php | 2 +- resources/views/project/database.blade.php | 5 -- .../project/database/configuration.blade.php | 65 +++++++++++++++++++ resources/views/project/resources.blade.php | 18 ++++- routes/web.php | 2 + 38 files changed, 430 insertions(+), 66 deletions(-) create mode 100644 app/Actions/Database/StartPostgresql.php create mode 100644 app/Http/Controllers/DatabaseController.php rename app/Http/Livewire/{ => Dev}/S3Test.php (94%) rename app/Http/Livewire/{ => Project}/Application/Heading.php (97%) create mode 100644 app/Http/Livewire/Project/Database/Heading.php create mode 100644 app/Http/Livewire/Project/Database/Postgresql/General.php create mode 100644 app/Models/Postgresql.php create mode 100644 database/migrations/2023_08_07_142950_create_postgresqls_table.php rename database/migrations/{2023_03_27_083620_create_databases_table.php => 2023_08_07_142951_add_description_field_to_applications_table.php} (51%) create mode 100644 database/seeders/PostgresqlSeeder.php create mode 100644 resources/views/components/databases/navbar.blade.php rename resources/views/components/{applications => resources}/breadcrumbs.blade.php (91%) rename resources/views/livewire/{ => dev}/s3-test.blade.php (100%) rename resources/views/livewire/{ => project}/application/heading.blade.php (63%) create mode 100644 resources/views/livewire/project/database/heading.blade.php create mode 100644 resources/views/livewire/project/database/postgresql/general.blade.php delete mode 100644 resources/views/project/database.blade.php create mode 100644 resources/views/project/database/configuration.blade.php diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php new file mode 100644 index 000000000..d9f2c8846 --- /dev/null +++ b/app/Actions/Database/StartPostgresql.php @@ -0,0 +1,25 @@ + $deploymentUuid, ]); } -} +} \ No newline at end of file diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 60549c381..a37672983 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -43,7 +43,9 @@ class Controller extends BaseController $s3s = S3Storage::ownedByCurrentTeam()->get(); $resources = 0; foreach ($projects as $project) { + ray($project->postgresqls); $resources += $project->applications->count(); + $resources += $project->postgresqls->count(); } return view('dashboard', [ diff --git a/app/Http/Controllers/DatabaseController.php b/app/Http/Controllers/DatabaseController.php new file mode 100644 index 000000000..7adb53f1f --- /dev/null +++ b/app/Http/Controllers/DatabaseController.php @@ -0,0 +1,30 @@ +load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); + if (!$project) { + return redirect()->route('dashboard'); + } + $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']); + if (!$environment) { + return redirect()->route('dashboard'); + } + $database = $environment->databases->where('uuid', request()->route('database_uuid'))->first(); + if (!$database) { + return redirect()->route('dashboard'); + } + return view('project.database.configuration', ['database' => $database]); + } +} \ No newline at end of file diff --git a/app/Http/Livewire/ActivityMonitor.php b/app/Http/Livewire/ActivityMonitor.php index 4352b9dc9..b11bcdb38 100644 --- a/app/Http/Livewire/ActivityMonitor.php +++ b/app/Http/Livewire/ActivityMonitor.php @@ -51,4 +51,4 @@ class ActivityMonitor extends Component ]); $this->activity->save(); } -} +} \ No newline at end of file diff --git a/app/Http/Livewire/S3Test.php b/app/Http/Livewire/Dev/S3Test.php similarity index 94% rename from app/Http/Livewire/S3Test.php rename to app/Http/Livewire/Dev/S3Test.php index 57ef3728e..7aaf732bc 100644 --- a/app/Http/Livewire/S3Test.php +++ b/app/Http/Livewire/Dev/S3Test.php @@ -1,6 +1,6 @@ s3 = S3Storage::first(); - ray($this->s3); } public function save() { try { diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index f632a4431..2d15489fb 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -33,6 +33,7 @@ class General extends Component protected $rules = [ 'application.name' => 'required', + 'application.description' => 'nullable', 'application.fqdn' => 'nullable', 'application.git_repository' => 'required', 'application.git_branch' => 'required', @@ -49,6 +50,7 @@ class General extends Component ]; protected $validationAttributes = [ 'application.name' => 'name', + 'application.description' => 'description', 'application.fqdn' => 'FQDN', 'application.git_repository' => 'Git repository', 'application.git_branch' => 'Git branch', diff --git a/app/Http/Livewire/Application/Heading.php b/app/Http/Livewire/Project/Application/Heading.php similarity index 97% rename from app/Http/Livewire/Application/Heading.php rename to app/Http/Livewire/Project/Application/Heading.php index b062862b5..8a52061ef 100644 --- a/app/Http/Livewire/Application/Heading.php +++ b/app/Http/Livewire/Project/Application/Heading.php @@ -1,6 +1,6 @@ parameters = getRouteParameters(); + } + public function start() { + if ($this->database->type() === 'postgresql') { + $activity = resolve(StartPostgresql::class)($this->database->destination->server, $this->database); + $this->emit('newMonitorActivity', $activity->id); + } + } +} \ No newline at end of file diff --git a/app/Http/Livewire/Project/Database/Postgresql/General.php b/app/Http/Livewire/Project/Database/Postgresql/General.php new file mode 100644 index 000000000..b3e2faa99 --- /dev/null +++ b/app/Http/Livewire/Project/Database/Postgresql/General.php @@ -0,0 +1,39 @@ + 'required', + 'database.description' => 'nullable', + 'database.postgres_user' => 'required', + 'database.postgres_password' => 'required', + 'database.postgres_db' => 'required', + 'database.postgres_initdb_args' => 'nullable', + 'database.postgres_host_auth_method' => 'nullable', + 'database.init_scripts' => 'nullable', + ]; + protected $validationAttributes = [ + 'database.name' => 'Name', + 'database.description' => 'Description', + 'database.postgres_user' => 'Postgres User', + 'database.postgres_password' => 'Postgres Password', + 'database.postgres_db' => 'Postgres DB', + 'database.postgres_initdb_args' => 'Postgres Initdb Args', + 'database.postgres_host_auth_method' => 'Postgres Host Auth Method', + 'database.init_scripts' => 'Init Scripts', + ]; + public function submit() { + try { + $this->validate(); + $this->database->save(); + $this->emit('success', 'Database updated successfully.'); + } catch (\Exception $e) { + return general_error_handler(err: $e, that: $this); + } + } +} \ No newline at end of file diff --git a/app/Models/Environment.php b/app/Models/Environment.php index c79472e88..e7139a5bd 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -17,6 +17,12 @@ class Environment extends Model set: fn (string $value) => strtolower($value), ); } + public function can_delete_environment() { + return $this->applications()->count() == 0 && $this->postgresqls()->count() == 0; + } + public function databases() { + return $this->postgresqls(); + } public function project() { return $this->belongsTo(Project::class); @@ -25,12 +31,12 @@ class Environment extends Model { return $this->hasMany(Application::class); } - public function databases() + public function postgresqls() { - return $this->hasMany(Database::class); + return $this->hasMany(Postgresql::class); } public function services() { return $this->hasMany(Service::class); } -} +} \ No newline at end of file diff --git a/app/Models/Postgresql.php b/app/Models/Postgresql.php new file mode 100644 index 000000000..10e536685 --- /dev/null +++ b/app/Models/Postgresql.php @@ -0,0 +1,25 @@ + 'encrypted', + ]; + public function type() { + return 'postgresql'; + } + public function environment() + { + return $this->belongsTo(Environment::class); + } + public function destination() + { + return $this->morphTo(); + } +} \ No newline at end of file diff --git a/app/Models/Project.php b/app/Models/Project.php index a0a342755..791b8a7cc 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -46,4 +46,8 @@ class Project extends BaseModel { return $this->hasManyThrough(Application::class, Environment::class); } -} + public function postgresqls() + { + return $this->hasManyThrough(Postgresql::class, Environment::class); + } +} \ No newline at end of file diff --git a/app/Models/S3Storage.php b/app/Models/S3Storage.php index 46fc37783..a6f6360ac 100644 --- a/app/Models/S3Storage.php +++ b/app/Models/S3Storage.php @@ -8,6 +8,10 @@ class S3Storage extends BaseModel { use HasFactory; protected $guarded = []; + protected $casts = [ + 'key' => 'encrypted', + 'secret' => 'encrypted', + ]; static public function ownedByCurrentTeam(array $select = ['*']) { diff --git a/app/Models/StandaloneDocker.php b/app/Models/StandaloneDocker.php index ea257dd60..e5f1cf3f3 100644 --- a/app/Models/StandaloneDocker.php +++ b/app/Models/StandaloneDocker.php @@ -13,9 +13,9 @@ class StandaloneDocker extends BaseModel { return $this->morphMany(Application::class, 'destination'); } - public function databases() + public function postgresqls() { - return $this->morphMany(Database::class, 'destination'); + return $this->morphMany(Postgresql::class, 'destination'); } public function server() { @@ -25,4 +25,4 @@ class StandaloneDocker extends BaseModel { return $this->applications->count() > 0 || $this->databases->count() > 0; } -} +} \ No newline at end of file diff --git a/app/View/Components/Modal.php b/app/View/Components/Modal.php index b317d3c44..22c5a7bba 100644 --- a/app/View/Components/Modal.php +++ b/app/View/Components/Modal.php @@ -14,7 +14,7 @@ class Modal extends Component */ public function __construct( public string $modalId, - public string $modalTitle, + public string|null $modalTitle = null, public string|null $modalBody = null, public string|null $modalSubmit = null, public bool $yesOrNo = false, @@ -30,4 +30,4 @@ class Modal extends Component { return view('components.modal'); } -} +} \ No newline at end of file diff --git a/database/migrations/2023_08_07_073651_create_s3_storages_table.php b/database/migrations/2023_08_07_073651_create_s3_storages_table.php index 711707e9e..cdda367a2 100644 --- a/database/migrations/2023_08_07_073651_create_s3_storages_table.php +++ b/database/migrations/2023_08_07_073651_create_s3_storages_table.php @@ -14,7 +14,7 @@ return new class extends Migration Schema::create('s3_storages', function (Blueprint $table) { $table->id(); $table->string('uuid')->unique(); - $table->string('name')->nullable(); + $table->string('name'); $table->longText('description')->nullable(); $table->string('region')->default('us-east-1'); $table->longText('key'); diff --git a/database/migrations/2023_08_07_142950_create_postgresqls_table.php b/database/migrations/2023_08_07_142950_create_postgresqls_table.php new file mode 100644 index 000000000..8d126ce3e --- /dev/null +++ b/database/migrations/2023_08_07_142950_create_postgresqls_table.php @@ -0,0 +1,42 @@ +id(); + $table->string('uuid')->unique(); + $table->string('name'); + $table->string('description')->nullable(); + + $table->string('postgres_user')->default('postgres'); + $table->string('postgres_password'); + $table->string('postgres_db')->default('postgres'); + $table->string('postgres_initdb_args')->nullable(); + $table->string('postgres_host_auth_method')->nullable(); + $table->json('init_scripts')->nullable(); + + $table->timestamp('started_at')->nullable(); + $table->morphs('destination'); + + $table->foreignId('environment_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('postgresqls'); + } +}; \ No newline at end of file diff --git a/database/migrations/2023_03_27_083620_create_databases_table.php b/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php similarity index 51% rename from database/migrations/2023_03_27_083620_create_databases_table.php rename to database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php index bfafb9c0c..02d4c5935 100644 --- a/database/migrations/2023_03_27_083620_create_databases_table.php +++ b/database/migrations/2023_08_07_142951_add_description_field_to_applications_table.php @@ -11,15 +11,8 @@ return new class extends Migration */ public function up(): void { - Schema::create('databases', function (Blueprint $table) { - $table->id(); - $table->string('uuid')->unique(); - $table->string('name'); - - $table->morphs('destination'); - - $table->foreignId('environment_id'); - $table->timestamps(); + Schema::table('applications', function (Blueprint $table) { + $table->string('description')->nullable(); }); } @@ -28,6 +21,8 @@ return new class extends Migration */ public function down(): void { - Schema::dropIfExists('databases'); + Schema::table('applications', function (Blueprint $table) { + $table->dropColumn('description'); + }); } -}; +}; \ No newline at end of file diff --git a/database/seeders/ApplicationSeeder.php b/database/seeders/ApplicationSeeder.php index 2859bed81..9cffe6fbe 100644 --- a/database/seeders/ApplicationSeeder.php +++ b/database/seeders/ApplicationSeeder.php @@ -19,13 +19,11 @@ class ApplicationSeeder extends Seeder */ public function run(): void { - $environment_1 = Environment::find(1); - $standalone_docker_1 = StandaloneDocker::find(1); - $github_public_source = GithubApp::where('name', 'Public GitHub')->first(); Application::create([ 'name' => 'coollabsio/coolify-examples:nodejs-fastify', + 'description' => 'NodeJS Fastify Example', 'fqdn' => 'http://foo.com', 'repository_project_id' => 603035348, 'git_repository' => 'coollabsio/coolify-examples', @@ -33,11 +31,11 @@ class ApplicationSeeder extends Seeder 'build_pack' => 'nixpacks', 'ports_exposes' => '3000', 'ports_mappings' => '3000:3000', - 'environment_id' => $environment_1->id, - 'destination_id' => $standalone_docker_1->id, + 'environment_id' => 1, + 'destination_id' => 1, 'destination_type' => StandaloneDocker::class, 'source_id' => $github_public_source->id, 'source_type' => GithubApp::class ]); } -} +} \ No newline at end of file diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index bba3978ac..7fa45e6b8 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -32,6 +32,7 @@ class DatabaseSeeder extends Seeder EnvironmentVariableSeeder::class, LocalPersistentVolumeSeeder::class, S3StorageSeeder::class, + PostgresqlSeeder::class, ]); } } \ No newline at end of file diff --git a/database/seeders/PostgresqlSeeder.php b/database/seeders/PostgresqlSeeder.php new file mode 100644 index 000000000..2568feb10 --- /dev/null +++ b/database/seeders/PostgresqlSeeder.php @@ -0,0 +1,26 @@ + 'Local PostgreSQL', + 'description' => 'Local PostgreSQL for testing', + 'postgres_password' => 'postgres', + 'environment_id' => 1, + 'destination_id' => 1, + 'destination_type' => StandaloneDocker::class, + ]); + } +} \ No newline at end of file diff --git a/resources/views/components/databases/navbar.blade.php b/resources/views/components/databases/navbar.blade.php new file mode 100644 index 000000000..fc8e7b68a --- /dev/null +++ b/resources/views/components/databases/navbar.blade.php @@ -0,0 +1,41 @@ + diff --git a/resources/views/components/modal.blade.php b/resources/views/components/modal.blade.php index 052c2b943..711515437 100644 --- a/resources/views/components/modal.blade.php +++ b/resources/views/components/modal.blade.php @@ -10,7 +10,9 @@
-

{{ $modalTitle }}

+ @isset($modalTitle) +

{{ $modalTitle }}

+ @endisset @isset($modalBody) {{ $modalBody }} @endisset @@ -31,8 +33,11 @@
@else -