mirror of
https://github.com/coollabsio/coolify.git
synced 2026-03-11 08:55:47 +00:00
Merge bd6b989280 into fc8f18a534
This commit is contained in:
commit
653d15228a
2 changed files with 280 additions and 46 deletions
|
|
@ -83,6 +83,16 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$osId = $this->patchData['osId'] ?? 'unknown';
|
||||
$packageManager = $this->patchData['package_manager'] ?? 'unknown';
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
|
||||
$hasCriticalPackages = $criticalPackages->count() > 0;
|
||||
|
||||
$description = "**{$totalUpdates} package updates** available for server {$this->server->name}\n\n";
|
||||
$description .= "**Summary:**\n";
|
||||
$description .= '• OS: '.ucfirst($osId)."\n";
|
||||
|
|
@ -91,7 +101,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
|
||||
// Show first few packages
|
||||
if (count($updates) > 0) {
|
||||
$description .= "**Sample Updates:**\n";
|
||||
$description .= "**Updates:**\n";
|
||||
$sampleUpdates = array_slice($updates, 0, 5);
|
||||
foreach ($sampleUpdates as $update) {
|
||||
$description .= "• {$update['package']}: {$update['current_version']} → {$update['new_version']}\n";
|
||||
|
|
@ -100,24 +110,20 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$description .= '• ... and '.(count($updates) - 5)." more packages\n";
|
||||
}
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
|
||||
if ($criticalPackages->count() > 0) {
|
||||
if ($hasCriticalPackages) {
|
||||
$description .= "\n **Critical packages detected** ({$criticalPackages->count()} packages may require restarts)";
|
||||
}
|
||||
$description .= "\n [Manage Server Patches]($this->serverUrl)";
|
||||
}
|
||||
|
||||
// Use warning color for critical packages, info color otherwise
|
||||
$color = $hasCriticalPackages ? DiscordMessage::warningColor() : DiscordMessage::infoColor();
|
||||
$icon = $hasCriticalPackages ? ':warning:' : ':information_source:';
|
||||
|
||||
return new DiscordMessage(
|
||||
title: ':warning: Coolify: [ACTION REQUIRED] Server patches available on '.$this->server->name,
|
||||
title: "{$icon} Coolify: [ACTION REQUIRED] Server patches available on ".$this->server->name,
|
||||
description: $description,
|
||||
color: DiscordMessage::errorColor(),
|
||||
color: $color,
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -152,14 +158,27 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$osId = $this->patchData['osId'] ?? 'unknown';
|
||||
$packageManager = $this->patchData['package_manager'] ?? 'unknown';
|
||||
|
||||
$message = "🔧 Coolify: [ACTION REQUIRED] {$totalUpdates} server patches available on {$this->server->name}!\n\n";
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
|
||||
$hasCriticalPackages = $criticalPackages->count() > 0;
|
||||
|
||||
// Use warning emoji for critical packages, info emoji otherwise
|
||||
$icon = $hasCriticalPackages ? '⚠️' : 'ℹ️';
|
||||
|
||||
$message = "{$icon} Coolify: [ACTION REQUIRED] {$totalUpdates} server patches available on {$this->server->name}!\n\n";
|
||||
$message .= "📊 Summary:\n";
|
||||
$message .= '• OS: '.ucfirst($osId)."\n";
|
||||
$message .= "• Package Manager: {$packageManager}\n";
|
||||
$message .= "• Total Updates: {$totalUpdates}\n\n";
|
||||
|
||||
if (count($updates) > 0) {
|
||||
$message .= "📦 Sample Updates:\n";
|
||||
$message .= "📦 Updates:\n";
|
||||
$sampleUpdates = array_slice($updates, 0, 5);
|
||||
foreach ($sampleUpdates as $update) {
|
||||
$message .= "• {$update['package']}: {$update['current_version']} → {$update['new_version']}\n";
|
||||
|
|
@ -168,15 +187,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$message .= '• ... and '.(count($updates) - 5)." more packages\n";
|
||||
}
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
|
||||
if ($criticalPackages->count() > 0) {
|
||||
if ($hasCriticalPackages) {
|
||||
$message .= "\n⚠️ Critical packages detected: {$criticalPackages->count()} packages may require restarts\n";
|
||||
foreach ($criticalPackages->take(3) as $package) {
|
||||
$message .= "• {$package['package']}: {$package['current_version']} → {$package['new_version']}\n";
|
||||
|
|
@ -230,6 +241,16 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$osId = $this->patchData['osId'] ?? 'unknown';
|
||||
$packageManager = $this->patchData['package_manager'] ?? 'unknown';
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
|
||||
$hasCriticalPackages = $criticalPackages->count() > 0;
|
||||
|
||||
$message = "[ACTION REQUIRED] {$totalUpdates} server patches available on {$this->server->name}!\n\n";
|
||||
$message .= "Summary:\n";
|
||||
$message .= '• OS: '.ucfirst($osId)."\n";
|
||||
|
|
@ -237,7 +258,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$message .= "• Total Updates: {$totalUpdates}\n\n";
|
||||
|
||||
if (count($updates) > 0) {
|
||||
$message .= "Sample Updates:\n";
|
||||
$message .= "Updates:\n";
|
||||
$sampleUpdates = array_slice($updates, 0, 3);
|
||||
foreach ($sampleUpdates as $update) {
|
||||
$message .= "• {$update['package']}: {$update['current_version']} → {$update['new_version']}\n";
|
||||
|
|
@ -246,22 +267,14 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$message .= '• ... and '.(count($updates) - 3)." more packages\n";
|
||||
}
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
|
||||
if ($criticalPackages->count() > 0) {
|
||||
if ($hasCriticalPackages) {
|
||||
$message .= "\nCritical packages detected: {$criticalPackages->count()} may require restarts";
|
||||
}
|
||||
}
|
||||
|
||||
return new PushoverMessage(
|
||||
title: 'Server patches available',
|
||||
level: 'error',
|
||||
level: $hasCriticalPackages ? 'warning' : 'info',
|
||||
message: $message,
|
||||
buttons: [
|
||||
[
|
||||
|
|
@ -299,6 +312,16 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$osId = $this->patchData['osId'] ?? 'unknown';
|
||||
$packageManager = $this->patchData['package_manager'] ?? 'unknown';
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
|
||||
$hasCriticalPackages = $criticalPackages->count() > 0;
|
||||
|
||||
$description = "{$totalUpdates} server patches available on '{$this->server->name}'!\n\n";
|
||||
$description .= "*Summary:*\n";
|
||||
$description .= '• OS: '.ucfirst($osId)."\n";
|
||||
|
|
@ -306,7 +329,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$description .= "• Total Updates: {$totalUpdates}\n\n";
|
||||
|
||||
if (count($updates) > 0) {
|
||||
$description .= "*Sample Updates:*\n";
|
||||
$description .= "*Updates:*\n";
|
||||
$sampleUpdates = array_slice($updates, 0, 5);
|
||||
foreach ($sampleUpdates as $update) {
|
||||
$description .= "• `{$update['package']}`: {$update['current_version']} → {$update['new_version']}\n";
|
||||
|
|
@ -315,15 +338,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
$description .= '• ... and '.(count($updates) - 5)." more packages\n";
|
||||
}
|
||||
|
||||
// Check for critical packages
|
||||
$criticalPackages = collect($updates)->filter(function ($update) {
|
||||
return str_contains(strtolower($update['package']), 'docker') ||
|
||||
str_contains(strtolower($update['package']), 'kernel') ||
|
||||
str_contains(strtolower($update['package']), 'openssh') ||
|
||||
str_contains(strtolower($update['package']), 'ssl');
|
||||
});
|
||||
|
||||
if ($criticalPackages->count() > 0) {
|
||||
if ($hasCriticalPackages) {
|
||||
$description .= "\n:warning: *Critical packages detected:* {$criticalPackages->count()} packages may require restarts\n";
|
||||
foreach ($criticalPackages->take(3) as $package) {
|
||||
$description .= "• `{$package['package']}`: {$package['current_version']} → {$package['new_version']}\n";
|
||||
|
|
@ -339,7 +354,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
return new SlackMessage(
|
||||
title: 'Coolify: [ACTION REQUIRED] Server patches available',
|
||||
description: $description,
|
||||
color: SlackMessage::errorColor()
|
||||
color: $hasCriticalPackages ? SlackMessage::warningColor() : SlackMessage::infoColor()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -372,7 +387,7 @@ class ServerPatchCheck extends CustomEmailNotification
|
|||
});
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'success' => true,
|
||||
'message' => 'Server patches available',
|
||||
'event' => 'server_patch_check',
|
||||
'server_name' => $this->server->name,
|
||||
|
|
|
|||
|
|
@ -144,3 +144,222 @@ it('uses correct url in error notifications', function () {
|
|||
expect($webhook['url'])->toBe('https://coolify.production.com/server/error-server-uuid/security/patches')
|
||||
->and($webhook['event'])->toBe('server_patch_check_error');
|
||||
});
|
||||
|
||||
it('uses correct level for patch notifications in Discord', function () {
|
||||
($this->setInstanceSettings)('https://coolify.test');
|
||||
|
||||
$mockServer = ($this->createMockServer)('test-uuid', 'Test Server');
|
||||
|
||||
// Regular patches (no critical packages)
|
||||
$regularPatchData = [
|
||||
'total_updates' => 5,
|
||||
'updates' => [
|
||||
['package' => 'nginx', 'current_version' => '1.18', 'new_version' => '1.20', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
['package' => 'curl', 'current_version' => '7.68', 'new_version' => '7.70', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$regularNotification = new ServerPatchCheck($mockServer, $regularPatchData);
|
||||
$regularDiscord = $regularNotification->toDiscord();
|
||||
|
||||
expect($regularDiscord->color)->toBe(\App\Notifications\Dto\DiscordMessage::infoColor())
|
||||
->and($regularDiscord->title)->toContain(':information_source:');
|
||||
|
||||
// Critical packages (docker, kernel, openssh, ssl)
|
||||
$criticalPatchData = [
|
||||
'total_updates' => 3,
|
||||
'updates' => [
|
||||
['package' => 'docker-ce', 'current_version' => '20.10', 'new_version' => '20.11', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
['package' => 'nginx', 'current_version' => '1.18', 'new_version' => '1.20', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$criticalNotification = new ServerPatchCheck($mockServer, $criticalPatchData);
|
||||
$criticalDiscord = $criticalNotification->toDiscord();
|
||||
|
||||
expect($criticalDiscord->color)->toBe(\App\Notifications\Dto\DiscordMessage::warningColor())
|
||||
->and($criticalDiscord->title)->toContain(':warning:');
|
||||
});
|
||||
|
||||
it('uses correct level for patch notifications in Slack', function () {
|
||||
($this->setInstanceSettings)('https://coolify.test');
|
||||
|
||||
$mockServer = ($this->createMockServer)('test-uuid', 'Test Server');
|
||||
|
||||
// Regular patches
|
||||
$regularPatchData = [
|
||||
'total_updates' => 5,
|
||||
'updates' => [
|
||||
['package' => 'nginx', 'current_version' => '1.18', 'new_version' => '1.20', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$regularNotification = new ServerPatchCheck($mockServer, $regularPatchData);
|
||||
$regularSlack = $regularNotification->toSlack();
|
||||
|
||||
expect($regularSlack->color)->toBe(\App\Notifications\Dto\SlackMessage::infoColor());
|
||||
|
||||
// Critical packages
|
||||
$criticalPatchData = [
|
||||
'total_updates' => 2,
|
||||
'updates' => [
|
||||
['package' => 'linux-kernel', 'current_version' => '5.4', 'new_version' => '5.5', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$criticalNotification = new ServerPatchCheck($mockServer, $criticalPatchData);
|
||||
$criticalSlack = $criticalNotification->toSlack();
|
||||
|
||||
expect($criticalSlack->color)->toBe(\App\Notifications\Dto\SlackMessage::warningColor());
|
||||
});
|
||||
|
||||
it('uses correct level for patch notifications in Pushover', function () {
|
||||
($this->setInstanceSettings)('https://coolify.test');
|
||||
|
||||
$mockServer = ($this->createMockServer)('test-uuid', 'Test Server');
|
||||
|
||||
// Regular patches
|
||||
$regularPatchData = [
|
||||
'total_updates' => 5,
|
||||
'updates' => [
|
||||
['package' => 'nginx', 'current_version' => '1.18', 'new_version' => '1.20', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$regularNotification = new ServerPatchCheck($mockServer, $regularPatchData);
|
||||
$regularPushover = $regularNotification->toPushover();
|
||||
|
||||
expect($regularPushover->level)->toBe('info');
|
||||
|
||||
// Critical packages
|
||||
$criticalPatchData = [
|
||||
'total_updates' => 2,
|
||||
'updates' => [
|
||||
['package' => 'openssh-server', 'current_version' => '8.2', 'new_version' => '8.3', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$criticalNotification = new ServerPatchCheck($mockServer, $criticalPatchData);
|
||||
$criticalPushover = $criticalNotification->toPushover();
|
||||
|
||||
expect($criticalPushover->level)->toBe('warning');
|
||||
});
|
||||
|
||||
it('uses correct icon for patch notifications in Telegram', function () {
|
||||
($this->setInstanceSettings)('https://coolify.test');
|
||||
|
||||
$mockServer = ($this->createMockServer)('test-uuid', 'Test Server');
|
||||
|
||||
// Regular patches
|
||||
$regularPatchData = [
|
||||
'total_updates' => 5,
|
||||
'updates' => [
|
||||
['package' => 'nginx', 'current_version' => '1.18', 'new_version' => '1.20', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$regularNotification = new ServerPatchCheck($mockServer, $regularPatchData);
|
||||
$regularTelegram = $regularNotification->toTelegram();
|
||||
|
||||
expect($regularTelegram['message'])->toContain('ℹ️');
|
||||
|
||||
// Critical packages
|
||||
$criticalPatchData = [
|
||||
'total_updates' => 2,
|
||||
'updates' => [
|
||||
['package' => 'libssl1.1', 'current_version' => '1.1.1', 'new_version' => '1.1.2', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$criticalNotification = new ServerPatchCheck($mockServer, $criticalPatchData);
|
||||
$criticalTelegram = $criticalNotification->toTelegram();
|
||||
|
||||
expect($criticalTelegram['message'])->toContain('⚠️');
|
||||
});
|
||||
|
||||
it('returns success true for regular patches and false for errors in webhook', function () {
|
||||
($this->setInstanceSettings)('https://coolify.test');
|
||||
|
||||
$mockServer = ($this->createMockServer)('test-uuid', 'Test Server');
|
||||
|
||||
// Regular patches
|
||||
$regularPatchData = [
|
||||
'total_updates' => 5,
|
||||
'updates' => [
|
||||
['package' => 'nginx', 'current_version' => '1.18', 'new_version' => '1.20', 'architecture' => 'amd64', 'repository' => 'main'],
|
||||
],
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$regularNotification = new ServerPatchCheck($mockServer, $regularPatchData);
|
||||
$regularWebhook = $regularNotification->toWebhook();
|
||||
|
||||
expect($regularWebhook['success'])->toBeTrue()
|
||||
->and($regularWebhook['message'])->toBe('Server patches available')
|
||||
->and($regularWebhook['event'])->toBe('server_patch_check');
|
||||
|
||||
// Error case
|
||||
$errorPatchData = [
|
||||
'error' => 'Failed to connect to package manager',
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$errorNotification = new ServerPatchCheck($mockServer, $errorPatchData);
|
||||
$errorWebhook = $errorNotification->toWebhook();
|
||||
|
||||
expect($errorWebhook['success'])->toBeFalse()
|
||||
->and($errorWebhook['message'])->toBe('Failed to check patches')
|
||||
->and($errorWebhook['event'])->toBe('server_patch_check_error');
|
||||
});
|
||||
|
||||
it('uses error level for actual errors in all channels', function () {
|
||||
($this->setInstanceSettings)('https://coolify.test');
|
||||
|
||||
$mockServer = ($this->createMockServer)('test-uuid', 'Test Server');
|
||||
|
||||
$errorPatchData = [
|
||||
'error' => 'Connection refused',
|
||||
'osId' => 'ubuntu',
|
||||
'package_manager' => 'apt',
|
||||
];
|
||||
|
||||
$notification = new ServerPatchCheck($mockServer, $errorPatchData);
|
||||
|
||||
// Discord should use error color
|
||||
$discord = $notification->toDiscord();
|
||||
expect($discord->color)->toBe(\App\Notifications\Dto\DiscordMessage::errorColor());
|
||||
|
||||
// Slack should use error color
|
||||
$slack = $notification->toSlack();
|
||||
expect($slack->color)->toBe(\App\Notifications\Dto\SlackMessage::errorColor());
|
||||
|
||||
// Pushover should use error level
|
||||
$pushover = $notification->toPushover();
|
||||
expect($pushover->level)->toBe('error');
|
||||
|
||||
// Telegram should use error icon
|
||||
$telegram = $notification->toTelegram();
|
||||
expect($telegram['message'])->toContain('❌');
|
||||
|
||||
// Webhook should return success false
|
||||
$webhook = $notification->toWebhook();
|
||||
expect($webhook['success'])->toBeFalse();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue