Add live TLS certificate probing and improve restart error handling.
Configure CertificateCheckUrl per container for curl-like TLS checks, classify Sonic permission errors, and extend setup wizard for container management. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using ZA.CoreService.ESBCertificateManager.Models;
|
||||
using ZA.CoreService.ESBCertificateManager.Services;
|
||||
|
||||
namespace ZA.CoreService.ESBCertificateManager.Setup;
|
||||
|
||||
@@ -11,8 +12,10 @@ public sealed class AddContainerForm : Form
|
||||
private readonly ComboBox _cmbSystem;
|
||||
private readonly TextBox _txtName;
|
||||
private readonly TextBox _txtDisplay;
|
||||
private readonly TextBox _txtCheckUrl;
|
||||
private readonly TextBox _txtTimeout;
|
||||
private readonly Button _btnSave;
|
||||
private readonly Button _btnProbeUrl;
|
||||
private bool _running;
|
||||
|
||||
public int? CreatedSonicContainerId { get; private set; }
|
||||
@@ -36,7 +39,7 @@ public sealed class AddContainerForm : Form
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
ShowInTaskbar = false;
|
||||
ClientSize = new Size(540, 470);
|
||||
ClientSize = new Size(540, 560);
|
||||
BackColor = SettingsUi.Background;
|
||||
ForeColor = SettingsUi.Text;
|
||||
Font = new Font("Segoe UI", 10f);
|
||||
@@ -55,7 +58,7 @@ public sealed class AddContainerForm : Form
|
||||
Label subtitle = new()
|
||||
{
|
||||
Text =
|
||||
"Container einer Company und einem Sonic-System zuordnen.",
|
||||
"Container zuordnen und optional TLS-Prüf-URL hinterlegen.",
|
||||
Location = new Point(30, 58),
|
||||
AutoSize = true,
|
||||
ForeColor = SettingsUi.Muted
|
||||
@@ -63,13 +66,14 @@ public sealed class AddContainerForm : Form
|
||||
|
||||
Panel card = SettingsUi.CreateCard();
|
||||
card.Location = new Point(28, 95);
|
||||
card.Size = new Size(484, 290);
|
||||
card.Size = new Size(484, 370);
|
||||
card.Paint += SettingsUi.PaintCardBorder;
|
||||
|
||||
_cmbCompany = SettingsUi.CreateComboBox();
|
||||
_cmbSystem = SettingsUi.CreateComboBox();
|
||||
_txtName = SettingsUi.CreateTextBox();
|
||||
_txtDisplay = SettingsUi.CreateTextBox();
|
||||
_txtCheckUrl = SettingsUi.CreateTextBox();
|
||||
_txtTimeout = SettingsUi.CreateTextBox();
|
||||
_txtTimeout.Text = "180";
|
||||
|
||||
@@ -77,6 +81,7 @@ public sealed class AddContainerForm : Form
|
||||
{
|
||||
_txtName.Text = _existing.ContainerName;
|
||||
_txtDisplay.Text = _existing.ContainerDisplayName ?? string.Empty;
|
||||
_txtCheckUrl.Text = _existing.CertificateCheckUrl ?? string.Empty;
|
||||
_txtTimeout.Text = _existing.RestartTimeoutSeconds.ToString();
|
||||
}
|
||||
|
||||
@@ -85,15 +90,39 @@ public sealed class AddContainerForm : Form
|
||||
AddField(card, "Container-Name", _txtName, 18, 138, 440);
|
||||
AddField(card, "Anzeigename (optional)", _txtDisplay, 18, 198, 280);
|
||||
AddField(card, "Timeout (s)", _txtTimeout, 318, 198, 140);
|
||||
AddField(
|
||||
card,
|
||||
"Zertifikat prüfen (URL / Host:Port)",
|
||||
_txtCheckUrl,
|
||||
18,
|
||||
258,
|
||||
440);
|
||||
|
||||
Label urlHint = new()
|
||||
{
|
||||
Text = "z. B. https://server:8443 oder server:8443",
|
||||
Location = new Point(18, 312),
|
||||
AutoSize = true,
|
||||
ForeColor = SettingsUi.Muted,
|
||||
Font = new Font("Segoe UI", 8.5f)
|
||||
};
|
||||
|
||||
_btnProbeUrl = SettingsUi.CreateGhostButton("URL prüfen");
|
||||
_btnProbeUrl.Location = new Point(318, 318);
|
||||
_btnProbeUrl.Size = new Size(140, 30);
|
||||
_btnProbeUrl.Click += (_, _) => ProbeUrl();
|
||||
|
||||
card.Controls.Add(urlHint);
|
||||
card.Controls.Add(_btnProbeUrl);
|
||||
|
||||
_btnSave = SettingsUi.CreatePrimaryButton(
|
||||
IsEditMode ? "Änderungen speichern" : "Container anlegen");
|
||||
_btnSave.Location = new Point(292, 405);
|
||||
_btnSave.Location = new Point(292, 490);
|
||||
_btnSave.Size = new Size(220, 40);
|
||||
_btnSave.Click += async (_, _) => await SaveAsync();
|
||||
|
||||
Button cancel = SettingsUi.CreateGhostButton("Abbrechen");
|
||||
cancel.Location = new Point(170, 405);
|
||||
cancel.Location = new Point(170, 490);
|
||||
cancel.Size = new Size(110, 40);
|
||||
cancel.Click += (_, _) =>
|
||||
{
|
||||
@@ -110,6 +139,53 @@ public sealed class AddContainerForm : Form
|
||||
Shown += async (_, _) => await LoadLookupsAsync();
|
||||
}
|
||||
|
||||
private void ProbeUrl()
|
||||
{
|
||||
string url = _txtCheckUrl.Text.Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
MessageBox.Show(
|
||||
this,
|
||||
"Bitte zuerst eine Prüf-URL eintragen.",
|
||||
"URL prüfen",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
TlsEndpointProbeService probe = new();
|
||||
CertificateProbeResult result = probe.Probe(url);
|
||||
|
||||
if (result.Success && result.Certificate is not null)
|
||||
{
|
||||
string expiry = result.Certificate.ValidUntil
|
||||
.ToLocalTime()
|
||||
.ToString("dd.MM.yyyy HH:mm");
|
||||
|
||||
MessageBox.Show(
|
||||
this,
|
||||
$"TLS-Zertifikat erreichbar.\n\n"
|
||||
+ $"Subject: {result.Certificate.Subject}\n"
|
||||
+ $"Aussteller: {result.Certificate.Issuer}\n"
|
||||
+ $"Gültig bis: {expiry}\n"
|
||||
+ $"Status: {(result.Certificate.IsCurrentlyValid ? "gültig" : "abgelaufen")}",
|
||||
"URL prüfen",
|
||||
MessageBoxButtons.OK,
|
||||
result.Certificate.IsCurrentlyValid
|
||||
? MessageBoxIcon.Information
|
||||
: MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
MessageBox.Show(
|
||||
this,
|
||||
result.Message,
|
||||
"URL prüfen",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
}
|
||||
|
||||
private async Task LoadLookupsAsync()
|
||||
{
|
||||
try
|
||||
@@ -211,6 +287,29 @@ public sealed class AddContainerForm : Form
|
||||
return;
|
||||
}
|
||||
|
||||
string? checkUrl = _txtCheckUrl.Text.Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(checkUrl))
|
||||
{
|
||||
checkUrl = null;
|
||||
}
|
||||
else if (!TlsEndpointProbeService.TryParseEndpoint(
|
||||
checkUrl,
|
||||
out _,
|
||||
out _,
|
||||
out _,
|
||||
out string? parseError))
|
||||
{
|
||||
MessageBox.Show(
|
||||
this,
|
||||
parseError ?? "Ungültige Prüf-URL.",
|
||||
"Container",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
_txtCheckUrl.Focus();
|
||||
return;
|
||||
}
|
||||
|
||||
_running = true;
|
||||
_btnSave.Enabled = false;
|
||||
Cursor = Cursors.WaitCursor;
|
||||
@@ -225,7 +324,8 @@ public sealed class AddContainerForm : Form
|
||||
system.SonicConnectionId,
|
||||
_txtName.Text,
|
||||
_txtDisplay.Text,
|
||||
timeout);
|
||||
timeout,
|
||||
checkUrl);
|
||||
|
||||
CreatedSonicContainerId = _existing.SonicContainerId;
|
||||
}
|
||||
@@ -237,7 +337,8 @@ public sealed class AddContainerForm : Form
|
||||
system.SonicConnectionId,
|
||||
_txtName.Text,
|
||||
_txtDisplay.Text,
|
||||
timeout);
|
||||
timeout,
|
||||
checkUrl);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
|
||||
Reference in New Issue
Block a user