fix: redis database user and password
This commit is contained in:
@@ -4,7 +4,6 @@ namespace App\Livewire\Project\Database\Redis;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Database\StopDatabaseProxy;
|
||||
use App\Models\EnvironmentVariable;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneRedis;
|
||||
use Exception;
|
||||
@@ -12,12 +11,21 @@ use Livewire\Component;
|
||||
|
||||
class General extends Component
|
||||
{
|
||||
protected $listeners = ['refresh'];
|
||||
protected $listeners = [
|
||||
'envsUpdated' => 'refresh',
|
||||
'refresh',
|
||||
];
|
||||
|
||||
public Server $server;
|
||||
|
||||
public StandaloneRedis $database;
|
||||
|
||||
public ?string $redis_username;
|
||||
|
||||
public ?string $redis_password;
|
||||
|
||||
public string $redis_version;
|
||||
|
||||
public ?string $db_url = null;
|
||||
|
||||
public ?string $db_url_public = null;
|
||||
@@ -26,35 +34,33 @@ 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',
|
||||
'database.is_public' => 'nullable|boolean',
|
||||
'database.public_port' => 'nullable|integer',
|
||||
'database.is_log_drain_enabled' => 'nullable|boolean',
|
||||
'database.custom_docker_run_options' => 'nullable',
|
||||
'redis_username' => 'required',
|
||||
'redis_password' => 'required',
|
||||
];
|
||||
|
||||
protected $validationAttributes = [
|
||||
'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',
|
||||
'database.is_public' => 'Is Public',
|
||||
'database.public_port' => 'Public Port',
|
||||
'database.custom_docker_run_options' => 'Custom Docker Options',
|
||||
'redis_username' => 'Redis Username',
|
||||
'redis_password' => 'Redis Password',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->db_url = $this->database->internal_db_url;
|
||||
$this->db_url_public = $this->database->external_db_url;
|
||||
$this->server = data_get($this->database, 'destination.server');
|
||||
|
||||
$this->refreshView();
|
||||
}
|
||||
|
||||
public function instantSaveAdvanced()
|
||||
@@ -79,31 +85,26 @@ class General extends Component
|
||||
try {
|
||||
$this->validate();
|
||||
|
||||
$redis_version = $this->get_redis_version();
|
||||
|
||||
if (version_compare($redis_version, '6.0', '>=') && $this->database->isDirty('redis_username')) {
|
||||
$this->updateEnvironmentVariable('REDIS_USERNAME', $this->database->redis_username);
|
||||
}
|
||||
|
||||
if ($this->database->isDirty('redis_password')) {
|
||||
$this->updateEnvironmentVariable('REDIS_PASSWORD', $this->database->redis_password);
|
||||
if (version_compare($this->redis_version, '6.0', '>=')) {
|
||||
$this->database->runtime_environment_variables()->updateOrCreate(
|
||||
['key' => 'REDIS_USERNAME'],
|
||||
['value' => $this->redis_username, 'standalone_redis_id' => $this->database->id]
|
||||
);
|
||||
}
|
||||
$this->database->runtime_environment_variables()->updateOrCreate(
|
||||
['key' => 'REDIS_PASSWORD'],
|
||||
['value' => $this->redis_password, 'standalone_redis_id' => $this->database->id]
|
||||
);
|
||||
|
||||
$this->database->save();
|
||||
|
||||
$this->dispatch('success', 'Database updated.');
|
||||
} catch (Exception $e) {
|
||||
return handleError($e, $this);
|
||||
} finally {
|
||||
$this->dispatch('refreshEnvs');
|
||||
}
|
||||
}
|
||||
|
||||
private function get_redis_version()
|
||||
{
|
||||
$image_parts = explode(':', $this->database->image);
|
||||
|
||||
return $image_parts[1] ?? '0.0';
|
||||
}
|
||||
|
||||
public function instantSave()
|
||||
{
|
||||
try {
|
||||
@@ -138,6 +139,14 @@ class General extends Component
|
||||
public function refresh(): void
|
||||
{
|
||||
$this->database->refresh();
|
||||
$this->refreshView();
|
||||
}
|
||||
private function refreshView() {
|
||||
$this->db_url = $this->database->internal_db_url;
|
||||
$this->db_url_public = $this->database->external_db_url;
|
||||
$this->redis_version = $this->database->getRedisVersion();
|
||||
$this->redis_username = $this->database->redis_username;
|
||||
$this->redis_password = $this->database->redis_password;
|
||||
}
|
||||
|
||||
public function render()
|
||||
@@ -147,28 +156,7 @@ class General extends Component
|
||||
|
||||
public function isSharedVariable($name)
|
||||
{
|
||||
return EnvironmentVariable::where('key', $name)
|
||||
->where('standalone_redis_id', $this->database->id)
|
||||
->where('is_shared', true)
|
||||
->exists();
|
||||
return $this->database->runtime_environment_variables()->where('key', $name)->where('is_shared', true)->exists();
|
||||
}
|
||||
|
||||
private function updateEnvironmentVariable($key, $value)
|
||||
{
|
||||
$envVar = $this->database->runtime_environment_variables()
|
||||
->where('key', $key)
|
||||
->first();
|
||||
|
||||
if ($envVar) {
|
||||
if (! $envVar->is_shared) {
|
||||
$envVar->update(['value' => $value]);
|
||||
}
|
||||
} else {
|
||||
$this->database->runtime_environment_variables()->create([
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
'is_shared' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -33,8 +33,6 @@ class Index extends Component
|
||||
|
||||
protected Server $server;
|
||||
|
||||
public $timezones;
|
||||
|
||||
protected $rules = [
|
||||
'settings.fqdn' => 'nullable',
|
||||
'settings.resale_license' => 'nullable',
|
||||
|
@@ -16,13 +16,6 @@ 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' => 'default',
|
||||
];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
@@ -219,7 +212,7 @@ class StandaloneRedis extends BaseModel
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
$redis_version = $this->get_redis_version();
|
||||
$redis_version = $this->getRedisVersion();
|
||||
$username_part = version_compare($redis_version, '6.0', '>=') ? "{$this->redis_username}:" : '';
|
||||
|
||||
return "redis://{$username_part}{$this->redis_password}@{$this->uuid}:6379/0";
|
||||
@@ -232,7 +225,7 @@ class StandaloneRedis extends BaseModel
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
if ($this->is_public && $this->public_port) {
|
||||
$redis_version = $this->get_redis_version();
|
||||
$redis_version = $this->getRedisVersion();
|
||||
$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";
|
||||
@@ -243,7 +236,7 @@ class StandaloneRedis extends BaseModel
|
||||
);
|
||||
}
|
||||
|
||||
private function get_redis_version()
|
||||
public function getRedisVersion()
|
||||
{
|
||||
$image_parts = explode(':', $this->image);
|
||||
|
||||
@@ -318,4 +311,32 @@ class StandaloneRedis extends BaseModel
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function redisPassword(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
$password = $this->runtime_environment_variables()->where('key', 'REDIS_PASSWORD')->first();
|
||||
if (! $password) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $password->value;
|
||||
},
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
public function redisUsername(): Attribute
|
||||
{
|
||||
return new Attribute(
|
||||
get: function () {
|
||||
$username = $this->runtime_environment_variables()->where('key', 'REDIS_USERNAME')->first();
|
||||
if (! $username) {
|
||||
return null;
|
||||
}
|
||||
return $username->value;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -50,7 +50,6 @@ function create_standalone_redis($environment_id, $destination_uuid, ?array $oth
|
||||
$database = new StandaloneRedis;
|
||||
$database->name = generate_database_name('redis');
|
||||
$database->redis_password = \Illuminate\Support\Str::password(length: 64, symbols: false);
|
||||
$database->redis_username = 'default';
|
||||
$database->environment_id = $environment_id;
|
||||
$database->destination_id = $destination->id;
|
||||
$database->destination_type = $destination->getMorphClass();
|
||||
@@ -68,7 +67,7 @@ function create_standalone_redis($environment_id, $destination_uuid, ?array $oth
|
||||
|
||||
EnvironmentVariable::create([
|
||||
'key' => 'REDIS_USERNAME',
|
||||
'value' => $database->redis_username,
|
||||
'value' => 'default',
|
||||
'standalone_redis_id' => $database->id,
|
||||
'is_shared' => false,
|
||||
]);
|
||||
|
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('standalone_redis', function (Blueprint $table) {
|
||||
$table->string('redis_username')->default('redis')->after('description');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('standalone_redis', function (Blueprint $table) {
|
||||
$table->dropColumn('redis_username');
|
||||
});
|
||||
}
|
||||
};
|
@@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class EncryptExistingRedisPasswords extends Migration
|
||||
class MoveRedisPasswordToEnvs extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
@@ -14,13 +14,15 @@ class EncryptExistingRedisPasswords extends Migration
|
||||
try {
|
||||
DB::table('standalone_redis')->chunkById(100, function ($redisInstances) {
|
||||
foreach ($redisInstances as $redis) {
|
||||
DB::table('standalone_redis')
|
||||
->where('id', $redis->id)
|
||||
->update(['redis_password' => Crypt::encryptString($redis->redis_password)]);
|
||||
$redis->runtime_environment_variables()->firstOrCreate([
|
||||
'key' => 'REDIS_PASSWORD',
|
||||
'value' => $redis->redis_password,
|
||||
]);
|
||||
}
|
||||
});
|
||||
DB::statement('ALTER TABLE standalone_redis DROP COLUMN redis_password');
|
||||
} catch (\Exception $e) {
|
||||
echo 'Encrypting Redis passwords failed.';
|
||||
echo 'Moving Redis passwords to envs failed.';
|
||||
echo $e->getMessage();
|
||||
}
|
||||
}
|
@@ -12,25 +12,21 @@
|
||||
<x-forms.input label="Image" id="database.image" required helper="For all available images, check here:<br><br><a target='_blank' href='https://hub.docker.com/_/redis'>https://hub.docker.com/_/redis</a>" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
@php
|
||||
$redis_version = explode(':', $database->image)[1] ?? '0.0';
|
||||
@endphp
|
||||
@if (version_compare($redis_version, '6.0', '>='))
|
||||
<x-forms.input label="Username" id="database.redis_username" required
|
||||
<x-forms.input label="Username" id="redis_username" required
|
||||
helper="You can change the Redis Username in the input field below or by editing the value of the REDIS_USERNAME environment variable.
|
||||
<br><br>
|
||||
If you change the Redis Username in the database, please sync it here, otherwise automations (like backups) won't work.
|
||||
If you change the Redis Username in the database, please sync it here, otherwise automations (like backups) won't work.
|
||||
<br><br>
|
||||
Note: If the environment variable REDIS_USERNAME is set as a shared variable (environment, project, or team-based), this input field will become read-only."
|
||||
:disabled="$this->isSharedVariable('REDIS_USERNAME')" />
|
||||
@endif
|
||||
<x-forms.input label="Password" id="database.redis_password" type="password" required
|
||||
<x-forms.input label="Password" id="redis_password" type="password" required
|
||||
helper="You can change the Redis Password in the input field below or by editing the value of the REDIS_PASSWORD environment variable.
|
||||
<br><br>
|
||||
If you change the Redis Password in the database, please sync it here, otherwise automations (like backups) won't work.
|
||||
<br><br>
|
||||
Note: If the environment variable REDIS_PASSWORD is set as a shared variable (environment, project, or team-based), this input field will become read-only."
|
||||
wire:model.defer="database.redis_password"
|
||||
:disabled="$this->isSharedVariable('REDIS_PASSWORD')" />
|
||||
</div>
|
||||
<x-forms.input
|
||||
|
Reference in New Issue
Block a user