mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-20 19:14:45 +02:00
Remove nests
This commit is contained in:
parent
05681641d3
commit
a296084d6e
3
.github/workflows/ci.yaml
vendored
3
.github/workflows/ci.yaml
vendored
@ -1,9 +1,6 @@
|
|||||||
name: Tests
|
name: Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '**'
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- '**'
|
||||||
|
@ -30,9 +30,4 @@ interface EggRepositoryInterface extends RepositoryInterface
|
|||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithExportAttributes(int $id): Egg;
|
public function getWithExportAttributes(int $id): Egg;
|
||||||
|
|
||||||
/**
|
|
||||||
* Confirm a copy script belongs to the same nest as the item trying to use it.
|
|
||||||
*/
|
|
||||||
public function isCopyableScript(int $copyFromId, int $service): bool;
|
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Contracts\Repository;
|
|
||||||
|
|
||||||
use App\Models\Nest;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
|
|
||||||
interface NestRepositoryInterface extends RepositoryInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Return a nest or all nests with their associated eggs and variables.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function getWithEggs(int $id = null): Collection|Nest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a nest or all nests and the count of eggs and servers for that nest.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function getWithCounts(int $id = null): Collection|Nest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a nest along with its associated eggs and the servers relation on those eggs.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function getWithEggServers(int $id): Nest;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions\Service\Egg;
|
|
||||||
|
|
||||||
use App\Exceptions\DisplayException;
|
|
||||||
|
|
||||||
class InvalidCopyFromException extends DisplayException
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Nests;
|
namespace App\Http\Controllers\Admin\Eggs;
|
||||||
|
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
@ -13,7 +13,6 @@ use App\Services\Eggs\EggCreationService;
|
|||||||
use App\Services\Eggs\EggDeletionService;
|
use App\Services\Eggs\EggDeletionService;
|
||||||
use App\Http\Requests\Admin\Egg\EggFormRequest;
|
use App\Http\Requests\Admin\Egg\EggFormRequest;
|
||||||
use App\Contracts\Repository\EggRepositoryInterface;
|
use App\Contracts\Repository\EggRepositoryInterface;
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
|
|
||||||
class EggController extends Controller
|
class EggController extends Controller
|
||||||
{
|
{
|
||||||
@ -26,11 +25,22 @@ class EggController extends Controller
|
|||||||
protected EggDeletionService $deletionService,
|
protected EggDeletionService $deletionService,
|
||||||
protected EggRepositoryInterface $repository,
|
protected EggRepositoryInterface $repository,
|
||||||
protected EggUpdateService $updateService,
|
protected EggUpdateService $updateService,
|
||||||
protected NestRepositoryInterface $nestRepository,
|
|
||||||
protected ViewFactory $view
|
protected ViewFactory $view
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render eggs listing page.
|
||||||
|
*
|
||||||
|
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
||||||
|
*/
|
||||||
|
public function index(): View
|
||||||
|
{
|
||||||
|
return $this->view->make('admin.eggs.index', [
|
||||||
|
'eggs' => Egg::all(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a request to display the Egg creation page.
|
* Handle a request to display the Egg creation page.
|
||||||
*
|
*
|
||||||
@ -38,10 +48,10 @@ class EggController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(): View
|
public function create(): View
|
||||||
{
|
{
|
||||||
$nests = $this->nestRepository->getWithEggs();
|
$eggs = Egg::all();
|
||||||
\JavaScript::put(['nests' => $nests->keyBy('id')]);
|
\JavaScript::put(['eggs' => $eggs->keyBy('id')]);
|
||||||
|
|
||||||
return $this->view->make('admin.eggs.new', ['nests' => $nests]);
|
return $this->view->make('admin.eggs.new', ['eggs' => $eggs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,9 +66,9 @@ class EggController extends Controller
|
|||||||
$data['docker_images'] = $this->normalizeDockerImages($data['docker_images'] ?? null);
|
$data['docker_images'] = $this->normalizeDockerImages($data['docker_images'] ?? null);
|
||||||
|
|
||||||
$egg = $this->creationService->handle($data);
|
$egg = $this->creationService->handle($data);
|
||||||
$this->alert->success(trans('admin/nests.eggs.notices.egg_created'))->flash();
|
$this->alert->success(trans('admin/eggs.notices.egg_created'))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.egg.view', $egg->id);
|
return redirect()->route('admin.eggs.view', $egg->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,9 +99,9 @@ class EggController extends Controller
|
|||||||
$data['docker_images'] = $this->normalizeDockerImages($data['docker_images'] ?? null);
|
$data['docker_images'] = $this->normalizeDockerImages($data['docker_images'] ?? null);
|
||||||
|
|
||||||
$this->updateService->handle($egg, $data);
|
$this->updateService->handle($egg, $data);
|
||||||
$this->alert->success(trans('admin/nests.eggs.notices.updated'))->flash();
|
$this->alert->success(trans('admin/eggs.notices.updated'))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.egg.view', $egg->id);
|
return redirect()->route('admin.eggs.view', $egg->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,9 +113,9 @@ class EggController extends Controller
|
|||||||
public function destroy(Egg $egg): RedirectResponse
|
public function destroy(Egg $egg): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->deletionService->handle($egg->id);
|
$this->deletionService->handle($egg->id);
|
||||||
$this->alert->success(trans('admin/nests.eggs.notices.deleted'))->flash();
|
$this->alert->success(trans('admin/eggs.notices.deleted'))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.view', $egg->nest_id);
|
return redirect()->route('admin.eggs.view', $egg->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Nests;
|
namespace App\Http\Controllers\Admin\Eggs;
|
||||||
|
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
@ -33,7 +33,6 @@ class EggScriptController extends Controller
|
|||||||
$egg = $this->repository->getWithCopyAttributes($egg);
|
$egg = $this->repository->getWithCopyAttributes($egg);
|
||||||
$copy = $this->repository->findWhere([
|
$copy = $this->repository->findWhere([
|
||||||
['copy_script_from', '=', null],
|
['copy_script_from', '=', null],
|
||||||
['nest_id', '=', $egg->nest_id],
|
|
||||||
['id', '!=', $egg],
|
['id', '!=', $egg],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -53,13 +52,12 @@ class EggScriptController extends Controller
|
|||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
* @throws \App\Exceptions\Model\DataValidationException
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
||||||
* @throws \App\Exceptions\Service\Egg\InvalidCopyFromException
|
|
||||||
*/
|
*/
|
||||||
public function update(EggScriptFormRequest $request, Egg $egg): RedirectResponse
|
public function update(EggScriptFormRequest $request, Egg $egg): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->installScriptService->handle($egg, $request->normalize());
|
$this->installScriptService->handle($egg, $request->normalize());
|
||||||
$this->alert->success(trans('admin/nests.eggs.notices.script_updated'))->flash();
|
$this->alert->success(trans('admin/eggs.notices.script_updated'))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.egg.scripts', $egg);
|
return redirect()->route('admin.eggs.scripts', $egg);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Nests;
|
namespace App\Http\Controllers\Admin\Eggs;
|
||||||
|
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
@ -41,7 +41,7 @@ class EggShareController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Import a new service option using an XML file.
|
* Import a new egg using an XML file.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
* @throws \App\Exceptions\Model\DataValidationException
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
||||||
@ -50,10 +50,10 @@ class EggShareController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function import(EggImportFormRequest $request): RedirectResponse
|
public function import(EggImportFormRequest $request): RedirectResponse
|
||||||
{
|
{
|
||||||
$egg = $this->importerService->handle($request->file('import_file'), $request->input('import_to_nest'));
|
$egg = $this->importerService->handle($request->file('import_file'));
|
||||||
$this->alert->success(trans('admin/nests.eggs.notices.imported'))->flash();
|
$this->alert->success(trans('admin/eggs.notices.imported'))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.egg.view', ['egg' => $egg->id]);
|
return redirect()->route('admin.eggs.view', ['egg' => $egg->id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,8 +67,8 @@ class EggShareController extends Controller
|
|||||||
public function update(EggImportFormRequest $request, Egg $egg): RedirectResponse
|
public function update(EggImportFormRequest $request, Egg $egg): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->updateImporterService->handle($egg, $request->file('import_file'));
|
$this->updateImporterService->handle($egg, $request->file('import_file'));
|
||||||
$this->alert->success(trans('admin/nests.eggs.notices.updated_via_import'))->flash();
|
$this->alert->success(trans('admin/eggs.notices.updated_via_import'))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.egg.view', ['egg' => $egg]);
|
return redirect()->route('admin.eggs.view', ['egg' => $egg]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Nests;
|
namespace App\Http\Controllers\Admin\Eggs;
|
||||||
|
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
@ -52,9 +52,9 @@ class EggVariableController extends Controller
|
|||||||
public function store(EggVariableFormRequest $request, Egg $egg): RedirectResponse
|
public function store(EggVariableFormRequest $request, Egg $egg): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->creationService->handle($egg->id, $request->normalize());
|
$this->creationService->handle($egg->id, $request->normalize());
|
||||||
$this->alert->success(trans('admin/nests.variables.notices.variable_created'))->flash();
|
$this->alert->success(trans('admin/eggs.variables.notices.variable_created'))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.egg.variables', $egg->id);
|
return redirect()->route('admin.eggs.variables', $egg->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,11 +68,11 @@ class EggVariableController extends Controller
|
|||||||
public function update(EggVariableFormRequest $request, Egg $egg, EggVariable $variable): RedirectResponse
|
public function update(EggVariableFormRequest $request, Egg $egg, EggVariable $variable): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->updateService->handle($variable, $request->normalize());
|
$this->updateService->handle($variable, $request->normalize());
|
||||||
$this->alert->success(trans('admin/nests.variables.notices.variable_updated', [
|
$this->alert->success(trans('admin/eggs.variables.notices.variable_updated', [
|
||||||
'variable' => $variable->name,
|
'variable' => $variable->name,
|
||||||
]))->flash();
|
]))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.egg.variables', $egg->id);
|
return redirect()->route('admin.eggs.variables', $egg->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,10 +81,10 @@ class EggVariableController extends Controller
|
|||||||
public function destroy(int $egg, EggVariable $variable): RedirectResponse
|
public function destroy(int $egg, EggVariable $variable): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->variableRepository->delete($variable->id);
|
$this->variableRepository->delete($variable->id);
|
||||||
$this->alert->success(trans('admin/nests.variables.notices.variable_deleted', [
|
$this->alert->success(trans('admin/eggs.variables.notices.variable_deleted', [
|
||||||
'variable' => $variable->name,
|
'variable' => $variable->name,
|
||||||
]))->flash();
|
]))->flash();
|
||||||
|
|
||||||
return redirect()->route('admin.nests.egg.variables', $egg);
|
return redirect()->route('admin.eggs.variables', $egg);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Models\Egg;
|
||||||
use Ramsey\Uuid\Uuid;
|
use Ramsey\Uuid\Uuid;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\Nest;
|
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use App\Models\Mount;
|
use App\Models\Mount;
|
||||||
use App\Models\Location;
|
use App\Models\Location;
|
||||||
@ -15,7 +15,6 @@ use Illuminate\View\Factory as ViewFactory;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\MountFormRequest;
|
use App\Http\Requests\Admin\MountFormRequest;
|
||||||
use App\Repositories\Eloquent\MountRepository;
|
use App\Repositories\Eloquent\MountRepository;
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use App\Contracts\Repository\LocationRepositoryInterface;
|
use App\Contracts\Repository\LocationRepositoryInterface;
|
||||||
|
|
||||||
class MountController extends Controller
|
class MountController extends Controller
|
||||||
@ -25,7 +24,6 @@ class MountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected AlertsMessageBag $alert,
|
protected AlertsMessageBag $alert,
|
||||||
protected NestRepositoryInterface $nestRepository,
|
|
||||||
protected LocationRepositoryInterface $locationRepository,
|
protected LocationRepositoryInterface $locationRepository,
|
||||||
protected MountRepository $repository,
|
protected MountRepository $repository,
|
||||||
protected ViewFactory $view
|
protected ViewFactory $view
|
||||||
@ -49,12 +47,12 @@ class MountController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function view(string $id): View
|
public function view(string $id): View
|
||||||
{
|
{
|
||||||
$nests = Nest::query()->with('eggs')->get();
|
$eggs = Egg::all();
|
||||||
$locations = Location::query()->with('nodes')->get();
|
$locations = Location::query()->with('nodes')->get();
|
||||||
|
|
||||||
return $this->view->make('admin.mounts.view', [
|
return $this->view->make('admin.mounts.view', [
|
||||||
'mount' => $this->repository->getWithRelations($id),
|
'mount' => $this->repository->getWithRelations($id),
|
||||||
'nests' => $nests,
|
'eggs' => $eggs,
|
||||||
'locations' => $locations,
|
'locations' => $locations,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Nests;
|
|
||||||
|
|
||||||
use Illuminate\View\View;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Prologue\Alerts\AlertsMessageBag;
|
|
||||||
use Illuminate\View\Factory as ViewFactory;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Services\Nests\NestUpdateService;
|
|
||||||
use App\Services\Nests\NestCreationService;
|
|
||||||
use App\Services\Nests\NestDeletionService;
|
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use App\Http\Requests\Admin\Nest\StoreNestFormRequest;
|
|
||||||
|
|
||||||
class NestController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* NestController constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
protected AlertsMessageBag $alert,
|
|
||||||
protected NestCreationService $nestCreationService,
|
|
||||||
protected NestDeletionService $nestDeletionService,
|
|
||||||
protected NestRepositoryInterface $repository,
|
|
||||||
protected NestUpdateService $nestUpdateService,
|
|
||||||
protected ViewFactory $view
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render nest listing page.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function index(): View
|
|
||||||
{
|
|
||||||
return $this->view->make('admin.nests.index', [
|
|
||||||
'nests' => $this->repository->getWithCounts(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render nest creation page.
|
|
||||||
*/
|
|
||||||
public function create(): View
|
|
||||||
{
|
|
||||||
return $this->view->make('admin.nests.new');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the storage of a new nest.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
public function store(StoreNestFormRequest $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$nest = $this->nestCreationService->handle($request->normalize());
|
|
||||||
$this->alert->success(trans('admin/nests.notices.created', ['name' => $nest->name]))->flash();
|
|
||||||
|
|
||||||
return redirect()->route('admin.nests.view', $nest->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return details about a nest including all the eggs and servers per egg.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function view(int $nest): View
|
|
||||||
{
|
|
||||||
return $this->view->make('admin.nests.view', [
|
|
||||||
'nest' => $this->repository->getWithEggServers($nest),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle request to update a nest.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function update(StoreNestFormRequest $request, int $nest): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->nestUpdateService->handle($nest, $request->normalize());
|
|
||||||
$this->alert->success(trans('admin/nests.notices.updated'))->flash();
|
|
||||||
|
|
||||||
return redirect()->route('admin.nests.view', $nest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle request to delete a nest.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Service\HasActiveServersException
|
|
||||||
*/
|
|
||||||
public function destroy(int $nest): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->nestDeletionService->handle($nest);
|
|
||||||
$this->alert->success(trans('admin/nests.notices.deleted'))->flash();
|
|
||||||
|
|
||||||
return redirect()->route('admin.nests');
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Servers;
|
namespace App\Http\Controllers\Admin\Servers;
|
||||||
|
|
||||||
|
use App\Models\Egg;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use App\Models\Node;
|
use App\Models\Node;
|
||||||
use App\Models\Location;
|
use App\Models\Location;
|
||||||
@ -9,7 +10,6 @@ use Illuminate\Http\RedirectResponse;
|
|||||||
use Prologue\Alerts\AlertsMessageBag;
|
use Prologue\Alerts\AlertsMessageBag;
|
||||||
use Illuminate\View\Factory as ViewFactory;
|
use Illuminate\View\Factory as ViewFactory;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Repositories\Eloquent\NestRepository;
|
|
||||||
use App\Repositories\Eloquent\NodeRepository;
|
use App\Repositories\Eloquent\NodeRepository;
|
||||||
use App\Http\Requests\Admin\ServerFormRequest;
|
use App\Http\Requests\Admin\ServerFormRequest;
|
||||||
use App\Services\Servers\ServerCreationService;
|
use App\Services\Servers\ServerCreationService;
|
||||||
@ -21,7 +21,6 @@ class CreateServerController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private AlertsMessageBag $alert,
|
private AlertsMessageBag $alert,
|
||||||
private NestRepository $nestRepository,
|
|
||||||
private NodeRepository $nodeRepository,
|
private NodeRepository $nodeRepository,
|
||||||
private ServerCreationService $creationService,
|
private ServerCreationService $creationService,
|
||||||
private ViewFactory $view
|
private ViewFactory $view
|
||||||
@ -42,20 +41,16 @@ class CreateServerController extends Controller
|
|||||||
return redirect()->route('admin.nodes');
|
return redirect()->route('admin.nodes');
|
||||||
}
|
}
|
||||||
|
|
||||||
$nests = $this->nestRepository->getWithEggs();
|
$eggs = Egg::with('variables')->get();
|
||||||
|
|
||||||
\JavaScript::put([
|
\JavaScript::put([
|
||||||
'nodeData' => $this->nodeRepository->getNodesForServerCreation(),
|
'nodeData' => $this->nodeRepository->getNodesForServerCreation(),
|
||||||
'nests' => $nests->map(function ($item) {
|
'eggs' => $eggs->keyBy('id'),
|
||||||
return array_merge($item->toArray(), [
|
|
||||||
'eggs' => $item->eggs->keyBy('id')->toArray(),
|
|
||||||
]);
|
|
||||||
})->keyBy('id'),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->view->make('admin.servers.new', [
|
return $this->view->make('admin.servers.new', [
|
||||||
'locations' => Location::all(),
|
'locations' => Location::all(),
|
||||||
'nests' => $nests,
|
'eggs' => $eggs,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Admin\Servers;
|
namespace App\Http\Controllers\Admin\Servers;
|
||||||
|
|
||||||
|
use App\Models\Egg;
|
||||||
|
use App\Repositories\Eloquent\EggRepository;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\Nest;
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Exceptions\DisplayException;
|
use App\Exceptions\DisplayException;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Services\Servers\EnvironmentService;
|
use App\Services\Servers\EnvironmentService;
|
||||||
use Illuminate\Contracts\View\Factory as ViewFactory;
|
use Illuminate\Contracts\View\Factory as ViewFactory;
|
||||||
use App\Repositories\Eloquent\NestRepository;
|
|
||||||
use App\Repositories\Eloquent\NodeRepository;
|
use App\Repositories\Eloquent\NodeRepository;
|
||||||
use App\Repositories\Eloquent\MountRepository;
|
use App\Repositories\Eloquent\MountRepository;
|
||||||
use App\Repositories\Eloquent\ServerRepository;
|
use App\Repositories\Eloquent\ServerRepository;
|
||||||
@ -29,7 +29,7 @@ class ServerViewController extends Controller
|
|||||||
private DatabaseHostRepository $databaseHostRepository,
|
private DatabaseHostRepository $databaseHostRepository,
|
||||||
private LocationRepository $locationRepository,
|
private LocationRepository $locationRepository,
|
||||||
private MountRepository $mountRepository,
|
private MountRepository $mountRepository,
|
||||||
private NestRepository $nestRepository,
|
private EggRepository $eggRepository,
|
||||||
private NodeRepository $nodeRepository,
|
private NodeRepository $nodeRepository,
|
||||||
private ServerRepository $repository,
|
private ServerRepository $repository,
|
||||||
private EnvironmentService $environmentService,
|
private EnvironmentService $environmentService,
|
||||||
@ -74,20 +74,16 @@ class ServerViewController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function startup(Request $request, Server $server): View
|
public function startup(Request $request, Server $server): View
|
||||||
{
|
{
|
||||||
$nests = $this->nestRepository->getWithEggs();
|
|
||||||
$variables = $this->environmentService->handle($server);
|
$variables = $this->environmentService->handle($server);
|
||||||
|
$eggs = Egg::all()->keyBy('id');
|
||||||
|
|
||||||
$this->plainInject([
|
$this->plainInject([
|
||||||
'server' => $server,
|
'server' => $server,
|
||||||
'server_variables' => $variables,
|
'server_variables' => $variables,
|
||||||
'nests' => $nests->map(function (Nest $item) {
|
'eggs' => $eggs,
|
||||||
return array_merge($item->toArray(), [
|
|
||||||
'eggs' => $item->eggs->keyBy('id')->toArray(),
|
|
||||||
]);
|
|
||||||
})->keyBy('id'),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $this->view->make('admin.servers.view.startup', compact('server', 'nests'));
|
return $this->view->make('admin.servers.view.startup', compact('server', 'eggs'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,7 +24,6 @@ use App\Services\Servers\BuildModificationService;
|
|||||||
use App\Services\Databases\DatabasePasswordService;
|
use App\Services\Databases\DatabasePasswordService;
|
||||||
use App\Services\Servers\DetailsModificationService;
|
use App\Services\Servers\DetailsModificationService;
|
||||||
use App\Services\Servers\StartupModificationService;
|
use App\Services\Servers\StartupModificationService;
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use App\Repositories\Eloquent\DatabaseHostRepository;
|
use App\Repositories\Eloquent\DatabaseHostRepository;
|
||||||
use App\Services\Databases\DatabaseManagementService;
|
use App\Services\Databases\DatabaseManagementService;
|
||||||
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||||
@ -54,7 +53,6 @@ class ServersController extends Controller
|
|||||||
protected ReinstallServerService $reinstallService,
|
protected ReinstallServerService $reinstallService,
|
||||||
protected ServerRepositoryInterface $repository,
|
protected ServerRepositoryInterface $repository,
|
||||||
protected MountRepository $mountRepository,
|
protected MountRepository $mountRepository,
|
||||||
protected NestRepositoryInterface $nestRepository,
|
|
||||||
protected ServerConfigurationStructureService $serverConfigurationStructureService,
|
protected ServerConfigurationStructureService $serverConfigurationStructureService,
|
||||||
protected StartupModificationService $startupModificationService,
|
protected StartupModificationService $startupModificationService,
|
||||||
protected SuspensionService $suspensionService
|
protected SuspensionService $suspensionService
|
||||||
|
32
app/Http/Controllers/Api/Application/Eggs/EggController.php
Normal file
32
app/Http/Controllers/Api/Application/Eggs/EggController.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api\Application\Eggs;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
use App\Http\Requests\Api\Application\Eggs\GetEggRequest;
|
||||||
|
use App\Http\Requests\Api\Application\Eggs\GetEggsRequest;
|
||||||
|
use App\Models\Egg;
|
||||||
|
use App\Transformers\Api\Application\EggTransformer;
|
||||||
|
|
||||||
|
class EggController extends ApplicationApiController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return all eggs
|
||||||
|
*/
|
||||||
|
public function index(GetEggsRequest $request): array
|
||||||
|
{
|
||||||
|
return $this->fractal->collection(Egg::all())
|
||||||
|
->transformWith($this->getTransformer(EggTransformer::class))
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a single egg that exists
|
||||||
|
*/
|
||||||
|
public function view(GetEggRequest $request, Egg $egg): array
|
||||||
|
{
|
||||||
|
return $this->fractal->item($egg)
|
||||||
|
->transformWith($this->getTransformer(EggTransformer::class))
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Api\Application\Nests;
|
|
||||||
|
|
||||||
use App\Models\Egg;
|
|
||||||
use App\Models\Nest;
|
|
||||||
use App\Transformers\Api\Application\EggTransformer;
|
|
||||||
use App\Http\Requests\Api\Application\Nests\Eggs\GetEggRequest;
|
|
||||||
use App\Http\Requests\Api\Application\Nests\Eggs\GetEggsRequest;
|
|
||||||
use App\Http\Controllers\Api\Application\ApplicationApiController;
|
|
||||||
|
|
||||||
class EggController extends ApplicationApiController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Return all eggs that exist for a given nest.
|
|
||||||
*/
|
|
||||||
public function index(GetEggsRequest $request, Nest $nest): array
|
|
||||||
{
|
|
||||||
return $this->fractal->collection($nest->eggs)
|
|
||||||
->transformWith($this->getTransformer(EggTransformer::class))
|
|
||||||
->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a single egg that exists on the specified nest.
|
|
||||||
*/
|
|
||||||
public function view(GetEggRequest $request, Nest $nest, Egg $egg): array
|
|
||||||
{
|
|
||||||
return $this->fractal->item($egg)
|
|
||||||
->transformWith($this->getTransformer(EggTransformer::class))
|
|
||||||
->toArray();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Api\Application\Nests;
|
|
||||||
|
|
||||||
use App\Models\Nest;
|
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use App\Transformers\Api\Application\NestTransformer;
|
|
||||||
use App\Http\Requests\Api\Application\Nests\GetNestsRequest;
|
|
||||||
use App\Http\Controllers\Api\Application\ApplicationApiController;
|
|
||||||
|
|
||||||
class NestController extends ApplicationApiController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* NestController constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(private NestRepositoryInterface $repository)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return all Nests that exist on the Panel.
|
|
||||||
*/
|
|
||||||
public function index(GetNestsRequest $request): array
|
|
||||||
{
|
|
||||||
$nests = $this->repository->paginated($request->query('per_page') ?? 50);
|
|
||||||
|
|
||||||
return $this->fractal->collection($nests)
|
|
||||||
->transformWith($this->getTransformer(NestTransformer::class))
|
|
||||||
->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return information about a single Nest model.
|
|
||||||
*/
|
|
||||||
public function view(GetNestsRequest $request, Nest $nest): array
|
|
||||||
{
|
|
||||||
return $this->fractal->item($nest)
|
|
||||||
->transformWith($this->getTransformer(NestTransformer::class))
|
|
||||||
->toArray();
|
|
||||||
}
|
|
||||||
}
|
|
@ -54,7 +54,6 @@ class StartupController extends ClientApiController
|
|||||||
{
|
{
|
||||||
/** @var \App\Models\EggVariable $variable */
|
/** @var \App\Models\EggVariable $variable */
|
||||||
$variable = $server->variables()->where('env_variable', $request->input('key'))->first();
|
$variable = $server->variables()->where('env_variable', $request->input('key'))->first();
|
||||||
$original = $variable->server_value;
|
|
||||||
|
|
||||||
if (is_null($variable) || !$variable->user_viewable) {
|
if (is_null($variable) || !$variable->user_viewable) {
|
||||||
throw new BadRequestHttpException('The environment variable you are trying to edit does not exist.');
|
throw new BadRequestHttpException('The environment variable you are trying to edit does not exist.');
|
||||||
@ -62,6 +61,8 @@ class StartupController extends ClientApiController
|
|||||||
throw new BadRequestHttpException('The environment variable you are trying to edit is read-only.');
|
throw new BadRequestHttpException('The environment variable you are trying to edit is read-only.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$original = $variable->server_value;
|
||||||
|
|
||||||
// Revalidate the variable value using the egg variable specific validation rules for it.
|
// Revalidate the variable value using the egg variable specific validation rules for it.
|
||||||
$this->validate($request, ['value' => $variable->rules]);
|
$this->validate($request, ['value' => $variable->rules]);
|
||||||
|
|
||||||
|
@ -22,10 +22,6 @@ class EggFormRequest extends AdminFormRequest
|
|||||||
'config_files' => 'required_without:config_from|nullable|json',
|
'config_files' => 'required_without:config_from|nullable|json',
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->method() === 'POST') {
|
|
||||||
$rules['nest_id'] = 'required|numeric|exists:nests,id';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,8 @@ class EggImportFormRequest extends AdminFormRequest
|
|||||||
{
|
{
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
$rules = [
|
return [
|
||||||
'import_file' => 'bail|required|file|max:1000|mimetypes:application/json,text/plain',
|
'import_file' => 'bail|required|file|max:1000|mimetypes:application/json,text/plain',
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->method() !== 'PUT') {
|
|
||||||
$rules['import_to_nest'] = 'bail|required|integer|exists:nests,id';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rules;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Admin\Nest;
|
|
||||||
|
|
||||||
use App\Http\Requests\Admin\AdminFormRequest;
|
|
||||||
|
|
||||||
class StoreNestFormRequest extends AdminFormRequest
|
|
||||||
{
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'name' => 'required|string|min:1|max:191',
|
|
||||||
'description' => 'string|nullable',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Requests\Api\Application\Nests\Eggs;
|
namespace App\Http\Requests\Api\Application\Eggs;
|
||||||
|
|
||||||
use App\Services\Acl\Api\AdminAcl;
|
|
||||||
use App\Http\Requests\Api\Application\ApplicationApiRequest;
|
use App\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||||
|
use App\Services\Acl\Api\AdminAcl;
|
||||||
|
|
||||||
class GetEggRequest extends ApplicationApiRequest
|
class GetEggRequest extends ApplicationApiRequest
|
||||||
{
|
{
|
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Requests\Api\Application\Nests\Eggs;
|
namespace App\Http\Requests\Api\Application\Eggs;
|
||||||
|
|
||||||
use App\Services\Acl\Api\AdminAcl;
|
|
||||||
use App\Http\Requests\Api\Application\ApplicationApiRequest;
|
use App\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||||
|
use App\Services\Acl\Api\AdminAcl;
|
||||||
|
|
||||||
class GetEggsRequest extends ApplicationApiRequest
|
class GetEggsRequest extends ApplicationApiRequest
|
||||||
{
|
{
|
@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Api\Application\Nests;
|
|
||||||
|
|
||||||
use App\Services\Acl\Api\AdminAcl;
|
|
||||||
use App\Http\Requests\Api\Application\ApplicationApiRequest;
|
|
||||||
|
|
||||||
class GetNestsRequest extends ApplicationApiRequest
|
|
||||||
{
|
|
||||||
protected ?string $resource = AdminAcl::RESOURCE_NESTS;
|
|
||||||
|
|
||||||
protected int $permission = AdminAcl::READ;
|
|
||||||
}
|
|
@ -26,7 +26,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||||||
* @property int $r_allocations
|
* @property int $r_allocations
|
||||||
* @property int $r_users
|
* @property int $r_users
|
||||||
* @property int $r_locations
|
* @property int $r_locations
|
||||||
* @property int $r_nests
|
|
||||||
* @property int $r_eggs
|
* @property int $r_eggs
|
||||||
* @property int $r_database_hosts
|
* @property int $r_database_hosts
|
||||||
* @property int $r_server_databases
|
* @property int $r_server_databases
|
||||||
@ -48,7 +47,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRDatabaseHosts($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRDatabaseHosts($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereREggs($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereREggs($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRLocations($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRLocations($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRNests($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRNodes($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRNodes($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRServerDatabases($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRServerDatabases($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRServers($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ApiKey whereRServers($value)
|
||||||
@ -108,7 +106,7 @@ class ApiKey extends Model
|
|||||||
'r_' . AdminAcl::RESOURCE_SERVER_DATABASES => 'int',
|
'r_' . AdminAcl::RESOURCE_SERVER_DATABASES => 'int',
|
||||||
'r_' . AdminAcl::RESOURCE_EGGS => 'int',
|
'r_' . AdminAcl::RESOURCE_EGGS => 'int',
|
||||||
'r_' . AdminAcl::RESOURCE_LOCATIONS => 'int',
|
'r_' . AdminAcl::RESOURCE_LOCATIONS => 'int',
|
||||||
'r_' . AdminAcl::RESOURCE_NESTS => 'int',
|
'r_' . AdminAcl::RESOURCE_EGGS => 'int',
|
||||||
'r_' . AdminAcl::RESOURCE_NODES => 'int',
|
'r_' . AdminAcl::RESOURCE_NODES => 'int',
|
||||||
'r_' . AdminAcl::RESOURCE_SERVERS => 'int',
|
'r_' . AdminAcl::RESOURCE_SERVERS => 'int',
|
||||||
];
|
];
|
||||||
@ -150,7 +148,7 @@ class ApiKey extends Model
|
|||||||
'r_' . AdminAcl::RESOURCE_SERVER_DATABASES => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_SERVER_DATABASES => 'integer|min:0|max:3',
|
||||||
'r_' . AdminAcl::RESOURCE_EGGS => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_EGGS => 'integer|min:0|max:3',
|
||||||
'r_' . AdminAcl::RESOURCE_LOCATIONS => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_LOCATIONS => 'integer|min:0|max:3',
|
||||||
'r_' . AdminAcl::RESOURCE_NESTS => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_EGGS => 'integer|min:0|max:3',
|
||||||
'r_' . AdminAcl::RESOURCE_NODES => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_NODES => 'integer|min:0|max:3',
|
||||||
'r_' . AdminAcl::RESOURCE_SERVERS => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_SERVERS => 'integer|min:0|max:3',
|
||||||
];
|
];
|
||||||
|
@ -8,7 +8,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||||||
/**
|
/**
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string $uuid
|
* @property string $uuid
|
||||||
* @property int $nest_id
|
|
||||||
* @property string $author
|
* @property string $author
|
||||||
* @property string $name
|
* @property string $name
|
||||||
* @property string|null $description
|
* @property string|null $description
|
||||||
@ -40,7 +39,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||||||
* @property string|null $inherit_config_stop
|
* @property string|null $inherit_config_stop
|
||||||
* @property string $inherit_file_denylist
|
* @property string $inherit_file_denylist
|
||||||
* @property array|null $inherit_features
|
* @property array|null $inherit_features
|
||||||
* @property \App\Models\Nest $nest
|
|
||||||
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\Server[] $servers
|
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\Server[] $servers
|
||||||
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\EggVariable[] $variables
|
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\EggVariable[] $variables
|
||||||
* @property \App\Models\Egg|null $scriptFrom
|
* @property \App\Models\Egg|null $scriptFrom
|
||||||
@ -103,7 +101,6 @@ class Egg extends Model
|
|||||||
* Cast values to correct type.
|
* Cast values to correct type.
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'nest_id' => 'integer',
|
|
||||||
'config_from' => 'integer',
|
'config_from' => 'integer',
|
||||||
'script_is_privileged' => 'boolean',
|
'script_is_privileged' => 'boolean',
|
||||||
'force_outgoing_ip' => 'boolean',
|
'force_outgoing_ip' => 'boolean',
|
||||||
@ -114,7 +111,6 @@ class Egg extends Model
|
|||||||
];
|
];
|
||||||
|
|
||||||
public static array $validationRules = [
|
public static array $validationRules = [
|
||||||
'nest_id' => 'required|bail|numeric|exists:nests,id',
|
|
||||||
'uuid' => 'required|string|size:36',
|
'uuid' => 'required|string|size:36',
|
||||||
'name' => 'required|string|max:191',
|
'name' => 'required|string|max:191',
|
||||||
'description' => 'string|nullable',
|
'description' => 'string|nullable',
|
||||||
@ -257,14 +253,6 @@ class Egg extends Model
|
|||||||
return $this->configFrom->file_denylist;
|
return $this->configFrom->file_denylist;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets nest associated with an egg.
|
|
||||||
*/
|
|
||||||
public function nest(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Nest::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all servers associated with this egg.
|
* Gets all servers associated with this egg.
|
||||||
*/
|
*/
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property int $id
|
|
||||||
* @property string $uuid
|
|
||||||
* @property string $author
|
|
||||||
* @property string $name
|
|
||||||
* @property string|null $description
|
|
||||||
* @property \Carbon\Carbon $created_at
|
|
||||||
* @property \Carbon\Carbon $updated_at
|
|
||||||
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\Server[] $servers
|
|
||||||
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\Egg[] $eggs
|
|
||||||
*/
|
|
||||||
class Nest extends Model
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The resource name for this model when it is transformed into an
|
|
||||||
* API representation using fractal.
|
|
||||||
*/
|
|
||||||
public const RESOURCE_NAME = 'nest';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The table associated with the model.
|
|
||||||
*/
|
|
||||||
protected $table = 'nests';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fields that are mass assignable.
|
|
||||||
*/
|
|
||||||
protected $fillable = [
|
|
||||||
'name',
|
|
||||||
'description',
|
|
||||||
];
|
|
||||||
|
|
||||||
public static array $validationRules = [
|
|
||||||
'author' => 'required|string|email',
|
|
||||||
'name' => 'required|string|max:191',
|
|
||||||
'description' => 'nullable|string',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all eggs associated with this service.
|
|
||||||
*/
|
|
||||||
public function eggs(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Egg::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all servers associated with this nest.
|
|
||||||
*/
|
|
||||||
public function servers(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(Server::class);
|
|
||||||
}
|
|
||||||
}
|
|
@ -33,7 +33,6 @@ use App\Exceptions\Http\Server\ServerStateConflictException;
|
|||||||
* @property string|null $threads
|
* @property string|null $threads
|
||||||
* @property bool $oom_disabled
|
* @property bool $oom_disabled
|
||||||
* @property int $allocation_id
|
* @property int $allocation_id
|
||||||
* @property int $nest_id
|
|
||||||
* @property int $egg_id
|
* @property int $egg_id
|
||||||
* @property string $startup
|
* @property string $startup
|
||||||
* @property string $image
|
* @property string $image
|
||||||
@ -55,7 +54,6 @@ use App\Exceptions\Http\Server\ServerStateConflictException;
|
|||||||
* @property \App\Models\Egg|null $egg
|
* @property \App\Models\Egg|null $egg
|
||||||
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\Mount[] $mounts
|
* @property \Illuminate\Database\Eloquent\Collection|\App\Models\Mount[] $mounts
|
||||||
* @property int|null $mounts_count
|
* @property int|null $mounts_count
|
||||||
* @property \App\Models\Nest $nest
|
|
||||||
* @property \App\Models\Node $node
|
* @property \App\Models\Node $node
|
||||||
* @property \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications
|
* @property \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications
|
||||||
* @property int|null $notifications_count
|
* @property int|null $notifications_count
|
||||||
@ -87,7 +85,6 @@ use App\Exceptions\Http\Server\ServerStateConflictException;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereIo($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereIo($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereMemory($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereMemory($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereName($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereName($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereNestId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereNodeId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereNodeId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereOomDisabled($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereOomDisabled($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereOwnerId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereOwnerId($value)
|
||||||
@ -159,7 +156,6 @@ class Server extends Model
|
|||||||
'oom_disabled' => 'sometimes|boolean',
|
'oom_disabled' => 'sometimes|boolean',
|
||||||
'disk' => 'required|numeric|min:0',
|
'disk' => 'required|numeric|min:0',
|
||||||
'allocation_id' => 'required|bail|unique:servers|exists:allocations,id',
|
'allocation_id' => 'required|bail|unique:servers|exists:allocations,id',
|
||||||
'nest_id' => 'required|exists:nests,id',
|
|
||||||
'egg_id' => 'required|exists:eggs,id',
|
'egg_id' => 'required|exists:eggs,id',
|
||||||
'startup' => 'required|string',
|
'startup' => 'required|string',
|
||||||
'skip_scripts' => 'sometimes|boolean',
|
'skip_scripts' => 'sometimes|boolean',
|
||||||
@ -183,7 +179,6 @@ class Server extends Model
|
|||||||
'cpu' => 'integer',
|
'cpu' => 'integer',
|
||||||
'oom_disabled' => 'boolean',
|
'oom_disabled' => 'boolean',
|
||||||
'allocation_id' => 'integer',
|
'allocation_id' => 'integer',
|
||||||
'nest_id' => 'integer',
|
|
||||||
'egg_id' => 'integer',
|
'egg_id' => 'integer',
|
||||||
'database_limit' => 'integer',
|
'database_limit' => 'integer',
|
||||||
'allocation_limit' => 'integer',
|
'allocation_limit' => 'integer',
|
||||||
@ -246,14 +241,6 @@ class Server extends Model
|
|||||||
return $this->hasMany(Allocation::class, 'server_id');
|
return $this->hasMany(Allocation::class, 'server_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets information for the nest associated with this server.
|
|
||||||
*/
|
|
||||||
public function nest(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Nest::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets information for the egg associated with this server.
|
* Gets information for the egg associated with this server.
|
||||||
*/
|
*/
|
||||||
@ -263,7 +250,7 @@ class Server extends Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets information for the service variables associated with this server.
|
* Gets information for the egg variables associated with this server.
|
||||||
*/
|
*/
|
||||||
public function variables(): HasMany
|
public function variables(): HasMany
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,6 @@ namespace App\Providers;
|
|||||||
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use App\Repositories\Eloquent\EggRepository;
|
use App\Repositories\Eloquent\EggRepository;
|
||||||
use App\Repositories\Eloquent\NestRepository;
|
|
||||||
use App\Repositories\Eloquent\NodeRepository;
|
use App\Repositories\Eloquent\NodeRepository;
|
||||||
use App\Repositories\Eloquent\TaskRepository;
|
use App\Repositories\Eloquent\TaskRepository;
|
||||||
use App\Repositories\Eloquent\UserRepository;
|
use App\Repositories\Eloquent\UserRepository;
|
||||||
@ -19,7 +18,6 @@ use App\Repositories\Eloquent\SettingsRepository;
|
|||||||
use App\Repositories\Eloquent\AllocationRepository;
|
use App\Repositories\Eloquent\AllocationRepository;
|
||||||
use App\Contracts\Repository\EggRepositoryInterface;
|
use App\Contracts\Repository\EggRepositoryInterface;
|
||||||
use App\Repositories\Eloquent\EggVariableRepository;
|
use App\Repositories\Eloquent\EggVariableRepository;
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use App\Contracts\Repository\NodeRepositoryInterface;
|
use App\Contracts\Repository\NodeRepositoryInterface;
|
||||||
use App\Contracts\Repository\TaskRepositoryInterface;
|
use App\Contracts\Repository\TaskRepositoryInterface;
|
||||||
use App\Contracts\Repository\UserRepositoryInterface;
|
use App\Contracts\Repository\UserRepositoryInterface;
|
||||||
@ -53,7 +51,6 @@ class RepositoryServiceProvider extends ServiceProvider
|
|||||||
$this->app->bind(EggRepositoryInterface::class, EggRepository::class);
|
$this->app->bind(EggRepositoryInterface::class, EggRepository::class);
|
||||||
$this->app->bind(EggVariableRepositoryInterface::class, EggVariableRepository::class);
|
$this->app->bind(EggVariableRepositoryInterface::class, EggVariableRepository::class);
|
||||||
$this->app->bind(LocationRepositoryInterface::class, LocationRepository::class);
|
$this->app->bind(LocationRepositoryInterface::class, LocationRepository::class);
|
||||||
$this->app->bind(NestRepositoryInterface::class, NestRepository::class);
|
|
||||||
$this->app->bind(NodeRepositoryInterface::class, NodeRepository::class);
|
$this->app->bind(NodeRepositoryInterface::class, NodeRepository::class);
|
||||||
$this->app->bind(ScheduleRepositoryInterface::class, ScheduleRepository::class);
|
$this->app->bind(ScheduleRepositoryInterface::class, ScheduleRepository::class);
|
||||||
$this->app->bind(ServerRepositoryInterface::class, ServerRepository::class);
|
$this->app->bind(ServerRepositoryInterface::class, ServerRepository::class);
|
||||||
|
@ -72,15 +72,4 @@ class EggRepository extends EloquentRepository implements EggRepositoryInterface
|
|||||||
throw new RecordNotFoundException();
|
throw new RecordNotFoundException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Confirm a copy script belongs to the same nest as the item trying to use it.
|
|
||||||
*/
|
|
||||||
public function isCopyableScript(int $copyFromId, int $service): bool
|
|
||||||
{
|
|
||||||
return $this->getBuilder()->whereNull('copy_script_from')
|
|
||||||
->where('id', '=', $copyFromId)
|
|
||||||
->where('nest_id', '=', $service)
|
|
||||||
->exists();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Repositories\Eloquent;
|
|
||||||
|
|
||||||
use App\Models\Nest;
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use App\Exceptions\Repository\RecordNotFoundException;
|
|
||||||
|
|
||||||
class NestRepository extends EloquentRepository implements NestRepositoryInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Return the model backing this repository.
|
|
||||||
*/
|
|
||||||
public function model(): string
|
|
||||||
{
|
|
||||||
return Nest::class;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a nest or all nests with their associated eggs and variables.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function getWithEggs(int $id = null): Collection|Nest
|
|
||||||
{
|
|
||||||
$instance = $this->getBuilder()->with('eggs', 'eggs.variables');
|
|
||||||
|
|
||||||
if (!is_null($id)) {
|
|
||||||
$instance = $instance->find($id, $this->getColumns());
|
|
||||||
if (!$instance) {
|
|
||||||
throw new RecordNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $instance->get($this->getColumns());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a nest or all nests and the count of eggs and servers for that nest.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function getWithCounts(int $id = null): Collection|Nest
|
|
||||||
{
|
|
||||||
$instance = $this->getBuilder()->withCount(['eggs', 'servers']);
|
|
||||||
|
|
||||||
if (!is_null($id)) {
|
|
||||||
$instance = $instance->find($id, $this->getColumns());
|
|
||||||
if (!$instance) {
|
|
||||||
throw new RecordNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $instance->get($this->getColumns());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a nest along with its associated eggs and the servers relation on those eggs.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function getWithEggServers(int $id): Nest
|
|
||||||
{
|
|
||||||
$instance = $this->getBuilder()->with('eggs.servers')->find($id, $this->getColumns());
|
|
||||||
if (!$instance) {
|
|
||||||
throw new RecordNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @var Nest $instance */
|
|
||||||
return $instance;
|
|
||||||
}
|
|
||||||
}
|
|
@ -146,7 +146,7 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt
|
|||||||
try {
|
try {
|
||||||
/** @var \App\Models\Server $model */
|
/** @var \App\Models\Server $model */
|
||||||
$model = $this->getBuilder()
|
$model = $this->getBuilder()
|
||||||
->with('nest', 'node')
|
->with('egg', 'node')
|
||||||
->where(function (Builder $query) use ($uuid) {
|
->where(function (Builder $query) use ($uuid) {
|
||||||
$query->where('uuidShort', $uuid)->orWhere('uuid', $uuid);
|
$query->where('uuidShort', $uuid)->orWhere('uuid', $uuid);
|
||||||
})
|
})
|
||||||
@ -172,7 +172,7 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt
|
|||||||
public function loadAllServersForNode(int $node, int $limit): LengthAwarePaginator
|
public function loadAllServersForNode(int $node, int $limit): LengthAwarePaginator
|
||||||
{
|
{
|
||||||
return $this->getBuilder()
|
return $this->getBuilder()
|
||||||
->with(['user', 'nest', 'egg'])
|
->with(['user', 'egg'])
|
||||||
->where('node_id', '=', $node)
|
->where('node_id', '=', $node)
|
||||||
->paginate($limit);
|
->paginate($limit);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ class AdminAcl
|
|||||||
public const RESOURCE_ALLOCATIONS = 'allocations';
|
public const RESOURCE_ALLOCATIONS = 'allocations';
|
||||||
public const RESOURCE_USERS = 'users';
|
public const RESOURCE_USERS = 'users';
|
||||||
public const RESOURCE_LOCATIONS = 'locations';
|
public const RESOURCE_LOCATIONS = 'locations';
|
||||||
public const RESOURCE_NESTS = 'nests';
|
|
||||||
public const RESOURCE_EGGS = 'eggs';
|
public const RESOURCE_EGGS = 'eggs';
|
||||||
public const RESOURCE_DATABASE_HOSTS = 'database_hosts';
|
public const RESOURCE_DATABASE_HOSTS = 'database_hosts';
|
||||||
public const RESOURCE_SERVER_DATABASES = 'server_databases';
|
public const RESOURCE_SERVER_DATABASES = 'server_databases';
|
||||||
|
@ -18,7 +18,7 @@ class EggCreationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new service option and assign it to the given service.
|
* Create a new egg.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
* @throws \App\Exceptions\Model\DataValidationException
|
||||||
* @throws \App\Exceptions\Service\Egg\NoParentConfigurationFoundException
|
* @throws \App\Exceptions\Service\Egg\NoParentConfigurationFoundException
|
||||||
@ -28,12 +28,11 @@ class EggCreationService
|
|||||||
$data['config_from'] = array_get($data, 'config_from');
|
$data['config_from'] = array_get($data, 'config_from');
|
||||||
if (!is_null($data['config_from'])) {
|
if (!is_null($data['config_from'])) {
|
||||||
$results = $this->repository->findCountWhere([
|
$results = $this->repository->findCountWhere([
|
||||||
['nest_id', '=', array_get($data, 'nest_id')],
|
|
||||||
['id', '=', array_get($data, 'config_from')],
|
['id', '=', array_get($data, 'config_from')],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($results !== 1) {
|
if ($results !== 1) {
|
||||||
throw new NoParentConfigurationFoundException(trans('exceptions.nest.egg.must_be_child'));
|
throw new NoParentConfigurationFoundException(trans('exceptions.egg.invalid_copy_id'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@ class EggDeletionService
|
|||||||
{
|
{
|
||||||
$servers = $this->serverRepository->findCountWhere([['egg_id', '=', $egg]]);
|
$servers = $this->serverRepository->findCountWhere([['egg_id', '=', $egg]]);
|
||||||
if ($servers > 0) {
|
if ($servers > 0) {
|
||||||
throw new HasActiveServersException(trans('exceptions.nest.egg.delete_has_servers'));
|
throw new HasActiveServersException(trans('exceptions.egg.delete_has_servers'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$children = $this->repository->findCountWhere([['config_from', '=', $egg]]);
|
$children = $this->repository->findCountWhere([['config_from', '=', $egg]]);
|
||||||
if ($children > 0) {
|
if ($children > 0) {
|
||||||
throw new HasChildrenException(trans('exceptions.nest.egg.has_children'));
|
throw new HasChildrenException(trans('exceptions.egg.has_children'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->repository->delete($egg);
|
return $this->repository->delete($egg);
|
||||||
|
@ -16,7 +16,7 @@ class EggUpdateService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a service option.
|
* Update an egg.
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
* @throws \App\Exceptions\Model\DataValidationException
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
||||||
@ -26,12 +26,11 @@ class EggUpdateService
|
|||||||
{
|
{
|
||||||
if (!is_null(array_get($data, 'config_from'))) {
|
if (!is_null(array_get($data, 'config_from'))) {
|
||||||
$results = $this->repository->findCountWhere([
|
$results = $this->repository->findCountWhere([
|
||||||
['nest_id', '=', $egg->nest_id],
|
|
||||||
['id', '=', array_get($data, 'config_from')],
|
['id', '=', array_get($data, 'config_from')],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($results !== 1) {
|
if ($results !== 1) {
|
||||||
throw new NoParentConfigurationFoundException(trans('exceptions.nest.egg.must_be_child'));
|
throw new NoParentConfigurationFoundException(trans('exceptions.egg.invalid_copy_id'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ namespace App\Services\Eggs\Scripts;
|
|||||||
|
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
use App\Contracts\Repository\EggRepositoryInterface;
|
use App\Contracts\Repository\EggRepositoryInterface;
|
||||||
use App\Exceptions\Service\Egg\InvalidCopyFromException;
|
|
||||||
|
|
||||||
class InstallScriptService
|
class InstallScriptService
|
||||||
{
|
{
|
||||||
@ -20,16 +19,9 @@ class InstallScriptService
|
|||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
* @throws \App\Exceptions\Model\DataValidationException
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
||||||
* @throws \App\Exceptions\Service\Egg\InvalidCopyFromException
|
|
||||||
*/
|
*/
|
||||||
public function handle(Egg $egg, array $data): void
|
public function handle(Egg $egg, array $data): void
|
||||||
{
|
{
|
||||||
if (!is_null(array_get($data, 'copy_script_from'))) {
|
|
||||||
if (!$this->repository->isCopyableScript(array_get($data, 'copy_script_from'), $egg->nest_id)) {
|
|
||||||
throw new InvalidCopyFromException(trans('exceptions.nest.egg.invalid_copy_id'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->repository->withoutFreshModel()->update($egg->id, [
|
$this->repository->withoutFreshModel()->update($egg->id, [
|
||||||
'script_install' => array_get($data, 'script_install'),
|
'script_install' => array_get($data, 'script_install'),
|
||||||
'script_is_privileged' => array_get($data, 'script_is_privileged', 1),
|
'script_is_privileged' => array_get($data, 'script_is_privileged', 1),
|
||||||
|
@ -5,7 +5,6 @@ namespace App\Services\Eggs\Sharing;
|
|||||||
use Ramsey\Uuid\Uuid;
|
use Ramsey\Uuid\Uuid;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
use App\Models\Nest;
|
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
use App\Models\EggVariable;
|
use App\Models\EggVariable;
|
||||||
use Illuminate\Database\ConnectionInterface;
|
use Illuminate\Database\ConnectionInterface;
|
||||||
@ -22,17 +21,13 @@ class EggImporterService
|
|||||||
*
|
*
|
||||||
* @throws \App\Exceptions\Service\InvalidFileUploadException|\Throwable
|
* @throws \App\Exceptions\Service\InvalidFileUploadException|\Throwable
|
||||||
*/
|
*/
|
||||||
public function handle(UploadedFile $file, int $nest): Egg
|
public function handle(UploadedFile $file): Egg
|
||||||
{
|
{
|
||||||
$parsed = $this->parser->handle($file);
|
$parsed = $this->parser->handle($file);
|
||||||
|
|
||||||
/** @var \App\Models\Nest $nest */
|
return $this->connection->transaction(function () use ($parsed) {
|
||||||
$nest = Nest::query()->with('eggs', 'eggs.variables')->findOrFail($nest);
|
|
||||||
|
|
||||||
return $this->connection->transaction(function () use ($nest, $parsed) {
|
|
||||||
$egg = (new Egg())->forceFill([
|
$egg = (new Egg())->forceFill([
|
||||||
'uuid' => Uuid::uuid4()->toString(),
|
'uuid' => Uuid::uuid4()->toString(),
|
||||||
'nest_id' => $nest->id,
|
|
||||||
'author' => Arr::get($parsed, 'author'),
|
'author' => Arr::get($parsed, 'author'),
|
||||||
'copy_script_from' => null,
|
'copy_script_from' => null,
|
||||||
]);
|
]);
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Services\Nests;
|
|
||||||
|
|
||||||
use Ramsey\Uuid\Uuid;
|
|
||||||
use App\Models\Nest;
|
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
|
||||||
|
|
||||||
class NestCreationService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* NestCreationService constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(private ConfigRepository $config, private NestRepositoryInterface $repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new nest on the system.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
public function handle(array $data, string $author = null): Nest
|
|
||||||
{
|
|
||||||
return $this->repository->create([
|
|
||||||
'uuid' => Uuid::uuid4()->toString(),
|
|
||||||
'author' => $author ?? $this->config->get('panel.service.author'),
|
|
||||||
'name' => array_get($data, 'name'),
|
|
||||||
'description' => array_get($data, 'description'),
|
|
||||||
], true, true);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Services\Nests;
|
|
||||||
|
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use App\Exceptions\Service\HasActiveServersException;
|
|
||||||
use App\Contracts\Repository\ServerRepositoryInterface;
|
|
||||||
|
|
||||||
class NestDeletionService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* NestDeletionService constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
protected ServerRepositoryInterface $serverRepository,
|
|
||||||
protected NestRepositoryInterface $repository
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a nest from the system only if there are no servers attached to it.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Service\HasActiveServersException
|
|
||||||
*/
|
|
||||||
public function handle(int $nest): int
|
|
||||||
{
|
|
||||||
$count = $this->serverRepository->findCountWhere([['nest_id', '=', $nest]]);
|
|
||||||
if ($count > 0) {
|
|
||||||
throw new HasActiveServersException(trans('exceptions.nest.delete_has_servers'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->repository->delete($nest);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Services\Nests;
|
|
||||||
|
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
|
|
||||||
class NestUpdateService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* NestUpdateService constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(protected NestRepositoryInterface $repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a nest and prevent changing the author once it is set.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
* @throws \App\Exceptions\Repository\RecordNotFoundException
|
|
||||||
*/
|
|
||||||
public function handle(int $nest, array $data): void
|
|
||||||
{
|
|
||||||
if (!is_null(array_get($data, 'author'))) {
|
|
||||||
unset($data['author']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->repository->withoutFreshModel()->update($nest, $data);
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,6 @@ namespace App\Services\Servers;
|
|||||||
|
|
||||||
use Ramsey\Uuid\Uuid;
|
use Ramsey\Uuid\Uuid;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use App\Models\Egg;
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Webmozart\Assert\Assert;
|
use Webmozart\Assert\Assert;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
@ -67,12 +66,6 @@ class ServerCreationService
|
|||||||
$data['node_id'] = Allocation::query()->findOrFail($data['allocation_id'])->node_id;
|
$data['node_id'] = Allocation::query()->findOrFail($data['allocation_id'])->node_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($data['nest_id'])) {
|
|
||||||
Assert::false(empty($data['egg_id']), 'Expected a non-empty egg_id in server creation data.');
|
|
||||||
|
|
||||||
$data['nest_id'] = Egg::query()->findOrFail($data['egg_id'])->nest_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$eggVariableData = $this->validatorService
|
$eggVariableData = $this->validatorService
|
||||||
->setUserLevel(User::USER_LEVEL_ADMIN)
|
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||||
->handle(Arr::get($data, 'egg_id'), Arr::get($data, 'environment', []));
|
->handle(Arr::get($data, 'egg_id'), Arr::get($data, 'environment', []));
|
||||||
@ -155,7 +148,6 @@ class ServerCreationService
|
|||||||
'threads' => Arr::get($data, 'threads'),
|
'threads' => Arr::get($data, 'threads'),
|
||||||
'oom_disabled' => Arr::get($data, 'oom_disabled') ?? true,
|
'oom_disabled' => Arr::get($data, 'oom_disabled') ?? true,
|
||||||
'allocation_id' => Arr::get($data, 'allocation_id'),
|
'allocation_id' => Arr::get($data, 'allocation_id'),
|
||||||
'nest_id' => Arr::get($data, 'nest_id'),
|
|
||||||
'egg_id' => Arr::get($data, 'egg_id'),
|
'egg_id' => Arr::get($data, 'egg_id'),
|
||||||
'startup' => Arr::get($data, 'startup'),
|
'startup' => Arr::get($data, 'startup'),
|
||||||
'image' => Arr::get($data, 'image'),
|
'image' => Arr::get($data, 'image'),
|
||||||
|
@ -75,7 +75,6 @@ class StartupModificationService
|
|||||||
|
|
||||||
$server = $server->forceFill([
|
$server = $server->forceFill([
|
||||||
'egg_id' => $egg->id,
|
'egg_id' => $egg->id,
|
||||||
'nest_id' => $egg->nest_id,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class VariableValidatorService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate all of the passed data against the given service option variables.
|
* Validate all of the passed data against the given egg variables.
|
||||||
*
|
*
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
*/
|
*/
|
||||||
|
@ -23,7 +23,7 @@ trait ValidatesValidationRules
|
|||||||
} catch (\BadMethodCallException $exception) {
|
} catch (\BadMethodCallException $exception) {
|
||||||
$matches = [];
|
$matches = [];
|
||||||
if (preg_match('/Method \[(.+)\] does not exist\./', $exception->getMessage(), $matches)) {
|
if (preg_match('/Method \[(.+)\] does not exist\./', $exception->getMessage(), $matches)) {
|
||||||
throw new BadValidationRuleException(trans('exceptions.nest.variables.bad_validation_rule', ['rule' => Str::snake(str_replace('validate', '', array_get($matches, 1, 'unknownRule')))]), $exception);
|
throw new BadValidationRuleException(trans('exceptions.variables.bad_validation_rule', ['rule' => Str::snake(str_replace('validate', '', array_get($matches, 1, 'unknownRule')))]), $exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw $exception;
|
throw $exception;
|
||||||
|
@ -4,7 +4,6 @@ namespace App\Transformers\Api\Application;
|
|||||||
|
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
use App\Models\Nest;
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use League\Fractal\Resource\Item;
|
use League\Fractal\Resource\Item;
|
||||||
use App\Models\EggVariable;
|
use App\Models\EggVariable;
|
||||||
@ -18,7 +17,6 @@ class EggTransformer extends BaseTransformer
|
|||||||
* Relationships that can be loaded onto this transformation.
|
* Relationships that can be loaded onto this transformation.
|
||||||
*/
|
*/
|
||||||
protected array $availableIncludes = [
|
protected array $availableIncludes = [
|
||||||
'nest',
|
|
||||||
'servers',
|
'servers',
|
||||||
'config',
|
'config',
|
||||||
'script',
|
'script',
|
||||||
@ -42,15 +40,11 @@ class EggTransformer extends BaseTransformer
|
|||||||
public function transform(Egg $model): array
|
public function transform(Egg $model): array
|
||||||
{
|
{
|
||||||
$files = json_decode($model->config_files, true, 512, JSON_THROW_ON_ERROR);
|
$files = json_decode($model->config_files, true, 512, JSON_THROW_ON_ERROR);
|
||||||
if (empty($files)) {
|
|
||||||
$files = new \stdClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'id' => $model->id,
|
'id' => $model->id,
|
||||||
'uuid' => $model->uuid,
|
'uuid' => $model->uuid,
|
||||||
'name' => $model->name,
|
'name' => $model->name,
|
||||||
'nest' => $model->nest_id,
|
|
||||||
'author' => $model->author,
|
'author' => $model->author,
|
||||||
'description' => $model->description,
|
'description' => $model->description,
|
||||||
// "docker_image" is deprecated, but left here to avoid breaking too many things at once
|
// "docker_image" is deprecated, but left here to avoid breaking too many things at once
|
||||||
@ -79,22 +73,6 @@ class EggTransformer extends BaseTransformer
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Include the Nest relationship for the given Egg in the transformation.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Transformer\InvalidTransformerLevelException
|
|
||||||
*/
|
|
||||||
public function includeNest(Egg $model): Item|NullResource
|
|
||||||
{
|
|
||||||
if (!$this->authorize(AdminAcl::RESOURCE_NESTS)) {
|
|
||||||
return $this->null();
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->loadMissing('nest');
|
|
||||||
|
|
||||||
return $this->item($model->getRelation('nest'), $this->makeTransformer(NestTransformer::class), Nest::RESOURCE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Include the Servers relationship for the given Egg in the transformation.
|
* Include the Servers relationship for the given Egg in the transformation.
|
||||||
*
|
*
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Transformers\Api\Application;
|
|
||||||
|
|
||||||
use App\Models\Egg;
|
|
||||||
use App\Models\Nest;
|
|
||||||
use App\Models\Server;
|
|
||||||
use League\Fractal\Resource\Collection;
|
|
||||||
use League\Fractal\Resource\NullResource;
|
|
||||||
use App\Services\Acl\Api\AdminAcl;
|
|
||||||
|
|
||||||
class NestTransformer extends BaseTransformer
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Relationships that can be loaded onto this transformation.
|
|
||||||
*/
|
|
||||||
protected array $availableIncludes = [
|
|
||||||
'eggs', 'servers',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the resource name for the JSONAPI output.
|
|
||||||
*/
|
|
||||||
public function getResourceName(): string
|
|
||||||
{
|
|
||||||
return Nest::RESOURCE_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform a Nest model into a representation that can be consumed by the
|
|
||||||
* application API.
|
|
||||||
*/
|
|
||||||
public function transform(Nest $model): array
|
|
||||||
{
|
|
||||||
$response = $model->toArray();
|
|
||||||
|
|
||||||
$response[$model->getUpdatedAtColumn()] = $this->formatTimestamp($model->updated_at);
|
|
||||||
$response[$model->getCreatedAtColumn()] = $this->formatTimestamp($model->created_at);
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Include the Eggs relationship on the given Nest model transformation.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Transformer\InvalidTransformerLevelException
|
|
||||||
*/
|
|
||||||
public function includeEggs(Nest $model): Collection|NullResource
|
|
||||||
{
|
|
||||||
if (!$this->authorize(AdminAcl::RESOURCE_EGGS)) {
|
|
||||||
return $this->null();
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->loadMissing('eggs');
|
|
||||||
|
|
||||||
return $this->collection($model->getRelation('eggs'), $this->makeTransformer(EggTransformer::class), Egg::RESOURCE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Include the servers relationship on the given Nest model.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Transformer\InvalidTransformerLevelException
|
|
||||||
*/
|
|
||||||
public function includeServers(Nest $model): Collection|NullResource
|
|
||||||
{
|
|
||||||
if (!$this->authorize(AdminAcl::RESOURCE_SERVERS)) {
|
|
||||||
return $this->null();
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->loadMissing('servers');
|
|
||||||
|
|
||||||
return $this->collection($model->getRelation('servers'), $this->makeTransformer(ServerTransformer::class), Server::RESOURCE_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,7 +20,6 @@ class ServerTransformer extends BaseTransformer
|
|||||||
'allocations',
|
'allocations',
|
||||||
'user',
|
'user',
|
||||||
'subusers',
|
'subusers',
|
||||||
'nest',
|
|
||||||
'egg',
|
'egg',
|
||||||
'variables',
|
'variables',
|
||||||
'location',
|
'location',
|
||||||
@ -77,7 +76,6 @@ class ServerTransformer extends BaseTransformer
|
|||||||
'user' => $server->owner_id,
|
'user' => $server->owner_id,
|
||||||
'node' => $server->node_id,
|
'node' => $server->node_id,
|
||||||
'allocation' => $server->allocation_id,
|
'allocation' => $server->allocation_id,
|
||||||
'nest' => $server->nest_id,
|
|
||||||
'egg' => $server->egg_id,
|
'egg' => $server->egg_id,
|
||||||
'container' => [
|
'container' => [
|
||||||
'startup_command' => $server->startup,
|
'startup_command' => $server->startup,
|
||||||
@ -139,22 +137,6 @@ class ServerTransformer extends BaseTransformer
|
|||||||
return $this->item($server->getRelation('user'), $this->makeTransformer(UserTransformer::class), 'user');
|
return $this->item($server->getRelation('user'), $this->makeTransformer(UserTransformer::class), 'user');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a generic array with nest information for this server.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Transformer\InvalidTransformerLevelException
|
|
||||||
*/
|
|
||||||
public function includeNest(Server $server): Item|NullResource
|
|
||||||
{
|
|
||||||
if (!$this->authorize(AdminAcl::RESOURCE_NESTS)) {
|
|
||||||
return $this->null();
|
|
||||||
}
|
|
||||||
|
|
||||||
$server->loadMissing('nest');
|
|
||||||
|
|
||||||
return $this->item($server->getRelation('nest'), $this->makeTransformer(NestTransformer::class), 'nest');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a generic array with egg information for this server.
|
* Return a generic array with egg information for this server.
|
||||||
*
|
*
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Factories;
|
|
||||||
|
|
||||||
use Ramsey\Uuid\Uuid;
|
|
||||||
use App\Models\Nest;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
|
||||||
|
|
||||||
class NestFactory extends Factory
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The name of the factory's corresponding model.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $model = Nest::class;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the model's default state.
|
|
||||||
*/
|
|
||||||
public function definition(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'uuid' => Uuid::uuid4()->toString(),
|
|
||||||
'author' => 'testauthor@example.com',
|
|
||||||
'name' => $this->faker->word,
|
|
||||||
'description' => null,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,7 +11,6 @@ class DatabaseSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$this->call(NestSeeder::class);
|
|
||||||
$this->call(EggSeeder::class);
|
$this->call(EggSeeder::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
use App\Models\Nest;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
@ -19,7 +18,7 @@ class EggSeeder extends Seeder
|
|||||||
/**
|
/**
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
public static array $import = [
|
public static array $imports = [
|
||||||
'Minecraft',
|
'Minecraft',
|
||||||
'Source Engine',
|
'Source Engine',
|
||||||
'Voice Servers',
|
'Voice Servers',
|
||||||
@ -42,22 +41,20 @@ class EggSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
foreach (static::$import as $nest) {
|
foreach (static::$imports as $import) {
|
||||||
/* @noinspection PhpParamsInspection */
|
/* @noinspection PhpParamsInspection */
|
||||||
$this->parseEggFiles(
|
$this->parseEggFiles($import);
|
||||||
Nest::query()->where('author', 'panel@example.com')->where('name', $nest)->firstOrFail()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loop through the list of egg files and import them.
|
* Loop through the list of egg files and import them.
|
||||||
*/
|
*/
|
||||||
protected function parseEggFiles(Nest $nest)
|
protected function parseEggFiles($name)
|
||||||
{
|
{
|
||||||
$files = new \DirectoryIterator(database_path('Seeders/eggs/' . kebab_case($nest->name)));
|
$files = new \DirectoryIterator(database_path('Seeders/eggs/' . kebab_case($name)));
|
||||||
|
|
||||||
$this->command->alert('Updating Eggs for Nest: ' . $nest->name);
|
$this->command->alert('Updating Eggs for: ' . $name);
|
||||||
/** @var \DirectoryIterator $file */
|
/** @var \DirectoryIterator $file */
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (!$file->isFile() || !$file->isReadable()) {
|
if (!$file->isFile() || !$file->isReadable()) {
|
||||||
@ -72,7 +69,7 @@ class EggSeeder extends Seeder
|
|||||||
|
|
||||||
$file = new UploadedFile($file->getPathname(), $file->getFilename(), 'application/json');
|
$file = new UploadedFile($file->getPathname(), $file->getFilename(), 'application/json');
|
||||||
|
|
||||||
$egg = $nest->eggs()
|
$egg = Egg::query()
|
||||||
->where('author', $decoded['author'])
|
->where('author', $decoded['author'])
|
||||||
->where('name', $decoded['name'])
|
->where('name', $decoded['name'])
|
||||||
->first();
|
->first();
|
||||||
@ -81,7 +78,7 @@ class EggSeeder extends Seeder
|
|||||||
$this->updateImporterService->handle($egg, $file);
|
$this->updateImporterService->handle($egg, $file);
|
||||||
$this->command->info('Updated ' . $decoded['name']);
|
$this->command->info('Updated ' . $decoded['name']);
|
||||||
} else {
|
} else {
|
||||||
$this->importerService->handle($file, $nest->id);
|
$this->importerService->handle($file);
|
||||||
$this->command->comment('Created ' . $decoded['name']);
|
$this->command->comment('Created ' . $decoded['name']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Seeders;
|
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
use App\Services\Nests\NestCreationService;
|
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
|
|
||||||
class NestSeeder extends Seeder
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var \App\Services\Nests\NestCreationService
|
|
||||||
*/
|
|
||||||
private $creationService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \App\Contracts\Repository\NestRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NestSeeder constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
NestCreationService $creationService,
|
|
||||||
NestRepositoryInterface $repository
|
|
||||||
) {
|
|
||||||
$this->creationService = $creationService;
|
|
||||||
$this->repository = $repository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the seeder to add missing nests to the Panel.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
public function run()
|
|
||||||
{
|
|
||||||
$items = $this->repository->findWhere([
|
|
||||||
'author' => 'panel@example.com',
|
|
||||||
])->keyBy('name')->toArray();
|
|
||||||
|
|
||||||
$this->createMinecraftNest(array_get($items, 'Minecraft'));
|
|
||||||
$this->createSourceEngineNest(array_get($items, 'Source Engine'));
|
|
||||||
$this->createVoiceServersNest(array_get($items, 'Voice Servers'));
|
|
||||||
$this->createRustNest(array_get($items, 'Rust'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the Minecraft nest to be used later on.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
private function createMinecraftNest(array $nest = null)
|
|
||||||
{
|
|
||||||
if (is_null($nest)) {
|
|
||||||
$this->creationService->handle([
|
|
||||||
'name' => 'Minecraft',
|
|
||||||
'description' => 'Minecraft - the classic game from Mojang. With support for Vanilla MC, Spigot, and many others!',
|
|
||||||
], 'panel@example.com');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the Source Engine Games nest to be used later on.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
private function createSourceEngineNest(array $nest = null)
|
|
||||||
{
|
|
||||||
if (is_null($nest)) {
|
|
||||||
$this->creationService->handle([
|
|
||||||
'name' => 'Source Engine',
|
|
||||||
'description' => 'Includes support for most Source Dedicated Server games.',
|
|
||||||
], 'panel@example.com');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the Voice Servers nest to be used later on.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
private function createVoiceServersNest(array $nest = null)
|
|
||||||
{
|
|
||||||
if (is_null($nest)) {
|
|
||||||
$this->creationService->handle([
|
|
||||||
'name' => 'Voice Servers',
|
|
||||||
'description' => 'Voice servers such as Mumble and Teamspeak 3.',
|
|
||||||
], 'panel@example.com');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the Rust nest to be used later on.
|
|
||||||
*
|
|
||||||
* @throws \App\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
private function createRustNest(array $nest = null)
|
|
||||||
{
|
|
||||||
if (is_null($nest)) {
|
|
||||||
$this->creationService->handle([
|
|
||||||
'name' => 'Rust',
|
|
||||||
'description' => 'Rust - A game where you must fight to survive.',
|
|
||||||
], 'panel@example.com');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
60
database/migrations/2024_03_12_154408_remove_nests_table.php
Normal file
60
database/migrations/2024_03_12_154408_remove_nests_table.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('eggs', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('service_options_nest_id_foreign');
|
||||||
|
$table->dropColumn('nest_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('servers_nest_id_foreign');
|
||||||
|
$table->dropColumn('nest_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::drop('nests');
|
||||||
|
|
||||||
|
Schema::table('api_keys', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('r_nests');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('api_keys', function (Blueprint $table) {
|
||||||
|
$table->unsignedTinyInteger('r_nests')->default(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('nests', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->char('uuid', 36)->unique();
|
||||||
|
$table->string('author');
|
||||||
|
$table->string('name');
|
||||||
|
$table->text('description')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('eggs', function (Blueprint $table) {
|
||||||
|
$table->mediumInteger('nest_id')->unsigned();
|
||||||
|
$table->foreign(['nest_id'], 'service_options_nest_id_foreign');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->mediumInteger('nest_id')->unsigned();
|
||||||
|
$table->foreign(['nest_id'], 'servers_nest_id_foreign');
|
||||||
|
});
|
||||||
|
|
||||||
|
if (class_exists('Database\Seeders\NestSeeder')) {
|
||||||
|
Artisan::call('db:seed', [
|
||||||
|
'--class' => 'NestSeeder',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
File diff suppressed because one or more lines are too long
@ -1,11 +1,7 @@
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#pNestId').select2({
|
|
||||||
placeholder: 'Select a Nest',
|
|
||||||
}).change();
|
|
||||||
|
|
||||||
$('#pEggId').select2({
|
$('#pEggId').select2({
|
||||||
placeholder: 'Select a Nest Egg',
|
placeholder: 'Select an Egg',
|
||||||
});
|
}).change();
|
||||||
|
|
||||||
$('#pPackId').select2({
|
$('#pPackId').select2({
|
||||||
placeholder: 'Select a Service Pack',
|
placeholder: 'Select a Service Pack',
|
||||||
@ -48,20 +44,8 @@ $('#pNodeId').on('change', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#pNestId').on('change', function (event) {
|
|
||||||
$('#pEggId').html('').select2({
|
|
||||||
data: $.map(_.get(Panel.nests, $(this).val() + '.eggs', []), function (item) {
|
|
||||||
return {
|
|
||||||
id: item.id,
|
|
||||||
text: item.name,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
}).change();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#pEggId').on('change', function (event) {
|
$('#pEggId').on('change', function (event) {
|
||||||
let parentChain = _.get(Panel.nests, $('#pNestId').val(), null);
|
let objectChain = _.get(Panel.eggs, $('#pEggId').val(), null);
|
||||||
let objectChain = _.get(parentChain, 'eggs.' + $(this).val(), null);
|
|
||||||
|
|
||||||
const images = _.get(objectChain, 'docker_images', {})
|
const images = _.get(objectChain, 'docker_images', {})
|
||||||
$('#pDefaultContainer').html('');
|
$('#pDefaultContainer').html('');
|
||||||
@ -73,11 +57,7 @@ $('#pEggId').on('change', function (event) {
|
|||||||
$('#pDefaultContainer').append(opt);
|
$('#pDefaultContainer').append(opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_.get(objectChain, 'startup', false)) {
|
|
||||||
$('#pStartup').val(_.get(parentChain, 'startup', 'ERROR: Startup Not Defined!'));
|
|
||||||
} else {
|
|
||||||
$('#pStartup').val(_.get(objectChain, 'startup'));
|
$('#pStartup').val(_.get(objectChain, 'startup'));
|
||||||
}
|
|
||||||
|
|
||||||
$('#pPackId').html('').select2({
|
$('#pPackId').html('').select2({
|
||||||
data: [{ id: 0, text: 'No Service Pack' }].concat(
|
data: [{ id: 0, text: 'No Service Pack' }].concat(
|
||||||
@ -110,7 +90,7 @@ $('#pEggId').on('change', function (event) {
|
|||||||
|
|
||||||
// If you receive a warning on this line, it should be fine to ignore. this function is
|
// If you receive a warning on this line, it should be fine to ignore. this function is
|
||||||
// defined in "resources/views/admin/servers/new.blade.php" near the bottom of the file.
|
// defined in "resources/views/admin/servers/new.blade.php" near the bottom of the file.
|
||||||
serviceVariablesUpdated($('#pEggId').val(), variableIds);
|
eggVariablesUpdated($('#pEggId').val(), variableIds);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#pAllocation').on('change', function () {
|
$('#pAllocation').on('change', function () {
|
||||||
|
19
resources/lang/en/admin/eggs.php
Normal file
19
resources/lang/en/admin/eggs.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'notices' => [
|
||||||
|
'imported' => 'Successfully imported this Egg and its associated variables.',
|
||||||
|
'updated_via_import' => 'This Egg has been updated using the file provided.',
|
||||||
|
'deleted' => 'Successfully deleted the requested egg from the Panel.',
|
||||||
|
'updated' => 'Egg configuration has been updated successfully.',
|
||||||
|
'script_updated' => 'Egg install script has been updated and will run whenever servers are installed.',
|
||||||
|
'egg_created' => 'A new egg was laid successfully. You will need to restart any running daemons to apply this new egg.',
|
||||||
|
],
|
||||||
|
'variables' => [
|
||||||
|
'notices' => [
|
||||||
|
'variable_deleted' => 'The variable ":variable" has been deleted and will no longer be available to servers once rebuilt.',
|
||||||
|
'variable_updated' => 'The variable ":variable" has been updated. You will need to rebuild any servers using this variable in order to apply changes.',
|
||||||
|
'variable_created' => 'New variable has successfully been created and assigned to this egg.',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
'notices' => [
|
|
||||||
'created' => 'A new nest, :name, has been successfully created.',
|
|
||||||
'deleted' => 'Successfully deleted the requested nest from the Panel.',
|
|
||||||
'updated' => 'Successfully updated the nest configuration options.',
|
|
||||||
],
|
|
||||||
'eggs' => [
|
|
||||||
'notices' => [
|
|
||||||
'imported' => 'Successfully imported this Egg and its associated variables.',
|
|
||||||
'updated_via_import' => 'This Egg has been updated using the file provided.',
|
|
||||||
'deleted' => 'Successfully deleted the requested egg from the Panel.',
|
|
||||||
'updated' => 'Egg configuration has been updated successfully.',
|
|
||||||
'script_updated' => 'Egg install script has been updated and will run whenever servers are installed.',
|
|
||||||
'egg_created' => 'A new egg was laid successfully. You will need to restart any running daemons to apply this new egg.',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'variables' => [
|
|
||||||
'notices' => [
|
|
||||||
'variable_deleted' => 'The variable ":variable" has been deleted and will no longer be available to servers once rebuilt.',
|
|
||||||
'variable_updated' => 'The variable ":variable" has been updated. You will need to rebuild any servers using this variable in order to apply changes.',
|
|
||||||
'variable_created' => 'New variable has successfully been created and assigned to this egg.',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
@ -9,7 +9,7 @@ return [
|
|||||||
'default_allocation_not_found' => 'The requested default allocation was not found in this server\'s allocations.',
|
'default_allocation_not_found' => 'The requested default allocation was not found in this server\'s allocations.',
|
||||||
],
|
],
|
||||||
'alerts' => [
|
'alerts' => [
|
||||||
'startup_changed' => 'The startup configuration for this server has been updated. If this server\'s nest or egg was changed a reinstall will be occurring now.',
|
'startup_changed' => 'The startup configuration for this server has been updated. If this server\'s egg was changed a reinstall will be occurring now.',
|
||||||
'server_deleted' => 'Server has successfully been deleted from the system.',
|
'server_deleted' => 'Server has successfully been deleted from the system.',
|
||||||
'server_created' => 'Server was successfully created on the panel. Please allow the daemon a few minutes to completely install this server.',
|
'server_created' => 'Server was successfully created on the panel. Please allow the daemon a few minutes to completely install this server.',
|
||||||
'build_updated' => 'The build details for this server have been updated. Some changes may require a restart to take effect.',
|
'build_updated' => 'The build details for this server have been updated. Some changes may require a restart to take effect.',
|
||||||
|
@ -13,12 +13,9 @@ return [
|
|||||||
'cidr_out_of_range' => 'CIDR notation only allows masks between /25 and /32.',
|
'cidr_out_of_range' => 'CIDR notation only allows masks between /25 and /32.',
|
||||||
'port_out_of_range' => 'Ports in an allocation must be greater than 1024 and less than or equal to 65535.',
|
'port_out_of_range' => 'Ports in an allocation must be greater than 1024 and less than or equal to 65535.',
|
||||||
],
|
],
|
||||||
'nest' => [
|
|
||||||
'delete_has_servers' => 'A Nest with active servers attached to it cannot be deleted from the Panel.',
|
|
||||||
'egg' => [
|
'egg' => [
|
||||||
'delete_has_servers' => 'An Egg with active servers attached to it cannot be deleted from the Panel.',
|
'delete_has_servers' => 'An Egg with active servers attached to it cannot be deleted from the Panel.',
|
||||||
'invalid_copy_id' => 'The Egg selected for copying a script from either does not exist, or is copying a script itself.',
|
'invalid_copy_id' => 'The Egg selected for copying a script from either does not exist, or is copying a script itself.',
|
||||||
'must_be_child' => 'The "Copy Settings From" directive for this Egg must be a child option for the selected Nest.',
|
|
||||||
'has_children' => 'This Egg is a parent to one or more other Eggs. Please delete those Eggs before deleting this Egg.',
|
'has_children' => 'This Egg is a parent to one or more other Eggs. Please delete those Eggs before deleting this Egg.',
|
||||||
],
|
],
|
||||||
'variables' => [
|
'variables' => [
|
||||||
@ -31,7 +28,6 @@ return [
|
|||||||
'file_error' => 'The JSON file provided was not valid.',
|
'file_error' => 'The JSON file provided was not valid.',
|
||||||
'invalid_json_provided' => 'The JSON file provided is not in a format that can be recognized.',
|
'invalid_json_provided' => 'The JSON file provided is not in a format that can be recognized.',
|
||||||
],
|
],
|
||||||
],
|
|
||||||
'subusers' => [
|
'subusers' => [
|
||||||
'editing_self' => 'Editing your own subuser account is not permitted.',
|
'editing_self' => 'Editing your own subuser account is not permitted.',
|
||||||
'user_is_owner' => 'You cannot add the server owner as a subuser for this server.',
|
'user_is_owner' => 'You cannot add the server owner as a subuser for this server.',
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('title')
|
@section('title')
|
||||||
Nests
|
Eggs
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content-header')
|
@section('content-header')
|
||||||
<h1>Nests<small>All nests currently available on this system.</small></h1>
|
<h1>Eggs</h1>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||||
<li class="active">Nests</li>
|
<li class="active">Eggs</li>
|
||||||
</ol>
|
</ol>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-warning">
|
||||||
Eggs are a powerful feature of Panel that allow for extreme flexibility and configuration. Please note that while powerful, modifying an egg wrongly can very easily brick your servers and cause more problems. Please avoid editing our default eggs — those provided by <code>panel@example.com</code> — unless you are absolutely sure of what you are doing.
|
Eggs allow extreme flexibility and configuration. Please note that modifying an egg can cause issues with your server may brick it.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="box">
|
<div class="box box-primary">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">Configured Nests</h3>
|
<h3 class="box-title">Eggs</h3>
|
||||||
<div class="box-tools">
|
<div class="box-tools">
|
||||||
<a href="#" class="btn btn-sm btn-success" data-toggle="modal" data-target="#importServiceOptionModal" role="button"><i class="fa fa-upload"></i> Import Egg</a>
|
<a href="#" class="btn btn-sm btn-success" data-toggle="modal" data-target="#importServiceOptionModal" role="button"><i class="fa fa-upload"></i> Import Egg</a>
|
||||||
<a href="{{ route('admin.nests.new') }}" class="btn btn-primary btn-sm">Create New</a>
|
<a href="{{ route('admin.eggs.new') }}" class="btn btn-primary btn-sm">Create New</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body table-responsive no-padding">
|
<div class="box-body table-responsive no-padding">
|
||||||
@ -36,16 +36,18 @@
|
|||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th class="text-center">Eggs</th>
|
|
||||||
<th class="text-center">Servers</th>
|
<th class="text-center">Servers</th>
|
||||||
|
<th class="text-center"></th>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach($nests as $nest)
|
@foreach($eggs as $egg)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="middle"><code>{{ $nest->id }}</code></td>
|
<td class="align-middle"><code>{{ $egg->id }}</code></td>
|
||||||
<td class="middle"><a href="{{ route('admin.nests.view', $nest->id) }}" data-toggle="tooltip" data-placement="right" title="{{ $nest->author }}">{{ $nest->name }}</a></td>
|
<td class="align-middle"><a href="{{ route('admin.eggs.view', $egg->id) }}" data-toggle="tooltip" data-placement="right" title="{{ $egg->author }}">{{ $egg->name }}</a></td>
|
||||||
<td class="col-xs-6 middle">{{ $nest->description }}</td>
|
<td class="col-xs-8 align-middle">{{ $egg->description }}</td>
|
||||||
<td class="text-center middle">{{ $nest->eggs_count }}</td>
|
<td class="text-center align-middle"><code>{{ $egg->servers->count() }}</code></td>
|
||||||
<td class="text-center middle">{{ $nest->servers_count }}</td>
|
<td class="align-middle">
|
||||||
|
<a href="{{ route('admin.eggs.export', ['egg' => $egg->id]) }}"><i class="fa fa-download"></i></a>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</table>
|
</table>
|
||||||
@ -53,6 +55,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal fade" tabindex="-1" role="dialog" id="importServiceOptionModal">
|
<div class="modal fade" tabindex="-1" role="dialog" id="importServiceOptionModal">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@ -60,7 +63,7 @@
|
|||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title">Import an Egg</h4>
|
<h4 class="modal-title">Import an Egg</h4>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.nests.egg.import') }}" enctype="multipart/form-data" method="POST">
|
<form action="{{ route('admin.eggs.import') }}" enctype="multipart/form-data" method="POST">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label" for="pImportFile">Egg File <span class="field-required"></span></label>
|
<label class="control-label" for="pImportFile">Egg File <span class="field-required"></span></label>
|
||||||
@ -69,17 +72,6 @@
|
|||||||
<p class="small text-muted">Select the <code>.json</code> file for the new egg that you wish to import.</p>
|
<p class="small text-muted">Select the <code>.json</code> file for the new egg that you wish to import.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label" for="pImportToNest">Associated Nest <span class="field-required"></span></label>
|
|
||||||
<div>
|
|
||||||
<select id="pImportToNest" name="import_to_nest">
|
|
||||||
@foreach($nests as $nest)
|
|
||||||
<option value="{{ $nest->id }}">{{ $nest->name }} <{{ $nest->author }}></option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
<p class="small text-muted">Select the nest that this egg will be associated with from the dropdown. If you wish to associate it with a new nest you will need to create that nest before continuing.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
{{ csrf_field() }}
|
{{ csrf_field() }}
|
||||||
@ -91,12 +83,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('footer-scripts')
|
|
||||||
@parent
|
|
||||||
<script>
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('#pImportToNest').select2();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endsection
|
|
@ -1,20 +1,20 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('title')
|
@section('title')
|
||||||
Nests → New Egg
|
Eggs → New Egg
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content-header')
|
@section('content-header')
|
||||||
<h1>New Egg<small>Create a new Egg to assign to servers.</small></h1>
|
<h1>New Egg<small>Create a new Egg to assign to servers.</small></h1>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||||
<li><a href="{{ route('admin.nests') }}">Nests</a></li>
|
<li><a href="{{ route('admin.eggs') }}">Eggs</a></li>
|
||||||
<li class="active">New Egg</li>
|
<li class="active">New Egg</li>
|
||||||
</ol>
|
</ol>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<form action="{{ route('admin.nests.egg.new') }}" method="POST">
|
<form action="{{ route('admin.eggs.new') }}" method="POST">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
@ -24,17 +24,6 @@
|
|||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="form-group">
|
|
||||||
<label for="pNestId" class="form-label">Associated Nest</label>
|
|
||||||
<div>
|
|
||||||
<select name="nest_id" id="pNestId">
|
|
||||||
@foreach($nests as $nest)
|
|
||||||
<option value="{{ $nest->id }}" {{ old('nest_id') != $nest->id ?: 'selected' }}>{{ $nest->name }} <{{ $nest->author }}></option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
<p class="text-muted small">Think of a Nest as a category. You can put multiple Eggs in a nest, but consider putting only Eggs that are related to each other in each Nest.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pName" class="form-label">Name</label>
|
<label for="pName" class="form-label">Name</label>
|
||||||
<input type="text" id="pName" name="name" value="{{ old('name') }}" class="form-control" />
|
<input type="text" id="pName" name="name" value="{{ old('name') }}" class="form-control" />
|
||||||
@ -63,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pDockerImage" class="control-label">Docker Images</label>
|
<label for="pDockerImages" class="control-label">Docker Images</label>
|
||||||
<textarea id="pDockerImages" name="docker_images" rows="4" placeholder="quay.io/panel/service" class="form-control">{{ old('docker_images') }}</textarea>
|
<textarea id="pDockerImages" name="docker_images" rows="4" placeholder="quay.io/panel/service" class="form-control">{{ old('docker_images') }}</textarea>
|
||||||
<p class="text-muted small">The docker images available to servers using this egg. Enter one per line. Users will be able to select from this list of images if more than one value is provided.</p>
|
<p class="text-muted small">The docker images available to servers using this egg. Enter one per line. Users will be able to select from this list of images if more than one value is provided.</p>
|
||||||
</div>
|
</div>
|
||||||
@ -137,19 +126,8 @@
|
|||||||
{!! Theme::js('vendor/lodash/lodash.js') !!}
|
{!! Theme::js('vendor/lodash/lodash.js') !!}
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#pNestId').select2().change();
|
|
||||||
$('#pConfigFrom').select2();
|
$('#pConfigFrom').select2();
|
||||||
});
|
});
|
||||||
$('#pNestId').on('change', function (event) {
|
|
||||||
$('#pConfigFrom').html('<option value="">None</option>').select2({
|
|
||||||
data: $.map(_.get(Panel.nests, $(this).val() + '.eggs', []), function (item) {
|
|
||||||
return {
|
|
||||||
id: item.id,
|
|
||||||
text: item.name + ' <' + item.author + '>',
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
$('textarea[data-action="handle-tabs"]').on('keydown', function(event) {
|
$('textarea[data-action="handle-tabs"]').on('keydown', function(event) {
|
||||||
if (event.keyCode === 9) {
|
if (event.keyCode === 9) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('title')
|
@section('title')
|
||||||
Nests → Egg: {{ $egg->name }} → Install Script
|
Eggs → Egg: {{ $egg->name }} → Install Script
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content-header')
|
@section('content-header')
|
||||||
<h1>{{ $egg->name }}<small>Manage the install script for this Egg.</small></h1>
|
<h1>{{ $egg->name }}<small>Manage the install script for this Egg.</small></h1>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||||
<li><a href="{{ route('admin.nests') }}">Nests</a></li>
|
<li><a href="{{ route('admin.eggs') }}">Eggs</a></li>
|
||||||
<li><a href="{{ route('admin.nests.view', $egg->nest->id) }}">{{ $egg->nest->name }}</a></li>
|
<li><a href="{{ route('admin.eggs.view', $egg->id) }}">{{ $egg->name }}</a></li>
|
||||||
<li><a href="{{ route('admin.nests.egg.view', $egg->id) }}">{{ $egg->name }}</a></li>
|
|
||||||
<li class="active">{{ $egg->name }}</li>
|
<li class="active">{{ $egg->name }}</li>
|
||||||
</ol>
|
</ol>
|
||||||
@endsection
|
@endsection
|
||||||
@ -20,14 +19,14 @@
|
|||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="nav-tabs-custom nav-tabs-floating">
|
<div class="nav-tabs-custom nav-tabs-floating">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li><a href="{{ route('admin.nests.egg.view', $egg->id) }}">Configuration</a></li>
|
<li><a href="{{ route('admin.eggs.view', $egg->id) }}">Configuration</a></li>
|
||||||
<li><a href="{{ route('admin.nests.egg.variables', $egg->id) }}">Variables</a></li>
|
<li><a href="{{ route('admin.eggs.variables', $egg->id) }}">Variables</a></li>
|
||||||
<li class="active"><a href="{{ route('admin.nests.egg.scripts', $egg->id) }}">Install Script</a></li>
|
<li class="active"><a href="{{ route('admin.eggs.scripts', $egg->id) }}">Install Script</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.nests.egg.scripts', $egg->id) }}" method="POST">
|
<form action="{{ route('admin.eggs.scripts', $egg->id) }}" method="POST">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
@ -37,7 +36,7 @@
|
|||||||
@if(! is_null($egg->copyFrom))
|
@if(! is_null($egg->copyFrom))
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="callout callout-warning no-margin">
|
<div class="callout callout-warning no-margin">
|
||||||
This service option is copying installation scripts and container options from <a href="{{ route('admin.nests.egg.view', $egg->copyFrom->id) }}">{{ $egg->copyFrom->name }}</a>. Any changes you make to this script will not apply unless you select "None" from the dropdown box below.
|
This egg option is copying installation scripts and container options from <a href="{{ route('admin.eggs.view', $egg->copyFrom->id) }}">{{ $egg->copyFrom->name }}</a>. Any changes you make to this script will not apply unless you select "None" from the dropdown box below.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@ -69,10 +68,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12 text-muted">
|
<div class="col-xs-12 text-muted">
|
||||||
The following service options rely on this script:
|
The following eggs rely on this script:
|
||||||
@if(count($relyOnScript) > 0)
|
@if(count($relyOnScript) > 0)
|
||||||
@foreach($relyOnScript as $rely)
|
@foreach($relyOnScript as $rely)
|
||||||
<a href="{{ route('admin.nests.egg.view', $rely->id) }}">
|
<a href="{{ route('admin.eggs.view', $rely->id) }}">
|
||||||
<code>{{ $rely->name }}</code>@if(!$loop->last), @endif
|
<code>{{ $rely->name }}</code>@if(!$loop->last), @endif
|
||||||
</a>
|
</a>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -8,9 +8,8 @@
|
|||||||
<h1>{{ $egg->name }}<small>Managing variables for this Egg.</small></h1>
|
<h1>{{ $egg->name }}<small>Managing variables for this Egg.</small></h1>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||||
<li><a href="{{ route('admin.nests') }}">Nests</a></li>
|
<li><a href="{{ route('admin.eggs') }}">Eggs</a></li>
|
||||||
<li><a href="{{ route('admin.nests.view', $egg->nest->id) }}">{{ $egg->nest->name }}</a></li>
|
<li><a href="{{ route('admin.eggs.view', $egg->id) }}">{{ $egg->name }}</a></li>
|
||||||
<li><a href="{{ route('admin.nests.egg.view', $egg->id) }}">{{ $egg->name }}</a></li>
|
|
||||||
<li class="active">Variables</li>
|
<li class="active">Variables</li>
|
||||||
</ol>
|
</ol>
|
||||||
@endsection
|
@endsection
|
||||||
@ -20,9 +19,9 @@
|
|||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="nav-tabs-custom nav-tabs-floating">
|
<div class="nav-tabs-custom nav-tabs-floating">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li><a href="{{ route('admin.nests.egg.view', $egg->id) }}">Configuration</a></li>
|
<li><a href="{{ route('admin.eggs.view', $egg->id) }}">Configuration</a></li>
|
||||||
<li class="active"><a href="{{ route('admin.nests.egg.variables', $egg->id) }}">Variables</a></li>
|
<li class="active"><a href="{{ route('admin.eggs.variables', $egg->id) }}">Variables</a></li>
|
||||||
<li><a href="{{ route('admin.nests.egg.scripts', $egg->id) }}">Install Script</a></li>
|
<li><a href="{{ route('admin.eggs.scripts', $egg->id) }}">Install Script</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -43,7 +42,7 @@
|
|||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">{{ $variable->name }}</h3>
|
<h3 class="box-title">{{ $variable->name }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.nests.egg.variables.edit', ['egg' => $egg->id, 'variable' => $variable->id]) }}" method="POST">
|
<form action="{{ route('admin.eggs.variables.edit', ['egg' => $egg->id, 'variable' => $variable->id]) }}" method="POST">
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Name</label>
|
<label class="form-label">Name</label>
|
||||||
@ -96,7 +95,7 @@
|
|||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h4 class="modal-title">Create New Egg Variable</h4>
|
<h4 class="modal-title">Create New Egg Variable</h4>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.nests.egg.variables', $egg->id) }}" method="POST">
|
<form action="{{ route('admin.eggs.variables', $egg->id) }}" method="POST">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Name <span class="field-required"></span></label>
|
<label class="control-label">Name <span class="field-required"></span></label>
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('title')
|
@section('title')
|
||||||
Nests → Egg: {{ $egg->name }}
|
Eggs → Egg: {{ $egg->name }}
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content-header')
|
@section('content-header')
|
||||||
<h1>{{ $egg->name }}<small>{{ str_limit($egg->description, 50) }}</small></h1>
|
<h1>{{ $egg->name }}<small>{{ str_limit($egg->description, 50) }}</small></h1>
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
||||||
<li><a href="{{ route('admin.nests') }}">Nests</a></li>
|
<li><a href="{{ route('admin.eggs') }}">Eggs</a></li>
|
||||||
<li><a href="{{ route('admin.nests.view', $egg->nest->id) }}">{{ $egg->nest->name }}</a></li>
|
|
||||||
<li class="active">{{ $egg->name }}</li>
|
<li class="active">{{ $egg->name }}</li>
|
||||||
</ol>
|
</ol>
|
||||||
@endsection
|
@endsection
|
||||||
@ -19,14 +18,14 @@
|
|||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="nav-tabs-custom nav-tabs-floating">
|
<div class="nav-tabs-custom nav-tabs-floating">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active"><a href="{{ route('admin.nests.egg.view', $egg->id) }}">Configuration</a></li>
|
<li class="active"><a href="{{ route('admin.eggs.view', $egg->id) }}">Configuration</a></li>
|
||||||
<li><a href="{{ route('admin.nests.egg.variables', $egg->id) }}">Variables</a></li>
|
<li><a href="{{ route('admin.eggs.variables', $egg->id) }}">Variables</a></li>
|
||||||
<li><a href="{{ route('admin.nests.egg.scripts', $egg->id) }}">Install Script</a></li>
|
<li><a href="{{ route('admin.eggs.scripts', $egg->id) }}">Install Script</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.nests.egg.view', $egg->id) }}" enctype="multipart/form-data" method="POST">
|
<form action="{{ route('admin.eggs.view', $egg->id) }}" enctype="multipart/form-data" method="POST">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="box box-danger">
|
<div class="box box-danger">
|
||||||
@ -51,7 +50,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<form action="{{ route('admin.nests.egg.view', $egg->id) }}" method="POST">
|
<form action="{{ route('admin.eggs.view', $egg->id) }}" method="POST">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
@ -137,7 +136,7 @@
|
|||||||
<label for="pConfigFrom" class="form-label">Copy Settings From</label>
|
<label for="pConfigFrom" class="form-label">Copy Settings From</label>
|
||||||
<select name="config_from" id="pConfigFrom" class="form-control">
|
<select name="config_from" id="pConfigFrom" class="form-control">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
@foreach($egg->nest->eggs as $o)
|
@foreach($egg->newQuery()->get() as $o)
|
||||||
<option value="{{ $o->id }}" {{ ($egg->config_from !== $o->id) ?: 'selected' }}>{{ $o->name }} <{{ $o->author }}></option>
|
<option value="{{ $o->id }}" {{ ($egg->config_from !== $o->id) ?: 'selected' }}>{{ $o->name }} <{{ $o->author }}></option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@ -171,7 +170,7 @@
|
|||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
<button type="submit" name="_method" value="PATCH" class="btn btn-primary btn-sm pull-right">Save</button>
|
<button type="submit" name="_method" value="PATCH" class="btn btn-primary btn-sm pull-right">Save</button>
|
||||||
<a href="{{ route('admin.nests.egg.export', $egg->id) }}" class="btn btn-sm btn-info pull-right" style="margin-right:10px;">Export</a>
|
<a href="{{ route('admin.eggs.export', $egg->id) }}" class="btn btn-sm btn-info pull-right" style="margin-right:10px;">Export</a>
|
||||||
<button id="deleteButton" type="submit" name="_method" value="DELETE" class="btn btn-danger btn-sm muted muted-hover">
|
<button id="deleteButton" type="submit" name="_method" value="DELETE" class="btn btn-danger btn-sm muted muted-hover">
|
||||||
<i class="fa fa-trash-o"></i>
|
<i class="fa fa-trash-o"></i>
|
||||||
</button>
|
</button>
|
||||||
|
@ -118,7 +118,7 @@
|
|||||||
@foreach ($mount->eggs as $egg)
|
@foreach ($mount->eggs as $egg)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="col-sm-2 middle"><code>{{ $egg->id }}</code></td>
|
<td class="col-sm-2 middle"><code>{{ $egg->id }}</code></td>
|
||||||
<td class="middle"><a href="{{ route('admin.nests.egg.view', $egg->id) }}">{{ $egg->name }}</a></td>
|
<td class="middle"><a href="{{ route('admin.eggs.view', $egg->id) }}">{{ $egg->name }}</a></td>
|
||||||
<td class="col-sm-1 middle">
|
<td class="col-sm-1 middle">
|
||||||
<button data-action="detach-egg" data-id="{{ $egg->id }}" class="btn btn-sm btn-danger"><i class="fa fa-trash-o"></i></button>
|
<button data-action="detach-egg" data-id="{{ $egg->id }}" class="btn btn-sm btn-danger"><i class="fa fa-trash-o"></i></button>
|
||||||
</td>
|
</td>
|
||||||
@ -179,16 +179,10 @@
|
|||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label for="pEggs">Eggs</label>
|
<label for="pEggs">Eggs</label>
|
||||||
<select id="pEggs" name="eggs[]" class="form-control" multiple>
|
<select id="pEggs" name="eggs[]" class="form-control" multiple>
|
||||||
@foreach ($nests as $nest)
|
@foreach ($eggs as $egg)
|
||||||
<optgroup label="{{ $nest->name }}">
|
|
||||||
@foreach ($nest->eggs as $egg)
|
|
||||||
|
|
||||||
@if (! in_array($egg->id, $mount->eggs->pluck('id')->toArray()))
|
@if (! in_array($egg->id, $mount->eggs->pluck('id')->toArray()))
|
||||||
<option value="{{ $egg->id }}">{{ $egg->name }}</option>
|
<option value="{{ $egg->id }}">{{ $egg->name }}</option>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@endforeach
|
|
||||||
</optgroup>
|
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
|
|
||||||
@section('title')
|
|
||||||
New Nest
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('content-header')
|
|
||||||
<h1>New Nest<small>Configure a new nest to deploy to all nodes.</small></h1>
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
|
||||||
<li><a href="{{ route('admin.nests') }}">Nests</a></li>
|
|
||||||
<li class="active">New</li>
|
|
||||||
</ol>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<form action="{{ route('admin.nests.new') }}" method="POST">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-header with-border">
|
|
||||||
<h3 class="box-title">New Nest</h3>
|
|
||||||
</div>
|
|
||||||
<div class="box-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Name</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" name="name" class="form-control" value="{{ old('name') }}" />
|
|
||||||
<p class="text-muted"><small>This should be a descriptive category name that encompasses all of the eggs within the nest.</small></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Description</label>
|
|
||||||
<div>
|
|
||||||
<textarea name="description" class="form-control" rows="6">{{ old('description') }}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box-footer">
|
|
||||||
{!! csrf_field() !!}
|
|
||||||
<button type="submit" class="btn btn-primary pull-right">Save</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
@endsection
|
|
@ -1,117 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
|
|
||||||
@section('title')
|
|
||||||
Nests → {{ $nest->name }}
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('content-header')
|
|
||||||
<h1>{{ $nest->name }}<small>{{ str_limit($nest->description, 50) }}</small></h1>
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
|
||||||
<li><a href="{{ route('admin.nests') }}">Nests</a></li>
|
|
||||||
<li class="active">{{ $nest->name }}</li>
|
|
||||||
</ol>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<div class="row">
|
|
||||||
<form action="{{ route('admin.nests.view', $nest->id) }}" method="POST">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Name <span class="field-required"></span></label>
|
|
||||||
<div>
|
|
||||||
<input type="text" name="name" class="form-control" value="{{ $nest->name }}" />
|
|
||||||
<p class="text-muted"><small>This should be a descriptive category name that encompasses all of the options within the service.</small></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Description</label>
|
|
||||||
<div>
|
|
||||||
<textarea name="description" class="form-control" rows="7">{{ $nest->description }}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box-footer">
|
|
||||||
{!! csrf_field() !!}
|
|
||||||
<button type="submit" name="_method" value="PATCH" class="btn btn-primary btn-sm pull-right">Save</button>
|
|
||||||
<button id="deleteButton" type="submit" name="_method" value="DELETE" class="btn btn-sm btn-danger muted muted-hover"><i class="fa fa-trash-o"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Nest ID</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" readonly class="form-control" value="{{ $nest->id }}" />
|
|
||||||
<p class="text-muted small">A unique ID used for identification of this nest internally and through the API.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Author</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" readonly class="form-control" value="{{ $nest->author }}" />
|
|
||||||
<p class="text-muted small">The author of this service option. Please direct questions and issues to them unless this is an official option authored by <code>panel@example.com</code>.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">UUID</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" readonly class="form-control" value="{{ $nest->uuid }}" />
|
|
||||||
<p class="text-muted small">A UUID that all servers using this option are assigned for identification purposes.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<div class="box box-primary">
|
|
||||||
<div class="box-header with-border">
|
|
||||||
<h3 class="box-title">Nest Eggs</h3>
|
|
||||||
</div>
|
|
||||||
<div class="box-body table-responsive no-padding">
|
|
||||||
<table class="table table-hover">
|
|
||||||
<tr>
|
|
||||||
<th>ID</th>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Description</th>
|
|
||||||
<th class="text-center">Servers</th>
|
|
||||||
<th class="text-center"></th>
|
|
||||||
</tr>
|
|
||||||
@foreach($nest->eggs as $egg)
|
|
||||||
<tr>
|
|
||||||
<td class="align-middle"><code>{{ $egg->id }}</code></td>
|
|
||||||
<td class="align-middle"><a href="{{ route('admin.nests.egg.view', $egg->id) }}" data-toggle="tooltip" data-placement="right" title="{{ $egg->author }}">{{ $egg->name }}</a></td>
|
|
||||||
<td class="col-xs-8 align-middle">{{ $egg->description }}</td>
|
|
||||||
<td class="text-center align-middle"><code>{{ $egg->servers->count() }}</code></td>
|
|
||||||
<td class="align-middle">
|
|
||||||
<a href="{{ route('admin.nests.egg.export', ['egg' => $egg->id]) }}"><i class="fa fa-download"></i></a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="box-footer">
|
|
||||||
<a href="{{ route('admin.nests.egg.new') }}"><button class="btn btn-success btn-sm pull-right">New Egg</button></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('footer-scripts')
|
|
||||||
@parent
|
|
||||||
<script>
|
|
||||||
$('#deleteButton').on('mouseenter', function (event) {
|
|
||||||
$(this).find('i').html(' Delete Nest');
|
|
||||||
}).on('mouseleave', function (event) {
|
|
||||||
$(this).find('i').html('');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endsection
|
|
@ -40,14 +40,14 @@
|
|||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Server Name</th>
|
<th>Server Name</th>
|
||||||
<th>Owner</th>
|
<th>Owner</th>
|
||||||
<th>Service</th>
|
<th>Egg</th>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach($servers as $server)
|
@foreach($servers as $server)
|
||||||
<tr data-server="{{ $server->uuid }}">
|
<tr data-server="{{ $server->uuid }}">
|
||||||
<td><code>{{ $server->uuidShort }}</code></td>
|
<td><code>{{ $server->uuidShort }}</code></td>
|
||||||
<td><a href="{{ route('admin.servers.view', $server->id) }}">{{ $server->name }}</a></td>
|
<td><a href="{{ route('admin.servers.view', $server->id) }}">{{ $server->name }}</a></td>
|
||||||
<td><a href="{{ route('admin.users.view', $server->owner_id) }}">{{ $server->user->username }}</a></td>
|
<td><a href="{{ route('admin.users.view', $server->owner_id) }}">{{ $server->user->username }}</a></td>
|
||||||
<td>{{ $server->nest->name }} ({{ $server->egg->name }})</td>
|
<td><a href="{{ route('admin.eggs.view', $server->egg) }}">{{ $server->egg->name }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</table>
|
</table>
|
||||||
|
@ -226,31 +226,25 @@
|
|||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">Nest Configuration</h3>
|
<h3 class="box-title">Egg Configuration</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="box-body row">
|
<div class="box-body row">
|
||||||
<div class="form-group col-xs-12">
|
<div class="form-group col-xs-12">
|
||||||
<label for="pNestId">Nest</label>
|
<label for="pEggId">Egg</label>
|
||||||
|
<select id="pEggId" name="egg_id" class="form-control">
|
||||||
<select id="pNestId" name="nest_id" class="form-control">
|
@foreach($eggs as $egg)
|
||||||
@foreach($nests as $nest)
|
<option value="{{ $egg->id }}"
|
||||||
<option value="{{ $nest->id }}"
|
@if($egg->id === old('egg_id'))
|
||||||
@if($nest->id === old('nest_id'))
|
|
||||||
selected="selected"
|
selected="selected"
|
||||||
@endif
|
@endif
|
||||||
>{{ $nest->name }}</option>
|
>{{ $egg->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<p class="small text-muted no-margin">Select the Nest that this server will be grouped under.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-xs-12">
|
|
||||||
<label for="pEggId">Egg</label>
|
|
||||||
<select id="pEggId" name="egg_id" class="form-control"></select>
|
|
||||||
<p class="small text-muted no-margin">Select the Egg that will define how this server should operate.</p>
|
<p class="small text-muted no-margin">Select the Egg that will define how this server should operate.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group col-xs-12">
|
<div class="form-group col-xs-12">
|
||||||
<div class="checkbox checkbox-primary no-margin-bottom">
|
<div class="checkbox checkbox-primary no-margin-bottom">
|
||||||
<input type="checkbox" id="pSkipScripting" name="skip_scripts" value="1" {{ \App\Helpers\Utilities::checked('skip_scripts', 0) }} />
|
<input type="checkbox" id="pSkipScripting" name="skip_scripts" value="1" {{ \App\Helpers\Utilities::checked('skip_scripts', 0) }} />
|
||||||
@ -297,7 +291,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="box-header with-border" style="margin-top:-10px;">
|
<div class="box-header with-border" style="margin-top:-10px;">
|
||||||
<h3 class="box-title">Service Variables</h3>
|
<h3 class="box-title">Egg Variables</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="box-body row" id="appendVariablesTo"></div>
|
<div class="box-body row" id="appendVariablesTo"></div>
|
||||||
@ -317,8 +311,8 @@
|
|||||||
{!! Theme::js('vendor/lodash/lodash.js') !!}
|
{!! Theme::js('vendor/lodash/lodash.js') !!}
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
// Persist 'Service Variables'
|
// Persist 'Egg Variables'
|
||||||
function serviceVariablesUpdated(eggId, ids) {
|
function eggVariablesUpdated(eggId, ids) {
|
||||||
@if (old('egg_id'))
|
@if (old('egg_id'))
|
||||||
// Check if the egg id matches.
|
// Check if the egg id matches.
|
||||||
if (eggId != '{{ old('egg_id') }}') {
|
if (eggId != '{{ old('egg_id') }}') {
|
||||||
@ -335,7 +329,7 @@
|
|||||||
$('#pDefaultContainer').val('{{ old('image') }}');
|
$('#pDefaultContainer').val('{{ old('image') }}');
|
||||||
@endif
|
@endif
|
||||||
}
|
}
|
||||||
// END Persist 'Service Variables'
|
// END Persist 'Egg Variables'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{!! Theme::js('js/admin/new-server.js?v=20220530') !!}
|
{!! Theme::js('js/admin/new-server.js?v=20220530') !!}
|
||||||
@ -379,17 +373,11 @@
|
|||||||
@endif
|
@endif
|
||||||
// END Persist 'Node' select2
|
// END Persist 'Node' select2
|
||||||
|
|
||||||
// Persist 'Nest' select2
|
|
||||||
@if (old('nest_id'))
|
|
||||||
$('#pNestId').val('{{ old('nest_id') }}').change();
|
|
||||||
|
|
||||||
// Persist 'Egg' select2
|
// Persist 'Egg' select2
|
||||||
@if (old('egg_id'))
|
@if (old('egg_id'))
|
||||||
$('#pEggId').val('{{ old('egg_id') }}').change();
|
$('#pEggId').val('{{ old('egg_id') }}').change();
|
||||||
@endif
|
@endif
|
||||||
// END Persist 'Egg' select2
|
// END Persist 'Egg' select2
|
||||||
@endif
|
|
||||||
// END Persist 'Nest' select2
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
@ -44,8 +44,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Current Egg</td>
|
<td>Current Egg</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ route('admin.nests.view', $server->nest_id) }}">{{ $server->nest->name }}</a> ::
|
<a href="{{ route('admin.eggs.view', $server->egg_id) }}">{{ $server->egg->name }}</a>
|
||||||
<a href="{{ route('admin.nests.egg.view', $server->egg_id) }}">{{ $server->egg->name }}</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<h3 class="box-title">Reinstall Server</h3>
|
<h3 class="box-title">Reinstall Server</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<p>This will reinstall the server with the assigned service scripts. <strong>Danger!</strong> This could overwrite server data.</p>
|
<p>This will reinstall the server with the assigned egg scripts. <strong>Danger!</strong> This could overwrite server data.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
@if($server->isInstalled())
|
@if($server->isInstalled())
|
||||||
|
@ -43,34 +43,29 @@
|
|||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">Service Configuration</h3>
|
<h3 class="box-title">Egg Configuration</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body row">
|
<div class="box-body row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<p class="small text-danger">
|
<p class="small text-danger">
|
||||||
Changing any of the below values will result in the server processing a re-install command. The server will be stopped and will then proceed.
|
Changing any of the below values will result in the server processing a re-install command. The server will be stopped and will then proceed.
|
||||||
If you would like the service scripts to not run, ensure the box is checked at the bottom.
|
If you would like the egg scripts to not run, ensure the box is checked at the bottom.
|
||||||
</p>
|
</p>
|
||||||
<p class="small text-danger">
|
<p class="small text-danger">
|
||||||
<strong>This is a destructive operation in many cases. This server will be stopped immediately in order for this action to proceed.</strong>
|
<strong>This is a destructive operation in many cases. This server will be stopped immediately in order for this action to proceed.</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-xs-12">
|
<div class="form-group col-xs-12">
|
||||||
<label for="pNestId">Nest</label>
|
<label for="pEggId">Egg</label>
|
||||||
<select name="nest_id" id="pNestId" class="form-control">
|
<select name="egg_id" id="pEggId" class="form-control">
|
||||||
@foreach($nests as $nest)
|
@foreach($eggs as $egg)
|
||||||
<option value="{{ $nest->id }}"
|
<option value="{{ $egg->id }}"
|
||||||
@if($nest->id === $server->nest_id)
|
@if($egg->id === $server->egg_id)
|
||||||
selected
|
selected
|
||||||
@endif
|
@endif
|
||||||
>{{ $nest->name }}</option>
|
>{{ $egg->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
<p class="small text-muted no-margin">Select the Nest that this server will be grouped into.</p>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-xs-12">
|
|
||||||
<label for="pEggId">Egg</label>
|
|
||||||
<select name="egg_id" id="pEggId" class="form-control"></select>
|
|
||||||
<p class="small text-muted no-margin">Select the Egg that will provide processing data for this server.</p>
|
<p class="small text-muted no-margin">Select the Egg that will provide processing data for this server.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-xs-12">
|
<div class="form-group col-xs-12">
|
||||||
@ -82,6 +77,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">Docker Image Configuration</h3>
|
<h3 class="box-title">Docker Image Configuration</h3>
|
||||||
@ -108,10 +105,8 @@
|
|||||||
{!! Theme::js('vendor/lodash/lodash.js') !!}
|
{!! Theme::js('vendor/lodash/lodash.js') !!}
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('#pEggId').select2({placeholder: 'Select a Nest Egg'}).on('change', function () {
|
$('#pEggId').select2({placeholder: 'Select an Egg'}).on('change', function () {
|
||||||
var selectedEgg = _.isNull($(this).val()) ? $(this).find('option').first().val() : $(this).val();
|
var objectChain = _.get(Panel.eggs, $("#pEggId").val());
|
||||||
var parentChain = _.get(Panel.nests, $("#pNestId").val());
|
|
||||||
var objectChain = _.get(parentChain, 'eggs.' + selectedEgg);
|
|
||||||
|
|
||||||
const images = _.get(objectChain, 'docker_images', [])
|
const images = _.get(objectChain, 'docker_images', [])
|
||||||
$('#pDockerImage').html('');
|
$('#pDockerImage').html('');
|
||||||
@ -135,11 +130,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_.get(objectChain, 'startup', false)) {
|
|
||||||
$('#pDefaultStartupCommand').val(_.get(parentChain, 'startup', 'ERROR: Startup Not Defined!'));
|
|
||||||
} else {
|
|
||||||
$('#pDefaultStartupCommand').val(_.get(objectChain, 'startup'));
|
$('#pDefaultStartupCommand').val(_.get(objectChain, 'startup'));
|
||||||
}
|
|
||||||
|
|
||||||
$('#appendVariablesTo').html('');
|
$('#appendVariablesTo').html('');
|
||||||
$.each(_.get(objectChain, 'variables', []), function (i, item) {
|
$.each(_.get(objectChain, 'variables', []), function (i, item) {
|
||||||
@ -163,23 +154,6 @@
|
|||||||
</div>';
|
</div>';
|
||||||
$('#appendVariablesTo').append(dataAppend).find('#egg_variable_' + item.env_variable).val(setValue);
|
$('#appendVariablesTo').append(dataAppend).find('#egg_variable_' + item.env_variable).val(setValue);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
$('#pNestId').select2({placeholder: 'Select a Nest'}).on('change', function () {
|
|
||||||
$('#pEggId').html('').select2({
|
|
||||||
data: $.map(_.get(Panel.nests, $(this).val() + '.eggs', []), function (item) {
|
|
||||||
return {
|
|
||||||
id: item.id,
|
|
||||||
text: item.name,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (_.isObject(_.get(Panel.nests, $(this).val() + '.eggs.' + Panel.server.egg_id))) {
|
|
||||||
$('#pEggId').val(Panel.server.egg_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#pEggId').change();
|
|
||||||
}).change();
|
}).change();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -69,23 +69,12 @@
|
|||||||
<aside class="main-sidebar">
|
<aside class="main-sidebar">
|
||||||
<section class="sidebar">
|
<section class="sidebar">
|
||||||
<ul class="sidebar-menu">
|
<ul class="sidebar-menu">
|
||||||
<li class="header">BASIC ADMINISTRATION</li>
|
<li class="header">MANAGEMENT</li>
|
||||||
<li class="{{ Route::currentRouteName() !== 'admin.index' ?: 'active' }}">
|
<li class="{{ Route::currentRouteName() !== 'admin.index' ?: 'active' }}">
|
||||||
<a href="{{ route('admin.index') }}">
|
<a href="{{ route('admin.index') }}">
|
||||||
<i class="fa fa-home"></i> <span>Overview</span>
|
<i class="fa fa-home"></i> <span>Overview</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.settings') ?: 'active' }}">
|
|
||||||
<a href="{{ route('admin.settings')}}">
|
|
||||||
<i class="fa fa-wrench"></i> <span>Settings</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.api') ?: 'active' }}">
|
|
||||||
<a href="{{ route('admin.api.index')}}">
|
|
||||||
<i class="fa fa-gamepad"></i> <span>Application API</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="header">MANAGEMENT</li>
|
|
||||||
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.databases') ?: 'active' }}">
|
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.databases') ?: 'active' }}">
|
||||||
<a href="{{ route('admin.databases') }}">
|
<a href="{{ route('admin.databases') }}">
|
||||||
<i class="fa fa-database"></i> <span>Databases</span>
|
<i class="fa fa-database"></i> <span>Databases</span>
|
||||||
@ -111,15 +100,26 @@
|
|||||||
<i class="fa fa-users"></i> <span>Users</span>
|
<i class="fa fa-users"></i> <span>Users</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="header">SERVICE MANAGEMENT</li>
|
<li class="header">SERVICES</li>
|
||||||
|
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.eggs') ?: 'active' }}">
|
||||||
|
<a href="{{ route('admin.eggs') }}">
|
||||||
|
<i class="fa fa-th-large"></i> <span>Eggs</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.mounts') ?: 'active' }}">
|
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.mounts') ?: 'active' }}">
|
||||||
<a href="{{ route('admin.mounts') }}">
|
<a href="{{ route('admin.mounts') }}">
|
||||||
<i class="fa fa-magic"></i> <span>Mounts</span>
|
<i class="fa fa-magic"></i> <span>Mounts</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.nests') ?: 'active' }}">
|
<li class="header">OTHER</li>
|
||||||
<a href="{{ route('admin.nests') }}">
|
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.settings') ?: 'active' }}">
|
||||||
<i class="fa fa-th-large"></i> <span>Nests</span>
|
<a href="{{ route('admin.settings')}}">
|
||||||
|
<i class="fa fa-wrench"></i> <span>Settings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="{{ ! starts_with(Route::currentRouteName(), 'admin.api') ?: 'active' }}">
|
||||||
|
<a href="{{ route('admin.api.index')}}">
|
||||||
|
<i class="fa fa-gamepad"></i> <span>Application API</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -194,35 +194,37 @@ Route::group(['prefix' => 'mounts'], function () {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Nest Controller Routes
|
| Egg Controller Routes
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Endpoint: /admin/nests
|
| Endpoint: /admin/eggs
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
Route::group(['prefix' => 'nests'], function () {
|
Route::group(['prefix' => 'eggs'], function () {
|
||||||
Route::get('/', [Admin\Nests\NestController::class, 'index'])->name('admin.nests');
|
Route::controller(Admin\Eggs\EggController::class)->group(function () {
|
||||||
Route::get('/new', [Admin\Nests\NestController::class, 'create'])->name('admin.nests.new');
|
Route::get('/', 'index')->name('admin.eggs');
|
||||||
Route::get('/view/{nest:id}', [Admin\Nests\NestController::class, 'view'])->name('admin.nests.view');
|
Route::get('/new', 'create')->name('admin.eggs.new');
|
||||||
Route::get('/egg/new', [Admin\Nests\EggController::class, 'create'])->name('admin.nests.egg.new');
|
Route::post('/new', 'store');
|
||||||
Route::get('/egg/{egg:id}', [Admin\Nests\EggController::class, 'view'])->name('admin.nests.egg.view');
|
Route::patch('/{egg:id}', 'update');
|
||||||
Route::get('/egg/{egg:id}/export', [Admin\Nests\EggShareController::class, 'export'])->name('admin.nests.egg.export');
|
Route::get('/{egg:id}', 'view')->name('admin.eggs.view');
|
||||||
Route::get('/egg/{egg:id}/variables', [Admin\Nests\EggVariableController::class, 'view'])->name('admin.nests.egg.variables');
|
Route::delete('/{egg:id}', 'destroy');
|
||||||
Route::get('/egg/{egg:id}/scripts', [Admin\Nests\EggScriptController::class, 'index'])->name('admin.nests.egg.scripts');
|
});
|
||||||
|
|
||||||
Route::post('/new', [Admin\Nests\NestController::class, 'store']);
|
Route::controller(Admin\Eggs\EggShareController::class)->group(function () {
|
||||||
Route::post('/import', [Admin\Nests\EggShareController::class, 'import'])->name('admin.nests.egg.import');
|
Route::put('/{egg:id}', 'update');
|
||||||
Route::post('/egg/new', [Admin\Nests\EggController::class, 'store']);
|
Route::post('/import', 'import')->name('admin.eggs.import');
|
||||||
Route::post('/egg/{egg:id}/variables', [Admin\Nests\EggVariableController::class, 'store']);
|
Route::get('/{egg:id}/export', 'export')->name('admin.eggs.export');
|
||||||
|
});
|
||||||
|
|
||||||
Route::put('/egg/{egg:id}', [Admin\Nests\EggShareController::class, 'update']);
|
Route::controller(Admin\Eggs\EggScriptController::class)->group(function () {
|
||||||
|
Route::get('/{egg:id}/scripts', 'index')->name('admin.eggs.scripts');
|
||||||
|
Route::patch('/{egg:id}/scripts', 'update');
|
||||||
|
});
|
||||||
|
|
||||||
Route::patch('/view/{nest:id}', [Admin\Nests\NestController::class, 'update']);
|
Route::controller(Admin\Eggs\EggVariableController::class)->group(function () {
|
||||||
Route::patch('/egg/{egg:id}', [Admin\Nests\EggController::class, 'update']);
|
Route::patch('/{egg:id}/variables/{variable:id}', 'update')->name('admin.eggs.variables.edit');
|
||||||
Route::patch('/egg/{egg:id}/scripts', [Admin\Nests\EggScriptController::class, 'update']);
|
Route::get('/{egg:id}/variables', 'view')->name('admin.eggs.variables');
|
||||||
Route::patch('/egg/{egg:id}/variables/{variable:id}', [Admin\Nests\EggVariableController::class, 'update'])->name('admin.nests.egg.variables.edit');
|
Route::post('/{egg:id}/variables', 'store');
|
||||||
|
Route::delete('/{egg:id}/variables/{variable:id}', 'destroy');
|
||||||
Route::delete('/view/{nest:id}', [Admin\Nests\NestController::class, 'destroy']);
|
});
|
||||||
Route::delete('/egg/{egg:id}', [Admin\Nests\EggController::class, 'destroy']);
|
|
||||||
Route::delete('/egg/{egg:id}/variables/{variable:id}', [Admin\Nests\EggVariableController::class, 'destroy']);
|
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,6 @@ use App\Http\Controllers\Api\Application;
|
|||||||
| Endpoint: /api/application/users
|
| Endpoint: /api/application/users
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::group(['prefix' => '/users'], function () {
|
Route::group(['prefix' => '/users'], function () {
|
||||||
Route::get('/', [Application\Users\UserController::class, 'index'])->name('api.application.users');
|
Route::get('/', [Application\Users\UserController::class, 'index'])->name('api.application.users');
|
||||||
Route::get('/{user:id}', [Application\Users\UserController::class, 'view'])->name('api.application.users.view');
|
Route::get('/{user:id}', [Application\Users\UserController::class, 'view'])->name('api.application.users.view');
|
||||||
@ -106,19 +105,13 @@ Route::group(['prefix' => '/servers'], function () {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Nest Controller Routes
|
| Egg Controller Routes
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Endpoint: /api/application/nests
|
| Endpoint: /api/application/eggs
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
Route::group(['prefix' => '/nests'], function () {
|
Route::group(['prefix' => '/eggs'], function () {
|
||||||
Route::get('/', [Application\Nests\NestController::class, 'index'])->name('api.application.nests');
|
Route::get('/', [Application\Eggs\EggController::class, 'index'])->name('api.application.eggs.eggs');
|
||||||
Route::get('/{nest:id}', [Application\Nests\NestController::class, 'view'])->name('api.application.nests.view');
|
Route::get('/{egg:id}', [Application\Eggs\EggController::class, 'view'])->name('api.application.eggs.eggs.view');
|
||||||
|
|
||||||
// Egg Management Endpoint
|
|
||||||
Route::group(['prefix' => '/{nest:id}/eggs'], function () {
|
|
||||||
Route::get('/', [Application\Nests\EggController::class, 'index'])->name('api.application.nests.eggs');
|
|
||||||
Route::get('/{egg:id}', [Application\Nests\EggController::class, 'view'])->name('api.application.nests.eggs.view');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -85,7 +85,6 @@ abstract class ApplicationApiIntegrationTestCase extends IntegrationTestCase
|
|||||||
'r_allocations' => AdminAcl::READ | AdminAcl::WRITE,
|
'r_allocations' => AdminAcl::READ | AdminAcl::WRITE,
|
||||||
'r_users' => AdminAcl::READ | AdminAcl::WRITE,
|
'r_users' => AdminAcl::READ | AdminAcl::WRITE,
|
||||||
'r_locations' => AdminAcl::READ | AdminAcl::WRITE,
|
'r_locations' => AdminAcl::READ | AdminAcl::WRITE,
|
||||||
'r_nests' => AdminAcl::READ | AdminAcl::WRITE,
|
|
||||||
'r_eggs' => AdminAcl::READ | AdminAcl::WRITE,
|
'r_eggs' => AdminAcl::READ | AdminAcl::WRITE,
|
||||||
'r_database_hosts' => AdminAcl::READ | AdminAcl::WRITE,
|
'r_database_hosts' => AdminAcl::READ | AdminAcl::WRITE,
|
||||||
'r_server_databases' => AdminAcl::READ | AdminAcl::WRITE,
|
'r_server_databases' => AdminAcl::READ | AdminAcl::WRITE,
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Tests\Integration\Api\Application\Nests;
|
namespace App\Tests\Integration\Api\Application;
|
||||||
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use App\Transformers\Api\Application\EggTransformer;
|
use App\Transformers\Api\Application\EggTransformer;
|
||||||
use App\Tests\Integration\Api\Application\ApplicationApiIntegrationTestCase;
|
use Illuminate\Http\Response;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class EggControllerTest extends ApplicationApiIntegrationTestCase
|
class EggControllerTest extends ApplicationApiIntegrationTestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Test that all the eggs belonging to a given nest can be returned.
|
* Test that all the eggs can be returned.
|
||||||
*/
|
*/
|
||||||
public function testListAllEggsInNest()
|
public function testListAllEggs()
|
||||||
{
|
{
|
||||||
$eggs = Egg::query()->where('nest_id', 1)->get();
|
$eggs = Egg::query()->get();
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests/' . $eggs->first()->nest_id . '/eggs');
|
$response = $this->getJson('/api/application/eggs');
|
||||||
$response->assertStatus(Response::HTTP_OK);
|
$response->assertStatus(Response::HTTP_OK);
|
||||||
$response->assertJsonCount(count($eggs), 'data');
|
$response->assertJsonCount(count($eggs), 'data');
|
||||||
$response->assertJsonStructure([
|
$response->assertJsonStructure([
|
||||||
@ -26,7 +25,7 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
|
|||||||
[
|
[
|
||||||
'object',
|
'object',
|
||||||
'attributes' => [
|
'attributes' => [
|
||||||
'id', 'uuid', 'nest', 'author', 'description', 'docker_image', 'startup', 'created_at', 'updated_at',
|
'id', 'uuid', 'author', 'description', 'docker_image', 'startup', 'created_at', 'updated_at',
|
||||||
'script' => ['privileged', 'install', 'entry', 'container', 'extends'],
|
'script' => ['privileged', 'install', 'entry', 'container', 'extends'],
|
||||||
'config' => [
|
'config' => [
|
||||||
'files' => [],
|
'files' => [],
|
||||||
@ -61,12 +60,12 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
|
|||||||
{
|
{
|
||||||
$egg = Egg::query()->findOrFail(1);
|
$egg = Egg::query()->findOrFail(1);
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests/' . $egg->nest_id . '/eggs/' . $egg->id);
|
$response = $this->getJson('/api/application/eggs/' . $egg->id);
|
||||||
$response->assertStatus(Response::HTTP_OK);
|
$response->assertStatus(Response::HTTP_OK);
|
||||||
$response->assertJsonStructure([
|
$response->assertJsonStructure([
|
||||||
'object',
|
'object',
|
||||||
'attributes' => [
|
'attributes' => [
|
||||||
'id', 'uuid', 'nest', 'author', 'description', 'docker_image', 'startup', 'script' => [], 'config' => [], 'created_at', 'updated_at',
|
'id', 'uuid', 'author', 'description', 'docker_image', 'startup', 'script' => [], 'config' => [], 'created_at', 'updated_at',
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -83,13 +82,12 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
|
|||||||
{
|
{
|
||||||
$egg = Egg::query()->findOrFail(1);
|
$egg = Egg::query()->findOrFail(1);
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests/' . $egg->nest_id . '/eggs/' . $egg->id . '?include=servers,variables,nest');
|
$response = $this->getJson('/api/application/eggs/' . $egg->id . '?include=servers,variables');
|
||||||
$response->assertStatus(Response::HTTP_OK);
|
$response->assertStatus(Response::HTTP_OK);
|
||||||
$response->assertJsonStructure([
|
$response->assertJsonStructure([
|
||||||
'object',
|
'object',
|
||||||
'attributes' => [
|
'attributes' => [
|
||||||
'relationships' => [
|
'relationships' => [
|
||||||
'nest' => ['object', 'attributes'],
|
|
||||||
'servers' => ['object', 'data' => []],
|
'servers' => ['object', 'data' => []],
|
||||||
'variables' => ['object', 'data' => []],
|
'variables' => ['object', 'data' => []],
|
||||||
],
|
],
|
||||||
@ -102,9 +100,7 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
|
|||||||
*/
|
*/
|
||||||
public function testGetMissingEgg()
|
public function testGetMissingEgg()
|
||||||
{
|
{
|
||||||
$egg = Egg::query()->findOrFail(1);
|
$response = $this->getJson('/api/application/eggs/nil');
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests/' . $egg->nest_id . '/eggs/nil');
|
|
||||||
$this->assertNotFoundJson($response);
|
$this->assertNotFoundJson($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +113,7 @@ class EggControllerTest extends ApplicationApiIntegrationTestCase
|
|||||||
$egg = Egg::query()->findOrFail(1);
|
$egg = Egg::query()->findOrFail(1);
|
||||||
$this->createNewDefaultApiKey($this->getApiUser(), ['r_eggs' => 0]);
|
$this->createNewDefaultApiKey($this->getApiUser(), ['r_eggs' => 0]);
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests/' . $egg->nest_id . '/eggs');
|
$response = $this->getJson('/api/application/eggs');
|
||||||
$this->assertAccessDeniedJson($response);
|
$this->assertAccessDeniedJson($response);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,127 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Tests\Integration\Api\Application\Nests;
|
|
||||||
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use App\Contracts\Repository\NestRepositoryInterface;
|
|
||||||
use App\Transformers\Api\Application\NestTransformer;
|
|
||||||
use App\Tests\Integration\Api\Application\ApplicationApiIntegrationTestCase;
|
|
||||||
|
|
||||||
class NestControllerTest extends ApplicationApiIntegrationTestCase
|
|
||||||
{
|
|
||||||
private NestRepositoryInterface $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup tests.
|
|
||||||
*/
|
|
||||||
public function setUp(): void
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
|
|
||||||
$this->repository = $this->app->make(NestRepositoryInterface::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that the expected nests are returned by the request.
|
|
||||||
*/
|
|
||||||
public function testNestResponse()
|
|
||||||
{
|
|
||||||
/** @var \App\Models\Nest[] $nests */
|
|
||||||
$nests = $this->repository->all();
|
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests');
|
|
||||||
$response->assertStatus(Response::HTTP_OK);
|
|
||||||
$response->assertJsonCount(count($nests), 'data');
|
|
||||||
$response->assertJsonStructure([
|
|
||||||
'object',
|
|
||||||
'data' => [['object', 'attributes' => ['id', 'uuid', 'author', 'name', 'description', 'created_at', 'updated_at']]],
|
|
||||||
'meta' => ['pagination' => ['total', 'count', 'per_page', 'current_page', 'total_pages']],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response->assertJson([
|
|
||||||
'object' => 'list',
|
|
||||||
'data' => [],
|
|
||||||
'meta' => [
|
|
||||||
'pagination' => [
|
|
||||||
'total' => 4,
|
|
||||||
'count' => 4,
|
|
||||||
'per_page' => 50,
|
|
||||||
'current_page' => 1,
|
|
||||||
'total_pages' => 1,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
foreach ($nests as $nest) {
|
|
||||||
$response->assertJsonFragment([
|
|
||||||
'object' => 'nest',
|
|
||||||
'attributes' => $this->getTransformer(NestTransformer::class)->transform($nest),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that getting a single nest returns the expected result.
|
|
||||||
*/
|
|
||||||
public function testSingleNestResponse()
|
|
||||||
{
|
|
||||||
$nest = $this->repository->find(1);
|
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests/' . $nest->id);
|
|
||||||
$response->assertStatus(Response::HTTP_OK);
|
|
||||||
$response->assertJsonStructure([
|
|
||||||
'object',
|
|
||||||
'attributes' => ['id', 'uuid', 'author', 'name', 'description', 'created_at', 'updated_at'],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response->assertJson([
|
|
||||||
'object' => 'nest',
|
|
||||||
'attributes' => $this->getTransformer(NestTransformer::class)->transform($nest),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that including eggs in the response works as expected.
|
|
||||||
*/
|
|
||||||
public function testSingleNestWithEggsIncluded()
|
|
||||||
{
|
|
||||||
$nest = $this->repository->find(1);
|
|
||||||
$nest->loadMissing('eggs');
|
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests/' . $nest->id . '?include=servers,eggs');
|
|
||||||
$response->assertStatus(Response::HTTP_OK);
|
|
||||||
$response->assertJsonStructure([
|
|
||||||
'object',
|
|
||||||
'attributes' => [
|
|
||||||
'relationships' => [
|
|
||||||
'eggs' => ['object', 'data' => []],
|
|
||||||
'servers' => ['object', 'data' => []],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response->assertJsonCount(count($nest->getRelation('eggs')), 'attributes.relationships.eggs.data');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that a missing nest returns a 404 error.
|
|
||||||
*/
|
|
||||||
public function testGetMissingNest()
|
|
||||||
{
|
|
||||||
$response = $this->getJson('/api/application/nests/nil');
|
|
||||||
$this->assertNotFoundJson($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that an authentication error occurs if a key does not have permission
|
|
||||||
* to access a resource.
|
|
||||||
*/
|
|
||||||
public function testErrorReturnedIfNoPermission()
|
|
||||||
{
|
|
||||||
$nest = $this->repository->find(1);
|
|
||||||
$this->createNewDefaultApiKey($this->getApiUser(), ['r_nests' => 0]);
|
|
||||||
|
|
||||||
$response = $this->getJson('/api/application/nests/' . $nest->id);
|
|
||||||
$this->assertAccessDeniedJson($response);
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Tests\Integration\Services\Servers;
|
namespace App\Tests\Integration\Services\Servers;
|
||||||
|
|
||||||
use Exception;
|
use App\Models\Egg;
|
||||||
use App\Models\Nest;
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\ServerVariable;
|
use App\Models\ServerVariable;
|
||||||
@ -16,7 +15,7 @@ class StartupModificationServiceTest extends IntegrationTestCase
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Test that a non-admin request to modify the server startup parameters does
|
* Test that a non-admin request to modify the server startup parameters does
|
||||||
* not perform any egg or nest updates. This also attempts to pass through an
|
* not perform any egg updates. This also attempts to pass through an
|
||||||
* egg_id variable which should have no impact if the request is coming from
|
* egg_id variable which should have no impact if the request is coming from
|
||||||
* a non-admin entity.
|
* a non-admin entity.
|
||||||
*/
|
*/
|
||||||
@ -71,12 +70,11 @@ class StartupModificationServiceTest extends IntegrationTestCase
|
|||||||
public function testServerIsProperlyModifiedAsAdminUser()
|
public function testServerIsProperlyModifiedAsAdminUser()
|
||||||
{
|
{
|
||||||
/** @var \App\Models\Egg $nextEgg */
|
/** @var \App\Models\Egg $nextEgg */
|
||||||
$nextEgg = Nest::query()->findOrFail(2)->eggs()->firstOrFail();
|
$nextEgg = Egg::query()->findOrFail(6);
|
||||||
|
|
||||||
$server = $this->createServerModel(['egg_id' => 1]);
|
$server = $this->createServerModel(['egg_id' => 1]);
|
||||||
|
|
||||||
$this->assertNotSame($nextEgg->id, $server->egg_id);
|
$this->assertNotSame($nextEgg->id, $server->egg_id);
|
||||||
$this->assertNotSame($nextEgg->nest_id, $server->nest_id);
|
|
||||||
|
|
||||||
$response = $this->getService()
|
$response = $this->getService()
|
||||||
->setUserLevel(User::USER_LEVEL_ADMIN)
|
->setUserLevel(User::USER_LEVEL_ADMIN)
|
||||||
@ -89,7 +87,6 @@ class StartupModificationServiceTest extends IntegrationTestCase
|
|||||||
|
|
||||||
$this->assertInstanceOf(Server::class, $response);
|
$this->assertInstanceOf(Server::class, $response);
|
||||||
$this->assertSame($nextEgg->id, $response->egg_id);
|
$this->assertSame($nextEgg->id, $response->egg_id);
|
||||||
$this->assertSame($nextEgg->nest_id, $response->nest_id);
|
|
||||||
$this->assertSame('sample startup', $response->startup);
|
$this->assertSame('sample startup', $response->startup);
|
||||||
$this->assertSame('docker/hodor', $response->image);
|
$this->assertSame('docker/hodor', $response->image);
|
||||||
$this->assertTrue($response->skip_scripts);
|
$this->assertTrue($response->skip_scripts);
|
||||||
|
@ -51,16 +51,9 @@ trait CreatesTestModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (empty($attributes['egg_id'])) {
|
if (empty($attributes['egg_id'])) {
|
||||||
$egg = !empty($attributes['nest_id'])
|
$egg = $this->getBungeecordEgg();
|
||||||
? Egg::query()->where('nest_id', $attributes['nest_id'])->firstOrFail()
|
|
||||||
: $this->getBungeecordEgg();
|
|
||||||
|
|
||||||
$attributes['egg_id'] = $egg->id;
|
$attributes['egg_id'] = $egg->id;
|
||||||
$attributes['nest_id'] = $egg->nest_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($attributes['nest_id'])) {
|
|
||||||
$attributes['nest_id'] = Egg::query()->findOrFail($attributes['egg_id'])->nest_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($attributes['user_id'], $attributes['location_id']);
|
unset($attributes['user_id'], $attributes['location_id']);
|
||||||
@ -71,7 +64,7 @@ trait CreatesTestModels
|
|||||||
Allocation::query()->where('id', $server->allocation_id)->update(['server_id' => $server->id]);
|
Allocation::query()->where('id', $server->allocation_id)->update(['server_id' => $server->id]);
|
||||||
|
|
||||||
return $server->fresh([
|
return $server->fresh([
|
||||||
'location', 'user', 'node', 'allocation', 'nest', 'egg',
|
'location', 'user', 'node', 'allocation', 'egg',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user