diff --git a/ZA.CoreService.ESBCertificateManager/Form1.cs b/ZA.CoreService.ESBCertificateManager/Form1.cs index a588088..507b8c2 100644 --- a/ZA.CoreService.ESBCertificateManager/Form1.cs +++ b/ZA.CoreService.ESBCertificateManager/Form1.cs @@ -1462,8 +1462,8 @@ namespace ZA.CoreService.ESBCertificateManager btnRestartOnly.Anchor = AnchorStyles.Top | AnchorStyles.Right; btnRestartOnly.Click += async (_, _) => await RunRestartOnlyAsync(); - btnDeploy = CreatePrimaryButton("Deployment starten"); - btnDeploy.Size = new Size(170, 42); + btnDeploy = CreatePrimaryButton("Austauschen + Neustart"); + btnDeploy.Size = new Size(190, 42); btnDeploy.Anchor = AnchorStyles.Top | AnchorStyles.Right; btnDeploy.Visible = true; btnDeploy.Click += async (_, _) => await RunDeploymentAsync(); @@ -2013,11 +2013,24 @@ namespace ZA.CoreService.ESBCertificateManager return; } + string targetSummary = string.Join( + Environment.NewLine, + selectedTargets.Select(target => + $"• {target.Name}" + + Environment.NewLine + + $" Datei → {target.FullTargetPath}" + + Environment.NewLine + + $" danach Neustart: {target.ContainerName}")); + DialogResult confirm = MessageBox.Show( this, - $"Zertifikat wirklich auf {selectedTargets.Count} Ziel(e) kopieren?\n\n" + - $"Datei: {Path.GetFileName(txtCertificatePath.Text)}", - "Deployment starten", + "Zertifikat wirklich austauschen?\n\n" + + "Ablauf je Ziel:\n" + + "1) Datei kopieren (Backup der alten Datei)\n" + + "2) Sonic-Container neu starten (MfApi)\n\n" + + $"Quelle: {Path.GetFileName(txtCertificatePath.Text)}\n\n" + + targetSummary, + "Austauschen + Neustart", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); @@ -2033,7 +2046,7 @@ namespace ZA.CoreService.ESBCertificateManager UpdateToNextStep(3); SetStatus( - $"Kopiere Zertifikat auf {selectedTargets.Count} Ziel(e) ...", + $"Tausche Zertifikat auf {selectedTargets.Count} Ziel(e) und starte Container neu …", isError: false); Progress progress = new(update => @@ -2061,15 +2074,16 @@ namespace ZA.CoreService.ESBCertificateManager if (runResult.OverallSuccess) { SetStatus( - $"Deployment erfolgreich: {runResult.TargetResults.Count} Ziel(e).", + $"Austausch + Neustart OK ({runResult.TargetResults.Count} Ziel(e)).", isError: false); UpdateToNextStep(4); + await ProbeTargetCertificatesAsync(); } else { SetStatus( - "Deployment für mindestens ein Ziel fehlgeschlagen.", + "Austausch für mindestens ein Ziel fehlgeschlagen.", isError: true); string details = string.Join( @@ -2083,23 +2097,25 @@ namespace ZA.CoreService.ESBCertificateManager CopyableErrorDialog.Show( this, - "Deployment fehlgeschlagen", + "Austausch fehlgeschlagen", details); + + await ProbeTargetCertificatesAsync(); } } catch (OperationCanceledException) { - SetStatus("Deployment abgebrochen.", isError: true); + SetStatus("Austausch abgebrochen.", isError: true); } catch (Exception ex) { SetStatus( - $"Deployment fehlgeschlagen: {ex.Message}", + $"Austausch fehlgeschlagen: {ex.Message}", isError: true); CopyableErrorDialog.Show( this, - "Deployment fehlgeschlagen", + "Austausch fehlgeschlagen", ex.ToString()); } finally diff --git a/ZA.CoreService.ESBCertificateManager/Services/DeploymentOrchestrator.cs b/ZA.CoreService.ESBCertificateManager/Services/DeploymentOrchestrator.cs index 639226d..a0b62d7 100644 --- a/ZA.CoreService.ESBCertificateManager/Services/DeploymentOrchestrator.cs +++ b/ZA.CoreService.ESBCertificateManager/Services/DeploymentOrchestrator.cs @@ -191,29 +191,85 @@ public sealed class DeploymentOrchestrator target.BackupDirectoryName, cancellationToken); - string copyStatus = $"Zertifikat kopiert: {Path.GetFileName(deployedFilePath)}"; + string copyStatus = + $"Zertifikat kopiert: {Path.GetFileName(deployedFilePath)}"; steps.Add(copyStatus); - logger.Write($"[{target.Name}] {copyStatus} | Ziel={deployedFilePath}"); + logger.Write( + $"[{target.Name}] {copyStatus} | Ziel={deployedFilePath}"); progress?.Report(new TargetProgressUpdate( target.Id, copyStatus, true)); + // Nach dem Dateitausch Container neu starten, damit Sonic + // das neue Zertifikat lädt. Ohne Neustart bleibt oft das Alte aktiv. + bool restartNeeded = + target.RestartType is RestartType.SonicContainer + or RestartType.SonicContainerWithXapi + || !string.IsNullOrWhiteSpace(target.ContainerName); + + if (!restartNeeded) + { + return new TargetStepResult + { + TargetId = target.Id, + TargetName = target.Name, + Success = true, + StatusText = "Kopieren erfolgreich (kein Neustart)", + Detail = deployedFilePath, + Steps = steps, + StartedAt = targetStart, + FinishedAt = DateTimeOffset.Now, + CopySucceeded = true, + RestartSucceeded = true, + TlsSucceeded = true, + ObservedFingerprint = null + }; + } + + progress?.Report(new TargetProgressUpdate( + target.Id, + "Zertifikat kopiert – Container-Neustart …", + true)); + + (bool restartOk, string restartStatus, string? restartDetail) = + await _restartExecutor.ExecuteAsync( + target, + cancellationToken); + + string restartStep = + $"{restartStatus}: {restartDetail}"; + + steps.Add(restartStep); + logger.Write( + $"[{target.Name}] Restart nach Deploy: {restartStep}"); + + progress?.Report(new TargetProgressUpdate( + target.Id, + restartOk + ? "Austausch + Neustart OK" + : restartStatus, + restartOk)); + return new TargetStepResult { TargetId = target.Id, TargetName = target.Name, - Success = true, - StatusText = "Kopieren erfolgreich", - Detail = deployedFilePath, + Success = restartOk, + StatusText = restartOk + ? "Austausch + Neustart OK" + : $"Kopiert, Neustart fehlgeschlagen: {restartStatus}", + Detail = + $"Datei={deployedFilePath}" + + Environment.NewLine + + (restartDetail ?? string.Empty), Steps = steps, StartedAt = targetStart, FinishedAt = DateTimeOffset.Now, - CopySucceeded = true, - RestartSucceeded = true, + RestartSucceeded = restartOk, TlsSucceeded = true, ObservedFingerprint = null };