Added server tab provider. Moved power actions to seperate controller
This commit is contained in:
@@ -0,0 +1,125 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using MoonCore.Exceptions;
|
||||||
|
using MoonCore.Extended.Abstractions;
|
||||||
|
using MoonCore.Extensions;
|
||||||
|
using MoonlightServers.ApiServer.Database.Entities;
|
||||||
|
using MoonlightServers.ApiServer.Services;
|
||||||
|
|
||||||
|
namespace MoonlightServers.ApiServer.Http.Controllers.Users;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
[Route("api/servers")]
|
||||||
|
public class ServerPowerController : Controller
|
||||||
|
{
|
||||||
|
private readonly DatabaseRepository<Server> ServerRepository;
|
||||||
|
private readonly NodeService NodeService;
|
||||||
|
|
||||||
|
public ServerPowerController(DatabaseRepository<Server> serverRepository, NodeService nodeService)
|
||||||
|
{
|
||||||
|
ServerRepository = serverRepository;
|
||||||
|
NodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{serverId:int}/start")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task Start([FromRoute] int serverId)
|
||||||
|
{
|
||||||
|
var server = await GetServerWithPermCheck(serverId);
|
||||||
|
|
||||||
|
using var apiClient = await NodeService.CreateApiClient(server.Node);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await apiClient.Post($"api/servers/{server.Id}/start");
|
||||||
|
}
|
||||||
|
catch (HttpRequestException e)
|
||||||
|
{
|
||||||
|
throw new HttpApiException("Unable to access the node the server is running on", 502);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{serverId:int}/stop")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task Stop([FromRoute] int serverId)
|
||||||
|
{
|
||||||
|
var server = await GetServerWithPermCheck(serverId);
|
||||||
|
|
||||||
|
using var apiClient = await NodeService.CreateApiClient(server.Node);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await apiClient.Post($"api/servers/{server.Id}/stop");
|
||||||
|
}
|
||||||
|
catch (HttpRequestException e)
|
||||||
|
{
|
||||||
|
throw new HttpApiException("Unable to access the node the server is running on", 502);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{serverId:int}/kill")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task Kill([FromRoute] int serverId)
|
||||||
|
{
|
||||||
|
var server = await GetServerWithPermCheck(serverId);
|
||||||
|
|
||||||
|
using var apiClient = await NodeService.CreateApiClient(server.Node);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await apiClient.Post($"api/servers/{server.Id}/kill");
|
||||||
|
}
|
||||||
|
catch (HttpRequestException e)
|
||||||
|
{
|
||||||
|
throw new HttpApiException("Unable to access the node the server is running on", 502);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{serverId:int}/install")]
|
||||||
|
[Authorize]
|
||||||
|
public async Task Install([FromRoute] int serverId)
|
||||||
|
{
|
||||||
|
var server = await GetServerWithPermCheck(serverId);
|
||||||
|
|
||||||
|
using var apiClient = await NodeService.CreateApiClient(server.Node);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await apiClient.Post($"api/servers/{server.Id}/install");
|
||||||
|
}
|
||||||
|
catch (HttpRequestException e)
|
||||||
|
{
|
||||||
|
throw new HttpApiException("Unable to access the node the server is running on", 502);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Server> GetServerWithPermCheck(int serverId,
|
||||||
|
Func<IQueryable<Server>, IQueryable<Server>>? queryModifier = null)
|
||||||
|
{
|
||||||
|
var userIdClaim = User.Claims.First(x => x.Type == "userId");
|
||||||
|
var userId = int.Parse(userIdClaim.Value);
|
||||||
|
|
||||||
|
var query = ServerRepository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Node) as IQueryable<Server>;
|
||||||
|
|
||||||
|
if (queryModifier != null)
|
||||||
|
query = queryModifier.Invoke(query);
|
||||||
|
|
||||||
|
var server = await query
|
||||||
|
.FirstOrDefaultAsync(x => x.Id == serverId);
|
||||||
|
|
||||||
|
if (server == null)
|
||||||
|
throw new HttpApiException("No server with this id found", 404);
|
||||||
|
|
||||||
|
if (server.OwnerId == userId) // The current user is the owner
|
||||||
|
return server;
|
||||||
|
|
||||||
|
if (User.HasPermission("admin.servers.get")) // The current user is an admin
|
||||||
|
return server;
|
||||||
|
|
||||||
|
throw new HttpApiException("No server with this id found", 404);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -176,60 +176,6 @@ public class ServersController : Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("{serverId:int}/start")]
|
|
||||||
[Authorize]
|
|
||||||
public async Task Start([FromRoute] int serverId)
|
|
||||||
{
|
|
||||||
var server = await GetServerWithPermCheck(serverId);
|
|
||||||
|
|
||||||
using var apiClient = await NodeService.CreateApiClient(server.Node);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await apiClient.Post($"api/servers/{server.Id}/start");
|
|
||||||
}
|
|
||||||
catch (HttpRequestException e)
|
|
||||||
{
|
|
||||||
throw new HttpApiException("Unable to access the node the server is running on", 502);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("{serverId:int}/stop")]
|
|
||||||
[Authorize]
|
|
||||||
public async Task Stop([FromRoute] int serverId)
|
|
||||||
{
|
|
||||||
var server = await GetServerWithPermCheck(serverId);
|
|
||||||
|
|
||||||
using var apiClient = await NodeService.CreateApiClient(server.Node);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await apiClient.Post($"api/servers/{server.Id}/stop");
|
|
||||||
}
|
|
||||||
catch (HttpRequestException e)
|
|
||||||
{
|
|
||||||
throw new HttpApiException("Unable to access the node the server is running on", 502);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("{serverId:int}/kill")]
|
|
||||||
[Authorize]
|
|
||||||
public async Task Kill([FromRoute] int serverId)
|
|
||||||
{
|
|
||||||
var server = await GetServerWithPermCheck(serverId);
|
|
||||||
|
|
||||||
using var apiClient = await NodeService.CreateApiClient(server.Node);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await apiClient.Post($"api/servers/{server.Id}/kill");
|
|
||||||
}
|
|
||||||
catch (HttpRequestException e)
|
|
||||||
{
|
|
||||||
throw new HttpApiException("Unable to access the node the server is running on", 502);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<Server> GetServerWithPermCheck(int serverId,
|
private async Task<Server> GetServerWithPermCheck(int serverId,
|
||||||
Func<IQueryable<Server>, IQueryable<Server>>? queryModifier = null)
|
Func<IQueryable<Server>, IQueryable<Server>>? queryModifier = null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using MoonlightServers.Frontend.Interfaces;
|
||||||
|
using MoonlightServers.Frontend.Models;
|
||||||
|
using MoonlightServers.Frontend.UI.Components.Servers.ServerTabs;
|
||||||
|
using MoonlightServers.Shared.Http.Responses.Users.Servers;
|
||||||
|
|
||||||
|
namespace MoonlightServers.Frontend.Implementations;
|
||||||
|
|
||||||
|
public class DefaultServerTabProvider : IServerTabProvider
|
||||||
|
{
|
||||||
|
public Task<ServerTab[]> GetTabs(ServerDetailResponse server)
|
||||||
|
{
|
||||||
|
ServerTab[] tabs =
|
||||||
|
[
|
||||||
|
ServerTab.CreateFromComponent<ConsoleTab>("Console", "console", 0),
|
||||||
|
ServerTab.CreateFromComponent<FilesTab>("Files", "files", 1),
|
||||||
|
ServerTab.CreateFromComponent<SettingsTab>("Settings", "settings", 10),
|
||||||
|
];
|
||||||
|
|
||||||
|
return Task.FromResult(tabs);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using MoonlightServers.Frontend.Models;
|
||||||
|
using MoonlightServers.Shared.Http.Responses.Users.Servers;
|
||||||
|
|
||||||
|
namespace MoonlightServers.Frontend.Interfaces;
|
||||||
|
|
||||||
|
public interface IServerTabProvider
|
||||||
|
{
|
||||||
|
public Task<ServerTab[]> GetTabs(ServerDetailResponse server);
|
||||||
|
}
|
||||||
@@ -1,7 +1,22 @@
|
|||||||
|
using MoonlightServers.Frontend.UI.Components.Servers.ServerTabs;
|
||||||
|
|
||||||
namespace MoonlightServers.Frontend.Models;
|
namespace MoonlightServers.Frontend.Models;
|
||||||
|
|
||||||
public class ServerTab
|
public class ServerTab
|
||||||
{
|
{
|
||||||
public string Path { get; set; }
|
public string Name { get; private set; }
|
||||||
public string Name { get; set; }
|
public string Path { get; private set; }
|
||||||
|
public int Priority { get; set; }
|
||||||
|
public Type ComponentType { get; private set; }
|
||||||
|
|
||||||
|
public static ServerTab CreateFromComponent<T>(string name, string path, int priority) where T : BaseServerTab
|
||||||
|
{
|
||||||
|
return new()
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Path = path,
|
||||||
|
Priority = priority,
|
||||||
|
ComponentType = typeof(T)
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Helpers\"/>
|
<Folder Include="Helpers\"/>
|
||||||
<Folder Include="Interfaces\"/>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
using MoonCore.Extensions;
|
using MoonCore.Extensions;
|
||||||
|
using MoonCore.PluginFramework.Extensions;
|
||||||
using Moonlight.Client.Interfaces;
|
using Moonlight.Client.Interfaces;
|
||||||
|
using MoonlightServers.Frontend.Interfaces;
|
||||||
|
|
||||||
namespace MoonlightServers.Frontend.Startup;
|
namespace MoonlightServers.Frontend.Startup;
|
||||||
|
|
||||||
@@ -10,6 +12,13 @@ public class PluginStartup : IAppStartup
|
|||||||
{
|
{
|
||||||
builder.Services.AutoAddServices<PluginStartup>();
|
builder.Services.AutoAddServices<PluginStartup>();
|
||||||
|
|
||||||
|
builder.Services.AddInterfaces(configuration =>
|
||||||
|
{
|
||||||
|
configuration.AddAssembly(GetType().Assembly);
|
||||||
|
|
||||||
|
configuration.AddInterface<IServerTabProvider>();
|
||||||
|
});
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "Styles",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/forms": "^0.5.9"
|
"@tailwindcss/forms": "^0.5.9"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@inherits BaseServerTab
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
@using MoonCore.Blazor.Tailwind.Alerts
|
||||||
|
@using MoonCore.Helpers
|
||||||
|
@using MoonCore.Blazor.Tailwind.Components
|
||||||
|
@using MoonlightServers.Shared.Enums
|
||||||
|
|
||||||
|
@inherits BaseServerTab
|
||||||
|
|
||||||
|
@inject HttpApiClient HttpApiClient
|
||||||
|
@inject AlertService AlertService
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 md:col-span-2 lg:grid-cols-3">
|
||||||
|
<div class="col-span-1 card card-body">
|
||||||
|
@if (State != ServerState.Offline)
|
||||||
|
{
|
||||||
|
<button class="btn btn-primary" disabled="disabled">
|
||||||
|
<i class="align-middle icon-hammer me-1"></i>
|
||||||
|
<span class="align-middle">Reinstall</span>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<WButton CssClasses="btn btn-primary" OnClick="Reinstall">
|
||||||
|
<i class="align-middle icon-hammer me-1"></i>
|
||||||
|
<span class="align-middle">Reinstall</span>
|
||||||
|
</WButton>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
private async Task Reinstall(WButton _)
|
||||||
|
{
|
||||||
|
await AlertService.ConfirmDanger(
|
||||||
|
"Server installation",
|
||||||
|
"Do you really want to reinstall the server? This can potentially lead to loss of data",
|
||||||
|
() => HttpApiClient.Post($"api/servers/{Server.Id}/install")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,11 +5,14 @@
|
|||||||
@using MoonCore.Blazor.Tailwind.Components
|
@using MoonCore.Blazor.Tailwind.Components
|
||||||
@using MoonCore.Exceptions
|
@using MoonCore.Exceptions
|
||||||
@using MoonCore.Helpers
|
@using MoonCore.Helpers
|
||||||
|
@using MoonlightServers.Frontend.Interfaces
|
||||||
|
@using MoonlightServers.Frontend.Models
|
||||||
@using MoonlightServers.Shared.Enums
|
@using MoonlightServers.Shared.Enums
|
||||||
@using MoonlightServers.Frontend.UI.Components
|
@using MoonlightServers.Frontend.UI.Components
|
||||||
@using MoonlightServers.Frontend.UI.Components.Servers.ServerTabs
|
@using MoonlightServers.Frontend.UI.Components.Servers.ServerTabs
|
||||||
|
|
||||||
@inject HttpApiClient ApiClient
|
@inject HttpApiClient ApiClient
|
||||||
|
@inject IServerTabProvider[] TabProviders
|
||||||
|
|
||||||
@implements IAsyncDisposable
|
@implements IAsyncDisposable
|
||||||
|
|
||||||
@@ -119,15 +122,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-5">
|
<div class="mt-3">
|
||||||
<Tabs NavStyle="true">
|
<Tabs>
|
||||||
<Tab Name="Console">
|
@foreach (var tab in Tabs)
|
||||||
<ConsoleTab Parent="this" Server="Server" State="State" HubConnection="HubConnection" InitialConsoleMessage="@InitialConsoleMessage" />
|
{
|
||||||
</Tab>
|
<Tab Name="@tab.Name">
|
||||||
|
@{
|
||||||
|
var rf = ComponentHelper.FromType(tab.ComponentType, parameters =>
|
||||||
|
{
|
||||||
|
parameters.Add("Server", Server);
|
||||||
|
parameters.Add("State", State);
|
||||||
|
parameters.Add("InitialConsoleMessage", InitialConsoleMessage);
|
||||||
|
parameters.Add("HubConnection", HubConnection);
|
||||||
|
parameters.Add("Parent", this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
<Tab Name="Testy">
|
@rf
|
||||||
|
</Tab>
|
||||||
</Tab>
|
}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -137,6 +150,8 @@
|
|||||||
{
|
{
|
||||||
[Parameter] public int ServerId { get; set; }
|
[Parameter] public int ServerId { get; set; }
|
||||||
|
|
||||||
|
private List<ServerTab> Tabs = new();
|
||||||
|
|
||||||
private ServerDetailResponse Server;
|
private ServerDetailResponse Server;
|
||||||
private bool NotFound = false;
|
private bool NotFound = false;
|
||||||
private ServerState State;
|
private ServerState State;
|
||||||
@@ -153,6 +168,10 @@
|
|||||||
$"api/servers/{ServerId}"
|
$"api/servers/{ServerId}"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Load server tabs
|
||||||
|
foreach (var serverTabProvider in TabProviders)
|
||||||
|
Tabs.AddRange(await serverTabProvider.GetTabs(Server));
|
||||||
|
|
||||||
// Load initial status for first render
|
// Load initial status for first render
|
||||||
var status = await ApiClient.GetJson<ServerStatusResponse>(
|
var status = await ApiClient.GetJson<ServerStatusResponse>(
|
||||||
$"api/servers/{ServerId}/status"
|
$"api/servers/{ServerId}/status"
|
||||||
|
|||||||
Reference in New Issue
Block a user