feat: SSL notification
This commit is contained in:
151
app/Notifications/SslExpirationNotification.php
Normal file
151
app/Notifications/SslExpirationNotification.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use App\Notifications\Dto\DiscordMessage;
|
||||
use App\Notifications\Dto\PushoverMessage;
|
||||
use App\Notifications\Dto\SlackMessage;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Support\Collection;
|
||||
use Spatie\Url\Url;
|
||||
|
||||
class SslExpirationNotification extends CustomEmailNotification
|
||||
{
|
||||
protected Collection $resources;
|
||||
|
||||
protected array $urls = [];
|
||||
|
||||
public function __construct(array|Collection $resources)
|
||||
{
|
||||
$this->onQueue('high');
|
||||
$this->resources = collect($resources);
|
||||
|
||||
// Collect URLs for each resource
|
||||
$this->resources->each(function ($resource) {
|
||||
if (data_get($resource, 'environment.project.uuid')) {
|
||||
$routeName = match ($resource->type()) {
|
||||
'application' => 'project.application.configuration',
|
||||
'database' => 'project.database.configuration',
|
||||
'service' => 'project.service.configuration',
|
||||
default => null
|
||||
};
|
||||
|
||||
if ($routeName) {
|
||||
$route = route($routeName, [
|
||||
'project_uuid' => data_get($resource, 'environment.project.uuid'),
|
||||
'environment_uuid' => data_get($resource, 'environment.uuid'),
|
||||
$resource->type().'_uuid' => data_get($resource, 'uuid'),
|
||||
]);
|
||||
|
||||
$settings = instanceSettings();
|
||||
if (data_get($settings, 'fqdn')) {
|
||||
$url = Url::fromString($route);
|
||||
$url = $url->withPort(null);
|
||||
$fqdn = data_get($settings, 'fqdn');
|
||||
$fqdn = str_replace(['http://', 'https://'], '', $fqdn);
|
||||
$url = $url->withHost($fqdn);
|
||||
|
||||
$this->urls[$resource->name] = $url->__toString();
|
||||
} else {
|
||||
$this->urls[$resource->name] = $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function via(object $notifiable): array
|
||||
{
|
||||
return $notifiable->getEnabledChannels('ssl_certificate_renewal');
|
||||
}
|
||||
|
||||
public function toMail(): MailMessage
|
||||
{
|
||||
$mail = new MailMessage;
|
||||
$mail->subject('Coolify: [Action Required] SSL Certificates Renewed - Manual Redeployment Needed');
|
||||
$mail->view('emails.ssl-certificate-renewed', [
|
||||
'resources' => $this->resources,
|
||||
'urls' => $this->urls,
|
||||
]);
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
public function toDiscord(): DiscordMessage
|
||||
{
|
||||
$resourceNames = $this->resources->pluck('name')->join(', ');
|
||||
|
||||
$message = new DiscordMessage(
|
||||
title: '🔒 SSL Certificates Renewed',
|
||||
description: "SSL certificates have been renewed for: {$resourceNames}.\n\n**Action Required:** These resources need to be redeployed manually.",
|
||||
color: DiscordMessage::warningColor(),
|
||||
);
|
||||
|
||||
foreach ($this->urls as $name => $url) {
|
||||
$message->addField($name, "[View Resource]({$url})");
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
public function toTelegram(): array
|
||||
{
|
||||
$resourceNames = $this->resources->pluck('name')->join(', ');
|
||||
$message = "Coolify: SSL certificates have been renewed for: {$resourceNames}.\n\nAction Required: These resources need to be redeployed manually for the new SSL certificates to take effect.";
|
||||
|
||||
$buttons = [];
|
||||
foreach ($this->urls as $name => $url) {
|
||||
$buttons[] = [
|
||||
'text' => "View {$name}",
|
||||
'url' => $url,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'message' => $message,
|
||||
'buttons' => $buttons,
|
||||
];
|
||||
}
|
||||
|
||||
public function toPushover(): PushoverMessage
|
||||
{
|
||||
$resourceNames = $this->resources->pluck('name')->join(', ');
|
||||
$message = "SSL certificates have been renewed for: {$resourceNames}<br/><br/>";
|
||||
$message .= '<b>Action Required:</b> These resources need to be redeployed manually for the new SSL certificates to take effect.';
|
||||
|
||||
$buttons = [];
|
||||
foreach ($this->urls as $name => $url) {
|
||||
$buttons[] = [
|
||||
'text' => "View {$name}",
|
||||
'url' => $url,
|
||||
];
|
||||
}
|
||||
|
||||
return new PushoverMessage(
|
||||
title: 'SSL Certificates Renewed',
|
||||
level: 'warning',
|
||||
message: $message,
|
||||
buttons: $buttons,
|
||||
);
|
||||
}
|
||||
|
||||
public function toSlack(): SlackMessage
|
||||
{
|
||||
$resourceNames = $this->resources->pluck('name')->join(', ');
|
||||
$description = "SSL certificates have been renewed for: {$resourceNames}\n\n";
|
||||
$description .= '**Action Required:** These resources need to be redeployed manually for the new SSL certificates to take effect.';
|
||||
|
||||
if (! empty($this->urls)) {
|
||||
$description .= "\n\n**Resource URLs:**\n";
|
||||
foreach ($this->urls as $name => $url) {
|
||||
$description .= "• {$name}: {$url}\n";
|
||||
}
|
||||
}
|
||||
|
||||
return new SlackMessage(
|
||||
title: '🔒 SSL Certificates Renewed',
|
||||
description: $description,
|
||||
color: SlackMessage::warningColor()
|
||||
);
|
||||
}
|
||||
}
|
28
resources/views/emails/ssl-certificate-renewed.blade.php
Normal file
28
resources/views/emails/ssl-certificate-renewed.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<x-emails.layout>
|
||||
<h2>SSL Certificates Renewed</h2>
|
||||
|
||||
<p>SSL certificates have been renewed for the following resources:</p>
|
||||
|
||||
<ul>
|
||||
@foreach($resources as $resource)
|
||||
<li>{{ $resource->name }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
|
||||
<div style="margin: 20px 0; padding: 15px; background-color: #fff3cd; border: 1px solid #ffeeba; border-radius: 4px;">
|
||||
<strong>⚠️ Action Required:</strong> These resources need to be redeployed manually for the new SSL certificates to take effect. Please do this in the next few days to ensure your database connections remain accessible.
|
||||
</div>
|
||||
|
||||
<p>The old SSL certificates will remain valid for approximately 14 more days, as we renew certificates 14 days before their expiration.</p>
|
||||
|
||||
@if(isset($urls) && count($urls) > 0)
|
||||
<div style="margin-top: 20px;">
|
||||
<p>You can redeploy these resources here:</p>
|
||||
<ul>
|
||||
@foreach($urls as $name => $url)
|
||||
<li><a href="{{ $url }}">{{ $name }}</a></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
</x-emails.layout>
|
Reference in New Issue
Block a user