Fix network connection issues in Server and Service models

This commit is contained in:
Andras Bacsai 2023-11-27 09:58:31 +01:00
parent 8d0c3abf2e
commit fae97e4dee
4 changed files with 99 additions and 3 deletions

View File

@ -19,6 +19,7 @@ public function mount()
if (is_null($this->server)) {
return redirect()->route('server.all');
}
} catch (\Throwable $e) {
return handleError($e, $this);
}

View File

@ -442,4 +442,10 @@ public function parse(bool $isNew = false): Collection
{
return parseDockerComposeFile($this, $isNew);
}
public function networks()
{
$networks = getTopLevelNetworks($this);
// ray($networks);
return $networks;
}
}

View File

@ -12,10 +12,16 @@ function get_proxy_path()
}
function connectProxyToNetworks(Server $server)
{
// TODO: Connect to service + compose based application networks as well.
// TODO: Connect to compose based application networks as well.
// Standalone networks
$networks = collect($server->standaloneDockers)->map(function ($docker) {
return $docker['network'];
})->unique();
});
// Service networks
foreach($server->services()->get() as $service) {
$networks->push($service->networks());
}
$networks = collect($networks)->flatten()->unique();
if ($networks->count() === 0) {
$networks = collect(['coolify']);
}

View File

@ -495,6 +495,89 @@ function removeAnsiColors($text)
return preg_replace('/\e[[][A-Za-z0-9];?[0-9]*m?/', '', $text);
}
function getTopLevelNetworks(Service|Application $resource)
{
if ($resource->getMorphClass() === 'App\Models\Service') {
if ($resource->docker_compose_raw) {
try {
$yaml = Yaml::parse($resource->docker_compose_raw);
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
$services = data_get($yaml, 'services');
$topLevelNetworks = collect(data_get($yaml, 'networks', []));
$definedNetwork = collect([$resource->uuid]);
$services = collect($services)->map(function ($service, $_) use ($topLevelNetworks, $definedNetwork) {
$serviceNetworks = collect(data_get($service, 'networks', []));
// Collect/create/update networks
if ($serviceNetworks->count() > 0) {
foreach ($serviceNetworks as $networkName => $networkDetails) {
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName;
});
if (!$networkExists) {
$topLevelNetworks->put($networkDetails, null);
}
}
}
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
return $value == $definedNetwork;
});
if (!$definedNetworkExists) {
foreach ($definedNetwork as $network) {
$topLevelNetworks->put($network, [
'name' => $network,
'external' => true
]);
}
}
return $service;
});
return $topLevelNetworks->keys();
}
} else if ($resource->getMorphClass() === 'App\Models\Application') {
try {
$yaml = Yaml::parse($resource->docker_compose_raw);
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
$server = $resource->destination->server;
$topLevelNetworks = collect(data_get($yaml, 'networks', []));
$services = data_get($yaml, 'services');
$definedNetwork = collect([$resource->uuid]);
$services = collect($services)->map(function ($service, $_) use ($topLevelNetworks, $definedNetwork) {
$serviceNetworks = collect(data_get($service, 'networks', []));
// Collect/create/update networks
if ($serviceNetworks->count() > 0) {
foreach ($serviceNetworks as $networkName => $networkDetails) {
$networkExists = $topLevelNetworks->contains(function ($value, $key) use ($networkName) {
return $value == $networkName || $key == $networkName;
});
if (!$networkExists) {
$topLevelNetworks->put($networkDetails, null);
}
}
}
$definedNetworkExists = $topLevelNetworks->contains(function ($value, $_) use ($definedNetwork) {
return $value == $definedNetwork;
});
if (!$definedNetworkExists) {
foreach ($definedNetwork as $network) {
$topLevelNetworks->put($network, [
'name' => $network,
'external' => true
]);
}
}
return $service;
});
return $topLevelNetworks->keys();
}
}
function parseDockerComposeFile(Service|Application $resource, bool $isNew = false)
{
ray()->clearAll();
@ -1010,7 +1093,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$resource->docker_compose = Yaml::dump($finalServices, 10, 2);
$resource->save();
$resource->saveComposeConfigs();
return collect([]);
return $finalServices;
} else {
return collect([]);
}