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 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(); _taskManager = Ioc.Default.GetService(); _toastManager = (IToastManager)Ioc.Default.GetService(); 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 list = await hetznerCloudClient.Server.Get(); foreach (var server in list) { var uiDispatcher = Ioc.Default.GetService(); 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(); 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_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(); }); } }