pschelpdesk/HetznerServer/Service/ServerService.cs
2024-11-14 07:53:50 +01:00

183 lines
7.3 KiB
C#

using System.Collections.ObjectModel;
using System.Net.Http.Headers;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.DependencyInjection;
using DynamicData;
using DynamicData.Binding;
using HetznerCloudApi;
using Newtonsoft.Json.Linq;
using PSCHelpdesk.Plugins.HetznerServer.Models;
using PSCHelpdesk.Shared.Service;
using PSCHelpdesk.Shared.Setting;
using PSCHelpdesk.Shared.Tasks;
using ReactiveUI;
using Renci.SshNet;
namespace PSCHelpdesk.Plugins.HetznerServer.Service;
public class ServerService: IServerService
{
public SourceCache<Server, long> SourceCache = new (x => x.Id);
private SettingsManager _settingsManager;
private readonly DispatcherTimer _reloadTimer = new DispatcherTimer();
private string _searchText = string.Empty;
private static readonly HttpClient httpClient = new HttpClient();
private ITaskManager _taskManager;
private readonly IToastManager? _toastManager;
public ServerService()
{
_settingsManager = (SettingsManager)Ioc.Default.GetService<ISettingsManager>();
_taskManager = Ioc.Default.GetService<ITaskManager>();
_toastManager = (IToastManager)Ioc.Default.GetService<IToastManager>();
this._reloadTimer.Tick += (sender, args) =>
{
this.reloadServerStatus();
};
_reloadTimer.Interval = TimeSpan.FromMinutes(10);
_reloadTimer.Start();
this.reloadServer();
}
private async Task reloadServer()
{
var settings = new Settings();
_settingsManager.LoadPluginSettings("HetznerSettings", settings);
if (settings.HetznerApiKey != "")
{
HetznerCloudClient hetznerCloudClient = new HetznerCloudClient(settings.HetznerApiKey);
List<HetznerCloudApi.Object.Server.Server> list = await hetznerCloudClient.Server.Get();
foreach (var server in list)
{
var uiDispatcher = Ioc.Default.GetService<IUserInterfaceDispatchService>();
await uiDispatcher.InvokeAsync(() =>
{
SourceCache.AddOrUpdate(new Server(server.Id, server.Name, server.ServerType.Name, server.Status,
server.PublicNet.Ipv4.Ip, server.PublicNet.Ipv6.Ip));
});
}
}
Task.Run(async () => await this.reloadServerStatus());
}
private async Task reloadServerStatus()
{
var uiDispatcher = Ioc.Default.GetService<IUserInterfaceDispatchService>();
await uiDispatcher.InvokeAsync(() =>
{
_reloadTimer.Stop();
});
foreach (Server serv in SourceCache.Items)
{
var connectionInfo = new ConnectionInfo(serv.Ipv4,
"root",
new PrivateKeyAuthenticationMethod("root", new PrivateKeyFile(this._settingsManager.CoreSettings.PrivateSSHKeyPath)));
using (var client = new SshClient(connectionInfo))
{
try
{
client.Connect();
var command = client.RunCommand("borgmatic info --json");
if (command.ExitStatus == 0)
{
serv.HasBackup = true;
JArray borgMatic = JArray.Parse(command.Result);
await uiDispatcher.InvokeAsync(() =>
{
serv.BackupLastModified = DateTime.Parse(borgMatic[0]["repository"]["last_modified"].ToString());
});
}
command = client.RunCommand("docker inspect psc_mongodb_1");
if (command.ExitStatus == 0)
{
JArray mongoDB = JArray.Parse(command.Result);
var mongoDBEnvArray = mongoDB[0]["Config"]["Env"];
foreach (String entry in mongoDBEnvArray)
{
var mongodDBexploded = entry.Split("=");
if (mongodDBexploded[0] == "MONGO_VERSION")
{
serv.MongoVersion = mongodDBexploded[1];
}
}
}
command = client.RunCommand("docker inspect psc_mysql_1");
if (command.ExitStatus == 0)
{
JArray mongoDB = JArray.Parse(command.Result);
var mongoDBEnvArray = mongoDB[0]["Config"]["Env"];
foreach (String entry in mongoDBEnvArray)
{
var mongodDBexploded = entry.Split("=");
if (mongodDBexploded[0] == "MARIADB_VERSION")
{
serv.MysqlVersion = mongodDBexploded[1];
}
}
}
command = client.RunCommand("docker ps|wc -l");
if (command.ExitStatus == 0)
{
serv.RunningContainerCount = int.Parse(command.Result);
}
command = client.RunCommand("docker inspect psc_web_1");
if (command.ExitStatus == 0)
{
JArray web = JArray.Parse(command.Result);
var webEnvArray = web[0]["Config"]["Env"];
foreach (String entry in webEnvArray)
{
var webExploded = entry.Split("=");
if (webExploded[0] == "LETSENCRYPT_HOST")
{
var webHosts = webExploded[1].Split(",");
serv.Domains.Clear();
foreach (String dom in webHosts)
{
serv.Domains.Add(new Domain(dom));
}
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/ld+json"));
httpClient.DefaultRequestHeaders.Add("User-Agent", "PSC Client");
var stringTask = httpClient.GetStringAsync("https://" + webHosts[0] + "/apps/api/system/version");
var msg = await stringTask;
JObject versionMSg = JObject.Parse(msg);
serv.Datum = versionMSg["datum"].ToString();
serv.Release = float.Parse(versionMSg["release"].ToString());
}
}
}
client.Disconnect();
_toastManager.DisplayNewToast("Server " + serv.Name + " finished");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
await uiDispatcher.InvokeAsync(() =>
{
this._reloadTimer.Start();
});
}
}