fix: aaaaaaaaaaaaaaaaa

This commit is contained in:
Andras Bacsai
2023-09-27 15:48:19 +02:00
parent f0abdcc2da
commit 398f122593
9 changed files with 159 additions and 109 deletions

View File

@@ -70,11 +70,10 @@ class ProjectController extends Controller
$oneClickServiceName = $type->after('one-click-service-')->value(); $oneClickServiceName = $type->after('one-click-service-')->value();
$oneClickService = data_get($services, "$oneClickServiceName.compose"); $oneClickService = data_get($services, "$oneClickServiceName.compose");
$oneClickDotEnvs = data_get($services, "$oneClickServiceName.envs", null); $oneClickDotEnvs = data_get($services, "$oneClickServiceName.envs", null);
$oneClickConfiguration = data_get($services, "$oneClickServiceName.configuration.proxy", []);
$oneClickConfiguration = collect($oneClickConfiguration);
if ($oneClickDotEnvs) { if ($oneClickDotEnvs) {
$oneClickDotEnvs = Str::of(base64_decode($oneClickDotEnvs))->split('/\r\n|\r|\n/'); $oneClickDotEnvs = Str::of(base64_decode($oneClickDotEnvs))->split('/\r\n|\r|\n/');
} }
ray($oneClickDotEnvs);
if ($oneClickService) { if ($oneClickService) {
$service = Service::create([ $service = Service::create([
'name' => "$oneClickServiceName-" . Str::random(10), 'name' => "$oneClickServiceName-" . Str::random(10),
@@ -84,38 +83,44 @@ class ProjectController extends Controller
]); ]);
$service->name = "$oneClickServiceName-" . $service->uuid; $service->name = "$oneClickServiceName-" . $service->uuid;
$service->save(); $service->save();
if ($oneClickDotEnvs && $oneClickDotEnvs->count() > 0) { if ($oneClickDotEnvs->count() > 0) {
$oneClickDotEnvs->each(function ($value) use ($service) { $oneClickDotEnvs->each(function ($value) use ($service) {
$key = Str::before($value, '='); $key = Str::before($value, '=');
$value = Str::of(Str::after($value, '=')); $value = Str::of(Str::after($value, '='));
if ($value->contains('SERVICE_USER')) { $generatedValue = $value;
$value = Str::of(Str::random(10)); if ($value->contains('SERVICE_')) {
} $command = $value->after('SERVICE_')->beforeLast('_');
if ($value->contains('SERVICE_PASSWORD')) { switch ($command->value()) {
$value = Str::of(Str::password(symbols: false)); case 'PASSWORD':
} $generatedValue = Str::password(symbols: false);
if ($value->contains('SERVICE_PASSWORD64')) { break;
$value = Str::of(Str::password(length: 64, symbols: false)); case 'PASSWORD_64':
} $generatedValue = Str::password(length: 64, symbols: false);
if ($value->contains('SERVICE_BASE64')) { break;
$length = Str::of($value)->after('SERVICE_BASE64_')->beforeLast('_')->value(); case 'BASE64_64':
if (is_numeric($length)) { $generatedValue = Str::random(64);
$length = (int) $length; break;
} else { case 'BASE64_128':
$length = 1; $generatedValue = Str::random(128);
break;
case 'BASE64':
$generatedValue = Str::random(32);
break;
case 'USER':
$generatedValue = Str::random(16);
break;
} }
$value = Str::of(base64_encode(Str::password(length: $length, symbols: false)));
} }
EnvironmentVariable::create([ EnvironmentVariable::create([
'key' => $key, 'key' => $key,
'value' => $value->value(), 'value' => $generatedValue,
'service_id' => $service->id, 'service_id' => $service->id,
'is_build_time' => false, 'is_build_time' => false,
'is_preview' => false, 'is_preview' => false,
]); ]);
}); });
} }
$service->parse(isNew: true, configuration: $oneClickConfiguration); $service->parse(isNew: true);
return redirect()->route('project.service', [ return redirect()->route('project.service', [
'service_uuid' => $service->uuid, 'service_uuid' => $service->uuid,

View File

@@ -53,19 +53,6 @@ class Index extends Component
{ {
return view('livewire.project.service.index'); return view('livewire.project.service.index');
} }
// public function save()
// {
// try {
// $this->service->save();
// $this->service->parse();
// $this->service->refresh();
// $this->emit('refreshEnvs');
// $this->emit('success', 'Service saved successfully.');
// $this->service->saveComposeConfigs();
// } catch (\Throwable $e) {
// return handleError($e, $this);
// }
// }
public function submit() public function submit()
{ {
try { try {

View File

@@ -5,12 +5,14 @@ namespace App\Http\Livewire\Project\Shared\EnvironmentVariable;
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable; use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
use Livewire\Component; use Livewire\Component;
use Visus\Cuid2\Cuid2; use Visus\Cuid2\Cuid2;
use Illuminate\Support\Str;
class Show extends Component class Show extends Component
{ {
public $parameters; public $parameters;
public ModelsEnvironmentVariable $env; public ModelsEnvironmentVariable $env;
public ?string $modalId = null; public ?string $modalId = null;
public bool $isDisabled = false;
public string $type; public string $type;
protected $rules = [ protected $rules = [
@@ -26,6 +28,10 @@ class Show extends Component
public function mount() public function mount()
{ {
$this->isDisabled = false;
if (Str::of($this->env->key)->startsWith('SERVICE_FQDN') || Str::of($this->env->key)->startsWith('SERVICE_URL')) {
$this->isDisabled = true;
}
$this->modalId = new Cuid2(7); $this->modalId = new Cuid2(7);
$this->parameters = get_route_parameters(); $this->parameters = get_route_parameters();
} }

View File

@@ -141,7 +141,7 @@ class Service extends BaseModel
} }
public function parse(bool $isNew = false): Collection public function parse(bool $isNew = false): Collection
{ {
ray()->clearAll(); // ray()->clearAll();
if ($this->docker_compose_raw) { if ($this->docker_compose_raw) {
try { try {
$yaml = Yaml::parse($this->docker_compose_raw); $yaml = Yaml::parse($this->docker_compose_raw);
@@ -155,7 +155,9 @@ class Service extends BaseModel
$services = data_get($yaml, 'services'); $services = data_get($yaml, 'services');
$definedNetwork = $this->uuid; $definedNetwork = $this->uuid;
$services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew) { $generatedServiceFQDNS = collect([]);
$services = collect($services)->map(function ($service, $serviceName) use ($topLevelVolumes, $topLevelNetworks, $definedNetwork, $isNew, $generatedServiceFQDNS) {
$serviceVolumes = collect(data_get($service, 'volumes', [])); $serviceVolumes = collect(data_get($service, 'volumes', []));
$servicePorts = collect(data_get($service, 'ports', [])); $servicePorts = collect(data_get($service, 'ports', []));
$serviceNetworks = collect(data_get($service, 'networks', [])); $serviceNetworks = collect(data_get($service, 'networks', []));
@@ -207,6 +209,21 @@ class Service extends BaseModel
])->first(); ])->first();
} }
} }
if (is_null($savedService)) {
if ($isDatabase) {
$savedService = ServiceDatabase::create([
'name' => $serviceName,
'image' => $image,
'service_id' => $this->id
]);
} else {
$savedService = ServiceApplication::create([
'name' => $serviceName,
'image' => $image,
'service_id' => $this->id
]);
}
}
// Collect/create/update networks // Collect/create/update networks
if ($serviceNetworks->count() > 0) { if ($serviceNetworks->count() > 0) {
@@ -258,6 +275,7 @@ class Service extends BaseModel
$type = null; $type = null;
$source = null; $source = null;
$target = null; $target = null;
$content = null;
if (is_string($volume)) { if (is_string($volume)) {
$source = Str::of($volume)->before(':'); $source = Str::of($volume)->before(':');
$target = Str::of($volume)->after(':')->beforeLast(':'); $target = Str::of($volume)->after(':')->beforeLast(':');
@@ -270,8 +288,15 @@ class Service extends BaseModel
$type = data_get_str($volume, 'type'); $type = data_get_str($volume, 'type');
$source = data_get_str($volume, 'source'); $source = data_get_str($volume, 'source');
$target = data_get_str($volume, 'target'); $target = data_get_str($volume, 'target');
$content = data_get($volume, 'content');
} }
if ($type->value() === 'bind') { if ($type->value() === 'bind') {
if ($source->value() === "/var/run/docker.sock") {
continue;
}
if ($source->value() === '/tmp' || $source->value() === '/tmp/' ) {
continue;
}
LocalFileVolume::updateOrCreate( LocalFileVolume::updateOrCreate(
[ [
'mount_path' => $target, 'mount_path' => $target,
@@ -281,6 +306,7 @@ class Service extends BaseModel
[ [
'fs_path' => $source, 'fs_path' => $source,
'mount_path' => $target, 'mount_path' => $target,
'content' => $content,
'resource_id' => $savedService->id, 'resource_id' => $savedService->id,
'resource_type' => get_class($savedService) 'resource_type' => get_class($savedService)
] ]
@@ -305,15 +331,15 @@ class Service extends BaseModel
} }
// Add env_file with at least .env to the service // Add env_file with at least .env to the service
$envFile = collect(data_get($service, 'env_file', [])); // $envFile = collect(data_get($service, 'env_file', []));
if ($envFile->count() > 0) { // if ($envFile->count() > 0) {
if (!$envFile->contains('.env')) { // if (!$envFile->contains('.env')) {
$envFile->push('.env'); // $envFile->push('.env');
} // }
} else { // } else {
$envFile = collect(['.env']); // $envFile = collect(['.env']);
} // }
data_set($service, 'env_file', $envFile->toArray()); // data_set($service, 'env_file', $envFile->toArray());
// Get variables from the service // Get variables from the service
@@ -333,9 +359,38 @@ class Service extends BaseModel
} else { } else {
// SESSION_SECRET: 123 // SESSION_SECRET: 123
// SESSION_SECRET: // SESSION_SECRET:
$key = $variableName; $key = Str::of($variableName);
$value = Str::of($variable); $value = Str::of($variable);
} }
if ($key->startsWith('SERVICE_FQDN')) {
if (is_null(data_get($savedService, 'fqdn'))) {
$sslip = $this->sslip($this->server);
$fqdn = "http://$containerName.$sslip";
if (substr_count($key->value(),'_') === 2) {
$path = $value->value();
if ($generatedServiceFQDNS->count() > 0) {
$alreadyGenerated = $generatedServiceFQDNS->has($key->value());
if ($alreadyGenerated) {
$fqdn = $generatedServiceFQDNS->get($key->value());
} else {
$generatedServiceFQDNS->put($key->value(), $fqdn);
}
} else {
ray($key, $fqdn);
$generatedServiceFQDNS->put($key->value(), $fqdn);
}
$fqdn = "http://$containerName.$sslip$path";
ray($fqdn);
}
if (!$isDatabase) {
$savedService->fqdn = $fqdn;
$savedService->save();
}
}
continue;
}
if ($value?->startsWith('$')) { if ($value?->startsWith('$')) {
$value = Str::of(replaceVariables($value)); $value = Str::of(replaceVariables($value));
$key = $value; $key = $value;
@@ -415,6 +470,9 @@ class Service extends BaseModel
$key = $value; $key = $value;
$defaultValue = null; $defaultValue = null;
} }
if ($foundEnv) {
$defaultValue = data_get($foundEnv, 'value');
}
EnvironmentVariable::updateOrCreate([ EnvironmentVariable::updateOrCreate([
'key' => $key, 'key' => $key,
'service_id' => $this->id, 'service_id' => $this->id,
@@ -429,7 +487,7 @@ class Service extends BaseModel
} }
// Add labels to the service // Add labels to the service
$fqdns = collect(data_get($savedService, 'fqdn')); $fqdns = collect(data_get($savedService, 'fqdns'));
$defaultLabels = defaultLabels($this->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id); $defaultLabels = defaultLabels($this->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id);
$serviceLabels = $serviceLabels->merge($defaultLabels); $serviceLabels = $serviceLabels->merge($defaultLabels);
if (!$isDatabase && $fqdns->count() > 0) { if (!$isDatabase && $fqdns->count() > 0) {
@@ -443,6 +501,15 @@ class Service extends BaseModel
data_set($service, 'restart', RESTART_MODE); data_set($service, 'restart', RESTART_MODE);
data_set($service, 'container_name', $containerName); data_set($service, 'container_name', $containerName);
data_forget($service, 'volumes.*.content'); data_forget($service, 'volumes.*.content');
// Remove unnecessary variables from service.environment
$withoutServiceEnvs = collect([]);
collect(data_get($service, 'environment'))->each(function ($value, $key) use ($withoutServiceEnvs) {
if (!Str::of($key)->startsWith('$SERVICE_')) {
$withoutServiceEnvs->put($key, $value);
}
});
data_set($service, 'environment', $withoutServiceEnvs->toArray());
return $service; return $service;
}); });
$finalServices = [ $finalServices = [

View File

@@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
@@ -26,6 +27,15 @@ class ServiceApplication extends BaseModel
{ {
return $this->morphMany(LocalFileVolume::class, 'resource'); return $this->morphMany(LocalFileVolume::class, 'resource');
} }
public function fqdns(): Attribute
{
return Attribute::make(
get: fn () => is_null($this->fqdn)
? []
: explode(',', $this->fqdn),
);
}
public function saveFileVolumes() public function saveFileVolumes()
{ {
saveFileVolumesHelper($this); saveFileVolumesHelper($this);

View File

@@ -109,19 +109,13 @@ function updateCompose($resource) {
// Update FQDN // Update FQDN
$variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper(); $variableName = "SERVICE_FQDN_" . Str::of($resource->name)->upper();
ray($variableName);
$generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first(); $generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
if ($generatedEnv){ if ($generatedEnv){
$generatedEnv->value = $resource->fqdn; $generatedEnv->value = $resource->fqdn;
$generatedEnv->save(); $generatedEnv->save();
} }
// // Update URL
// $variableName = "SERVICE_URL_" . Str::of($resource->name)->upper();
// $generatedEnv = EnvironmentVariable::where('service_id', $resource->service_id)->where('key', $variableName)->first();
// if ($generatedEnv){
// $generatedEnv->value = $resource->url;
// $generatedEnv->save();
// }
$dockerComposeRaw = Yaml::dump($dockerCompose, 10, 2); $dockerComposeRaw = Yaml::dump($dockerCompose, 10, 2);
$resource->service->docker_compose_raw = $dockerComposeRaw; $resource->service->docker_compose_raw = $dockerComposeRaw;

File diff suppressed because one or more lines are too long

View File

@@ -79,10 +79,10 @@
<span class="text-xs text-error">(configuration required)</span> <span class="text-xs text-error">(configuration required)</span>
@endif @endif
@if ($application->description) @if ($application->description)
<span class="text-xs">{{ $application->description }}</span> <span class="text-xs">{{ Str::limit($application->description, 60) }}</span>
@endif @endif
@if ($application->fqdn) @if ($application->fqdn)
<span class="text-xs">{{ $application->fqdn }}</span> <span class="text-xs">{{ Str::limit($application->fqdn, 60) }}</span>
@endif @endif
<div class="text-xs">{{ $application->status }}</div> <div class="text-xs">{{ $application->status }}</div>
</a> </a>
@@ -107,7 +107,7 @@
<span class="text-xs text-error">(configuration required)</span> <span class="text-xs text-error">(configuration required)</span>
@endif @endif
@if ($database->description) @if ($database->description)
<span class="text-xs">{{ $database->description }}</span> <span class="text-xs">{{ Str::limit($database->description, 60) }}</span>
@endif @endif
<div class="text-xs">{{ $database->status }}</div> <div class="text-xs">{{ $database->status }}</div>
</a> </a>

View File

@@ -6,18 +6,36 @@
</x-slot:modalBody> </x-slot:modalBody>
</x-modal> </x-modal>
<form wire:submit.prevent='submit' class="flex flex-col items-center gap-2 xl:flex-row"> <form wire:submit.prevent='submit' class="flex flex-col items-center gap-2 xl:flex-row">
<x-forms.input id="env.key" /> @if ($isDisabled)
<x-forms.input type="password" id="env.value" /> <x-forms.input disabled id="env.key" />
@if ($type !== 'service') <x-forms.input disabled type="password" id="env.value" />
<x-forms.checkbox instantSave id="env.is_build_time" label="Build Variable?" /> @if ($type !== 'service')
<x-forms.checkbox instantSave id="env.is_build_time" label="Build Variable?" />
@endif
@else
<x-forms.input id="env.key" />
<x-forms.input type="password" id="env.value" />
@if ($type !== 'service')
<x-forms.checkbox instantSave id="env.is_build_time" label="Build Variable?" />
@endif
@endif @endif
<div class="flex gap-2"> <div class="flex gap-2">
<x-forms.button type="submit"> @if ($isDisabled)
Update <x-forms.button disabled type="submit">
</x-forms.button> Update
<x-forms.button isError isModal modalId="{{ $modalId }}"> </x-forms.button>
Delete <x-forms.button disabled isError isModal modalId="{{ $modalId }}">
</x-forms.button> Delete
</x-forms.button>
@else
<x-forms.button type="submit">
Update
</x-forms.button>
<x-forms.button isError isModal modalId="{{ $modalId }}">
Delete
</x-forms.button>
@endif
</div> </div>
</form> </form>
</div> </div>