Primo Committ

This commit is contained in:
paoloar77
2024-05-07 12:17:25 +02:00
commit e73d0e5113
7204 changed files with 884387 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
<?php
namespace Spatie\Backup\Tasks\Monitor;
use Exception;
use Illuminate\Support\Collection;
use Spatie\Backup\BackupDestination\BackupDestination;
use Spatie\Backup\Tasks\Monitor\HealthChecks\IsReachable;
class BackupDestinationStatus
{
/** @var \Spatie\Backup\BackupDestination\BackupDestination */
protected $backupDestination;
/** @var array */
protected $healthChecks;
/** @var HealthCheckFailure|null */
protected $healthCheckFailure;
public function __construct(BackupDestination $backupDestination, array $healthChecks = [])
{
$this->backupDestination = $backupDestination;
$this->healthChecks = $healthChecks;
}
public function backupDestination(): BackupDestination
{
return $this->backupDestination;
}
public function check(HealthCheck $check)
{
try {
$check->checkHealth($this->backupDestination());
} catch (Exception $exception) {
return new HealthCheckFailure($check, $exception);
}
return true;
}
public function getHealthChecks(): Collection
{
return collect($this->healthChecks)->prepend(new IsReachable());
}
public function getHealthCheckFailure(): ?HealthCheckFailure
{
return $this->healthCheckFailure;
}
public function isHealthy(): bool
{
$healthChecks = $this->getHealthChecks();
foreach ($healthChecks as $healthCheck) {
$checkResult = $this->check($healthCheck);
if ($checkResult instanceof HealthCheckFailure) {
$this->healthCheckFailure = $checkResult;
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Spatie\Backup\Tasks\Monitor;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Spatie\Backup\BackupDestination\BackupDestination;
class BackupDestinationStatusFactory
{
public static function createForMonitorConfig(array $monitorConfiguration): Collection
{
return collect($monitorConfiguration)->flatMap(function (array $monitorProperties) {
return self::createForSingleMonitor($monitorProperties);
})->sortBy(function (BackupDestinationStatus $backupDestinationStatus) {
return $backupDestinationStatus->backupDestination()->backupName().'-'.
$backupDestinationStatus->backupDestination()->diskName();
});
}
public static function createForSingleMonitor(array $monitorConfig): Collection
{
return collect($monitorConfig['disks'])->map(function ($diskName) use ($monitorConfig) {
$backupDestination = BackupDestination::create($diskName, $monitorConfig['name']);
return new BackupDestinationStatus($backupDestination, static::buildHealthChecks($monitorConfig));
});
}
protected static function buildHealthChecks($monitorConfig)
{
return collect(Arr::get($monitorConfig, 'health_checks'))->map(function ($options, $class) {
if (is_int($class)) {
$class = $options;
$options = [];
}
return static::buildHealthCheck($class, $options);
})->toArray();
}
protected static function buildHealthCheck($class, $options)
{
// A single value was passed - we'll instantiate it manually assuming it's the first argument
if (! is_array($options)) {
return new $class($options);
}
// A config array was given. Use reflection to match arguments
return app()->makeWith($class, $options);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Spatie\Backup\Tasks\Monitor;
use Illuminate\Support\Str;
use Spatie\Backup\BackupDestination\BackupDestination;
use Spatie\Backup\Exceptions\InvalidHealthCheck;
abstract class HealthCheck
{
abstract public function checkHealth(BackupDestination $backupDestination);
public function name()
{
return Str::title(class_basename($this));
}
protected function fail(string $message)
{
throw InvalidHealthCheck::because($message);
}
protected function failIf(bool $condition, string $message)
{
if ($condition) {
$this->fail($message);
}
}
protected function failUnless(bool $condition, string $message)
{
if (! $condition) {
$this->fail($message);
}
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Spatie\Backup\Tasks\Monitor;
use Exception;
use Spatie\Backup\Exceptions\InvalidHealthCheck;
class HealthCheckFailure
{
/** @var \Spatie\Backup\Tasks\Monitor */
protected $healthCheck;
/** @var \Exception */
protected $exception;
public function __construct(HealthCheck $healthCheck, Exception $exception)
{
$this->healthCheck = $healthCheck;
$this->exception = $exception;
}
public function healthCheck(): HealthCheck
{
return $this->healthCheck;
}
public function exception(): Exception
{
return $this->exception;
}
public function wasUnexpected(): bool
{
return ! $this->exception instanceof InvalidHealthCheck;
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Spatie\Backup\Tasks\Monitor\HealthChecks;
use Spatie\Backup\BackupDestination\BackupDestination;
use Spatie\Backup\Tasks\Monitor\HealthCheck;
class IsReachable extends HealthCheck
{
public function checkHealth(BackupDestination $backupDestination)
{
$this->failUnless(
$backupDestination->isReachable(),
trans('backup::notification.unhealthy_backup_found_not_reachable', [
'error' => $backupDestination->connectionError,
])
);
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Spatie\Backup\Tasks\Monitor\HealthChecks;
use Spatie\Backup\BackupDestination\Backup;
use Spatie\Backup\BackupDestination\BackupDestination;
use Spatie\Backup\Tasks\Monitor\HealthCheck;
class MaximumAgeInDays extends HealthCheck
{
/** @var int */
protected $days;
public function __construct($days = 1)
{
$this->days = $days;
}
public function checkHealth(BackupDestination $backupDestination)
{
$this->failIf(
$this->hasNoBackups($backupDestination),
trans('backup::notifications.unhealthy_backup_found_empty')
);
$newestBackup = $backupDestination->backups()->newest();
$this->failIf(
$this->isTooOld($newestBackup),
trans('backup::notifications.unhealthy_backup_found_old', ['date' => $newestBackup->date()->format('Y/m/d h:i:s')])
);
}
protected function hasNoBackups(BackupDestination $backupDestination)
{
return $backupDestination->backups()->isEmpty();
}
protected function isTooOld(Backup $backup)
{
if (is_null($this->days)) {
return false;
}
if ($backup->date()->gt(now()->subDays($this->days))) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Spatie\Backup\Tasks\Monitor\HealthChecks;
use Spatie\Backup\BackupDestination\BackupDestination;
use Spatie\Backup\Helpers\Format;
use Spatie\Backup\Tasks\Monitor\HealthCheck;
class MaximumStorageInMegabytes extends HealthCheck
{
/** @var int */
protected $maximumSizeInMegaBytes;
public function __construct(int $maximumSizeInMegaBytes = 5000)
{
$this->maximumSizeInMegaBytes = $maximumSizeInMegaBytes;
}
public function checkHealth(BackupDestination $backupDestination)
{
$usageInBytes = $backupDestination->usedStorage();
$this->failIf(
$this->exceedsAllowance($usageInBytes),
trans('backup::notifications.unhealthy_backup_found_full', [
'disk_usage' => $this->humanReadableSize($usageInBytes),
'disk_limit' => $this->humanReadableSize($this->bytes($this->maximumSizeInMegaBytes)),
])
);
}
protected function exceedsAllowance(float $usageInBytes): bool
{
return $usageInBytes > $this->bytes($this->maximumSizeInMegaBytes);
}
protected function bytes(int $megaBytes): int
{
return $megaBytes * 1024 * 1024;
}
protected function humanReadableSize(float $sizeInBytes): string
{
return Format::humanReadableSize($sizeInBytes);
}
}