Basic backend support to at least store a backup model in the DB

This commit is contained in:
Dane Everitt 2020-04-04 12:26:39 -07:00
parent 6d426e45d9
commit d27f0c6f2a
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
10 changed files with 138 additions and 18 deletions

View file

@ -3,6 +3,7 @@
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
use Pterodactyl\Models\Server;
use Pterodactyl\Services\Backups\InitiateBackupService;
use Pterodactyl\Transformers\Api\Client\BackupTransformer;
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\GetBackupsRequest;
@ -10,9 +11,21 @@ use Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest;
class BackupController extends ClientApiController
{
public function __construct()
/**
* @var \Pterodactyl\Services\Backups\InitiateBackupService
*/
private $initiateBackupService;
/**
* BackupController constructor.
*
* @param \Pterodactyl\Services\Backups\InitiateBackupService $initiateBackupService
*/
public function __construct(InitiateBackupService $initiateBackupService)
{
parent::__construct();
$this->initiateBackupService = $initiateBackupService;
}
/**
@ -35,9 +48,19 @@ class BackupController extends ClientApiController
*
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Backups\StoreBackupRequest $request
* @param \Pterodactyl\Models\Server $server
* @return array
*
* @throws \Exception
*/
public function store(StoreBackupRequest $request, Server $server)
{
$backup = $this->initiateBackupService
->setIgnoredFiles($request->input('ignored'))
->handle($server, $request->input('name'));
return $this->fractal->item($backup)
->transformWith($this->getTransformer(BackupTransformer::class))
->toArray();
}
public function view()

View file

@ -21,7 +21,7 @@ class StoreBackupRequest extends ClientApiRequest
public function rules(): array
{
return [
'name' => 'nullable|string|max:255',
'name' => 'nullable|string|max:255|regex:/^[w\][\w\s_.-]*[\w]$/',
'ignore' => 'nullable|string',
];
}

View file

@ -9,7 +9,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @property int $server_id
* @property int $uuid
* @property string $name
* @property string $ignore
* @property string $ignored_files
* @property string $disk
* @property string|null $sha256_hash
* @property int $bytes
@ -52,15 +52,25 @@ class Backup extends Model
];
/**
* Returns dates from this model as immutable Carbon instances.
*
* @param mixed $value
* @return \Carbon\CarbonImmutable
* @var array
*/
protected function asDateTime($value)
{
return $this->asImmutableDateTime($value);
}
protected $attributes = [
'sha256_hash' => null,
'bytes' => 0,
];
/**
* @var array
*/
public static $validationRules = [
'server_id' => 'bail|required|numeric|exists:servers,id',
'uuid' => 'required|uuid',
'name' => 'required|string|regex:/^[w\][\w\s_.-]*[\w]$/',
'ignored_files' => 'string',
'disk' => 'required|string',
'sha256_hash' => 'nullable|string',
'bytes' => 'numeric',
];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo

View file

@ -0,0 +1,16 @@
<?php
namespace Pterodactyl\Repositories\Eloquent;
use Pterodactyl\Models\Backup;
class BackupRepository extends EloquentRepository
{
/**
* @return string
*/
public function model()
{
return Backup::class;
}
}

View file

@ -0,0 +1,69 @@
<?php
namespace Pterodactyl\Services\Backups;
use Ramsey\Uuid\Uuid;
use Carbon\CarbonImmutable;
use Illuminate\Support\Str;
use Pterodactyl\Models\Backup;
use Pterodactyl\Models\Server;
use Pterodactyl\Repositories\Eloquent\BackupRepository;
class InitiateBackupService
{
/**
* @var string|null
*/
private $ignoredFiles;
/**
* @var \Pterodactyl\Repositories\Eloquent\BackupRepository
*/
private $repository;
/**
* InitiateBackupService constructor.
*
* @param \Pterodactyl\Repositories\Eloquent\BackupRepository $repository
*/
public function __construct(BackupRepository $repository)
{
$this->repository = $repository;
}
/**
* Sets the files to be ignored by this backup.
*
* @param string|null $ignored
* @return $this
*/
public function setIgnoredFiles(?string $ignored)
{
$this->ignoredFiles = $ignored;
return $this;
}
/**
* Initiates the backup process for a server on the daemon.
*
* @param \Pterodactyl\Models\Server $server
* @param string|null $name
* @return \Pterodactyl\Models\Backup
*
* @throws \Exception
*/
public function handle(Server $server, string $name = null): Backup
{
/** @var \Pterodactyl\Models\Backup $backup */
$backup = $this->repository->create([
'server_id' => $server->id,
'uuid' => Uuid::uuid4()->toString(),
'name' => Str::lower(str_replace(' ', '_', trim($name))) ?: sprintf('backup_%s', CarbonImmutable::create()->format('YmdHis')),
'ignored_files' => $this->ignoredFiles ?? '',
'disk' => 'local',
], true, true);
return $backup;
}
}

View file

@ -23,11 +23,11 @@ class BackupTransformer extends BaseClientTransformer
return [
'uuid' => $backup->uuid,
'name' => $backup->name,
'ignore' => $backup->ignore,
'ignored_files' => $backup->ignored_files,
'sha256_hash' => $backup->sha256_hash,
'bytes' => $backup->bytes,
'created_at' => $backup->created_at->toIso8601String(),
'completed_at' => $backup->completed_at->toIso8601String(),
'completed_at' => $backup->completed_at ? $backup->completed_at->toIso8601String() : null,
];
}
}

View file

@ -18,7 +18,7 @@ class CreateBackupsTable extends Migration
$table->unsignedInteger('server_id');
$table->char('uuid', 36);
$table->string('name');
$table->text('ignored');
$table->text('ignored_files');
$table->string('disk');
$table->string('sha256_hash')->nullable();
$table->integer('bytes')->default(0);

View file

@ -6,7 +6,7 @@ export default (uuid: string, name?: string, ignore?: string): Promise<ServerBac
http.post(`/api/client/servers/${uuid}/backups`, {
name, ignore,
})
.then(({ data }) => resolve(rawDataToServerBackup(data.attributes)))
.then(({ data }) => resolve(rawDataToServerBackup(data)))
.catch(reject);
});
};

View file

@ -3,7 +3,7 @@ import http, { FractalResponseData, getPaginationSet, PaginatedResult } from '@/
export interface ServerBackup {
uuid: string;
name: string;
contents: string;
ignoredFiles: string;
sha256Hash: string;
bytes: number;
createdAt: Date;
@ -13,7 +13,7 @@ export interface ServerBackup {
export const rawDataToServerBackup = ({ attributes }: FractalResponseData): ServerBackup => ({
uuid: attributes.uuid,
name: attributes.name,
contents: attributes.contents,
ignoredFiles: attributes.ignored_files,
sha256Hash: attributes.sha256_hash,
bytes: attributes.bytes,
createdAt: new Date(attributes.created_at),

View file

@ -96,7 +96,9 @@ export default ({ onBackupGenerated }: Props) => {
onSubmit={submit}
initialValues={{ name: '', ignored: '' }}
validationSchema={object().shape({
name: string().max(255),
name: string().required()
.matches(/^[w\][\w\s_.-]*[\w]$/, 'Backup name must only contain alpha-numeric characters, spaces, underscores, dashes, and periods. The name must start and end with an alpha-numeric character.')
.max(255),
ignored: string(),
})}
>