Upgraded servers page to new mooncore version
This commit is contained in:
@@ -14,14 +14,14 @@ public class Server
|
|||||||
|
|
||||||
public string? OverrideStartupCommand { get; set; }
|
public string? OverrideStartupCommand { get; set; }
|
||||||
|
|
||||||
public int Cpu { get; set; }
|
public int Cpu { get; set; } = 100;
|
||||||
public int Memory { get; set; }
|
public int Memory { get; set; }
|
||||||
public int Disk { get; set; }
|
public int Disk { get; set; }
|
||||||
public bool UseVirtualDisk { get; set; }
|
public bool UseVirtualDisk { get; set; } = false;
|
||||||
|
|
||||||
public ServerNode Node { get; set; }
|
public ServerNode Node { get; set; }
|
||||||
public ServerNetwork? Network { get; set; }
|
public ServerNetwork? Network { get; set; }
|
||||||
public bool DisablePublicNetwork { get; set; }
|
public bool DisablePublicNetwork { get; set; } = false;
|
||||||
|
|
||||||
public ServerAllocation MainAllocation { get; set; }
|
public ServerAllocation MainAllocation { get; set; }
|
||||||
public List<ServerAllocation> Allocations { get; set; } = new();
|
public List<ServerAllocation> Allocations { get; set; } = new();
|
||||||
|
|||||||
@@ -1,33 +1,36 @@
|
|||||||
@page "/admin/servers"
|
@page "/admin/servers"
|
||||||
|
|
||||||
|
@using System.ComponentModel.DataAnnotations
|
||||||
@using Moonlight.Features.Servers.UI.Components
|
@using Moonlight.Features.Servers.UI.Components
|
||||||
@using Microsoft.EntityFrameworkCore
|
@using Microsoft.EntityFrameworkCore
|
||||||
@using MoonCore.Abstractions
|
@using MoonCore.Abstractions
|
||||||
|
@using MoonCore.Blazor.Extensions
|
||||||
|
@using MoonCore.Blazor.Forms.Fast.Components
|
||||||
|
@using MoonCore.Blazor.Models.Fast
|
||||||
@using MoonCore.Exceptions
|
@using MoonCore.Exceptions
|
||||||
|
@using Moonlight.Core.Database.Entities
|
||||||
|
|
||||||
@using Moonlight.Features.Servers.Entities
|
@using Moonlight.Features.Servers.Entities
|
||||||
@using Moonlight.Features.Servers.Models.Enums
|
@using Moonlight.Features.Servers.Models.Enums
|
||||||
@using Moonlight.Features.Servers.Models.Forms.Admin.Servers
|
|
||||||
@using Moonlight.Features.Servers.Services
|
@using Moonlight.Features.Servers.Services
|
||||||
|
|
||||||
@inject ServerService ServerService
|
@inject ServerService ServerService
|
||||||
@inject Repository<Server> ServerRepository
|
@inject Repository<Server> ServerRepository
|
||||||
|
@inject Repository<ServerAllocation> AllocRepository
|
||||||
@inject ToastService ToastService
|
@inject ToastService ToastService
|
||||||
|
@inject AlertService AlertService
|
||||||
@inject ILogger<Index> Logger
|
@inject ILogger<Index> Logger
|
||||||
|
|
||||||
@attribute [RequirePermission(5000)]
|
@attribute [RequirePermission(5000)]
|
||||||
|
|
||||||
<AdminServersNavigation Index="0"/>
|
<AdminServersNavigation Index="0"/>
|
||||||
@*
|
|
||||||
<AutoCrud TItem="Server"
|
<FastCrud TItem="Server"
|
||||||
TCreateForm="CreateServerForm"
|
Loader="Loader"
|
||||||
TUpdateForm="CreateServerForm"
|
OnConfigure="OnConfigure"
|
||||||
Loader="Load"
|
OnConfigureCreate="OnConfigureCreate"
|
||||||
CustomAdd="CustomAdd"
|
OnConfigureEdit="OnConfigureEdit"
|
||||||
CustomUpdate="CustomUpdate"
|
@ref="Crud">
|
||||||
ValidateUpdate="ValidateUpdate"
|
|
||||||
CustomDelete="CustomDelete"
|
|
||||||
OnConfigure="OnConfigure">
|
|
||||||
<View>
|
<View>
|
||||||
<MCBColumn TItem="Server" Field="@(x => x.Id)" Title="Id" Filterable="true"/>
|
<MCBColumn TItem="Server" Field="@(x => x.Id)" Title="Id" Filterable="true"/>
|
||||||
<MCBColumn TItem="Server" Field="@(x => x.Name)" Title="Name" Filterable="true"/>
|
<MCBColumn TItem="Server" Field="@(x => x.Name)" Title="Name" Filterable="true"/>
|
||||||
@@ -47,56 +50,17 @@
|
|||||||
</Template>
|
</Template>
|
||||||
</MCBColumn>
|
</MCBColumn>
|
||||||
</View>
|
</View>
|
||||||
<NoItemsView>
|
<EditToolbar>
|
||||||
<IconAlert Title="No servers found" Color="primary" Icon="bx-search-alt">
|
<WButton CssClasses="btn btn-danger me-2" OnClick="() => StartForceDelete(context)">
|
||||||
Create a new server in order to manage it using this page. Need help? Check out our <a href="https://docs.moonlightpanel.xyz">documentation</a>
|
<i class="bx bx-sm bx-bomb"></i>
|
||||||
</IconAlert>
|
Force delete
|
||||||
</NoItemsView>
|
</WButton>
|
||||||
</AutoCrud>*@
|
</EditToolbar>
|
||||||
|
</FastCrud>
|
||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
/*
|
private FastCrud<Server> Crud;
|
||||||
private void OnConfigure(AutoCrudOptions options)
|
|
||||||
{
|
|
||||||
options.AddCustomItemLoader<Server, ServerAllocation>("FreeAllocations", LoadFreeAllocations);
|
|
||||||
|
|
||||||
options.AddCustomDisplayFunction<ServerAllocation>("AllocationWithIp",
|
|
||||||
allocation => allocation.IpAddress + ":" + allocation.Port);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
private IEnumerable<Server> Load(Repository<Server> repository)
|
|
||||||
{
|
|
||||||
return repository
|
|
||||||
.Get()
|
|
||||||
.Include(x => x.Owner)
|
|
||||||
.Include(x => x.Image)
|
|
||||||
.Include(x => x.Allocations)
|
|
||||||
.Include(x => x.Node);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<ServerAllocation> LoadFreeAllocations(Repository<ServerAllocation> repository, Server? currentServer)
|
|
||||||
{
|
|
||||||
if (currentServer == null)
|
|
||||||
{
|
|
||||||
return repository
|
|
||||||
.Get()
|
|
||||||
.FromSqlRaw("SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return currentServer.Allocations.Concat(
|
|
||||||
repository
|
|
||||||
.Get()
|
|
||||||
.FromSqlRaw($"SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL AND ServerNodeId = {currentServer.Node.Id}")
|
|
||||||
.AsEnumerable() // => executes the sql
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CustomAdd(Server form) => await ServerService.Create(form);
|
|
||||||
|
|
||||||
private async Task CustomDelete(Server s) => await ServerService.Delete(s);
|
|
||||||
|
|
||||||
private async Task CustomUpdate(Server server)
|
private async Task CustomUpdate(Server server)
|
||||||
{
|
{
|
||||||
@@ -154,4 +118,138 @@
|
|||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task StartForceDelete(Server server)
|
||||||
|
{
|
||||||
|
await AlertService.Confirm(
|
||||||
|
"Confirm forcefully server deletion",
|
||||||
|
"Do you really want to delete this server forcefully?",
|
||||||
|
async () =>
|
||||||
|
{
|
||||||
|
await ServerService.Delete(server, safeDelete: false);
|
||||||
|
await ToastService.Success("Successfully deleted server");
|
||||||
|
|
||||||
|
await Crud.SetState(FastCrudState.View);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<Server> Loader(Repository<Server> repository)
|
||||||
|
{
|
||||||
|
return repository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Image)
|
||||||
|
.Include(x => x.Node)
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Include(x => x.Allocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnConfigure(FastCrudConfiguration<Server> configuration)
|
||||||
|
{
|
||||||
|
configuration.CustomCreate = ServerService.Create;
|
||||||
|
configuration.CustomDelete = server => ServerService.Delete(server);
|
||||||
|
configuration.CustomEdit = CustomUpdate;
|
||||||
|
|
||||||
|
configuration.ValidateEdit = ValidateUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shared form
|
||||||
|
private void OnConfigureBase(FastConfiguration<Server> configuration, Server server)
|
||||||
|
{
|
||||||
|
configuration.AddProperty(x => x.Name)
|
||||||
|
.WithDefaultComponent()
|
||||||
|
.WithValidation(FastValidators.Required);
|
||||||
|
|
||||||
|
Func<User, string> usernameFunc = x => x.Username;
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Owner)
|
||||||
|
.WithComponent<User, DropdownComponent<User>>()
|
||||||
|
.WithAdditionalOption("SearchFunc", usernameFunc)
|
||||||
|
.WithAdditionalOption("DisplayFunc", usernameFunc)
|
||||||
|
.WithValidation(FastValidators.Required);
|
||||||
|
|
||||||
|
Func<ServerImage, string> imageNameFunc = x => x.Name;
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Image)
|
||||||
|
.WithComponent<ServerImage, DropdownComponent<ServerImage>>()
|
||||||
|
.WithAdditionalOption("SearchFunc", imageNameFunc)
|
||||||
|
.WithAdditionalOption("DisplayFunc", imageNameFunc)
|
||||||
|
.WithValidation(FastValidators.Required);
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Cpu)
|
||||||
|
.WithDefaultComponent()
|
||||||
|
.WithValidation<int>(x => x > 0 ? ValidationResult.Success : new("You need to provide a valid value"))
|
||||||
|
.WithSection("Resources", "bxs-chip")
|
||||||
|
.WithDescription("The cores the server will be able to use. 100 = 1 Core");
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Memory)
|
||||||
|
.WithComponent<int, ByteSizeComponent>()
|
||||||
|
.WithAdditionalOption("MinimumUnit", "MB")
|
||||||
|
.WithAdditionalOption("DefaultUnit", "GB")
|
||||||
|
.WithValidation<int>(x => x > 0 ? ValidationResult.Success : new("You need to provide a valid value"))
|
||||||
|
.WithSection("Resources")
|
||||||
|
.WithDescription("The amount of memory this server will be able to use");
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Disk)
|
||||||
|
.WithComponent<int, ByteSizeComponent>()
|
||||||
|
.WithAdditionalOption("MinimumUnit", "MB")
|
||||||
|
.WithAdditionalOption("DefaultUnit", "GB")
|
||||||
|
.WithValidation<int>(x => x > 0 ? ValidationResult.Success : new("You need to provide a valid value"))
|
||||||
|
.WithSection("Resources")
|
||||||
|
.WithDescription("The amount of disk space this server will be able to use");
|
||||||
|
|
||||||
|
Func<ServerNode, string> nodeNameFunc = x => x.Name;
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Node)
|
||||||
|
.WithComponent<ServerNode, DropdownComponent<ServerNode>>()
|
||||||
|
.WithAdditionalOption("SearchFunc", nodeNameFunc)
|
||||||
|
.WithAdditionalOption("DisplayFunc", nodeNameFunc)
|
||||||
|
.WithValidation(FastValidators.Required);
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.UseVirtualDisk)
|
||||||
|
.WithComponent<bool, SwitchComponent>()
|
||||||
|
.WithPage("Advanced options")
|
||||||
|
.WithDescription("Whether to use a virtual disk for storing server files. Dont use this if you want to overallocate as the virtual disks will fill out the space you allocate");
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.DisablePublicNetwork)
|
||||||
|
.WithComponent<bool, SwitchComponent>()
|
||||||
|
.WithPage("Network")
|
||||||
|
.WithDescription("Whether to block all incoming connections to this server from the internet");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specific form
|
||||||
|
private void OnConfigureCreate(FastConfiguration<Server> configuration, Server server)
|
||||||
|
{
|
||||||
|
OnConfigureBase(configuration, server);
|
||||||
|
|
||||||
|
// Allocations
|
||||||
|
var items = AllocRepository
|
||||||
|
.Get()
|
||||||
|
.FromSqlRaw("SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL")
|
||||||
|
.AsEnumerable();
|
||||||
|
|
||||||
|
Func<ServerAllocation, string> buildDisplay = x => $"{x.IpAddress}:{x.Port}";
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Allocations)
|
||||||
|
.WithMultiSelect(buildDisplay, buildDisplay, items)
|
||||||
|
.WithPage("Network");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnConfigureEdit(FastConfiguration<Server> configuration, Server server)
|
||||||
|
{
|
||||||
|
OnConfigureBase(configuration, server);
|
||||||
|
|
||||||
|
// Allocations
|
||||||
|
var items = server.Allocations.Concat(
|
||||||
|
AllocRepository
|
||||||
|
.Get()
|
||||||
|
.FromSqlRaw($"SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL AND ServerNodeId = {server.Node.Id}")
|
||||||
|
.AsEnumerable());
|
||||||
|
|
||||||
|
Func<ServerAllocation, string> buildDisplay = x => $"{x.IpAddress}:{x.Port}";
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Allocations)
|
||||||
|
.WithMultiSelect(buildDisplay, buildDisplay, items)
|
||||||
|
.WithPage("Network");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="MoonCore" Version="1.4.1" />
|
<PackageReference Include="MoonCore" Version="1.4.1" />
|
||||||
<PackageReference Include="MoonCore.Blazor" Version="1.1.1" />
|
<PackageReference Include="MoonCore.Blazor" Version="1.1.4" />
|
||||||
<PackageReference Include="Otp.NET" Version="1.3.0" />
|
<PackageReference Include="Otp.NET" Version="1.3.0" />
|
||||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
<PackageReference Include="QRCoder" Version="1.4.3" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.2" />
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.2" />
|
||||||
|
|||||||
Reference in New Issue
Block a user