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,
|
||||
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;
|
||||
|
||||
public class ServerTab
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Name { get; private 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>
|
||||
<Folder Include="Helpers\"/>
|
||||
<Folder Include="Interfaces\"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using MoonCore.Extensions;
|
||||
using MoonCore.PluginFramework.Extensions;
|
||||
using Moonlight.Client.Interfaces;
|
||||
using MoonlightServers.Frontend.Interfaces;
|
||||
|
||||
namespace MoonlightServers.Frontend.Startup;
|
||||
|
||||
@@ -10,6 +12,13 @@ public class PluginStartup : IAppStartup
|
||||
{
|
||||
builder.Services.AutoAddServices<PluginStartup>();
|
||||
|
||||
builder.Services.AddInterfaces(configuration =>
|
||||
{
|
||||
configuration.AddAssembly(GetType().Assembly);
|
||||
|
||||
configuration.AddInterface<IServerTabProvider>();
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "Styles",
|
||||
"dependencies": {
|
||||
"@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.Exceptions
|
||||
@using MoonCore.Helpers
|
||||
@using MoonlightServers.Frontend.Interfaces
|
||||
@using MoonlightServers.Frontend.Models
|
||||
@using MoonlightServers.Shared.Enums
|
||||
@using MoonlightServers.Frontend.UI.Components
|
||||
@using MoonlightServers.Frontend.UI.Components.Servers.ServerTabs
|
||||
|
||||
@inject HttpApiClient ApiClient
|
||||
@inject IServerTabProvider[] TabProviders
|
||||
|
||||
@implements IAsyncDisposable
|
||||
|
||||
@@ -119,15 +122,25 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
<Tabs NavStyle="true">
|
||||
<Tab Name="Console">
|
||||
<ConsoleTab Parent="this" Server="Server" State="State" HubConnection="HubConnection" InitialConsoleMessage="@InitialConsoleMessage" />
|
||||
</Tab>
|
||||
<div class="mt-3">
|
||||
<Tabs>
|
||||
@foreach (var tab in Tabs)
|
||||
{
|
||||
<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">
|
||||
|
||||
</Tab>
|
||||
@rf
|
||||
</Tab>
|
||||
}
|
||||
</Tabs>
|
||||
</div>
|
||||
}
|
||||
@@ -137,6 +150,8 @@
|
||||
{
|
||||
[Parameter] public int ServerId { get; set; }
|
||||
|
||||
private List<ServerTab> Tabs = new();
|
||||
|
||||
private ServerDetailResponse Server;
|
||||
private bool NotFound = false;
|
||||
private ServerState State;
|
||||
@@ -153,6 +168,10 @@
|
||||
$"api/servers/{ServerId}"
|
||||
);
|
||||
|
||||
// Load server tabs
|
||||
foreach (var serverTabProvider in TabProviders)
|
||||
Tabs.AddRange(await serverTabProvider.GetTabs(Server));
|
||||
|
||||
// Load initial status for first render
|
||||
var status = await ApiClient.GetJson<ServerStatusResponse>(
|
||||
$"api/servers/{ServerId}/status"
|
||||
|
||||
Reference in New Issue
Block a user