Merge branch 'main' into feature/72
This commit is contained in:
commit
329268697b
2
.github/docker/entrypoint.sh
vendored
2
.github/docker/entrypoint.sh
vendored
@ -1,7 +1,7 @@
|
|||||||
#!/bin/ash -e
|
#!/bin/ash -e
|
||||||
cd /app
|
cd /app
|
||||||
|
|
||||||
mkdir -p /var/log/panel/logs/ /var/log/supervisord/ /var/log/nginx/ /var/log/php7/ \
|
mkdir -p /var/log/panel/logs/ /var/log/supervisord/ /var/log/nginx/ /var/log/php8/ \
|
||||||
&& chmod 777 /var/log/panel/logs/ \
|
&& chmod 777 /var/log/panel/logs/ \
|
||||||
&& ln -s /app/storage/logs/ /var/log/panel/
|
&& ln -s /app/storage/logs/ /var/log/panel/
|
||||||
|
|
||||||
|
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@ -12,7 +12,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [18]
|
node-version: [18, 21]
|
||||||
steps:
|
steps:
|
||||||
- name: Code Checkout
|
- name: Code Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# Build the assets that are needed for the frontend. This build stage is then discarded
|
# Build the assets that are needed for the frontend. This build stage is then discarded
|
||||||
# since we won't need NodeJS anymore in the future. This Docker image ships a final production
|
# since we won't need NodeJS anymore in the future. This Docker image ships a final production
|
||||||
# level distribution
|
# level distribution
|
||||||
FROM --platform=$TARGETOS/$TARGETARCH mhart/alpine-node:14
|
FROM --platform=$TARGETOS/$TARGETARCH node:21-alpine
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . ./
|
COPY . ./
|
||||||
RUN yarn install --frozen-lockfile \
|
RUN yarn install --frozen-lockfile \
|
||||||
@ -10,13 +10,13 @@ RUN yarn install --frozen-lockfile \
|
|||||||
|
|
||||||
# Stage 1:
|
# Stage 1:
|
||||||
# Build the actual container with all of the needed PHP dependencies that will run the application.
|
# Build the actual container with all of the needed PHP dependencies that will run the application.
|
||||||
FROM --platform=$TARGETOS/$TARGETARCH php:8.1-fpm-alpine
|
FROM --platform=$TARGETOS/$TARGETARCH php:8.3-fpm-alpine
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY . ./
|
COPY . ./
|
||||||
COPY --from=0 /app/public/assets ./public/assets
|
COPY --from=0 /app/public/assets ./public/assets
|
||||||
RUN apk add --no-cache --update ca-certificates dcron curl git supervisor tar unzip nginx libpng-dev libxml2-dev libzip-dev certbot certbot-nginx \
|
RUN apk add --no-cache --update ca-certificates dcron curl git supervisor tar unzip nginx libpng-dev libxml2-dev libzip-dev icu-dev certbot certbot-nginx \
|
||||||
&& docker-php-ext-configure zip \
|
&& docker-php-ext-configure zip \
|
||||||
&& docker-php-ext-install bcmath gd pdo_mysql zip \
|
&& docker-php-ext-install bcmath gd intl pdo_mysql zip \
|
||||||
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
|
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
|
||||||
&& cp .env.example .env \
|
&& cp .env.example .env \
|
||||||
&& mkdir -p bootstrap/cache/ storage/logs storage/framework/sessions storage/framework/views storage/framework/cache \
|
&& mkdir -p bootstrap/cache/ storage/logs storage/framework/sessions storage/framework/views storage/framework/cache \
|
||||||
|
@ -58,9 +58,9 @@ class MakeNodeCommand extends Command
|
|||||||
$data['disk'] = $this->option('maxDisk') ?? $this->ask('Enter the maximum amount of disk space');
|
$data['disk'] = $this->option('maxDisk') ?? $this->ask('Enter the maximum amount of disk space');
|
||||||
$data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask('Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new server');
|
$data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask('Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new server');
|
||||||
$data['upload_size'] = $this->option('uploadSize') ?? $this->ask('Enter the maximum filesize upload', '100');
|
$data['upload_size'] = $this->option('uploadSize') ?? $this->ask('Enter the maximum filesize upload', '100');
|
||||||
$data['daemonListen'] = $this->option('daemonListeningPort') ?? $this->ask('Enter the daemon listening port', '8080');
|
$data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask('Enter the daemon listening port', '8080');
|
||||||
$data['daemonSFTP'] = $this->option('daemonSFTPPort') ?? $this->ask('Enter the daemon SFTP listening port', '2022');
|
$data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask('Enter the daemon SFTP listening port', '2022');
|
||||||
$data['daemonBase'] = $this->option('daemonBase') ?? $this->ask('Enter the base folder', '/var/lib/pelican/volumes');
|
$data['daemon_base'] = $this->option('daemonBase') ?? $this->ask('Enter the base folder', '/var/lib/pelican/volumes');
|
||||||
|
|
||||||
$node = $this->creationService->handle($data);
|
$node = $this->creationService->handle($data);
|
||||||
$this->line('Successfully created a new node with the name ' . $data['name'] . ' and has an id of ' . $node->id . '.');
|
$this->line('Successfully created a new node with the name ' . $data['name'] . ' and has an id of ' . $node->id . '.');
|
||||||
|
@ -100,11 +100,11 @@ class EggResource extends Resource
|
|||||||
->label('Log Configuration')
|
->label('Log Configuration')
|
||||||
->helperText('This should be a JSON representation of where log files are stored, and whether or not the daemon should be creating custom logs.'),
|
->helperText('This should be a JSON representation of where log files are stored, and whether or not the daemon should be creating custom logs.'),
|
||||||
]),
|
]),
|
||||||
Forms\Components\Tabs\Tab::make('Variables')
|
Forms\Components\Tabs\Tab::make('Egg Variables')
|
||||||
->columnSpanFull()
|
->columnSpanFull()
|
||||||
->columns(2)
|
->columns(2)
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\Repeater::make('Blah')
|
Forms\Components\Repeater::make('variables')
|
||||||
->grid()
|
->grid()
|
||||||
->relationship('variables')
|
->relationship('variables')
|
||||||
->name('name')
|
->name('name')
|
||||||
@ -113,12 +113,36 @@ class EggResource extends Resource
|
|||||||
->collapsible()->collapsed()
|
->collapsible()->collapsed()
|
||||||
->columnSpan(2)
|
->columnSpan(2)
|
||||||
->itemLabel(fn (array $state) => $state['name'])
|
->itemLabel(fn (array $state) => $state['name'])
|
||||||
|
->mutateRelationshipDataBeforeCreateUsing(function (array $data): array {
|
||||||
|
$data['default_value'] ??= '';
|
||||||
|
$data['description'] ??= '';
|
||||||
|
$data['rules'] ??= '';
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
})
|
||||||
|
->mutateRelationshipDataBeforeSaveUsing(function (array $data): array {
|
||||||
|
$data['default_value'] ??= '';
|
||||||
|
$data['description'] ??= '';
|
||||||
|
$data['rules'] ??= '';
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
})
|
||||||
->schema([
|
->schema([
|
||||||
Forms\Components\TextInput::make('name')->live()->maxLength(191)->columnSpanFull(),
|
Forms\Components\TextInput::make('name')
|
||||||
|
->live()
|
||||||
|
->debounce(1000)
|
||||||
|
->maxLength(191)
|
||||||
|
->columnSpanFull()
|
||||||
|
->afterStateUpdated(fn (Forms\Set $set, $state) => $set('env_variable', str($state)->trim()->snake()->upper()))
|
||||||
|
->required(),
|
||||||
Forms\Components\Textarea::make('description')->columnSpanFull(),
|
Forms\Components\Textarea::make('description')->columnSpanFull(),
|
||||||
Forms\Components\TextInput::make('env_variable')->maxLength(191)->required()->hint(fn ($state) => "{{{$state}}}"),
|
Forms\Components\TextInput::make('env_variable')
|
||||||
Forms\Components\TextInput::make('default_value')->maxLength(191)->required(),
|
->label('Environment Variable')
|
||||||
Forms\Components\TextInput::make('rules')->columnSpanFull()->required(),
|
->maxLength(191)
|
||||||
|
->hint(fn ($state) => "{{{$state}}}")
|
||||||
|
->required(),
|
||||||
|
Forms\Components\TextInput::make('default_value')->maxLength(191),
|
||||||
|
Forms\Components\Textarea::make('rules')->rows(3)->columnSpanFull(),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
Forms\Components\Tabs\Tab::make('Install Script')
|
Forms\Components\Tabs\Tab::make('Install Script')
|
||||||
|
@ -43,17 +43,17 @@ class NodeResource extends Resource
|
|||||||
->required()
|
->required()
|
||||||
->integer()
|
->integer()
|
||||||
->default(100),
|
->default(100),
|
||||||
Forms\Components\TextInput::make('daemonListen')
|
Forms\Components\TextInput::make('daemon_listen')
|
||||||
->required()
|
->required()
|
||||||
->integer()
|
->integer()
|
||||||
->label('Daemon Port')
|
->label('Daemon Port')
|
||||||
->default(8080),
|
->default(8080),
|
||||||
Forms\Components\TextInput::make('daemonSFTP')
|
Forms\Components\TextInput::make('daemon_sftp')
|
||||||
->required()
|
->required()
|
||||||
->integer()
|
->integer()
|
||||||
->label('Daemon SFTP Port')
|
->label('Daemon SFTP Port')
|
||||||
->default(2022),
|
->default(2022),
|
||||||
Forms\Components\TextInput::make('daemonBase')
|
Forms\Components\TextInput::make('daemon_base')
|
||||||
->required()
|
->required()
|
||||||
->maxLength(191)
|
->maxLength(191)
|
||||||
->default('/home/daemon-files'),
|
->default('/home/daemon-files'),
|
||||||
|
@ -113,7 +113,7 @@ class CreateNode extends CreateRecord
|
|||||||
'lg' => 1,
|
'lg' => 1,
|
||||||
]),
|
]),
|
||||||
|
|
||||||
Forms\Components\TextInput::make('daemonListen')
|
Forms\Components\TextInput::make('daemon_listen')
|
||||||
->columnSpan([
|
->columnSpan([
|
||||||
'default' => 1,
|
'default' => 1,
|
||||||
'sm' => 1,
|
'sm' => 1,
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
namespace App\Filament\Resources\NodeResource\Pages;
|
namespace App\Filament\Resources\NodeResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\NodeResource;
|
use App\Filament\Resources\NodeResource;
|
||||||
use App\Models\Allocation;
|
|
||||||
use App\Models\Node;
|
use App\Models\Node;
|
||||||
use Filament\Actions;
|
use Filament\Actions;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Components\Tabs;
|
use Filament\Forms\Components\Tabs;
|
||||||
use Filament\Resources\Pages\EditRecord;
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\HtmlString;
|
use Illuminate\Support\HtmlString;
|
||||||
use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction;
|
use Webbingbrasil\FilamentCopyActions\Forms\Actions\CopyAction;
|
||||||
|
|
||||||
@ -91,6 +91,52 @@ class EditNode extends EditRecord
|
|||||||
'md' => 1,
|
'md' => 1,
|
||||||
'lg' => 1,
|
'lg' => 1,
|
||||||
])
|
])
|
||||||
|
->live()
|
||||||
|
->afterStateUpdated(function ($state, Forms\Set $set) {
|
||||||
|
$ports = collect();
|
||||||
|
$update = false;
|
||||||
|
foreach ($state as $portEntry) {
|
||||||
|
if (!str_contains($portEntry, '-')) {
|
||||||
|
if (is_numeric($portEntry)) {
|
||||||
|
$ports->push((int) $portEntry);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not add non numerical ports
|
||||||
|
$update = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$update = true;
|
||||||
|
[$start, $end] = explode('-', $portEntry);
|
||||||
|
if (!is_numeric($start) || !is_numeric($end)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$start = max((int) $start, 0);
|
||||||
|
$end = min((int) $end, 2 ** 16 - 1);
|
||||||
|
for ($i = $start; $i <= $end; $i++) {
|
||||||
|
$ports->push($i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$uniquePorts = $ports->unique()->values();
|
||||||
|
if ($ports->count() > $uniquePorts->count()) {
|
||||||
|
$update = true;
|
||||||
|
$ports = $uniquePorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sortedPorts = $ports->sort()->values();
|
||||||
|
if ($sortedPorts->all() !== $ports->all()) {
|
||||||
|
$update = true;
|
||||||
|
$ports = $sortedPorts;
|
||||||
|
}
|
||||||
|
if ($update) {
|
||||||
|
$set('port', $ports->all());
|
||||||
|
}
|
||||||
|
})
|
||||||
->placeholder('25565')
|
->placeholder('25565')
|
||||||
->helperText('Individual ports or port ranges here separated by spaces')
|
->helperText('Individual ports or port ranges here separated by spaces')
|
||||||
->splitKeys(['Tab', ' ']),
|
->splitKeys(['Tab', ' ']),
|
||||||
@ -108,6 +154,15 @@ class EditNode extends EditRecord
|
|||||||
Forms\Components\Repeater::make('allocations')
|
Forms\Components\Repeater::make('allocations')
|
||||||
->orderColumn('server_id')
|
->orderColumn('server_id')
|
||||||
->columnSpan(4)
|
->columnSpan(4)
|
||||||
|
->collapsible()->collapsed()
|
||||||
|
->itemLabel(function (array $state) {
|
||||||
|
$host = $state['ip'] . ':' . $state['port'];
|
||||||
|
if ($state['ip_alias']) {
|
||||||
|
return $state['ip_alias'] ." ($host)";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $host;
|
||||||
|
})
|
||||||
->columns([
|
->columns([
|
||||||
'default' => 1,
|
'default' => 1,
|
||||||
'sm' => 3,
|
'sm' => 3,
|
||||||
@ -133,7 +188,7 @@ class EditNode extends EditRecord
|
|||||||
'default' => 1,
|
'default' => 1,
|
||||||
'sm' => 1,
|
'sm' => 1,
|
||||||
'md' => 1,
|
'md' => 1,
|
||||||
'lg' => 1,
|
'lg' => 2,
|
||||||
])
|
])
|
||||||
->minValue(0)
|
->minValue(0)
|
||||||
->maxValue(65535)
|
->maxValue(65535)
|
||||||
@ -147,15 +202,21 @@ class EditNode extends EditRecord
|
|||||||
'lg' => 3,
|
'lg' => 3,
|
||||||
])
|
])
|
||||||
->label('Alias'),
|
->label('Alias'),
|
||||||
Forms\Components\TextInput::make('server')
|
Forms\Components\Select::make('server')
|
||||||
->columnSpan([
|
->columnSpan([
|
||||||
'default' => 1,
|
'default' => 1,
|
||||||
'sm' => 1,
|
'sm' => 1,
|
||||||
'md' => 2,
|
'md' => 2,
|
||||||
'lg' => 3,
|
'lg' => 2,
|
||||||
])
|
])
|
||||||
->formatStateUsing(fn (Allocation $allocation) => $allocation->server?->name)
|
->searchable()
|
||||||
->activeUrl(true)
|
->preload()
|
||||||
|
->relationship(
|
||||||
|
'server',
|
||||||
|
'name',
|
||||||
|
fn (Builder $query, Forms\Get $get) => $query
|
||||||
|
->where('node_id', $get('node_id')),
|
||||||
|
)
|
||||||
->placeholder('Not assigned'),
|
->placeholder('Not assigned'),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
|
@ -96,7 +96,7 @@ class NodeViewController extends Controller
|
|||||||
{
|
{
|
||||||
$this->plainInject([
|
$this->plainInject([
|
||||||
'node' => Collection::wrap($node->makeVisible(['daemon_token_id', 'daemon_token']))
|
'node' => Collection::wrap($node->makeVisible(['daemon_token_id', 'daemon_token']))
|
||||||
->only(['scheme', 'fqdn', 'daemonListen', 'daemon_token_id', 'daemon_token']),
|
->only(['scheme', 'fqdn', 'daemon_listen', 'daemon_token_id', 'daemon_token']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return view('admin.nodes.view.servers', [
|
return view('admin.nodes.view.servers', [
|
||||||
|
@ -68,7 +68,7 @@ class ServerTransferController extends Controller
|
|||||||
|
|
||||||
// Check if the node is viable for the transfer.
|
// Check if the node is viable for the transfer.
|
||||||
$node = Node::query()
|
$node = Node::query()
|
||||||
->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemonListen', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate'])
|
->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemon_listen', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate'])
|
||||||
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk')
|
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk')
|
||||||
->leftJoin('servers', 'servers.node_id', '=', 'nodes.id')
|
->leftJoin('servers', 'servers.node_id', '=', 'nodes.id')
|
||||||
->where('nodes.id', $node_id)
|
->where('nodes.id', $node_id)
|
||||||
|
@ -33,7 +33,7 @@ class ServerController extends ApplicationApiController
|
|||||||
public function index(GetServersRequest $request): array
|
public function index(GetServersRequest $request): array
|
||||||
{
|
{
|
||||||
$servers = QueryBuilder::for(Server::query())
|
$servers = QueryBuilder::for(Server::query())
|
||||||
->allowedFilters(['uuid', 'uuidShort', 'name', 'description', 'image', 'external_id'])
|
->allowedFilters(['uuid', 'uuid_short', 'name', 'description', 'image', 'external_id'])
|
||||||
->allowedSorts(['id', 'uuid'])
|
->allowedSorts(['id', 'uuid'])
|
||||||
->paginate($request->query('per_page') ?? 50);
|
->paginate($request->query('per_page') ?? 50);
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ class SftpAuthenticationController extends Controller
|
|||||||
protected function getServer(Request $request, string $uuid): Server
|
protected function getServer(Request $request, string $uuid): Server
|
||||||
{
|
{
|
||||||
return Server::query()
|
return Server::query()
|
||||||
->where(fn ($builder) => $builder->where('uuid', $uuid)->orWhere('uuidShort', $uuid))
|
->where(fn ($builder) => $builder->where('uuid', $uuid)->orWhere('uuid_short', $uuid))
|
||||||
->where('node_id', $request->attributes->get('node')->id)
|
->where('node_id', $request->attributes->get('node')->id)
|
||||||
->firstOr(function () use ($request) {
|
->firstOr(function () use ($request) {
|
||||||
$this->reject($request);
|
$this->reject($request);
|
||||||
|
@ -29,11 +29,11 @@ class StoreNodeRequest extends ApplicationApiRequest
|
|||||||
'disk',
|
'disk',
|
||||||
'disk_overallocate',
|
'disk_overallocate',
|
||||||
'upload_size',
|
'upload_size',
|
||||||
'daemonListen',
|
'daemon_listen',
|
||||||
'daemonSFTP',
|
'daemon_sftp',
|
||||||
'daemonBase',
|
'daemon_base',
|
||||||
])->mapWithKeys(function ($value, $key) {
|
])->mapWithKeys(function ($value, $key) {
|
||||||
$key = ($key === 'daemonSFTP') ? 'daemonSftp' : $key;
|
$key = ($key === 'daemon_sftp') ? 'daemon_sftp' : $key;
|
||||||
|
|
||||||
return [snake_case($key) => $value];
|
return [snake_case($key) => $value];
|
||||||
})->toArray();
|
})->toArray();
|
||||||
@ -58,9 +58,9 @@ class StoreNodeRequest extends ApplicationApiRequest
|
|||||||
public function validated($key = null, $default = null): array
|
public function validated($key = null, $default = null): array
|
||||||
{
|
{
|
||||||
$response = parent::validated();
|
$response = parent::validated();
|
||||||
$response['daemonListen'] = $response['daemon_listen'];
|
$response['daemon_listen'] = $response['daemon_listen'];
|
||||||
$response['daemonSFTP'] = $response['daemon_sftp'];
|
$response['daemon_sftp'] = $response['daemon_sftp'];
|
||||||
$response['daemonBase'] = $response['daemon_base'] ?? (new Node())->getAttribute('daemonBase');
|
$response['daemon_base'] = $response['daemon_base'] ?? (new Node())->getAttribute('daemon_base');
|
||||||
|
|
||||||
unset($response['daemon_base'], $response['daemon_listen'], $response['daemon_sftp']);
|
unset($response['daemon_base'], $response['daemon_listen'], $response['daemon_sftp']);
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class EggVariable extends Model
|
|||||||
'default_value' => 'string',
|
'default_value' => 'string',
|
||||||
'user_viewable' => 'boolean',
|
'user_viewable' => 'boolean',
|
||||||
'user_editable' => 'boolean',
|
'user_editable' => 'boolean',
|
||||||
'rules' => 'required|string',
|
'rules' => 'string',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $attributes = [
|
protected $attributes = [
|
||||||
|
@ -24,7 +24,7 @@ class AdminServerFilter implements Filter
|
|||||||
->where(function (Builder $builder) use ($value) {
|
->where(function (Builder $builder) use ($value) {
|
||||||
$builder->where('servers.uuid', $value)
|
$builder->where('servers.uuid', $value)
|
||||||
->orWhere('servers.uuid', 'LIKE', "$value%")
|
->orWhere('servers.uuid', 'LIKE', "$value%")
|
||||||
->orWhere('servers.uuidShort', $value)
|
->orWhere('servers.uuid_short', $value)
|
||||||
->orWhere('servers.external_id', $value)
|
->orWhere('servers.external_id', $value)
|
||||||
->orWhereRaw('LOWER(users.username) LIKE ?', ["%$value%"])
|
->orWhereRaw('LOWER(users.username) LIKE ?', ["%$value%"])
|
||||||
->orWhereRaw('LOWER(users.email) LIKE ?', ["$value%"])
|
->orWhereRaw('LOWER(users.email) LIKE ?', ["$value%"])
|
||||||
|
@ -61,7 +61,7 @@ class MultiFieldServerFilter implements Filter
|
|||||||
->where(function (Builder $builder) use ($value) {
|
->where(function (Builder $builder) use ($value) {
|
||||||
$builder->where('servers.uuid', $value)
|
$builder->where('servers.uuid', $value)
|
||||||
->orWhere('servers.uuid', 'LIKE', "$value%")
|
->orWhere('servers.uuid', 'LIKE', "$value%")
|
||||||
->orWhere('servers.uuidShort', $value)
|
->orWhere('servers.uuid_short', $value)
|
||||||
->orWhere('servers.external_id', $value)
|
->orWhere('servers.external_id', $value)
|
||||||
->orWhereRaw('LOWER(servers.name) LIKE ?', ["%$value%"]);
|
->orWhereRaw('LOWER(servers.name) LIKE ?', ["%$value%"]);
|
||||||
});
|
});
|
||||||
|
@ -29,9 +29,9 @@ use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
|||||||
* @property int $upload_size
|
* @property int $upload_size
|
||||||
* @property string $daemon_token_id
|
* @property string $daemon_token_id
|
||||||
* @property string $daemon_token
|
* @property string $daemon_token
|
||||||
* @property int $daemonListen
|
* @property int $daemon_listen
|
||||||
* @property int $daemonSFTP
|
* @property int $daemon_sftp
|
||||||
* @property string $daemonBase
|
* @property string $daemon_base
|
||||||
* @property \Carbon\Carbon $created_at
|
* @property \Carbon\Carbon $created_at
|
||||||
* @property \Carbon\Carbon $updated_at
|
* @property \Carbon\Carbon $updated_at
|
||||||
* @property \App\Models\Mount[]|\Illuminate\Database\Eloquent\Collection $mounts
|
* @property \App\Models\Mount[]|\Illuminate\Database\Eloquent\Collection $mounts
|
||||||
@ -71,8 +71,8 @@ class Node extends Model
|
|||||||
'public', 'name',
|
'public', 'name',
|
||||||
'fqdn', 'scheme', 'behind_proxy',
|
'fqdn', 'scheme', 'behind_proxy',
|
||||||
'memory', 'memory_overallocate', 'disk',
|
'memory', 'memory_overallocate', 'disk',
|
||||||
'disk_overallocate', 'upload_size', 'daemonBase',
|
'disk_overallocate', 'upload_size', 'daemon_base',
|
||||||
'daemonSFTP', 'daemonListen',
|
'daemon_sftp', 'daemon_listen',
|
||||||
'description', 'maintenance_mode',
|
'description', 'maintenance_mode',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -87,9 +87,9 @@ class Node extends Model
|
|||||||
'memory_overallocate' => 'required|numeric|min:-1',
|
'memory_overallocate' => 'required|numeric|min:-1',
|
||||||
'disk' => 'required|numeric|min:0',
|
'disk' => 'required|numeric|min:0',
|
||||||
'disk_overallocate' => 'required|numeric|min:-1',
|
'disk_overallocate' => 'required|numeric|min:-1',
|
||||||
'daemonBase' => 'sometimes|required|regex:/^([\/][\d\w.\-\/]+)$/',
|
'daemon_base' => 'sometimes|required|regex:/^([\/][\d\w.\-\/]+)$/',
|
||||||
'daemonSFTP' => 'required|numeric|between:1,65535',
|
'daemon_sftp' => 'required|numeric|between:1,65535',
|
||||||
'daemonListen' => 'required|numeric|between:1,65535',
|
'daemon_listen' => 'required|numeric|between:1,65535',
|
||||||
'maintenance_mode' => 'boolean',
|
'maintenance_mode' => 'boolean',
|
||||||
'upload_size' => 'int|between:1,1024',
|
'upload_size' => 'int|between:1,1024',
|
||||||
];
|
];
|
||||||
@ -104,9 +104,9 @@ class Node extends Model
|
|||||||
'memory_overallocate' => 0,
|
'memory_overallocate' => 0,
|
||||||
'disk' => 0,
|
'disk' => 0,
|
||||||
'disk_overallocate' => 0,
|
'disk_overallocate' => 0,
|
||||||
'daemonBase' => '/var/lib/pelican/volumes',
|
'daemon_base' => '/var/lib/pelican/volumes',
|
||||||
'daemonSFTP' => 2022,
|
'daemon_sftp' => 2022,
|
||||||
'daemonListen' => 8080,
|
'daemon_listen' => 8080,
|
||||||
'maintenance_mode' => false,
|
'maintenance_mode' => false,
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -115,8 +115,8 @@ class Node extends Model
|
|||||||
return [
|
return [
|
||||||
'memory' => 'integer',
|
'memory' => 'integer',
|
||||||
'disk' => 'integer',
|
'disk' => 'integer',
|
||||||
'daemonListen' => 'integer',
|
'daemon_listen' => 'integer',
|
||||||
'daemonSFTP' => 'integer',
|
'daemon_sftp' => 'integer',
|
||||||
'behind_proxy' => 'boolean',
|
'behind_proxy' => 'boolean',
|
||||||
'public' => 'boolean',
|
'public' => 'boolean',
|
||||||
'maintenance_mode' => 'boolean',
|
'maintenance_mode' => 'boolean',
|
||||||
@ -148,7 +148,7 @@ class Node extends Model
|
|||||||
*/
|
*/
|
||||||
public function getConnectionAddress(): string
|
public function getConnectionAddress(): string
|
||||||
{
|
{
|
||||||
return "$this->scheme://$this->fqdn:$this->daemonListen";
|
return "$this->scheme://$this->fqdn:$this->daemon_listen";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,7 +163,7 @@ class Node extends Model
|
|||||||
'token' => decrypt($this->daemon_token),
|
'token' => decrypt($this->daemon_token),
|
||||||
'api' => [
|
'api' => [
|
||||||
'host' => '0.0.0.0',
|
'host' => '0.0.0.0',
|
||||||
'port' => $this->daemonListen,
|
'port' => $this->daemon_listen,
|
||||||
'ssl' => [
|
'ssl' => [
|
||||||
'enabled' => (!$this->behind_proxy && $this->scheme === 'https'),
|
'enabled' => (!$this->behind_proxy && $this->scheme === 'https'),
|
||||||
'cert' => '/etc/letsencrypt/live/' . Str::lower($this->fqdn) . '/fullchain.pem',
|
'cert' => '/etc/letsencrypt/live/' . Str::lower($this->fqdn) . '/fullchain.pem',
|
||||||
@ -172,9 +172,9 @@ class Node extends Model
|
|||||||
'upload_limit' => $this->upload_size,
|
'upload_limit' => $this->upload_size,
|
||||||
],
|
],
|
||||||
'system' => [
|
'system' => [
|
||||||
'data' => $this->daemonBase,
|
'data' => $this->daemon_base,
|
||||||
'sftp' => [
|
'sftp' => [
|
||||||
'bind_port' => $this->daemonSFTP,
|
'bind_port' => $this->daemon_sftp,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'allowed_mounts' => $this->mounts->pluck('source')->toArray(),
|
'allowed_mounts' => $this->mounts->pluck('source')->toArray(),
|
||||||
|
@ -22,7 +22,7 @@ use App\Exceptions\Http\Server\ServerStateConflictException;
|
|||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string|null $external_id
|
* @property string|null $external_id
|
||||||
* @property string $uuid
|
* @property string $uuid
|
||||||
* @property string $uuidShort
|
* @property string $uuid_short
|
||||||
* @property int $node_id
|
* @property int $node_id
|
||||||
* @property string $name
|
* @property string $name
|
||||||
* @property string $description
|
* @property string $description
|
||||||
@ -99,7 +99,7 @@ use App\Exceptions\Http\Server\ServerStateConflictException;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereThreads($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereThreads($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereUpdatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereUuid($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereUuid($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Server whereUuidShort($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|Server whereuuid_short($value)
|
||||||
*
|
*
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
@ -329,7 +329,7 @@ class Server extends Model
|
|||||||
public function resolveRouteBinding($value, $field = null): ?self
|
public function resolveRouteBinding($value, $field = null): ?self
|
||||||
{
|
{
|
||||||
return match ($field) {
|
return match ($field) {
|
||||||
'uuid' => $this->where('uuidShort', $value)->orWhere('uuid', $value)->firstOrFail(),
|
'uuid' => $this->where('uuid_short', $value)->orWhere('uuid', $value)->firstOrFail(),
|
||||||
default => $this->where('id', $value)->firstOrFail(),
|
default => $this->where('id', $value)->firstOrFail(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,6 @@ class AddedToServer extends Notification implements ShouldQueue
|
|||||||
->greeting('Hello ' . $this->server->user . '!')
|
->greeting('Hello ' . $this->server->user . '!')
|
||||||
->line('You have been added as a subuser for the following server, allowing you certain control over the server.')
|
->line('You have been added as a subuser for the following server, allowing you certain control over the server.')
|
||||||
->line('Server Name: ' . $this->server->name)
|
->line('Server Name: ' . $this->server->name)
|
||||||
->action('Visit Server', url('/server/' . $this->server->uuidShort));
|
->action('Visit Server', url('/server/' . $this->server->uuid_short));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ class SubuserObserver
|
|||||||
$subuser->user->notify(new AddedToServer([
|
$subuser->user->notify(new AddedToServer([
|
||||||
'user' => $subuser->user->name_first,
|
'user' => $subuser->user->name_first,
|
||||||
'name' => $subuser->server->name,
|
'name' => $subuser->server->name,
|
||||||
'uuidShort' => $subuser->server->uuidShort,
|
'uuid_short' => $subuser->server->uuid_short,
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ class ServerCreationService
|
|||||||
return Server::create([
|
return Server::create([
|
||||||
'external_id' => Arr::get($data, 'external_id'),
|
'external_id' => Arr::get($data, 'external_id'),
|
||||||
'uuid' => $uuid,
|
'uuid' => $uuid,
|
||||||
'uuidShort' => substr($uuid, 0, 8),
|
'uuid_short' => substr($uuid, 0, 8),
|
||||||
'node_id' => Arr::get($data, 'node_id'),
|
'node_id' => Arr::get($data, 'node_id'),
|
||||||
'name' => Arr::get($data, 'name'),
|
'name' => Arr::get($data, 'name'),
|
||||||
'description' => Arr::get($data, 'description') ?? '',
|
'description' => Arr::get($data, 'description') ?? '',
|
||||||
@ -194,7 +194,7 @@ class ServerCreationService
|
|||||||
$uuid = Uuid::uuid4()->toString();
|
$uuid = Uuid::uuid4()->toString();
|
||||||
|
|
||||||
$shortUuid = str($uuid)->substr(0, 8);
|
$shortUuid = str($uuid)->substr(0, 8);
|
||||||
if (Server::query()->where('uuid', $uuid)->orWhere('uuidShort', $shortUuid)->exists()) {
|
if (Server::query()->where('uuid', $uuid)->orWhere('uuid_short', $shortUuid)->exists()) {
|
||||||
return $this->generateUniqueUuidCombo();
|
return $this->generateUniqueUuidCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ trait AvailableLanguages
|
|||||||
'ja',
|
'ja',
|
||||||
'nl',
|
'nl',
|
||||||
'pl',
|
'pl',
|
||||||
|
'sk',
|
||||||
'ru',
|
'ru',
|
||||||
'tr',
|
'tr',
|
||||||
];
|
];
|
||||||
|
@ -31,7 +31,7 @@ class NodeTransformer extends BaseTransformer
|
|||||||
$response = collect($node->toArray())->mapWithKeys(function ($value, $key) {
|
$response = collect($node->toArray())->mapWithKeys(function ($value, $key) {
|
||||||
// I messed up early in 2016 when I named this column as poorly
|
// I messed up early in 2016 when I named this column as poorly
|
||||||
// as I did. This is the tragic result of my mistakes.
|
// as I did. This is the tragic result of my mistakes.
|
||||||
$key = ($key === 'daemonSFTP') ? 'daemonSftp' : $key;
|
$key = ($key === 'daemon_sftp') ? 'daemon_sftp' : $key;
|
||||||
|
|
||||||
return [snake_case($key) => $value];
|
return [snake_case($key) => $value];
|
||||||
})->toArray();
|
})->toArray();
|
||||||
|
@ -52,7 +52,7 @@ class ServerTransformer extends BaseTransformer
|
|||||||
'id' => $server->getKey(),
|
'id' => $server->getKey(),
|
||||||
'external_id' => $server->external_id,
|
'external_id' => $server->external_id,
|
||||||
'uuid' => $server->uuid,
|
'uuid' => $server->uuid,
|
||||||
'identifier' => $server->uuidShort,
|
'identifier' => $server->uuid_short,
|
||||||
'name' => $server->name,
|
'name' => $server->name,
|
||||||
'description' => $server->description,
|
'description' => $server->description,
|
||||||
'status' => $server->status,
|
'status' => $server->status,
|
||||||
|
@ -38,7 +38,7 @@ class ServerTransformer extends BaseClientTransformer
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'server_owner' => $user->id === $server->owner_id,
|
'server_owner' => $user->id === $server->owner_id,
|
||||||
'identifier' => $server->uuidShort,
|
'identifier' => $server->uuid_short,
|
||||||
'internal_id' => $server->id,
|
'internal_id' => $server->id,
|
||||||
'uuid' => $server->uuid,
|
'uuid' => $server->uuid,
|
||||||
'name' => $server->name,
|
'name' => $server->name,
|
||||||
@ -46,7 +46,7 @@ class ServerTransformer extends BaseClientTransformer
|
|||||||
'is_node_under_maintenance' => $server->node->isUnderMaintenance(),
|
'is_node_under_maintenance' => $server->node->isUnderMaintenance(),
|
||||||
'sftp_details' => [
|
'sftp_details' => [
|
||||||
'ip' => $server->node->fqdn,
|
'ip' => $server->node->fqdn,
|
||||||
'port' => $server->node->daemonSFTP,
|
'port' => $server->node->daemon_sftp,
|
||||||
],
|
],
|
||||||
'description' => $server->description,
|
'description' => $server->description,
|
||||||
'limits' => [
|
'limits' => [
|
||||||
|
@ -36,9 +36,9 @@ class NodeFactory extends Factory
|
|||||||
'upload_size' => 100,
|
'upload_size' => 100,
|
||||||
'daemon_token_id' => Str::random(Node::DAEMON_TOKEN_ID_LENGTH),
|
'daemon_token_id' => Str::random(Node::DAEMON_TOKEN_ID_LENGTH),
|
||||||
'daemon_token' => Crypt::encrypt(Str::random(Node::DAEMON_TOKEN_LENGTH)),
|
'daemon_token' => Crypt::encrypt(Str::random(Node::DAEMON_TOKEN_LENGTH)),
|
||||||
'daemonListen' => 8080,
|
'daemon_listen' => 8080,
|
||||||
'daemonSFTP' => 2022,
|
'daemon_sftp' => 2022,
|
||||||
'daemonBase' => '/var/lib/pelican/volumes',
|
'daemon_base' => '/var/lib/panel/volumes',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class ServerFactory extends Factory
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'uuid' => Uuid::uuid4()->toString(),
|
'uuid' => Uuid::uuid4()->toString(),
|
||||||
'uuidShort' => Str::lower(Str::random(8)),
|
'uuid_short' => Str::lower(Str::random(8)),
|
||||||
'name' => $this->faker->firstName(),
|
'name' => $this->faker->firstName(),
|
||||||
'description' => implode(' ', $this->faker->sentences()),
|
'description' => implode(' ', $this->faker->sentences()),
|
||||||
'skip_scripts' => 0,
|
'skip_scripts' => 0,
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('nodes', function (Blueprint $table) {
|
||||||
|
$table->string('daemonBase', 191)->default(null)->change();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('nodes', function (Blueprint $table) {
|
||||||
|
$table->renameColumn('daemonListen', 'daemon_listen');
|
||||||
|
$table->renameColumn('daemonBase', 'daemon_base');
|
||||||
|
$table->renameColumn('daemonSFTP', 'daemon_sftp');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->renameColumn('uuidShort', 'uuid_short');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('nodes', function (Blueprint $table) {
|
||||||
|
$table->renameColumn('daemon_listen', 'daemonListen');
|
||||||
|
$table->renameColumn('daemon_sftp', 'daemonSFTP');
|
||||||
|
$table->renameColumn('daemon_base', 'daemonBase');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('servers', function (Blueprint $table) {
|
||||||
|
$table->renameColumn('uuid_short', 'uuidShort');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -133,10 +133,10 @@
|
|||||||
"clean": "cd public/assets && find . \\( -name \"*.js\" -o -name \"*.map\" \\) -type f -delete",
|
"clean": "cd public/assets && find . \\( -name \"*.js\" -o -name \"*.map\" \\) -type f -delete",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"lint": "eslint ./resources/scripts/**/*.{ts,tsx} --ext .ts,.tsx",
|
"lint": "eslint ./resources/scripts/**/*.{ts,tsx} --ext .ts,.tsx",
|
||||||
"watch": "cross-env NODE_ENV=development ./node_modules/.bin/webpack --watch --progress",
|
"watch": "cross-env NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=development ./node_modules/.bin/webpack --watch --progress",
|
||||||
"build": "cross-env NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=development ./node_modules/.bin/webpack --progress",
|
"build": "cross-env NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=development ./node_modules/.bin/webpack --progress",
|
||||||
"build:production": "yarn run clean && cross-env NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=production ./node_modules/.bin/webpack --mode production",
|
"build:production": "yarn run clean && cross-env NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=production ./node_modules/.bin/webpack --mode production",
|
||||||
"serve": "yarn run clean && cross-env WEBPACK_PUBLIC_PATH=/webpack@hmr/ NODE_ENV=development webpack-dev-server --host 0.0.0.0 --port 8080 --public https://panel.test --hot"
|
"serve": "yarn run clean && cross-env WEBPACK_PUBLIC_PATH=/webpack@hmr/ NODE_OPTIONS='--openssl-legacy-provider' NODE_ENV=development webpack-dev-server --host 0.0.0.0 --port 8080 --public https://panel.test --hot"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 0.5%",
|
"> 0.5%",
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
@foreach ($nodes as $node)
|
@foreach ($nodes as $node)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center text-muted left-icon" data-action="ping" data-secret="{{ $node->getDecryptedKey() }}" data-location="{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/api/system"><i class="fa fa-fw fa-refresh fa-spin"></i></td>
|
<td class="text-center text-muted left-icon" data-action="ping" data-secret="{{ $node->getDecryptedKey() }}" data-location="{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemon_listen }}/api/system"><i class="fa fa-fw fa-refresh fa-spin"></i></td>
|
||||||
<td>{!! $node->maintenance_mode ? '<span class="label label-warning"><i class="fa fa-wrench"></i></span> ' : '' !!}<a href="{{ route('admin.nodes.view', $node->id) }}">{{ $node->name }}</a></td>
|
<td>{!! $node->maintenance_mode ? '<span class="label label-warning"><i class="fa fa-wrench"></i></span> ' : '' !!}<a href="{{ route('admin.nodes.view', $node->id) }}">{{ $node->name }}</a></td>
|
||||||
<td>{{ $node->memory }} MiB</td>
|
<td>{{ $node->memory }} MiB</td>
|
||||||
<td>{{ $node->disk }} MiB</td>
|
<td>{{ $node->disk }} MiB</td>
|
||||||
|
@ -94,8 +94,8 @@
|
|||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label for="pDaemonBase" class="form-label">Daemon Server File Directory</label>
|
<label for="pdaemon_base" class="form-label">Daemon Server File Directory</label>
|
||||||
<input type="text" name="daemonBase" id="pDaemonBase" class="form-control" value="/var/lib/pelican/volumes" />
|
<input type="text" name="daemon_base" id="pdaemon_base" class="form-control" value="/var/lib/pelican/volumes" />
|
||||||
<p class="text-muted small">Enter the directory where server files should be stored. <strong>If you use OVH you should check your partition scheme. You may need to use <code>/home/daemon-data</code> to have enough space.</strong></p>
|
<p class="text-muted small">Enter the directory where server files should be stored. <strong>If you use OVH you should check your partition scheme. You may need to use <code>/home/daemon-data</code> to have enough space.</strong></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
@ -137,12 +137,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label for="pDaemonListen" class="form-label">Daemon Port</label>
|
<label for="pdaemon_listen" class="form-label">Daemon Port</label>
|
||||||
<input type="text" name="daemonListen" class="form-control" id="pDaemonListen" value="8080" />
|
<input type="text" name="daemon_listen" class="form-control" id="pdaemon_listen" value="8080" />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label for="pDaemonSFTP" class="form-label">Daemon SFTP Port</label>
|
<label for="pdaemon_sftp" class="form-label">Daemon SFTP Port</label>
|
||||||
<input type="text" name="daemonSFTP" class="form-control" id="pDaemonSFTP" value="2022" />
|
<input type="text" name="daemon_sftp" class="form-control" id="pdaemon_sftp" value="2022" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<p class="text-muted small">The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. <Strong>Do not use the same port that you have assigned for your physical server's SSH process.</strong> If you will be running the daemon behind CloudFlare® you should set the daemon port to <code>8443</code> to allow websocket proxying over SSL.</p>
|
<p class="text-muted small">The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server. <Strong>Do not use the same port that you have assigned for your physical server's SSH process.</strong> If you will be running the daemon behind CloudFlare® you should set the daemon port to <code>8443</code> to allow websocket proxying over SSL.</p>
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
</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->uuid_short }}</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><a href="{{ route('admin.eggs.view', $server->egg) }}">{{ $server->egg->name }}</a></td>
|
<td><a href="{{ route('admin.eggs.view', $server->egg) }}">{{ $server->egg->name }}</a></td>
|
||||||
|
@ -174,15 +174,15 @@
|
|||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label for="daemonListen" class="control-label"><span class="label label-warning"><i class="fa fa-power-off"></i></span> Daemon Port</label>
|
<label for="daemon_listen" class="control-label"><span class="label label-warning"><i class="fa fa-power-off"></i></span> Daemon Port</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" name="daemonListen" class="form-control" value="{{ old('daemonListen', $node->daemonListen) }}"/>
|
<input type="text" name="daemon_listen" class="form-control" value="{{ old('daemon_listen', $node->daemon_listen) }}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-6">
|
<div class="form-group col-md-6">
|
||||||
<label for="daemonSFTP" class="control-label"><span class="label label-warning"><i class="fa fa-power-off"></i></span> Daemon SFTP Port</label>
|
<label for="daemon_sftp" class="control-label"><span class="label label-warning"><i class="fa fa-power-off"></i></span> Daemon SFTP Port</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" name="daemonSFTP" class="form-control" value="{{ old('daemonSFTP', $node->daemonSFTP) }}"/>
|
<input type="text" name="daemon_sftp" class="form-control" value="{{ old('daemon_sftp', $node->daemon_sftp) }}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach ($servers as $server)
|
@foreach ($servers as $server)
|
||||||
<tr data-server="{{ $server->uuidShort }}">
|
<tr data-server="{{ $server->uuid_short }}">
|
||||||
<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><code title="{{ $server->uuid }}">{{ $server->uuid }}</code></td>
|
<td><code title="{{ $server->uuid }}">{{ $server->uuid }}</code></td>
|
||||||
<td><a href="{{ route('admin.users.view', $server->user->id) }}">{{ $server->user->username }}</a></td>
|
<td><a href="{{ route('admin.users.view', $server->user->id) }}">{{ $server->user->username }}</a></td>
|
||||||
@ -61,7 +61,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a class="btn btn-xs btn-default" href="/server/{{ $server->uuidShort }}"><i class="fa fa-wrench"></i></a>
|
<a class="btn btn-xs btn-default" href="/server/{{ $server->uuid_short }}"><i class="fa fa-wrench"></i></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<a href="{{ route('admin.servers.view.delete', $server->id) }}">Delete</a>
|
<a href="{{ route('admin.servers.view.delete', $server->id) }}">Delete</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="tab-success">
|
<li class="tab-success">
|
||||||
<a href="/server/{{ $server->uuidShort }}" target="_blank"><i class="fa fa-external-link"></i></a>
|
<a href="/server/{{ $server->uuid_short }}" target="_blank"><i class="fa fa-external-link"></i></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-7">
|
<div class="col-sm-7">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
Database passwords can be viewed when <a href="/server/{{ $server->uuidShort }}/databases">visiting this server</a> on the front-end.
|
Database passwords can be viewed when <a href="/server/{{ $server->uuid_short }}/databases">visiting this server</a> on the front-end.
|
||||||
</div>
|
</div>
|
||||||
<div class="box box-primary">
|
<div class="box box-primary">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
|
@ -33,7 +33,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
|
|||||||
$response->assertOk();
|
$response->assertOk();
|
||||||
$response->assertJsonPath('object', 'list');
|
$response->assertJsonPath('object', 'list');
|
||||||
$response->assertJsonPath('data.0.object', Server::RESOURCE_NAME);
|
$response->assertJsonPath('data.0.object', Server::RESOURCE_NAME);
|
||||||
$response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuidShort);
|
$response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuid_short);
|
||||||
$response->assertJsonPath('data.0.attributes.server_owner', true);
|
$response->assertJsonPath('data.0.attributes.server_owner', true);
|
||||||
$response->assertJsonPath('meta.pagination.total', 1);
|
$response->assertJsonPath('meta.pagination.total', 1);
|
||||||
$response->assertJsonPath('meta.pagination.per_page', 50);
|
$response->assertJsonPath('meta.pagination.per_page', 50);
|
||||||
@ -52,7 +52,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
|
|||||||
/** @var \App\Models\Server[] $servers */
|
/** @var \App\Models\Server[] $servers */
|
||||||
$servers = [
|
$servers = [
|
||||||
$this->createServerModel(['user_id' => $users[0]->id, 'name' => 'Julia']),
|
$this->createServerModel(['user_id' => $users[0]->id, 'name' => 'Julia']),
|
||||||
$this->createServerModel(['user_id' => $users[1]->id, 'uuidShort' => '12121212', 'name' => 'Janice']),
|
$this->createServerModel(['user_id' => $users[1]->id, 'uuid_short' => '12121212', 'name' => 'Janice']),
|
||||||
$this->createServerModel(['user_id' => $users[1]->id, 'uuid' => '88788878-12356789', 'external_id' => 'ext123', 'name' => 'Julia']),
|
$this->createServerModel(['user_id' => $users[1]->id, 'uuid' => '88788878-12356789', 'external_id' => 'ext123', 'name' => 'Julia']),
|
||||||
$this->createServerModel(['user_id' => $users[1]->id, 'uuid' => '88788878-abcdefgh', 'name' => 'Jennifer']),
|
$this->createServerModel(['user_id' => $users[1]->id, 'uuid' => '88788878-abcdefgh', 'name' => 'Jennifer']),
|
||||||
];
|
];
|
||||||
@ -60,39 +60,39 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
|
|||||||
$this->actingAs($users[1])->getJson('/api/client?filter[*]=Julia')
|
$this->actingAs($users[1])->getJson('/api/client?filter[*]=Julia')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(1, 'data')
|
->assertJsonCount(1, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuidShort);
|
->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($users[1])->getJson('/api/client?filter[*]=ext123')
|
$this->actingAs($users[1])->getJson('/api/client?filter[*]=ext123')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(1, 'data')
|
->assertJsonCount(1, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuidShort);
|
->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($users[1])->getJson('/api/client?filter[*]=ext123')
|
$this->actingAs($users[1])->getJson('/api/client?filter[*]=ext123')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(1, 'data')
|
->assertJsonCount(1, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuidShort);
|
->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($users[1])->getJson('/api/client?filter[*]=12121212')
|
$this->actingAs($users[1])->getJson('/api/client?filter[*]=12121212')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(1, 'data')
|
->assertJsonCount(1, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $servers[1]->uuidShort);
|
->assertJsonPath('data.0.attributes.identifier', $servers[1]->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($users[1])->getJson('/api/client?filter[*]=88788878')
|
$this->actingAs($users[1])->getJson('/api/client?filter[*]=88788878')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(2, 'data')
|
->assertJsonCount(2, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuidShort)
|
->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short)
|
||||||
->assertJsonPath('data.1.attributes.identifier', $servers[3]->uuidShort);
|
->assertJsonPath('data.1.attributes.identifier', $servers[3]->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($users[1])->getJson('/api/client?filter[*]=88788878-abcd')
|
$this->actingAs($users[1])->getJson('/api/client?filter[*]=88788878-abcd')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(1, 'data')
|
->assertJsonCount(1, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $servers[3]->uuidShort);
|
->assertJsonPath('data.0.attributes.identifier', $servers[3]->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($users[0])->getJson('/api/client?filter[*]=Julia&type=admin-all')
|
$this->actingAs($users[0])->getJson('/api/client?filter[*]=Julia&type=admin-all')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(2, 'data')
|
->assertJsonCount(2, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuidShort)
|
->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuid_short)
|
||||||
->assertJsonPath('data.1.attributes.identifier', $servers[2]->uuidShort);
|
->assertJsonPath('data.1.attributes.identifier', $servers[2]->uuid_short);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,24 +118,24 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
|
|||||||
$this->actingAs($user)->getJson('/api/client?filter[*]=192.168.1.1')
|
$this->actingAs($user)->getJson('/api/client?filter[*]=192.168.1.1')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(2, 'data')
|
->assertJsonCount(2, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $server->uuidShort)
|
->assertJsonPath('data.0.attributes.identifier', $server->uuid_short)
|
||||||
->assertJsonPath('data.1.attributes.identifier', $server2->uuidShort);
|
->assertJsonPath('data.1.attributes.identifier', $server2->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($user)->getJson('/api/client?filter[*]=192.168.1.1:25565')
|
$this->actingAs($user)->getJson('/api/client?filter[*]=192.168.1.1:25565')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(1, 'data')
|
->assertJsonCount(1, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $server->uuidShort);
|
->assertJsonPath('data.0.attributes.identifier', $server->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($user)->getJson('/api/client?filter[*]=:25570')
|
$this->actingAs($user)->getJson('/api/client?filter[*]=:25570')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(1, 'data')
|
->assertJsonCount(1, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $server2->uuidShort);
|
->assertJsonPath('data.0.attributes.identifier', $server2->uuid_short);
|
||||||
|
|
||||||
$this->actingAs($user)->getJson('/api/client?filter[*]=:255')
|
$this->actingAs($user)->getJson('/api/client?filter[*]=:255')
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertJsonCount(2, 'data')
|
->assertJsonCount(2, 'data')
|
||||||
->assertJsonPath('data.0.attributes.identifier', $server->uuidShort)
|
->assertJsonPath('data.0.attributes.identifier', $server->uuid_short)
|
||||||
->assertJsonPath('data.1.attributes.identifier', $server2->uuidShort);
|
->assertJsonPath('data.1.attributes.identifier', $server2->uuid_short);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,9 +164,9 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
|
|||||||
$response->assertOk();
|
$response->assertOk();
|
||||||
$response->assertJsonCount(2, 'data');
|
$response->assertJsonCount(2, 'data');
|
||||||
$response->assertJsonPath('data.0.attributes.server_owner', true);
|
$response->assertJsonPath('data.0.attributes.server_owner', true);
|
||||||
$response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuidShort);
|
$response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuid_short);
|
||||||
$response->assertJsonPath('data.1.attributes.server_owner', false);
|
$response->assertJsonPath('data.1.attributes.server_owner', false);
|
||||||
$response->assertJsonPath('data.1.attributes.identifier', $servers[1]->uuidShort);
|
$response->assertJsonPath('data.1.attributes.identifier', $servers[1]->uuid_short);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,7 +195,7 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
|
|||||||
$response->assertOk();
|
$response->assertOk();
|
||||||
$response->assertJsonCount(1, 'data');
|
$response->assertJsonCount(1, 'data');
|
||||||
$response->assertJsonPath('data.0.attributes.server_owner', true);
|
$response->assertJsonPath('data.0.attributes.server_owner', true);
|
||||||
$response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuidShort);
|
$response->assertJsonPath('data.0.attributes.identifier', $servers[0]->uuid_short);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -248,9 +248,9 @@ class ClientControllerTest extends ClientApiIntegrationTestCase
|
|||||||
$response->assertJsonCount(2, 'data');
|
$response->assertJsonCount(2, 'data');
|
||||||
|
|
||||||
$response->assertJsonPath('data.0.attributes.server_owner', false);
|
$response->assertJsonPath('data.0.attributes.server_owner', false);
|
||||||
$response->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuidShort);
|
$response->assertJsonPath('data.0.attributes.identifier', $servers[2]->uuid_short);
|
||||||
$response->assertJsonPath('data.1.attributes.server_owner', false);
|
$response->assertJsonPath('data.1.attributes.server_owner', false);
|
||||||
$response->assertJsonPath('data.1.attributes.identifier', $servers[3]->uuidShort);
|
$response->assertJsonPath('data.1.attributes.identifier', $servers[3]->uuid_short);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,7 +142,7 @@ class SftpAuthenticationControllerTest extends IntegrationTestCase
|
|||||||
$this->setAuthorization($server->node);
|
$this->setAuthorization($server->node);
|
||||||
|
|
||||||
$this->postJson('/api/remote/sftp/auth', [
|
$this->postJson('/api/remote/sftp/auth', [
|
||||||
'username' => $user->username . '.' . $server->uuidShort,
|
'username' => $user->username . '.' . $server->uuid_short,
|
||||||
'password' => 'foobar',
|
'password' => 'foobar',
|
||||||
])
|
])
|
||||||
->assertForbidden()
|
->assertForbidden()
|
||||||
@ -172,7 +172,7 @@ class SftpAuthenticationControllerTest extends IntegrationTestCase
|
|||||||
$this->setAuthorization($server->node);
|
$this->setAuthorization($server->node);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'username' => $user->username . '.' . $server->uuidShort,
|
'username' => $user->username . '.' . $server->uuid_short,
|
||||||
'password' => 'foobar',
|
'password' => 'foobar',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ class SftpAuthenticationControllerTest extends IntegrationTestCase
|
|||||||
->assertJsonPath('permissions.0', '*');
|
->assertJsonPath('permissions.0', '*');
|
||||||
|
|
||||||
$this->setAuthorization();
|
$this->setAuthorization();
|
||||||
$data['username'] = $user->username . '.' . $this->server->uuidShort;
|
$data['username'] = $user->username . '.' . $this->server->uuid_short;
|
||||||
|
|
||||||
$this->post('/api/remote/sftp/auth', $data)
|
$this->post('/api/remote/sftp/auth', $data)
|
||||||
->assertOk()
|
->assertOk()
|
||||||
@ -219,7 +219,7 @@ class SftpAuthenticationControllerTest extends IntegrationTestCase
|
|||||||
*/
|
*/
|
||||||
protected function getUsername(bool $long = false): string
|
protected function getUsername(bool $long = false): string
|
||||||
{
|
{
|
||||||
return $this->user->username . '.' . ($long ? $this->server->uuid : $this->server->uuidShort);
|
return $this->user->username . '.' . ($long ? $this->server->uuid : $this->server->uuid_short);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,7 +118,7 @@ class ServerCreationServiceTest extends IntegrationTestCase
|
|||||||
|
|
||||||
$this->assertInstanceOf(Server::class, $response);
|
$this->assertInstanceOf(Server::class, $response);
|
||||||
$this->assertNotNull($response->uuid);
|
$this->assertNotNull($response->uuid);
|
||||||
$this->assertSame($response->uuidShort, substr($response->uuid, 0, 8));
|
$this->assertSame($response->uuid_short, substr($response->uuid, 0, 8));
|
||||||
$this->assertSame($egg->id, $response->egg_id);
|
$this->assertSame($egg->id, $response->egg_id);
|
||||||
$this->assertCount(2, $response->variables);
|
$this->assertCount(2, $response->variables);
|
||||||
$this->assertSame('123', $response->variables[0]->server_value);
|
$this->assertSame('123', $response->variables[0]->server_value);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user