From 6d4e1cdaaf133eb0e6e98cdb00ae4fe70bd0a4bb Mon Sep 17 00:00:00 2001 From: = <=> Date: Fri, 6 Sep 2024 13:53:41 +0000 Subject: [PATCH] Started adding node-daemon communication. Added status endpoint --- .../Extensions/NodeExtensions.cs | 22 +++++++++ .../Admin/Nodes/NodesController.cs | 19 +++++++- .../MoonlightServers.ApiServer.csproj | 2 +- .../MoonlightServers.Client.csproj | 2 +- .../App/Helpers/HostHelper.cs | 18 +++---- .../Http/Controllers/Sys/InfoController.cs | 47 +++++++++++++++++++ .../MoonlightServers.Daemon.csproj | 3 +- MoonlightServers.Daemon/Program.cs | 10 +--- .../Http/Resources/Sys/SystemInfoResponse.cs | 22 +++++++++ .../MoonlightServers.DaemonShared.csproj | 1 - .../Admin/Nodes/StatusNodeResponse.cs | 22 +++++++++ 11 files changed, 144 insertions(+), 24 deletions(-) create mode 100644 MoonlightServers.ApiServer/Extensions/NodeExtensions.cs create mode 100644 MoonlightServers.Daemon/App/Http/Controllers/Sys/InfoController.cs create mode 100644 MoonlightServers.DaemonShared/Http/Resources/Sys/SystemInfoResponse.cs create mode 100644 MoonlightServers.Shared/Http/Responses/Admin/Nodes/StatusNodeResponse.cs diff --git a/MoonlightServers.ApiServer/Extensions/NodeExtensions.cs b/MoonlightServers.ApiServer/Extensions/NodeExtensions.cs new file mode 100644 index 0000000..870ce5b --- /dev/null +++ b/MoonlightServers.ApiServer/Extensions/NodeExtensions.cs @@ -0,0 +1,22 @@ +using MoonCore.Helpers; +using MoonlightServers.ApiServer.Database.Entities; + +namespace MoonlightServers.ApiServer.Extensions; + +public static class NodeExtensions +{ + public static HttpApiClient CreateClient(this Node node) + { + var httpClient = new HttpClient(new HttpClientHandler() // TODO: Make global http config for proxy etc + { + UseProxy = false + }); + + var url = $"{(node.SslEnabled ? "https" : "http")}://{node.Fqdn}:{node.ApiPort}/"; + httpClient.BaseAddress = new Uri(url); + + httpClient.DefaultRequestHeaders.Add("Authorization", node.Token); + + return new HttpApiClient(httpClient); + } +} \ No newline at end of file diff --git a/MoonlightServers.ApiServer/Http/Controllers/Admin/Nodes/NodesController.cs b/MoonlightServers.ApiServer/Http/Controllers/Admin/Nodes/NodesController.cs index 6b8f551..96158b7 100644 --- a/MoonlightServers.ApiServer/Http/Controllers/Admin/Nodes/NodesController.cs +++ b/MoonlightServers.ApiServer/Http/Controllers/Admin/Nodes/NodesController.cs @@ -5,7 +5,9 @@ using MoonCore.Helpers; using Moonlight.ApiServer.App.Attributes; using Moonlight.ApiServer.App.Exceptions; using Moonlight.ApiServer.App.Helpers; +using MoonlightServers.DaemonShared.Http.Resources.Sys; using MoonlightServers.ApiServer.Database.Entities; +using MoonlightServers.ApiServer.Extensions; using MoonlightServers.Shared.Http.Requests.Admin.Nodes; using MoonlightServers.Shared.Http.Responses.Admin.Nodes; @@ -14,7 +16,7 @@ namespace MoonlightServers.ApiServer.Http.Controllers.Admin.Nodes; [ApiController] [Route("admin/servers/nodes")] public class NodesController : BaseCrudController -{ +{ public NodesController(DatabaseRepository itemRepository) : base(itemRepository) { PermissionPrefix = "admin.servers.nodes"; @@ -49,6 +51,21 @@ public class NodesController : BaseCrudController(item)); } + [HttpGet("{id}/status")] + [RequirePermission("admin.servers.nodes.status")] + public async Task> Status(int id) + { + var node = LoadItemById(id); + + using var httpClient = node.CreateClient(); + + var response = await httpClient.GetJson("system/info"); + + var result = Mapper.Map(response); + + return Ok(result); + } + private void ValidateFqdn(string fqdn, bool ssl) { if (ssl) diff --git a/MoonlightServers.ApiServer/MoonlightServers.ApiServer.csproj b/MoonlightServers.ApiServer/MoonlightServers.ApiServer.csproj index 676dbbb..8bef13b 100644 --- a/MoonlightServers.ApiServer/MoonlightServers.ApiServer.csproj +++ b/MoonlightServers.ApiServer/MoonlightServers.ApiServer.csproj @@ -16,7 +16,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/MoonlightServers.Client/MoonlightServers.Client.csproj b/MoonlightServers.Client/MoonlightServers.Client.csproj index 6858763..c0c825b 100644 --- a/MoonlightServers.Client/MoonlightServers.Client.csproj +++ b/MoonlightServers.Client/MoonlightServers.Client.csproj @@ -14,7 +14,7 @@ - + diff --git a/MoonlightServers.Daemon/App/Helpers/HostHelper.cs b/MoonlightServers.Daemon/App/Helpers/HostHelper.cs index 707b0d7..ee5d5ed 100644 --- a/MoonlightServers.Daemon/App/Helpers/HostHelper.cs +++ b/MoonlightServers.Daemon/App/Helpers/HostHelper.cs @@ -67,37 +67,37 @@ public class HostHelper return TimeSpan.FromSeconds(seconds); } - public async Task GetMemoryDetails() + public async Task GetMemoryDetails() // 0, total - 1, free - 2, available - 3, cached - 4, swap total - 5, swap free { - var result = new long[6]; + var result = new ulong[6]; var memInfoText = await File.ReadAllLinesAsync("/proc/meminfo"); foreach (var line in memInfoText) { if (line.StartsWith("MemTotal:")) - result[0] = 1024 * long.Parse(line.Replace("MemTotal:", "").Replace("kB", "").Trim()); + result[0] = 1024 * ulong.Parse(line.Replace("MemTotal:", "").Replace("kB", "").Trim()); if (line.StartsWith("MemFree:")) - result[1] = 1024 * long.Parse(line.Replace("MemFree:", "").Replace("kB", "").Trim()); + result[1] = 1024 * ulong.Parse(line.Replace("MemFree:", "").Replace("kB", "").Trim()); if (line.StartsWith("MemAvailable:")) - result[2] = 1024 * long.Parse(line.Replace("MemAvailable:", "").Replace("kB", "").Trim()); + result[2] = 1024 * ulong.Parse(line.Replace("MemAvailable:", "").Replace("kB", "").Trim()); if (line.StartsWith("Cached:")) - result[3] = 1024 * long.Parse(line.Replace("Cached:", "").Replace("kB", "").Trim()); + result[3] = 1024 * ulong.Parse(line.Replace("Cached:", "").Replace("kB", "").Trim()); if (line.StartsWith("SwapTotal:")) - result[4] = 1024 * long.Parse(line.Replace("SwapTotal:", "").Replace("kB", "").Trim()); + result[4] = 1024 * ulong.Parse(line.Replace("SwapTotal:", "").Replace("kB", "").Trim()); if (line.StartsWith("SwapFree:")) - result[5] = 1024 * long.Parse(line.Replace("SwapFree:", "").Replace("kB", "").Trim()); + result[5] = 1024 * ulong.Parse(line.Replace("SwapFree:", "").Replace("kB", "").Trim()); } return result; } - public async Task GetDiskUsage() // 0, Total size - 1, Free size, - 3, Total inodes - 4, free inodes + public async Task GetDiskUsage() // 0, Total size - 1, Free size, - 2, Total inodes - 3, free inodes { var sysCallRes = Syscall.statvfs("/", out var buf); diff --git a/MoonlightServers.Daemon/App/Http/Controllers/Sys/InfoController.cs b/MoonlightServers.Daemon/App/Http/Controllers/Sys/InfoController.cs new file mode 100644 index 0000000..a584091 --- /dev/null +++ b/MoonlightServers.Daemon/App/Http/Controllers/Sys/InfoController.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.Mvc; +using MoonlightServers.Daemon.App.Helpers; +using MoonlightServers.DaemonShared.Http.Resources.Sys; + +namespace MoonlightServers.Daemon.App.Http.Controllers.Sys; + +[ApiController] +[Route("system/info")] +public class InfoController : Controller +{ + private readonly HostHelper HostHelper; + + public InfoController(HostHelper hostHelper) + { + HostHelper = hostHelper; + } + + [HttpGet] + public async Task> Get() + { + var memoryDetails = await HostHelper.GetMemoryDetails(); + var diskDetails = await HostHelper.GetDiskUsage(); + + var response = new SystemInfoResponse() + { + CpuModel = await HostHelper.GetCpuModel(), + CpuUsage = await HostHelper.GetCpuUsage(), + + Uptime = await HostHelper.GetUptime(), + + MemoryTotal = memoryDetails[0], + MemoryFree = memoryDetails[1], + MemoryAvailable = memoryDetails[2], + MemoryCached = memoryDetails[3], + + SwapTotal = memoryDetails[4], + SwapFree = memoryDetails[5], + + DiskTotal = diskDetails[0], + DiskFree = diskDetails[1], + DiskTotalInodes = diskDetails[2], + DiskFreeInodes = diskDetails[3] + }; + + return Ok(response); + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj b/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj index b8b1ba9..9505a98 100644 --- a/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj +++ b/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj @@ -8,7 +8,7 @@ - + @@ -19,7 +19,6 @@ - diff --git a/MoonlightServers.Daemon/Program.cs b/MoonlightServers.Daemon/Program.cs index 9818199..704a873 100644 --- a/MoonlightServers.Daemon/Program.cs +++ b/MoonlightServers.Daemon/Program.cs @@ -1,6 +1,5 @@ using MoonCore.Extensions; using MoonCore.Helpers; -using MoonlightServers.Daemon.App.Helpers; var loggerFactory = new LoggerFactory(); @@ -30,13 +29,6 @@ builder.Services.AddControllers(); var app = builder.Build(); -var x = new HostHelper(); - -var data = await x.GetDiskUsage(); - -logger.LogInformation("Total disk: {value}", Formatter.FormatSize((long)data[0])); -logger.LogInformation("Free disk: {value}", Formatter.FormatSize((long)data[1])); -logger.LogInformation("Total inodes: {value}", data[2]); -logger.LogInformation("Free inodes: {value}", data[3]); +app.MapControllers(); app.Run(); \ No newline at end of file diff --git a/MoonlightServers.DaemonShared/Http/Resources/Sys/SystemInfoResponse.cs b/MoonlightServers.DaemonShared/Http/Resources/Sys/SystemInfoResponse.cs new file mode 100644 index 0000000..89b0163 --- /dev/null +++ b/MoonlightServers.DaemonShared/Http/Resources/Sys/SystemInfoResponse.cs @@ -0,0 +1,22 @@ +namespace MoonlightServers.DaemonShared.Http.Resources.Sys; + +public class SystemInfoResponse +{ + public string CpuModel { get; set; } + public double[] CpuUsage { get; set; } + public TimeSpan Uptime { get; set; } + + public ulong MemoryTotal { get; set; } + public ulong MemoryFree { get; set; } + public ulong MemoryAvailable { get; set; } + public ulong MemoryCached { get; set; } + + public ulong SwapTotal { get; set; } + public ulong SwapFree { get; set; } + + public ulong DiskTotal { get; set; } + public ulong DiskFree { get; set; } + + public ulong DiskTotalInodes { get; set; } + public ulong DiskFreeInodes { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj b/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj index d83c965..af2fbdf 100644 --- a/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj +++ b/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj @@ -8,7 +8,6 @@ - diff --git a/MoonlightServers.Shared/Http/Responses/Admin/Nodes/StatusNodeResponse.cs b/MoonlightServers.Shared/Http/Responses/Admin/Nodes/StatusNodeResponse.cs new file mode 100644 index 0000000..84c6177 --- /dev/null +++ b/MoonlightServers.Shared/Http/Responses/Admin/Nodes/StatusNodeResponse.cs @@ -0,0 +1,22 @@ +namespace MoonlightServers.Shared.Http.Responses.Admin.Nodes; + +public class StatusNodeResponse +{ + public string CpuModel { get; set; } + public double[] CpuUsage { get; set; } + public TimeSpan Uptime { get; set; } + + public ulong MemoryTotal { get; set; } + public ulong MemoryFree { get; set; } + public ulong MemoryAvailable { get; set; } + public ulong MemoryCached { get; set; } + + public ulong SwapTotal { get; set; } + public ulong SwapFree { get; set; } + + public ulong DiskTotal { get; set; } + public ulong DiskFree { get; set; } + + public ulong DiskTotalInodes { get; set; } + public ulong DiskFreeInodes { get; set; } +} \ No newline at end of file