diff --git a/.idea/.idea.PSCHelpdesk/.idea/workspace.xml b/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
index f895e55..f7dda8e 100644
--- a/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
+++ b/.idea/.idea.PSCHelpdesk/.idea/workspace.xml
@@ -12,17 +12,12 @@
-
-
-
-
-
-
-
-
+
+
+
+
-
@@ -269,7 +264,8 @@
-
+
+
@@ -311,7 +307,15 @@
1733247327690
-
+
+
+ 1733341591476
+
+
+
+ 1733341591476
+
+
@@ -440,6 +444,7 @@
+
diff --git a/HetznerServer/Models/Server.cs b/HetznerServer/Models/Server.cs
index a90276a..659edd8 100644
--- a/HetznerServer/Models/Server.cs
+++ b/HetznerServer/Models/Server.cs
@@ -12,7 +12,37 @@ namespace PSCHelpdesk.Plugins.HetznerServer.Models;
public class Server : ReactiveObject
{
- public long ServerId { get; set; }
+ private bool _isChecked;
+
+ public bool IsChecked
+ {
+ get => _isChecked;
+ set => this.RaiseAndSetIfChanged(ref _isChecked, value);
+ }
+
+ private bool _hasNeedRestart;
+
+ public bool HasNeedRestart
+ {
+ get => _hasNeedRestart;
+ set => this.RaiseAndSetIfChanged(ref _hasNeedRestart, value);
+ }
+
+ private bool _isRestartAlways;
+
+ public bool IsRestartAlways
+ {
+ get => _isRestartAlways;
+ set => this.RaiseAndSetIfChanged(ref _isRestartAlways, value);
+ }
+
+ private long _serverId;
+
+ public long ServerId
+ {
+ get => _serverId;
+ set => this.RaiseAndSetIfChanged(ref _serverId, value);
+ }
public string Name { get; set; }
private Instance _instance;
diff --git a/HetznerServer/Service/ServerService.cs b/HetznerServer/Service/ServerService.cs
index c4407fc..fd36bd8 100644
--- a/HetznerServer/Service/ServerService.cs
+++ b/HetznerServer/Service/ServerService.cs
@@ -35,7 +35,7 @@ public class ServerService: IServerService
{
this.reloadServerStatus();
};
- _reloadTimer.Interval = TimeSpan.FromMinutes(10);
+ _reloadTimer.Interval = TimeSpan.FromMinutes(60);
_reloadTimer.Start();
reloadServer();
@@ -78,174 +78,7 @@ public class ServerService: IServerService
foreach (Server serv in SourceCache.Items)
{
- if (settings.ServerSettings.Count(e => e.ServerId == serv.ServerId) > 0)
- {
- serv.FastBillId = settings.ServerSettings.First(e => e.ServerId == serv.ServerId).FastBillId;
- serv.FastBillNr = settings.ServerSettings.First(e => e.ServerId == serv.ServerId).FastBillNr;
- serv.PscApiKey = settings.ServerSettings.First(e => e.ServerId == serv.ServerId).PscApiKey;
- }
-
- 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));
- }
- var httpClient = new HttpClient();
- httpClient.DefaultRequestHeaders.Accept.Clear();
- httpClient.DefaultRequestHeaders.Accept.Add(
- new MediaTypeWithQualityHeaderValue("application/ld+json"));
- httpClient.DefaultRequestHeaders.Add("User-Agent", "PSC Client");
- try
- {
- 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());
- }
- catch (Exception ex)
- {
- }
-
- }
- }
- }
-
- if (serv.PscApiKey != "" && serv.Domains.Count > 0)
- {
- var httpClient = new HttpClient();
- httpClient.DefaultRequestHeaders.Accept.Clear();
- httpClient.DefaultRequestHeaders.Accept.Add(
- new MediaTypeWithQualityHeaderValue("application/ld+json"));
- httpClient.DefaultRequestHeaders.Add("User-Agent", "PSC Client");
- httpClient.DefaultRequestHeaders.Add("apiKey", serv.PscApiKey);
- try
- {
- var stringPlugins =
- httpClient.GetStringAsync("https://" + serv.Domains.First().Name + "/apps/api/plugins");
- var msg = await stringPlugins;
- JObject pluginMsg = JObject.Parse(msg);
- foreach (var plugin in pluginMsg["data"])
- {
- serv.Plugins.Add(new Plugin()
- {
- Installed = bool.Parse(plugin["installed"].ToString()),
- Title = plugin["title"].ToString(),
- Uuid = plugin["uuid"].ToString()
- });
- }
- }
- catch (Exception ex)
- {
- }
-
- }
-
- if (serv.PscApiKey != "" && serv.Domains.Count > 0)
- {
- var httpClient = new HttpClient();
- httpClient.DefaultRequestHeaders.Accept.Clear();
- httpClient.DefaultRequestHeaders.Accept.Add(
- new MediaTypeWithQualityHeaderValue("application/ld+json"));
- httpClient.DefaultRequestHeaders.Add("User-Agent", "PSC Client");
- httpClient.DefaultRequestHeaders.Add("apiKey", serv.PscApiKey);
- try
- {
- var stringPlugins =
- httpClient.GetStringAsync("https://" + serv.Domains.First().Name + "/apps/api/system/info");
- var msg = await stringPlugins;
- JObject systemInfo = JObject.Parse(msg);
- serv.Instance.SftpUserName = systemInfo["sftpUserName"].ToString();
- serv.Instance.SftpPassword = systemInfo["sftpPassword"].ToString();
- serv.Instance.SftpHostName = systemInfo["sftpHost"].ToString();
- serv.Instance.SmtpOwn = bool.Parse(systemInfo["smtpOwn"].ToString());
- }
- catch (Exception ex)
- {
- }
-
- }
-
- serv.IsGoodIcon = MaterialIconKind.Check;
- serv.IsGoodColor = Brushes.Green;
-
- client.Disconnect();
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- }
-
+ doScan(serv);
}
await uiDispatcher.InvokeAsync(() =>
@@ -270,4 +103,252 @@ public class ServerService: IServerService
}
_settingsManager.SavePluginSettings("HetznerSettings", settings);
}
+
+ public void DoAptUpgrade(Server serv)
+ {
+ 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("apt upgrade -y && apt auto-remove -y");
+ if (command.ExitStatus == 0)
+ {
+ Console.WriteLine(serv.Name + " SUCCESS upgraded apt.");
+ }
+ else
+ {
+ Console.WriteLine(serv.Name + " ERROR upgraded apt.");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ public void DoReboot(Server serv)
+ {
+ 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("reboot");
+ if (command.ExitStatus == 0)
+ {
+ Console.WriteLine(serv.Name + " SUCCESS Reboot");
+ }
+ else
+ {
+ Console.WriteLine(serv.Name + " ERROR Reboot");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ public void DoReScan(Server serv)
+ {
+ doScan(serv);
+ }
+
+ async private void doScan(Server serv)
+ {
+ var settings = new Settings();
+ _settingsManager.LoadPluginSettings("HetznerSettings", settings);
+
+ if (settings.ServerSettings.Count(e => e.ServerId == serv.ServerId) > 0)
+ {
+ serv.FastBillId = settings.ServerSettings.First(e => e.ServerId == serv.ServerId).FastBillId;
+ serv.FastBillNr = settings.ServerSettings.First(e => e.ServerId == serv.ServerId).FastBillNr;
+ serv.PscApiKey = settings.ServerSettings.First(e => e.ServerId == serv.ServerId).PscApiKey;
+ }
+
+ 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);
+ serv.BackupLastModified = DateTime.Parse(borgMatic[0]["repository"]["last_modified"].ToString());
+ }
+ command = client.RunCommand("whereis needrestart");
+ if (command.ExitStatus == 0)
+ {
+ if (command.Result.Length > 20)
+ {
+ serv.HasNeedRestart = true;
+ }
+ }
+ 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 hostConfigArray = web[0]["HostConfig"];
+ if (hostConfigArray["RestartPolicy"]["Name"].ToString() == "always")
+ {
+ serv.IsRestartAlways = true;
+ }
+
+ 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));
+ }
+ var httpClient = new HttpClient();
+ httpClient.DefaultRequestHeaders.Accept.Clear();
+ httpClient.DefaultRequestHeaders.Accept.Add(
+ new MediaTypeWithQualityHeaderValue("application/ld+json"));
+ httpClient.DefaultRequestHeaders.Add("User-Agent", "PSC Client");
+ try
+ {
+ 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());
+ }
+ catch (Exception ex)
+ {
+ }
+
+ }
+ }
+ }
+
+ if (serv.PscApiKey != "" && serv.Domains.Count > 0)
+ {
+ var httpClient = new HttpClient();
+ httpClient.DefaultRequestHeaders.Accept.Clear();
+ httpClient.DefaultRequestHeaders.Accept.Add(
+ new MediaTypeWithQualityHeaderValue("application/ld+json"));
+ httpClient.DefaultRequestHeaders.Add("User-Agent", "PSC Client");
+ httpClient.DefaultRequestHeaders.Add("apiKey", serv.PscApiKey);
+ try
+ {
+ var stringPlugins =
+ httpClient.GetStringAsync("https://" + serv.Domains.First().Name + "/apps/api/plugins");
+ var msg = await stringPlugins;
+ JObject pluginMsg = JObject.Parse(msg);
+ foreach (var plugin in pluginMsg["data"])
+ {
+ serv.Plugins.Add(new Plugin()
+ {
+ Installed = bool.Parse(plugin["installed"].ToString()),
+ Title = plugin["title"].ToString(),
+ Uuid = plugin["uuid"].ToString()
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+ }
+
+ }
+
+ if (serv.PscApiKey != "" && serv.Domains.Count > 0)
+ {
+ var httpClient = new HttpClient();
+ httpClient.DefaultRequestHeaders.Accept.Clear();
+ httpClient.DefaultRequestHeaders.Accept.Add(
+ new MediaTypeWithQualityHeaderValue("application/ld+json"));
+ httpClient.DefaultRequestHeaders.Add("User-Agent", "PSC Client");
+ httpClient.DefaultRequestHeaders.Add("apiKey", serv.PscApiKey);
+ try
+ {
+ var stringPlugins =
+ httpClient.GetStringAsync("https://" + serv.Domains.First().Name + "/apps/api/system/info");
+ var msg = await stringPlugins;
+ JObject systemInfo = JObject.Parse(msg);
+ serv.Instance.SftpUserName = systemInfo["sftpUserName"].ToString();
+ serv.Instance.SftpPassword = systemInfo["sftpPassword"].ToString();
+ serv.Instance.SftpHostName = systemInfo["sftpHost"].ToString();
+ serv.Instance.SmtpOwn = bool.Parse(systemInfo["smtpOwn"].ToString());
+ }
+ catch (Exception ex)
+ {
+ }
+
+ }
+
+ if (serv.PscApiKey.Length > 0)
+ {
+ serv.IsGoodIcon = MaterialIconKind.Check;
+ serv.IsGoodColor = Brushes.Green;
+ }
+
+ client.Disconnect();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/HetznerServer/ViewModels/ServerViewModel.cs b/HetznerServer/ViewModels/ServerViewModel.cs
index 286c3d0..695887f 100644
--- a/HetznerServer/ViewModels/ServerViewModel.cs
+++ b/HetznerServer/ViewModels/ServerViewModel.cs
@@ -42,6 +42,10 @@ public partial class ServerViewModel : ViewModelBase, IViewModelBase
public ReactiveCommand SelectionChanged { get; }
public ReactiveCommand SaveServerSettings { get; }
+ public ReactiveCommand AptUpdate { get; }
+ public ReactiveCommand ReScan { get; }
+ public ReactiveCommand Reboot { get; }
+
protected readonly ReadOnlyObservableCollection _server;
public ReadOnlyObservableCollection Server => _server;
@@ -53,6 +57,9 @@ public partial class ServerViewModel : ViewModelBase, IViewModelBase
SelectedServer = new Server(1,"","","","","");
SelectionChanged = ReactiveCommand.Create(selectionChanged);
SaveServerSettings = ReactiveCommand.Create(saveServerSettings);
+ AptUpdate = ReactiveCommand.Create(doAptUpdate);
+ ReScan = ReactiveCommand.Create(doReScan);
+ Reboot = ReactiveCommand.Create(doReboot);
_settingsManager = (SettingsManager)Ioc.Default.GetService();
ServerService.SourceCache.Connect()
// Sort Ascending on the OrderIndex property
@@ -137,4 +144,37 @@ public partial class ServerViewModel : ViewModelBase, IViewModelBase
{
ServerService.SaveSettings(SelectedServer);
}
+
+ void doAptUpdate()
+ {
+ foreach (var serv in Server)
+ {
+ if (serv.IsChecked)
+ {
+ ServerService.DoAptUpgrade(serv);
+ }
+ }
+ }
+
+ void doReboot()
+ {
+ foreach (var serv in Server)
+ {
+ if (serv.IsChecked)
+ {
+ ServerService.DoReboot(serv);
+ }
+ }
+ }
+
+ void doReScan()
+ {
+ foreach (var serv in Server)
+ {
+ if (serv.IsChecked)
+ {
+ ServerService.DoReScan(serv);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/HetznerServer/Views/ServerView.axaml b/HetznerServer/Views/ServerView.axaml
index bb63366..f6774aa 100644
--- a/HetznerServer/Views/ServerView.axaml
+++ b/HetznerServer/Views/ServerView.axaml
@@ -23,10 +23,17 @@
Suchtext
-
+
+
+
+
+
+
+
@@ -43,6 +50,13 @@
+
+
+
+
+
+
+
@@ -50,11 +64,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+