Skip to content

Commit

Permalink
WIP notifications and other refactors (#88)
Browse files Browse the repository at this point in the history
* WIP notifications and other refactors
- refactor notification channels
- send notifications on events related to the servers and sites
- delete server log files on server deletion
- add telegram notification channel
- add new icons
- cache configs and icons on installation and updates
- new navbar for dark mode and settings

* discord channel

* build assets

* pint
  • Loading branch information
saeedvaziry authored Jan 7, 2024
1 parent f06b8f7 commit e997d0d
Show file tree
Hide file tree
Showing 72 changed files with 1,151 additions and 478 deletions.
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_HOST=
MAIL_PORT=
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
Expand Down
4 changes: 2 additions & 2 deletions .env.prod
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_HOST=
MAIL_PORT=
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
Expand Down
4 changes: 2 additions & 2 deletions .env.sail
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_HOST=
MAIL_PORT=
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
Expand Down
13 changes: 11 additions & 2 deletions app/Actions/NotificationChannels/AddChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,25 @@ public function add(User $user, array $input): void
'label' => $input['label'],
]);
$this->validateType($channel, $input);
$channel->data = $channel->provider()->data($input);
$channel->data = $channel->provider()->createData($input);
$channel->save();

if (! $channel->provider()->connect()) {
$channel->delete();

if ($channel->provider === \App\Enums\NotificationChannel::EMAIL) {
throw ValidationException::withMessages([
'email' => __('Could not connect! Make sure you configured `.env` file correctly.'),
]);
}

throw ValidationException::withMessages([
'provider' => __('Could not connect'),
]);
}

$channel->connected = true;
$channel->save();
}

/**
Expand All @@ -49,7 +58,7 @@ protected function validate(array $input): void
*/
protected function validateType(NotificationChannel $channel, array $input): void
{
Validator::make($input, $channel->provider()->validationRules())
Validator::make($input, $channel->provider()->createRules($input))
->validate();
}
}
12 changes: 10 additions & 2 deletions app/Contracts/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@

namespace App\Contracts;

use Illuminate\Notifications\Messages\MailMessage;

interface Notification
{
public function subject(): string;
public function rawText(): string;

public function toMail(object $notifiable): MailMessage;

public function toSlack(object $notifiable): string;

public function toDiscord(object $notifiable): string;

public function message(bool $mail = false): mixed;
public function toTelegram(object $notifiable): string;
}
8 changes: 5 additions & 3 deletions app/Contracts/NotificationChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

interface NotificationChannel
{
public function validationRules(): array;
public function createRules(array $input): array;

public function data(array $input): array;
public function createData(array $input): array;

public function data(): array;

public function connect(): bool;

public function sendMessage(string $subject, string $text): void;
public function send(object $notifiable, Notification $notification): void;
}
2 changes: 2 additions & 0 deletions app/Enums/NotificationChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ final class NotificationChannel extends Enum
const SLACK = 'slack';

const DISCORD = 'discord';

const TELEGRAM = 'telegram';
}
17 changes: 17 additions & 0 deletions app/Facades/Notifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Facades;

use App\Contracts\Notification;
use Illuminate\Support\Facades\Facade;

/**
* @method static void send(object $notifiable, Notification $notification)
*/
class Notifier extends Facade
{
protected static function getFacadeAccessor(): string
{
return 'notifier';
}
}
19 changes: 19 additions & 0 deletions app/Helpers/Notifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Helpers;

use App\Contracts\Notification;
use App\Models\NotificationChannel;

class Notifier
{
/**
* In the future we can send notifications based on the notifiable instance
* For example, If it was a server then we will send the channels specified by that server
* For now, we will send all channels.
*/
public function send(object $notifiable, Notification $notification): void
{
NotificationChannel::notifyAll($notification);
}
}
5 changes: 4 additions & 1 deletion app/Http/Controllers/GitHookController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
namespace App\Http\Controllers;

use App\Exceptions\SourceControlIsNotConnected;
use App\Facades\Notifier;
use App\Models\GitHook;
use App\Notifications\SourceControlDisconnected;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Throwable;

class GitHookController extends Controller
Expand All @@ -25,7 +28,7 @@ public function __invoke(Request $request)
try {
$gitHook->site->deploy();
} catch (SourceControlIsNotConnected) {
// TODO: send notification
Notifier::send($gitHook->sourceControl, new SourceControlDisconnected($gitHook->sourceControl));
} catch (Throwable $e) {
Log::error('git-hook-exception', (array) $e);
}
Expand Down
4 changes: 4 additions & 0 deletions app/Http/Livewire/NotificationChannels/AddChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class AddChannel extends Component

public string $email;

public string $bot_token;

public string $chat_id;

public function add(): void
{
app(\App\Actions\NotificationChannels\AddChannel::class)->add(
Expand Down
4 changes: 3 additions & 1 deletion app/Jobs/Server/CheckConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace App\Jobs\Server;

use App\Events\Broadcast;
use App\Facades\Notifier;
use App\Jobs\Job;
use App\Models\Server;
use App\Notifications\ServerDisconnected;
use Throwable;

class CheckConnection extends Job
Expand Down Expand Up @@ -39,7 +41,7 @@ public function failed(): void
{
$this->server->status = 'disconnected';
$this->server->save();
/** @todo notify */
Notifier::send($this->server, new ServerDisconnected($this->server));
event(
new Broadcast('server-status-failed', [
'server' => $this->server,
Expand Down
47 changes: 0 additions & 47 deletions app/Mail/NotificationChannelMessage.php

This file was deleted.

25 changes: 25 additions & 0 deletions app/Mail/NotificationMail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class NotificationMail extends Mailable
{
use Queueable, SerializesModels;

public string $text;

public function __construct(string $subject, string $text)
{
$this->subject = $subject;
$this->text = $text;
}

public function build(): self
{
return $this->html($this->text);
}
}
29 changes: 20 additions & 9 deletions app/Models/NotificationChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@

namespace App\Models;

use App\Contracts\Notification;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;

/**
* @property string $provider
* @property string $label
* @property array $data
* @property bool $connected
* @property bool $is_default
* @property User $user
* @property int $id
* @property string provider
* @property array data
* @property string label
* @property bool connected
*/
class NotificationChannel extends AbstractModel
{
use HasFactory;
use Notifiable;

protected $fillable = [
'provider',
Expand All @@ -25,15 +27,24 @@ class NotificationChannel extends AbstractModel
];

protected $casts = [
'data' => 'json',
'project_id' => 'integer',
'data' => 'array',
'connected' => 'boolean',
'is_default' => 'boolean',
];

public function provider(): \App\Contracts\NotificationChannel
{
$provider = config('core.notification_channels_providers_class')[$this->provider];
$class = config('core.notification_channels_providers_class')[$this->provider];

return new $provider($this);
return new $class($this);
}

public static function notifyAll(Notification $notification): void
{
$channels = self::all();
foreach ($channels as $channel) {
$channel->notify($notification);
}
}
}
11 changes: 8 additions & 3 deletions app/Models/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@

use App\Contracts\ServerType;
use App\Enums\ServerStatus;
use App\Facades\Notifier;
use App\Facades\SSH;
use App\Jobs\Installation\Upgrade;
use App\Jobs\Server\CheckConnection;
use App\Jobs\Server\RebootServer;
use App\Notifications\ServerInstallationStarted;
use App\Support\Testing\SSHFake;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
Expand Down Expand Up @@ -110,7 +113,9 @@ public static function boot(): void
$site->delete();
});
$server->provider()->delete();
$server->logs()->delete();
$server->logs()->each(function (ServerLog $log) {
$log->delete();
});
$server->services()->delete();
$server->databases()->delete();
$server->databaseUsers()->delete();
Expand Down Expand Up @@ -239,7 +244,7 @@ public function getServiceByUnit($unit): ?Service
public function install(): void
{
$this->type()->install();
// $this->team->notify(new ServerInstallationStarted($this));
Notifier::send($this, new ServerInstallationStarted($this));
}

public function ssh(?string $user = null): \App\Helpers\SSH|SSHFake
Expand Down Expand Up @@ -343,7 +348,7 @@ public function sshKey(): array
];
}

/** @var \Illuminate\Filesystem\FilesystemAdapter $storageDisk */
/** @var FilesystemAdapter $storageDisk */
$storageDisk = Storage::disk(config('core.key_pairs_disk'));

return [
Expand Down
11 changes: 11 additions & 0 deletions app/Models/ServerLog.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ class ServerLog extends AbstractModel
'site_id' => 'integer',
];

public static function boot(): void
{
parent::boot();

static::deleting(function (ServerLog $log) {
if (Storage::disk($log->disk)->exists($log->name)) {
Storage::disk($log->disk)->delete($log->name);
}
});
}

public function getRouteKey(): string
{
return 'log';
Expand Down
Loading

0 comments on commit e997d0d

Please sign in to comment.