Skip to content

Commit

Permalink
support S3 compatible storage providers (#401)
Browse files Browse the repository at this point in the history
  • Loading branch information
saeedvaziry authored Dec 22, 2024
1 parent db81583 commit ea3d646
Show file tree
Hide file tree
Showing 20 changed files with 127 additions and 576 deletions.
2 changes: 0 additions & 2 deletions app/Enums/StorageProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,4 @@ final class StorageProvider
const LOCAL = 'local';

const S3 = 's3';

const WASABI = 'wasabi';
}
32 changes: 16 additions & 16 deletions app/SSH/Storage/S3.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,31 @@
namespace App\SSH\Storage;

use App\Exceptions\SSHCommandError;
use App\Models\Server;
use App\Models\StorageProvider;
use App\Exceptions\SSHError;
use App\SSH\HasS3Storage;
use App\SSH\HasScripts;
use Illuminate\Support\Facades\Log;

class S3 extends S3AbstractStorage
class S3 extends AbstractStorage
{
use HasS3Storage, HasScripts;

public function __construct(Server $server, StorageProvider $storageProvider)
{
parent::__construct($server, $storageProvider);
$this->setBucketRegion($this->storageProvider->credentials['region']);
$this->setApiUrl();
}

/**
* @throws SSHCommandError
* @throws SSHError
*/
public function upload(string $src, string $dest): array
{
/** @var \App\StorageProviders\S3 $provider */
$provider = $this->storageProvider->provider();

$uploadCommand = $this->getScript('s3/upload.sh', [
'src' => $src,
'bucket' => $this->storageProvider->credentials['bucket'],
'dest' => $this->prepareS3Path($this->storageProvider->credentials['path'].'/'.$dest),
'key' => $this->storageProvider->credentials['key'],
'secret' => $this->storageProvider->credentials['secret'],
'region' => $this->getBucketRegion(),
'endpoint' => $this->getApiUrl(),
'region' => $this->storageProvider->credentials['region'],
'endpoint' => $provider->getApiUrl(),
]);

$upload = $this->server->ssh()->exec($uploadCommand, 'upload-to-s3');
Expand All @@ -49,20 +44,25 @@ public function upload(string $src, string $dest): array
}

/**
* @throws SSHCommandError
* @throws SSHError
*/
public function download(string $src, string $dest): void
{
/** @var \App\StorageProviders\S3 $provider */
$provider = $this->storageProvider->provider();

$downloadCommand = $this->getScript('s3/download.sh', [
'src' => $this->prepareS3Path($this->storageProvider->credentials['path'].'/'.$src),
'dest' => $dest,
'bucket' => $this->storageProvider->credentials['bucket'],
'key' => $this->storageProvider->credentials['key'],
'secret' => $this->storageProvider->credentials['secret'],
'region' => $this->getBucketRegion(),
'endpoint' => $this->getApiUrl(),
'region' => $this->storageProvider->credentials['region'],
'endpoint' => $provider->getApiUrl(),
]);

Log::info('Downloading from S3', ['command' => $downloadCommand]);

$download = $this->server->ssh()->exec($downloadCommand, 'download-from-s3');

if (! str_contains($download, 'Download successful')) {
Expand Down
32 changes: 0 additions & 32 deletions app/SSH/Storage/S3AbstractStorage.php

This file was deleted.

84 changes: 0 additions & 84 deletions app/SSH/Storage/Wasabi.php

This file was deleted.

31 changes: 0 additions & 31 deletions app/SSH/Storage/scripts/wasabi/download.sh

This file was deleted.

59 changes: 0 additions & 59 deletions app/SSH/Storage/scripts/wasabi/upload.sh

This file was deleted.

55 changes: 49 additions & 6 deletions app/StorageProviders/S3.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,89 @@
namespace App\StorageProviders;

use App\Models\Server;
use App\Models\StorageProvider;
use App\SSH\Storage\S3 as S3Storage;
use App\SSH\Storage\Storage;
use Aws\S3\Exception\S3Exception;
use Aws\S3\S3Client;
use Illuminate\Support\Facades\Log;

class S3 extends S3AbstractStorageProvider
class S3 extends AbstractStorageProvider
{
protected StorageProvider $storageProvider;

protected ?S3Client $client = null;

protected array $clientConfig = [];

public function getApiUrl(): string
{
if (isset($this->storageProvider->credentials['api_url']) && $this->storageProvider->credentials['api_url']) {
return $this->storageProvider->credentials['api_url'];
}

$region = $this->storageProvider->credentials['region'];

return "https://s3.{$region}.amazonaws.com";
}

public function getClient(): S3Client
{
return new S3Client($this->clientConfig);
}

/**
* Build the configuration array for the S3 client.
* This method can be overridden by child classes to modify the configuration.
*/
public function buildClientConfig(): array
{
$this->clientConfig = [
'credentials' => [
'key' => $this->storageProvider->credentials['key'],
'secret' => $this->storageProvider->credentials['secret'],
],
'region' => $this->storageProvider->credentials['region'],
'version' => 'latest',
'endpoint' => $this->getApiUrl(),
];

return $this->clientConfig;
}

public function validationRules(): array
{
return [
'api_url' => 'nullable',
'key' => 'required',
'secret' => 'required',
'region' => 'required',
'bucket' => 'required',
'path' => 'required',
'path' => 'nullable',
];
}

public function credentialData(array $input): array
{
return [
'api_url' => $input['api_url'] ?? '',
'key' => $input['key'],
'secret' => $input['secret'],
'region' => $input['region'],
'bucket' => $input['bucket'],
'path' => $input['path'],
'path' => $input['path'] ?? '',
];
}

public function connect(): bool
{
try {
$this->setBucketRegion($this->storageProvider->credentials['region']);
$this->setApiUrl();
$this->buildClientConfig();
$this->getClient()->listBuckets();

return true;
} catch (S3Exception $e) {
Log::error('Failed to connect to S3', ['exception' => $e]);
Log::error('Failed to connect to the provider', ['exception' => $e]);

return false;
}
Expand Down
Loading

0 comments on commit ea3d646

Please sign in to comment.