mirror of
https://github.com/tiennm99/coolify.git
synced 2026-04-17 17:21:04 +00:00
feat: implement service environment variable parsing and add unit tests for port detection logic
This commit is contained in:
@@ -453,13 +453,9 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
// for example SERVICE_FQDN_APP_3000 (without a value)
|
||||
if ($key->startsWith('SERVICE_FQDN_')) {
|
||||
// SERVICE_FQDN_APP or SERVICE_FQDN_APP_3000
|
||||
if (substr_count(str($key)->value(), '_') === 3) {
|
||||
$fqdnFor = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower()->value();
|
||||
$port = $key->afterLast('_')->value();
|
||||
} else {
|
||||
$fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value();
|
||||
$port = null;
|
||||
}
|
||||
$parsed = parseServiceEnvironmentVariable($key->value());
|
||||
$fqdnFor = $parsed['service_name'];
|
||||
$port = $parsed['port'];
|
||||
$fqdn = $resource->fqdn;
|
||||
if (blank($resource->fqdn)) {
|
||||
$fqdn = generateFqdn(server: $server, random: "$uuid", parserVersion: $resource->compose_parsing_version);
|
||||
@@ -482,7 +478,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
$resource->save();
|
||||
}
|
||||
|
||||
if (substr_count(str($key)->value(), '_') === 2) {
|
||||
if (! $parsed['has_port']) {
|
||||
$resource->environment_variables()->updateOrCreate([
|
||||
'key' => $key->value(),
|
||||
'resourceable_type' => get_class($resource),
|
||||
@@ -492,7 +488,7 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
'is_preview' => false,
|
||||
]);
|
||||
}
|
||||
if (substr_count(str($key)->value(), '_') === 3) {
|
||||
if ($parsed['has_port']) {
|
||||
|
||||
$newKey = str($key)->beforeLast('_');
|
||||
$resource->environment_variables()->updateOrCreate([
|
||||
@@ -565,13 +561,9 @@ function applicationParser(Application $resource, int $pull_request_id = 0, ?int
|
||||
} elseif ($command->value() === 'URL') {
|
||||
// SERVICE_URL_APP or SERVICE_URL_APP_3000
|
||||
// Detect if there's a port suffix
|
||||
if (substr_count(str($key)->value(), '_') === 3) {
|
||||
$urlFor = $key->after('SERVICE_URL_')->beforeLast('_')->lower()->value();
|
||||
$port = $key->afterLast('_')->value();
|
||||
} else {
|
||||
$urlFor = $key->after('SERVICE_URL_')->lower()->value();
|
||||
$port = null;
|
||||
}
|
||||
$parsed = parseServiceEnvironmentVariable($key->value());
|
||||
$urlFor = $parsed['service_name'];
|
||||
$port = $parsed['port'];
|
||||
$originalUrlFor = str($urlFor)->replace('_', '-');
|
||||
if (str($urlFor)->contains('-')) {
|
||||
$urlFor = str($urlFor)->replace('-', '_')->replace('.', '_');
|
||||
@@ -1538,27 +1530,16 @@ function serviceParser(Service $resource): Collection
|
||||
// Get magic environments where we need to preset the FQDN / URL
|
||||
if ($key->startsWith('SERVICE_FQDN_') || $key->startsWith('SERVICE_URL_')) {
|
||||
// SERVICE_FQDN_APP or SERVICE_FQDN_APP_3000
|
||||
if (substr_count(str($key)->value(), '_') === 3) {
|
||||
if ($key->startsWith('SERVICE_FQDN_')) {
|
||||
$urlFor = null;
|
||||
$fqdnFor = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower()->value();
|
||||
}
|
||||
if ($key->startsWith('SERVICE_URL_')) {
|
||||
$fqdnFor = null;
|
||||
$urlFor = $key->after('SERVICE_URL_')->beforeLast('_')->lower()->value();
|
||||
}
|
||||
$port = $key->afterLast('_')->value();
|
||||
} else {
|
||||
if ($key->startsWith('SERVICE_FQDN_')) {
|
||||
$urlFor = null;
|
||||
$fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value();
|
||||
}
|
||||
if ($key->startsWith('SERVICE_URL_')) {
|
||||
$fqdnFor = null;
|
||||
$urlFor = $key->after('SERVICE_URL_')->lower()->value();
|
||||
}
|
||||
$port = null;
|
||||
$parsed = parseServiceEnvironmentVariable($key->value());
|
||||
if ($key->startsWith('SERVICE_FQDN_')) {
|
||||
$urlFor = null;
|
||||
$fqdnFor = $parsed['service_name'];
|
||||
}
|
||||
if ($key->startsWith('SERVICE_URL_')) {
|
||||
$fqdnFor = null;
|
||||
$urlFor = $parsed['service_name'];
|
||||
}
|
||||
$port = $parsed['port'];
|
||||
if (blank($savedService->fqdn)) {
|
||||
if ($fqdnFor) {
|
||||
$fqdn = generateFqdn(server: $server, random: "$fqdnFor-$uuid", parserVersion: $resource->compose_parsing_version);
|
||||
@@ -1603,7 +1584,7 @@ function serviceParser(Service $resource): Collection
|
||||
}
|
||||
$savedService->save();
|
||||
}
|
||||
if (substr_count(str($key)->value(), '_') === 2) {
|
||||
if (! $parsed['has_port']) {
|
||||
$resource->environment_variables()->updateOrCreate([
|
||||
'key' => $key->value(),
|
||||
'resourceable_type' => get_class($resource),
|
||||
@@ -1621,7 +1602,7 @@ function serviceParser(Service $resource): Collection
|
||||
'is_preview' => false,
|
||||
]);
|
||||
}
|
||||
if (substr_count(str($key)->value(), '_') === 3) {
|
||||
if ($parsed['has_port']) {
|
||||
// For port-specific variables (e.g., SERVICE_FQDN_UMAMI_3000),
|
||||
// keep the port suffix in the key and use the URL with port
|
||||
$resource->environment_variables()->updateOrCreate([
|
||||
|
||||
@@ -184,3 +184,53 @@ function serviceKeys()
|
||||
{
|
||||
return get_service_templates()->keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a SERVICE_URL_* or SERVICE_FQDN_* variable to extract the service name and port.
|
||||
*
|
||||
* This function detects if a service environment variable has a port suffix by checking
|
||||
* if the last segment after the underscore is numeric.
|
||||
*
|
||||
* Examples:
|
||||
* - SERVICE_URL_APP_3000 → ['service_name' => 'app', 'port' => '3000', 'has_port' => true]
|
||||
* - SERVICE_URL_MY_API_8080 → ['service_name' => 'my_api', 'port' => '8080', 'has_port' => true]
|
||||
* - SERVICE_URL_MY_APP → ['service_name' => 'my_app', 'port' => null, 'has_port' => false]
|
||||
* - SERVICE_FQDN_REDIS_CACHE_6379 → ['service_name' => 'redis_cache', 'port' => '6379', 'has_port' => true]
|
||||
*
|
||||
* @param string $key The environment variable key (e.g., SERVICE_URL_APP_3000)
|
||||
* @return array{service_name: string, port: string|null, has_port: bool} Parsed service information
|
||||
*/
|
||||
function parseServiceEnvironmentVariable(string $key): array
|
||||
{
|
||||
$strKey = str($key);
|
||||
$lastSegment = $strKey->afterLast('_')->value();
|
||||
$hasPort = is_numeric($lastSegment) && ctype_digit($lastSegment);
|
||||
|
||||
if ($hasPort) {
|
||||
// Port-specific variable (e.g., SERVICE_URL_APP_3000)
|
||||
if ($strKey->startsWith('SERVICE_URL_')) {
|
||||
$serviceName = $strKey->after('SERVICE_URL_')->beforeLast('_')->lower()->value();
|
||||
} elseif ($strKey->startsWith('SERVICE_FQDN_')) {
|
||||
$serviceName = $strKey->after('SERVICE_FQDN_')->beforeLast('_')->lower()->value();
|
||||
} else {
|
||||
$serviceName = '';
|
||||
}
|
||||
$port = $lastSegment;
|
||||
} else {
|
||||
// Base variable without port (e.g., SERVICE_URL_APP)
|
||||
if ($strKey->startsWith('SERVICE_URL_')) {
|
||||
$serviceName = $strKey->after('SERVICE_URL_')->lower()->value();
|
||||
} elseif ($strKey->startsWith('SERVICE_FQDN_')) {
|
||||
$serviceName = $strKey->after('SERVICE_FQDN_')->lower()->value();
|
||||
} else {
|
||||
$serviceName = '';
|
||||
}
|
||||
$port = null;
|
||||
}
|
||||
|
||||
return [
|
||||
'service_name' => $serviceName,
|
||||
'port' => $port,
|
||||
'has_port' => $hasPort,
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user