Jelajahi Sumber

Merge pull request #4 from Moonlight-Panel/ServerManager

Implemented server manager
Marcel Baumgartner 2 tahun lalu
induk
melakukan
8bd2a22195

+ 1 - 1
Moonlight/App/Models/Daemon/Resources/ContainerStats.cs

@@ -6,7 +6,7 @@ public class ContainerStats
     
     public class Container
     {
-        public Guid Name { get; set; }
+        public string Name { get; set; }
         public long Memory { get; set; }
         public double Cpu { get; set; }
         public long NetworkIn { get; set; }

+ 158 - 0
Moonlight/Shared/Views/Admin/Servers/Manager.razor

@@ -0,0 +1,158 @@
+@page "/admin/servers/manager"
+@using Moonlight.App.Repositories
+@using Moonlight.App.Repositories.Servers
+@using Moonlight.App.Services
+@using Moonlight.App.Services.Interop
+@using Moonlight.App.Database.Entities
+@using Moonlight.App.Models.Daemon.Resources
+@using Moonlight.App.Models.Wings
+@using BlazorTable
+@using Microsoft.EntityFrameworkCore
+@using Moonlight.App.Helpers
+
+@inject NodeRepository NodeRepository
+@inject NodeService NodeService
+@inject ServerRepository ServerRepository
+@inject SmartTranslateService SmartTranslateService
+@inject AlertService AlertService
+@inject ServerService ServerService
+
+<OnlyAdmin>
+    <div class="card mb-5">
+        <div class="card-body">
+            <WButton Text="@(SmartTranslateService.Translate("Refresh"))"
+                     WorkingText="@(SmartTranslateService.Translate("Working"))"
+                     CssClasses="btn-primary"
+                     OnClick="() => LazyLoader.Reload()">
+            </WButton>
+            <WButton Text="@(SmartTranslateService.Translate("Stop all"))"
+                     WorkingText="@(SmartTranslateService.Translate("Working"))"
+                     CssClasses="btn-danger"
+                     OnClick="StopAll">
+            </WButton>
+            <WButton Text="@(SmartTranslateService.Translate("Kill all"))"
+                     WorkingText="@(SmartTranslateService.Translate("Working"))"
+                     CssClasses="btn-danger"
+                     OnClick="KillAll">
+            </WButton>
+        </div>
+    </div>
+    <LazyLoader @ref="LazyLoader" Load="Load">
+        <div class="card card-body">
+            <div class="table-responsive">
+                <Table TableItem="ContainerStats.Container" Items="Containers.Values" PageSize="25" TableClass="table table-row-bordered table-row-gray-100 align-middle gs-0 gy-3" TableHeadClass="fw-bold text-muted">
+                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Name"))" Field="@(x => x.Name)" Sortable="true" Filterable="true">
+                        <Template>
+                            @{
+                                var server = Containers.First(x => x.Value == context).Key;
+                            }
+
+                            <a href="/server/@(server.Uuid)">@(server.Name)</a>
+                        </Template>
+                    </Column>
+                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Cpu usage"))" Field="@(x => x.Cpu)" Sortable="true" Filterable="true">
+                        <Template>
+                            <span>@(context.Cpu)%</span>
+                        </Template>
+                    </Column>
+                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Memory usage"))" Field="@(x => x.Memory)" Sortable="true" Filterable="true">
+                        <Template>
+                            <span>@(Formatter.FormatSize(context.Memory))</span>
+                        </Template>
+                    </Column>
+                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Network in"))" Field="@(x => x.NetworkIn)" Sortable="true" Filterable="true">
+                        <Template>
+                            <span>@(Formatter.FormatSize(context.NetworkIn))</span>
+                        </Template>
+                    </Column>
+                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Network out"))" Field="@(x => x.NetworkOut)" Sortable="true" Filterable="true">
+                        <Template>
+                            <span>@(Formatter.FormatSize(context.NetworkOut))</span>
+                        </Template>
+                    </Column>
+                    <Column TableItem="ContainerStats.Container" Title="@(SmartTranslateService.Translate("Owner"))" Field="@(x => x.Name)" Sortable="false" Filterable="false">
+                        <Template>
+                            @{
+                                var server = Containers.First(x => x.Value == context).Key;
+                            }
+
+                            <a href="/admin/users/view/@(server.Owner.Id)/">@server.Owner.Email</a>
+                        </Template>
+                    </Column>
+                    <Pager ShowPageNumber="true" ShowTotalCount="true"/>
+                </Table>
+            </div>
+        </div>
+    </LazyLoader>
+</OnlyAdmin>
+
+@code
+{
+    private LazyLoader LazyLoader;
+
+    private Dictionary<Server, ContainerStats.Container> Containers = new();
+
+    private async Task Load(LazyLoader lazyLoader)
+    {
+        Containers.Clear();
+
+        foreach (var node in NodeRepository.Get().ToArray())
+        {
+            await lazyLoader.SetText(node.Name);
+
+            var containerStats = await NodeService.GetContainerStats(node);
+
+            foreach (var container in containerStats.Containers)
+            {
+                if (Guid.TryParse(container.Name, out Guid uuid))
+                {
+                    var server = ServerRepository
+                        .Get()
+                        .Include(x => x.Owner)
+                        .FirstOrDefault(x => x.Uuid == uuid);
+
+                    if (server != null)
+                    {
+                        Containers.Add(server, container);
+                    }
+                }
+            }
+        }
+    }
+
+    private async Task StopAll()
+    {
+        var b = await AlertService.YesNo(
+            SmartTranslateService.Translate("Stop all servers"),
+            SmartTranslateService.Translate("Do you really want to stop all running servers?"),
+            SmartTranslateService.Translate("Yes"),
+            SmartTranslateService.Translate("No")
+            );
+
+        if (b)
+        {
+            foreach (var containerData in Containers)
+            {
+                await ServerService.SetPowerState(containerData.Key, PowerSignal.Stop);
+            }
+        }
+    }
+
+    private async Task KillAll()
+    {
+        var b = await AlertService.YesNo(
+            SmartTranslateService.Translate("Kill all servers"),
+            SmartTranslateService.Translate("Do you really want to kill all running servers?"),
+            SmartTranslateService.Translate("Yes"),
+            SmartTranslateService.Translate("No")
+            );
+
+        if (b)
+        {
+            foreach (var containerData in Containers)
+            {
+                await ServerService.SetPowerState(containerData.Key, PowerSignal.Kill);
+            }
+        }
+    }
+}

+ 10 - 0
Moonlight/resources/lang/de_de.lang

@@ -374,3 +374,13 @@ DDos attack started;DDos attack started
 packets;packets
 DDos attack stopped;DDos attack stopped
  packets; packets
+Stop all;Stop all
+Kill all;Kill all
+Network in;Network in
+Network out;Network out
+Kill all servers;Kill all servers
+Do you really want to kill all running servers?;Do you really want to kill all running servers?
+Change power state for;Change power state for
+to;to
+Stop all servers;Stop all servers
+Do you really want to stop all running servers?;Do you really want to stop all running servers?