From e77e807cdd830b71e0d6885b417c0ab14ef7de0f Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:54:16 +0200 Subject: [PATCH 1/9] Add UI --- .../project/database/redis/general.blade.php | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/resources/views/livewire/project/database/redis/general.blade.php b/resources/views/livewire/project/database/redis/general.blade.php index ceb12a802..35ee90583 100644 --- a/resources/views/livewire/project/database/redis/general.blade.php +++ b/resources/views/livewire/project/database/redis/general.blade.php @@ -9,48 +9,41 @@
- + +
+
+ +

Network

- +
- + @if ($db_url_public) - + @endif

Proxy

- + Proxy Logs - + - Proxy Logs + Proxy Logs
- +

Advanced

- +
+ From a2ba67ea34f33cad2bfeacf928ead01fa9a90baf Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:19:36 +0200 Subject: [PATCH 2/9] Add redis username --- app/Actions/Database/StartRedis.php | 16 +++++++++++- .../Project/Database/Redis/General.php | 25 ++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index f10afef5e..b3f240942 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -166,6 +166,14 @@ class StartRedis $environment_variables->push("$env->key=$env->real_value"); } + $redis_version = $this->get_redis_version(); + + if (version_compare($redis_version, '6.0', '>=')) { + if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_USERNAME'))->isEmpty()) { + $environment_variables->push("REDIS_USERNAME={$this->database->redis_username}"); + } + } + if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_PASSWORD'))->isEmpty()) { $environment_variables->push("REDIS_PASSWORD={$this->database->redis_password}"); } @@ -173,6 +181,12 @@ class StartRedis return $environment_variables->all(); } + private function get_redis_version() + { + $image_parts = explode(':', $this->database->image); + return $image_parts[1] ?? '0.0'; + } + private function add_custom_redis() { if (is_null($this->database->redis_conf) || empty($this->database->redis_conf)) { @@ -184,4 +198,4 @@ class StartRedis instant_scp($path, "{$this->configuration_dir}/{$filename}", $this->database->destination->server); Storage::disk('local')->delete("tmp/redis.conf_{$this->database->uuid}"); } -} +} \ No newline at end of file diff --git a/app/Livewire/Project/Database/Redis/General.php b/app/Livewire/Project/Database/Redis/General.php index a7ce0161a..6acd1095f 100644 --- a/app/Livewire/Project/Database/Redis/General.php +++ b/app/Livewire/Project/Database/Redis/General.php @@ -25,6 +25,7 @@ class General extends Component 'database.name' => 'required', 'database.description' => 'nullable', 'database.redis_conf' => 'nullable', + 'database.redis_username' => 'required', 'database.redis_password' => 'required', 'database.image' => 'required', 'database.ports_mappings' => 'nullable', @@ -37,6 +38,7 @@ class General extends Component 'database.name' => 'Name', 'database.description' => 'Description', 'database.redis_conf' => 'Redis Configuration', + 'database.redis_username' => 'Redis Username', 'database.redis_password' => 'Redis Password', 'database.image' => 'Image', 'database.ports_mappings' => 'Port Mapping', @@ -73,16 +75,33 @@ class General extends Component { try { $this->validate(); - if ($this->database->redis_conf === '') { - $this->database->redis_conf = null; + + $redis_version = $this->get_redis_version(); + + if (version_compare($redis_version, '6.0', '>=')) { + if ($this->database->isDirty('redis_username')) { + $this->database->redis_username = $this->database->redis_username; + } } + + if ($this->database->isDirty('redis_password')) { + $this->database->redis_password = $this->database->redis_password; + } + $this->database->save(); + $this->dispatch('success', 'Database updated.'); } catch (Exception $e) { return handleError($e, $this); } } + private function get_redis_version() + { + $image_parts = explode(':', $this->database->image); + return $image_parts[1] ?? '0.0'; + } + public function instantSave() { try { @@ -123,4 +142,4 @@ class General extends Component { return view('livewire.project.database.redis.general'); } -} +} \ No newline at end of file From 388f8c4e9533bdaa5f21398bde0119dded3095e5 Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:20:03 +0200 Subject: [PATCH 3/9] Security fix redis password and username logic --- app/Models/StandaloneRedis.php | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 8a202ea9e..b08825bd4 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -16,6 +16,14 @@ class StandaloneRedis extends BaseModel protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status']; + protected $casts = [ + 'redis_password' => 'encrypted', + ]; + + protected $attributes = [ + 'redis_username' => 'redis', + ]; + protected static function booted() { static::created(function ($database) { @@ -205,7 +213,11 @@ class StandaloneRedis extends BaseModel protected function internalDbUrl(): Attribute { return new Attribute( - get: fn () => "redis://:{$this->redis_password}@{$this->uuid}:6379/0", + get: function () { + $redis_version = $this->get_redis_version(); + $username_part = version_compare($redis_version, '6.0', '>=') ? "{$this->redis_username}:" : ""; + return "redis://{$username_part}{$this->redis_password}@{$this->uuid}:6379/0"; + } ); } @@ -214,14 +226,21 @@ class StandaloneRedis extends BaseModel return new Attribute( get: function () { if ($this->is_public && $this->public_port) { - return "redis://:{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0"; + $redis_version = $this->get_redis_version(); + $username_part = version_compare($redis_version, '6.0', '>=') ? "{$this->redis_username}:" : ""; + return "redis://{$username_part}{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0"; } - return null; } ); } + private function get_redis_version() + { + $image_parts = explode(':', $this->image); + return $image_parts[1] ?? '0.0'; + } + public function environment() { return $this->belongsTo(Environment::class); @@ -285,4 +304,4 @@ class StandaloneRedis extends BaseModel return $parsedCollection->toArray(); } } -} +} \ No newline at end of file From ae7e5487791c08a0f0a40ad5554af81050346876 Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:20:15 +0200 Subject: [PATCH 4/9] DB migration for redis username --- ...dis_username_to_standalone_redis_table.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 database/migrations/2024_08_21_165435_add_redis_username_to_standalone_redis_table.php diff --git a/database/migrations/2024_08_21_165435_add_redis_username_to_standalone_redis_table.php b/database/migrations/2024_08_21_165435_add_redis_username_to_standalone_redis_table.php new file mode 100644 index 000000000..397c6a68f --- /dev/null +++ b/database/migrations/2024_08_21_165435_add_redis_username_to_standalone_redis_table.php @@ -0,0 +1,22 @@ +string('redis_username')->default('redis')->after('description'); + }); + } + + public function down(): void + { + Schema::table('standalone_redis', function (Blueprint $table) { + $table->dropColumn('redis_username'); + }); + } +}; From 68060ef37dbe94c675925ad01b09ed05fbaab5ac Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:20:28 +0200 Subject: [PATCH 5/9] typo in redis seeder --- database/seeders/StandaloneRedisSeeder.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/database/seeders/StandaloneRedisSeeder.php b/database/seeders/StandaloneRedisSeeder.php index e7bf3373e..7c64b17a2 100644 --- a/database/seeders/StandaloneRedisSeeder.php +++ b/database/seeders/StandaloneRedisSeeder.php @@ -11,8 +11,9 @@ class StandaloneRedisSeeder extends Seeder public function run(): void { StandaloneRedis::create([ - 'name' => 'Local PostgreSQL', - 'description' => 'Local PostgreSQL for testing', + 'name' => 'Local Redis', + 'description' => 'Local Redis for testing', + 'redis_username' => 'redis', 'redis_password' => 'redis', 'environment_id' => 1, 'destination_id' => 0, From 462acda233507c19acd541f9b3d6a2893e2a7a8a Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:20:46 +0200 Subject: [PATCH 6/9] Feat: add UI for redis password and username --- .../livewire/project/database/redis/general.blade.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/resources/views/livewire/project/database/redis/general.blade.php b/resources/views/livewire/project/database/redis/general.blade.php index 35ee90583..e062a4bcd 100644 --- a/resources/views/livewire/project/database/redis/general.blade.php +++ b/resources/views/livewire/project/database/redis/general.blade.php @@ -12,8 +12,13 @@
- - + @php + $redis_version = explode(':', $database->image)[1] ?? '0.0'; + @endphp + @if (version_compare($redis_version, '6.0', '>=')) + + @endif +

Network

@@ -46,4 +51,4 @@
- + \ No newline at end of file From 3d7a467abf936f50167cf06445c4b61d008c2ae3 Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Fri, 23 Aug 2024 19:00:18 +0200 Subject: [PATCH 7/9] WIP WIP --- app/Actions/Database/StartRedis.php | 56 +++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index b3f240942..6d1548357 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -20,10 +20,42 @@ class StartRedis public function handle(StandaloneRedis $database) { $this->database = $database; + //$this->configuration_dir = database_configuration_dir().'/'.$this->database->uuid; + + //$this->add_custom_redis(); + + // $startCommand = "redis-server"; + // $additionalArgs = []; + + // if (!is_null($this->database->redis_conf) && !empty($this->database->redis_conf)) { + // ray("Using custom Redis configuration"); + // $additionalArgs[] = "{$this->configuration_dir}/redis.conf"; + + // // Check if the custom config contains a requirepass directive + // $configContent = file_get_contents("{$this->configuration_dir}/redis.conf"); + // if (strpos($configContent, 'requirepass') === false) { + // $additionalArgs[] = "--requirepass {$this->database->redis_password}"; + // ray("No requirepass in custom config, adding it as an argument"); + // } else { + // ray("requirepass found in custom config"); + // } + // } else { + // $additionalArgs[] = "--requirepass {$this->database->redis_password}"; + // $additionalArgs[] = "--appendonly yes"; + // ray("No custom config, using default arguments"); + // } + + // if (!empty($additionalArgs)) { + // $startCommand .= " " . implode(" ", $additionalArgs); + // } + + // ray("Final start command: " . $startCommand); $startCommand = "redis-server --requirepass {$this->database->redis_password} --appendonly yes"; + $container_name = $this->database->uuid; + $this->configuration_dir = database_configuration_dir().'/'.$container_name; $this->commands = [ @@ -31,12 +63,14 @@ class StartRedis "mkdir -p $this->configuration_dir", ]; + $persistent_storages = $this->generate_local_persistent_volumes(); $persistent_file_volumes = $this->database->fileStorages()->get(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $environment_variables = $this->generate_environment_variables(); $this->add_custom_redis(); + $docker_compose = [ 'services' => [ $container_name => [ @@ -113,6 +147,7 @@ class StartRedis 'read_only' => true, ]; $docker_compose['services'][$container_name]['command'] = "redis-server /usr/local/etc/redis/redis.conf --requirepass {$this->database->redis_password} --appendonly yes"; + } $docker_compose = Yaml::dump($docker_compose, 10); $docker_compose_base64 = base64_encode($docker_compose); @@ -178,13 +213,20 @@ class StartRedis $environment_variables->push("REDIS_PASSWORD={$this->database->redis_password}"); } - return $environment_variables->all(); - } + ray('Initial environment variables:', $environment_variables->toArray()); - private function get_redis_version() - { - $image_parts = explode(':', $this->database->image); - return $image_parts[1] ?? '0.0'; + // Overwrite with UI-set environment variables + $ui_variables = $this->database->environment_variables()->get();//this is working + ray('UI-set environment variables:', $ui_variables->toArray()); + + foreach ($ui_variables as $ui_variable) { //the overwrite is not working it is set wrong + $environment_variables = $environment_variables->reject(fn ($env) => str($env)->startsWith("{$ui_variable->key}=")); + $environment_variables->push("{$ui_variable->key}={$ui_variable->real_value}"); + } + + ray('Final environment variables:', $environment_variables->toArray()); + + return $environment_variables->all(); } private function add_custom_redis() @@ -194,7 +236,7 @@ class StartRedis } $filename = 'redis.conf'; Storage::disk('local')->put("tmp/redis.conf_{$this->database->uuid}", $this->database->redis_conf); - $path = Storage::path("tmp/redis.conf_{$this->database->uuid}"); + $path = Storage::path("tmp/redis.conf_{$this->database->uuid}"); instant_scp($path, "{$this->configuration_dir}/{$filename}", $this->database->destination->server); Storage::disk('local')->delete("tmp/redis.conf_{$this->database->uuid}"); } From 1ae145bf13de253107537b3b0018e9b433b95418 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:49:33 +0200 Subject: [PATCH 8/9] Revert "typo in redis seeder" This reverts commit 68060ef37dbe94c675925ad01b09ed05fbaab5ac. --- database/seeders/StandaloneRedisSeeder.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/database/seeders/StandaloneRedisSeeder.php b/database/seeders/StandaloneRedisSeeder.php index 7c64b17a2..e7bf3373e 100644 --- a/database/seeders/StandaloneRedisSeeder.php +++ b/database/seeders/StandaloneRedisSeeder.php @@ -11,9 +11,8 @@ class StandaloneRedisSeeder extends Seeder public function run(): void { StandaloneRedis::create([ - 'name' => 'Local Redis', - 'description' => 'Local Redis for testing', - 'redis_username' => 'redis', + 'name' => 'Local PostgreSQL', + 'description' => 'Local PostgreSQL for testing', 'redis_password' => 'redis', 'environment_id' => 1, 'destination_id' => 0, From e5b798964dce9489d0391b7337f850789801e658 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 26 Sep 2024 20:01:35 +0200 Subject: [PATCH 9/9] Update StartRedis.php --- app/Actions/Database/StartRedis.php | 74 ++++------------------------- 1 file changed, 9 insertions(+), 65 deletions(-) diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index 6d1548357..eeddab924 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -20,42 +20,10 @@ class StartRedis public function handle(StandaloneRedis $database) { $this->database = $database; - //$this->configuration_dir = database_configuration_dir().'/'.$this->database->uuid; - - //$this->add_custom_redis(); - - // $startCommand = "redis-server"; - // $additionalArgs = []; - - // if (!is_null($this->database->redis_conf) && !empty($this->database->redis_conf)) { - // ray("Using custom Redis configuration"); - // $additionalArgs[] = "{$this->configuration_dir}/redis.conf"; - - // // Check if the custom config contains a requirepass directive - // $configContent = file_get_contents("{$this->configuration_dir}/redis.conf"); - // if (strpos($configContent, 'requirepass') === false) { - // $additionalArgs[] = "--requirepass {$this->database->redis_password}"; - // ray("No requirepass in custom config, adding it as an argument"); - // } else { - // ray("requirepass found in custom config"); - // } - // } else { - // $additionalArgs[] = "--requirepass {$this->database->redis_password}"; - // $additionalArgs[] = "--appendonly yes"; - // ray("No custom config, using default arguments"); - // } - - // if (!empty($additionalArgs)) { - // $startCommand .= " " . implode(" ", $additionalArgs); - // } - - // ray("Final start command: " . $startCommand); $startCommand = "redis-server --requirepass {$this->database->redis_password} --appendonly yes"; - $container_name = $this->database->uuid; - $this->configuration_dir = database_configuration_dir().'/'.$container_name; $this->commands = [ @@ -63,14 +31,12 @@ class StartRedis "mkdir -p $this->configuration_dir", ]; - $persistent_storages = $this->generate_local_persistent_volumes(); $persistent_file_volumes = $this->database->fileStorages()->get(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $environment_variables = $this->generate_environment_variables(); $this->add_custom_redis(); - $docker_compose = [ 'services' => [ $container_name => [ @@ -116,14 +82,7 @@ class StartRedis data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset); } if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { - $docker_compose['services'][$container_name]['logging'] = [ - 'driver' => 'fluentd', - 'options' => [ - 'fluentd-address' => 'tcp://127.0.0.1:24224', - 'fluentd-async' => 'true', - 'fluentd-sub-second-precision' => 'true', - ], - ]; + $docker_compose['services'][$container_name]['logging'] = generate_fluentd_configuration(); } if (count($this->database->ports_mappings_array) > 0) { $docker_compose['services'][$container_name]['ports'] = $this->database->ports_mappings_array; @@ -147,8 +106,12 @@ class StartRedis 'read_only' => true, ]; $docker_compose['services'][$container_name]['command'] = "redis-server /usr/local/etc/redis/redis.conf --requirepass {$this->database->redis_password} --appendonly yes"; - } + + // Add custom docker run options + $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options); + $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network); + $docker_compose = Yaml::dump($docker_compose, 10); $docker_compose_base64 = base64_encode($docker_compose); $this->commands[] = "echo '{$docker_compose_base64}' | base64 -d | tee $this->configuration_dir/docker-compose.yml > /dev/null"; @@ -201,30 +164,11 @@ class StartRedis $environment_variables->push("$env->key=$env->real_value"); } - $redis_version = $this->get_redis_version(); - - if (version_compare($redis_version, '6.0', '>=')) { - if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_USERNAME'))->isEmpty()) { - $environment_variables->push("REDIS_USERNAME={$this->database->redis_username}"); - } - } - if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_PASSWORD'))->isEmpty()) { $environment_variables->push("REDIS_PASSWORD={$this->database->redis_password}"); } - ray('Initial environment variables:', $environment_variables->toArray()); - - // Overwrite with UI-set environment variables - $ui_variables = $this->database->environment_variables()->get();//this is working - ray('UI-set environment variables:', $ui_variables->toArray()); - - foreach ($ui_variables as $ui_variable) { //the overwrite is not working it is set wrong - $environment_variables = $environment_variables->reject(fn ($env) => str($env)->startsWith("{$ui_variable->key}=")); - $environment_variables->push("{$ui_variable->key}={$ui_variable->real_value}"); - } - - ray('Final environment variables:', $environment_variables->toArray()); + add_coolify_default_environment_variables($this->database, $environment_variables, $environment_variables); return $environment_variables->all(); } @@ -236,8 +180,8 @@ class StartRedis } $filename = 'redis.conf'; Storage::disk('local')->put("tmp/redis.conf_{$this->database->uuid}", $this->database->redis_conf); - $path = Storage::path("tmp/redis.conf_{$this->database->uuid}"); + $path = Storage::path("tmp/redis.conf_{$this->database->uuid}"); instant_scp($path, "{$this->configuration_dir}/{$filename}", $this->database->destination->server); Storage::disk('local')->delete("tmp/redis.conf_{$this->database->uuid}"); } -} \ No newline at end of file +}