mirror of
https://github.com/pelican-dev/panel.git
synced 2025-05-20 20:24:44 +02:00
Add Create Database btn on admin side (#721)
* Add Create Database btn on admin side * Remove unused function * readd function * replace refreshform function * add authorize, remove database limit check * add random words, use proper name function, catch exceptions on creation * add validation, match old client area more * Add more authorize to Database tab * Add confirmation to delete * make password hidden / revealable * better clarification * Set default and remove placeholder. * Remove server import, add database model to auth * Make same changes for the database host page * Update app/Filament/Resources/ServerResource/Pages/EditServer.php Co-authored-by: Boy132 <Boy132@users.noreply.github.com> * Update app/Filament/Resources/DatabaseHostResource/RelationManagers/DatabasesRelationManager.php Co-authored-by: Boy132 <Boy132@users.noreply.github.com> * Update app/Filament/Resources/DatabaseHostResource/RelationManagers/DatabasesRelationManager.php Co-authored-by: Boy132 <Boy132@users.noreply.github.com> * Remove each hidden * Return nothing if user has no perms * This is the way... Im done messing with it... * Fix view permission for relationship manager * Update app/Filament/Resources/DatabaseHostResource/RelationManagers/DatabasesRelationManager.php * Pint --------- Co-authored-by: Boy132 <Boy132@users.noreply.github.com> Co-authored-by: MartinOscar <40749467+RMartinOscar@users.noreply.github.com>
This commit is contained in:
parent
b208835ed4
commit
cd448cd9a7
@ -101,9 +101,13 @@ class EditDatabaseHost extends EditRecord
|
|||||||
|
|
||||||
public function getRelationManagers(): array
|
public function getRelationManagers(): array
|
||||||
{
|
{
|
||||||
return [
|
if (DatabasesRelationManager::canViewForRecord($this->getRecord(), static::class)) {
|
||||||
DatabasesRelationManager::class,
|
return [
|
||||||
];
|
DatabasesRelationManager::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function handleRecordUpdate(Model $record, array $data): Model
|
protected function handleRecordUpdate(Model $record, array $data): Model
|
||||||
|
@ -24,21 +24,30 @@ class DatabasesRelationManager extends RelationManager
|
|||||||
{
|
{
|
||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema([
|
||||||
TextInput::make('database')->columnSpanFull(),
|
TextInput::make('database')
|
||||||
|
->columnSpanFull(),
|
||||||
TextInput::make('username'),
|
TextInput::make('username'),
|
||||||
TextInput::make('password')
|
TextInput::make('password')
|
||||||
|
->password()
|
||||||
|
->revealable()
|
||||||
->hintAction(
|
->hintAction(
|
||||||
Action::make('rotate')
|
Action::make('rotate')
|
||||||
->icon('tabler-refresh')
|
->icon('tabler-refresh')
|
||||||
->requiresConfirmation()
|
->requiresConfirmation()
|
||||||
->action(fn (DatabasePasswordService $service, Database $database, $set, $get) => $this->rotatePassword($service, $database, $set, $get))
|
->action(fn (DatabasePasswordService $service, Database $database, $set, $get) => $this->rotatePassword($service, $database, $set, $get))
|
||||||
|
->authorize(fn (Database $database) => auth()->user()->can('update database', $database))
|
||||||
)
|
)
|
||||||
->formatStateUsing(fn (Database $database) => $database->password),
|
->formatStateUsing(fn (Database $database) => $database->password),
|
||||||
TextInput::make('remote')->label('Connections From'),
|
TextInput::make('remote')
|
||||||
TextInput::make('max_connections'),
|
->label('Connections From')
|
||||||
|
->formatStateUsing(fn ($record) => $record->remote === '%' ? 'Anywhere ( % )' : $record->remote),
|
||||||
|
TextInput::make('max_connections')
|
||||||
|
->formatStateUsing(fn ($record) => $record->max_connections === 0 ? 'Unlimited' : $record->max_connections),
|
||||||
TextInput::make('JDBC')
|
TextInput::make('JDBC')
|
||||||
->label('JDBC Connection String')
|
->label('JDBC Connection String')
|
||||||
->columnSpanFull()
|
->columnSpanFull()
|
||||||
|
->password()
|
||||||
|
->revealable()
|
||||||
->formatStateUsing(fn (Get $get, Database $database) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($database->password) . '@' . $database->host->host . ':' . $database->host->port . '/' . $get('database')),
|
->formatStateUsing(fn (Get $get, Database $database) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($database->password) . '@' . $database->host->host . ':' . $database->host->port . '/' . $get('database')),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -48,18 +57,25 @@ class DatabasesRelationManager extends RelationManager
|
|||||||
return $table
|
return $table
|
||||||
->recordTitleAttribute('servers')
|
->recordTitleAttribute('servers')
|
||||||
->columns([
|
->columns([
|
||||||
TextColumn::make('database')->icon('tabler-database'),
|
TextColumn::make('database')
|
||||||
TextColumn::make('username')->icon('tabler-user'),
|
->icon('tabler-database'),
|
||||||
TextColumn::make('remote'),
|
TextColumn::make('username')
|
||||||
|
->icon('tabler-user'),
|
||||||
|
TextColumn::make('remote')
|
||||||
|
->formatStateUsing(fn ($record) => $record->remote === '%' ? 'Anywhere ( % )' : $record->remote),
|
||||||
TextColumn::make('server.name')
|
TextColumn::make('server.name')
|
||||||
->icon('tabler-brand-docker')
|
->icon('tabler-brand-docker')
|
||||||
->url(fn (Database $database) => route('filament.admin.resources.servers.edit', ['record' => $database->server_id])),
|
->url(fn (Database $database) => route('filament.admin.resources.servers.edit', ['record' => $database->server_id])),
|
||||||
TextColumn::make('max_connections'),
|
TextColumn::make('max_connections')
|
||||||
|
->formatStateUsing(fn ($record) => $record->max_connections === 0 ? 'Unlimited' : $record->max_connections),
|
||||||
DateTimeColumn::make('created_at'),
|
DateTimeColumn::make('created_at'),
|
||||||
])
|
])
|
||||||
->actions([
|
->actions([
|
||||||
DeleteAction::make(),
|
DeleteAction::make()
|
||||||
ViewAction::make()->color('primary'),
|
->authorize(fn (Database $database) => auth()->user()->can('delete database', $database)),
|
||||||
|
ViewAction::make()
|
||||||
|
->color('primary')
|
||||||
|
->hidden(fn () => !auth()->user()->can('viewList database')),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ use App\Enums\ServerState;
|
|||||||
use App\Filament\Resources\ServerResource;
|
use App\Filament\Resources\ServerResource;
|
||||||
use App\Filament\Resources\ServerResource\RelationManagers\AllocationsRelationManager;
|
use App\Filament\Resources\ServerResource\RelationManagers\AllocationsRelationManager;
|
||||||
use App\Models\Database;
|
use App\Models\Database;
|
||||||
|
use App\Models\DatabaseHost;
|
||||||
use App\Models\Egg;
|
use App\Models\Egg;
|
||||||
use App\Models\Mount;
|
use App\Models\Mount;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
@ -608,7 +609,9 @@ class EditServer extends EditRecord
|
|||||||
->columnSpanFull(),
|
->columnSpanFull(),
|
||||||
]),
|
]),
|
||||||
Tab::make('Databases')
|
Tab::make('Databases')
|
||||||
|
->hidden(fn () => !auth()->user()->can('viewList database'))
|
||||||
->icon('tabler-database')
|
->icon('tabler-database')
|
||||||
|
->columns(4)
|
||||||
->schema([
|
->schema([
|
||||||
Repeater::make('databases')
|
Repeater::make('databases')
|
||||||
->grid()
|
->grid()
|
||||||
@ -622,35 +625,50 @@ class EditServer extends EditRecord
|
|||||||
->formatStateUsing(fn ($record) => $record->database)
|
->formatStateUsing(fn ($record) => $record->database)
|
||||||
->hintAction(
|
->hintAction(
|
||||||
Action::make('Delete')
|
Action::make('Delete')
|
||||||
|
->authorize(fn (Database $database) => auth()->user()->can('delete database', $database))
|
||||||
->color('danger')
|
->color('danger')
|
||||||
->icon('tabler-trash')
|
->icon('tabler-trash')
|
||||||
->action(fn (DatabaseManagementService $databaseManagementService, $record) => $databaseManagementService->delete($record))
|
->requiresConfirmation()
|
||||||
|
->modalIcon('tabler-database-x')
|
||||||
|
->modalHeading('Delete Database?')
|
||||||
|
->modalSubmitActionLabel(fn (Get $get) => 'Delete ' . $get('database') . '?')
|
||||||
|
->modalDescription(fn (Get $get) => 'Are you sure you want to delete ' . $get('database') . '?')
|
||||||
|
->action(function (DatabaseManagementService $databaseManagementService, $record) {
|
||||||
|
$databaseManagementService->delete($record);
|
||||||
|
$this->fillForm();
|
||||||
|
})
|
||||||
),
|
),
|
||||||
TextInput::make('username')
|
TextInput::make('username')
|
||||||
->disabled()
|
->disabled()
|
||||||
->formatStateUsing(fn ($record) => $record->username)
|
->formatStateUsing(fn ($record) => $record->username)
|
||||||
->columnSpan(2),
|
->columnSpan(1),
|
||||||
TextInput::make('password')
|
TextInput::make('password')
|
||||||
->disabled()
|
->disabled()
|
||||||
|
->password()
|
||||||
|
->revealable()
|
||||||
|
->columnSpan(1)
|
||||||
->hintAction(
|
->hintAction(
|
||||||
Action::make('rotate')
|
Action::make('rotate')
|
||||||
|
->authorize(fn (Database $database) => auth()->user()->can('update database', $database))
|
||||||
->icon('tabler-refresh')
|
->icon('tabler-refresh')
|
||||||
->requiresConfirmation()
|
->modalHeading('Change Database Password?')
|
||||||
->action(fn (DatabasePasswordService $service, $record, $set, $get) => $this->rotatePassword($service, $record, $set, $get))
|
->action(fn (DatabasePasswordService $service, $record, $set, $get) => $this->rotatePassword($service, $record, $set, $get))
|
||||||
|
->requiresConfirmation()
|
||||||
)
|
)
|
||||||
->formatStateUsing(fn (Database $database) => $database->password)
|
->formatStateUsing(fn (Database $database) => $database->password),
|
||||||
->columnSpan(2),
|
|
||||||
TextInput::make('remote')
|
TextInput::make('remote')
|
||||||
->disabled()
|
->disabled()
|
||||||
->formatStateUsing(fn ($record) => $record->remote)
|
->formatStateUsing(fn ($record) => $record->remote === '%' ? 'Anywhere ( % )' : $record->remote)
|
||||||
->columnSpan(1)
|
->columnSpan(1)
|
||||||
->label('Connections From'),
|
->label('Connections From'),
|
||||||
TextInput::make('max_connections')
|
TextInput::make('max_connections')
|
||||||
->disabled()
|
->disabled()
|
||||||
->formatStateUsing(fn ($record) => $record->max_connections)
|
->formatStateUsing(fn ($record) => $record->max_connections === 0 ? 'Unlimited' : $record->max_connections)
|
||||||
->columnSpan(1),
|
->columnSpan(1),
|
||||||
TextInput::make('JDBC')
|
TextInput::make('JDBC')
|
||||||
->disabled()
|
->disabled()
|
||||||
|
->password()
|
||||||
|
->revealable()
|
||||||
->label('JDBC Connection String')
|
->label('JDBC Connection String')
|
||||||
->columnSpan(2)
|
->columnSpan(2)
|
||||||
->formatStateUsing(fn (Get $get, $record) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($record->password) . '@' . $record->host->host . ':' . $record->host->port . '/' . $get('database')),
|
->formatStateUsing(fn (Get $get, $record) => 'jdbc:mysql://' . $get('username') . ':' . urlencode($record->password) . '@' . $record->host->host . ':' . $record->host->port . '/' . $get('database')),
|
||||||
@ -659,7 +677,57 @@ class EditServer extends EditRecord
|
|||||||
->deletable(false)
|
->deletable(false)
|
||||||
->addable(false)
|
->addable(false)
|
||||||
->columnSpan(4),
|
->columnSpan(4),
|
||||||
])->columns(4),
|
Forms\Components\Actions::make([
|
||||||
|
Action::make('createDatabase')
|
||||||
|
->authorize(fn () => auth()->user()->can('create database'))
|
||||||
|
->disabled(fn () => DatabaseHost::query()->count() < 1)
|
||||||
|
->label(fn () => DatabaseHost::query()->count() < 1 ? 'No Database Hosts' : 'Create Database')
|
||||||
|
->color(fn () => DatabaseHost::query()->count() < 1 ? 'danger' : 'primary')
|
||||||
|
->modalSubmitActionLabel('Create Database')
|
||||||
|
->action(function (array $data, DatabaseManagementService $service, Server $server, RandomWordService $randomWordService) {
|
||||||
|
if (empty($data['database'])) {
|
||||||
|
$data['database'] = $randomWordService->word() . random_int(1, 420);
|
||||||
|
}
|
||||||
|
if (empty($data['remote'])) {
|
||||||
|
$data['remote'] = '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['database'] = $service->generateUniqueDatabaseName($data['database'], $server->id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$service->setValidateDatabaseLimit(false)->create($server, $data);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Failed to Create Database')
|
||||||
|
->body($e->getMessage())
|
||||||
|
->danger()
|
||||||
|
->persistent()->send();
|
||||||
|
}
|
||||||
|
$this->fillForm();
|
||||||
|
})
|
||||||
|
->form([
|
||||||
|
Select::make('database_host_id')
|
||||||
|
->label('Database Host')
|
||||||
|
->required()
|
||||||
|
->placeholder('Select Database Host')
|
||||||
|
->relationship('node.databaseHosts', 'name')
|
||||||
|
->default(fn () => (DatabaseHost::query()->first())?->id)
|
||||||
|
->selectablePlaceholder(false),
|
||||||
|
TextInput::make('database')
|
||||||
|
->label('Database Name')
|
||||||
|
->alphaDash()
|
||||||
|
->prefix(fn (Server $server) => 's' . $server->id . '_')
|
||||||
|
->hintIcon('tabler-question-mark')
|
||||||
|
->hintIconTooltip('Leaving this blank will auto generate a random name'),
|
||||||
|
TextInput::make('remote')
|
||||||
|
->columnSpan(1)
|
||||||
|
->regex('/^[\w\-\/.%:]+$/')
|
||||||
|
->label('Connections From')
|
||||||
|
->hintIcon('tabler-question-mark')
|
||||||
|
->hintIconTooltip('Where connections should be allowed from. Leave blank to allow connections from anywhere.'),
|
||||||
|
]),
|
||||||
|
])->alignCenter()->columnSpanFull(),
|
||||||
|
]),
|
||||||
Tab::make('Actions')
|
Tab::make('Actions')
|
||||||
->icon('tabler-settings')
|
->icon('tabler-settings')
|
||||||
->schema([
|
->schema([
|
||||||
|
@ -243,6 +243,11 @@ class Node extends Model
|
|||||||
return $this->hasMany(Allocation::class);
|
return $this->hasMany(Allocation::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function databaseHosts(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(DatabaseHost::class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a boolean if the node is viable for an additional server to be placed on it.
|
* Returns a boolean if the node is viable for an additional server to be placed on it.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user