-
-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'upstream/main' into Settings
- Loading branch information
Showing
12 changed files
with
374 additions
and
1 deletion.
There are no files selected for viewing
165 changes: 165 additions & 0 deletions
165
app/Http/Controllers/Api/Application/Mounts/MountController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers\Api\Application\Mounts; | ||
|
||
use Ramsey\Uuid\Uuid; | ||
use Illuminate\Http\Request; | ||
use Illuminate\Http\JsonResponse; | ||
use Illuminate\Contracts\Translation\Translator; | ||
use Spatie\QueryBuilder\QueryBuilder; | ||
use App\Models\Mount; | ||
use App\Http\Controllers\Api\Application\ApplicationApiController; | ||
use App\Transformers\Api\Application\MountTransformer; | ||
use App\Http\Requests\Api\Application\Mounts\GetMountRequest; | ||
use App\Http\Requests\Api\Application\Mounts\StoreMountRequest; | ||
use App\Http\Requests\Api\Application\Mounts\DeleteMountRequest; | ||
use App\Http\Requests\Api\Application\Mounts\UpdateMountRequest; | ||
use App\Exceptions\Service\HasActiveServersException; | ||
|
||
class MountController extends ApplicationApiController | ||
{ | ||
/** | ||
* MountController constructor. | ||
*/ | ||
public function __construct( | ||
protected Translator $translator | ||
) { | ||
parent::__construct(); | ||
} | ||
|
||
/** | ||
* Return all the mounts currently available on the Panel. | ||
*/ | ||
public function index(GetMountRequest $request): array | ||
{ | ||
$mounts = QueryBuilder::for(Mount::query()) | ||
->allowedFilters(['uuid', 'name']) | ||
->allowedSorts(['id', 'uuid']) | ||
->paginate($request->query('per_page') ?? 50); | ||
|
||
return $this->fractal->collection($mounts) | ||
->transformWith($this->getTransformer(MountTransformer::class)) | ||
->toArray(); | ||
} | ||
|
||
/** | ||
* Return data for a single instance of a mount. | ||
*/ | ||
public function view(GetMountRequest $request, Mount $mount): array | ||
{ | ||
return $this->fractal->item($mount) | ||
->transformWith($this->getTransformer(MountTransformer::class)) | ||
->toArray(); | ||
} | ||
|
||
/** | ||
* Create a new mount on the Panel. Returns the created mount and an HTTP/201 | ||
* status response on success. | ||
* | ||
* @throws \App\Exceptions\Model\DataValidationException | ||
*/ | ||
public function store(StoreMountRequest $request): JsonResponse | ||
{ | ||
$model = (new Mount())->fill($request->validated()); | ||
$model->forceFill(['uuid' => Uuid::uuid4()->toString()]); | ||
|
||
$model->saveOrFail(); | ||
$mount = $model->fresh(); | ||
|
||
return $this->fractal->item($mount) | ||
->transformWith($this->getTransformer(MountTransformer::class)) | ||
->addMeta([ | ||
'resource' => route('api.application.mounts.view', [ | ||
'mount' => $mount->id, | ||
]), | ||
]) | ||
->respond(201); | ||
} | ||
|
||
/** | ||
* Update an existing mount on the Panel. | ||
* | ||
* @throws \Throwable | ||
*/ | ||
public function update(UpdateMountRequest $request, Mount $mount): array | ||
{ | ||
$mount->forceFill($request->validated())->save(); | ||
|
||
return $this->fractal->item($mount) | ||
->transformWith($this->getTransformer(MountTransformer::class)) | ||
->toArray(); | ||
} | ||
|
||
/** | ||
* Deletes a given mount from the Panel as long as there are no servers | ||
* currently attached to it. | ||
* | ||
* @throws \App\Exceptions\Service\HasActiveServersException | ||
*/ | ||
public function delete(DeleteMountRequest $request, Mount $mount): JsonResponse | ||
{ | ||
if ($mount->servers()->count() > 0) { | ||
throw new HasActiveServersException($this->translator->get('exceptions.mount.servers_attached')); | ||
} | ||
|
||
$mount->delete(); | ||
|
||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT); | ||
} | ||
|
||
/** | ||
* Adds eggs to the mount's many-to-many relation. | ||
*/ | ||
public function addEggs(Request $request, Mount $mount): array | ||
{ | ||
$validatedData = $request->validate([ | ||
'eggs' => 'required|exists:eggs,id', | ||
]); | ||
|
||
$eggs = $validatedData['eggs'] ?? []; | ||
if (count($eggs) > 0) { | ||
$mount->eggs()->attach($eggs); | ||
} | ||
|
||
return $this->fractal->item($mount) | ||
->transformWith($this->getTransformer(MountTransformer::class)) | ||
->toArray(); | ||
} | ||
|
||
/** | ||
* Adds nodes to the mount's many-to-many relation. | ||
*/ | ||
public function addNodes(Request $request, Mount $mount): array | ||
{ | ||
$data = $request->validate(['nodes' => 'required|exists:nodes,id']); | ||
|
||
$nodes = $data['nodes'] ?? []; | ||
if (count($nodes) > 0) { | ||
$mount->nodes()->attach($nodes); | ||
} | ||
|
||
return $this->fractal->item($mount) | ||
->transformWith($this->getTransformer(MountTransformer::class)) | ||
->toArray(); | ||
} | ||
|
||
/** | ||
* Deletes an egg from the mount's many-to-many relation. | ||
*/ | ||
public function deleteEgg(Mount $mount, int $egg_id): JsonResponse | ||
{ | ||
$mount->eggs()->detach($egg_id); | ||
|
||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT); | ||
} | ||
|
||
/** | ||
* Deletes a node from the mount's many-to-many relation. | ||
*/ | ||
public function deleteNode(Mount $mount, int $node_id): JsonResponse | ||
{ | ||
$mount->nodes()->detach($node_id); | ||
|
||
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
app/Http/Requests/Api/Application/Mounts/DeleteMountRequest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace App\Http\Requests\Api\Application\Mounts; | ||
|
||
use App\Services\Acl\Api\AdminAcl; | ||
use App\Http\Requests\Api\Application\ApplicationApiRequest; | ||
|
||
class DeleteMountRequest extends ApplicationApiRequest | ||
{ | ||
protected ?string $resource = AdminAcl::RESOURCE_MOUNTS; | ||
|
||
protected int $permission = AdminAcl::WRITE; | ||
} |
13 changes: 13 additions & 0 deletions
13
app/Http/Requests/Api/Application/Mounts/GetMountRequest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace App\Http\Requests\Api\Application\Mounts; | ||
|
||
use App\Services\Acl\Api\AdminAcl; | ||
use App\Http\Requests\Api\Application\ApplicationApiRequest; | ||
|
||
class GetMountRequest extends ApplicationApiRequest | ||
{ | ||
protected ?string $resource = AdminAcl::RESOURCE_MOUNTS; | ||
|
||
protected int $permission = AdminAcl::READ; | ||
} |
13 changes: 13 additions & 0 deletions
13
app/Http/Requests/Api/Application/Mounts/StoreMountRequest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace App\Http\Requests\Api\Application\Mounts; | ||
|
||
use App\Services\Acl\Api\AdminAcl; | ||
use App\Http\Requests\Api\Application\ApplicationApiRequest; | ||
|
||
class StoreMountRequest extends ApplicationApiRequest | ||
{ | ||
protected ?string $resource = AdminAcl::RESOURCE_MOUNTS; | ||
|
||
protected int $permission = AdminAcl::WRITE; | ||
} |
20 changes: 20 additions & 0 deletions
20
app/Http/Requests/Api/Application/Mounts/UpdateMountRequest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace App\Http\Requests\Api\Application\Mounts; | ||
|
||
use App\Models\Mount; | ||
|
||
class UpdateMountRequest extends StoreMountRequest | ||
{ | ||
/** | ||
* Apply validation rules to this request. Uses the parent class rules() | ||
* function but passes in the rules for updating rather than creating. | ||
*/ | ||
public function rules(array $rules = null): array | ||
{ | ||
/** @var Mount $mount */ | ||
$mount = $this->route()->parameter('mount'); | ||
|
||
return parent::rules(Mount::getRulesForUpdate($mount->id)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<?php | ||
|
||
namespace App\Transformers\Api\Application; | ||
|
||
use App\Models\Mount; | ||
use League\Fractal\Resource\Collection; | ||
use League\Fractal\Resource\NullResource; | ||
use App\Services\Acl\Api\AdminAcl; | ||
|
||
class MountTransformer extends BaseTransformer | ||
{ | ||
/** | ||
* List of resources that can be included. | ||
*/ | ||
protected array $availableIncludes = ['eggs', 'nodes', 'servers']; | ||
|
||
/** | ||
* Return the resource name for the JSONAPI output. | ||
*/ | ||
public function getResourceName(): string | ||
{ | ||
return Mount::RESOURCE_NAME; | ||
} | ||
|
||
public function transform(Mount $model) | ||
{ | ||
return $model->toArray(); | ||
} | ||
|
||
/** | ||
* Return the eggs associated with this mount. | ||
* | ||
* @throws \App\Exceptions\Transformer\InvalidTransformerLevelException | ||
*/ | ||
public function includeEggs(Mount $mount): Collection|NullResource | ||
{ | ||
if (!$this->authorize(AdminAcl::RESOURCE_EGGS)) { | ||
return $this->null(); | ||
} | ||
|
||
$mount->loadMissing('eggs'); | ||
|
||
return $this->collection( | ||
$mount->getRelation('eggs'), | ||
$this->makeTransformer(EggTransformer::class), | ||
'egg' | ||
); | ||
} | ||
|
||
/** | ||
* Return the nodes associated with this mount. | ||
* | ||
* @throws \App\Exceptions\Transformer\InvalidTransformerLevelException | ||
*/ | ||
public function includeNodes(Mount $mount): Collection|NullResource | ||
{ | ||
if (!$this->authorize(AdminAcl::RESOURCE_NODES)) { | ||
return $this->null(); | ||
} | ||
|
||
$mount->loadMissing('nodes'); | ||
|
||
return $this->collection( | ||
$mount->getRelation('nodes'), | ||
$this->makeTransformer(NodeTransformer::class), | ||
'node' | ||
); | ||
} | ||
|
||
/** | ||
* Return the servers associated with this mount. | ||
* | ||
* @throws \App\Exceptions\Transformer\InvalidTransformerLevelException | ||
*/ | ||
public function includeServers(Mount $mount): Collection|NullResource | ||
{ | ||
if (!$this->authorize(AdminAcl::RESOURCE_SERVERS)) { | ||
return $this->null(); | ||
} | ||
|
||
$mount->loadMissing('servers'); | ||
|
||
return $this->collection( | ||
$mount->getRelation('servers'), | ||
$this->makeTransformer(ServerTransformer::class), | ||
'server' | ||
); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
database/migrations/2024_04_28_184102_add_mounts_to_api_keys.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
|
||
return new class extends Migration | ||
{ | ||
/** | ||
* Run the migrations. | ||
*/ | ||
public function up(): void | ||
{ | ||
Schema::table('api_keys', function (Blueprint $table) { | ||
$table->unsignedTinyInteger('r_mounts')->default(0); | ||
}); | ||
} | ||
|
||
/** | ||
* Reverse the migrations. | ||
*/ | ||
public function down(): void | ||
{ | ||
Schema::table('api_keys', function (Blueprint $table) { | ||
$table->dropColumn('r_mounts'); | ||
}); | ||
} | ||
}; |
Oops, something went wrong.