Simplify app to certificate recognition and MfApi restart only.
Remove XApi, WinRM, LocalCmd, HTTP API, TLS probe, SQL deploy model, and deploy UI. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
using System.Diagnostics;
|
||||
using ZA.CoreService.ESBCertificateManager.Models;
|
||||
|
||||
namespace ZA.CoreService.ESBCertificateManager.Services;
|
||||
@@ -12,26 +11,13 @@ public sealed class RestartExecutor
|
||||
_sonicConnections = sonicConnections;
|
||||
}
|
||||
|
||||
public Task<(bool Success, string Status, string? Detail)> ExecuteAsync(
|
||||
public async Task<(bool Success, string Status, string? Detail)> ExecuteAsync(
|
||||
DeploymentTarget target,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> target.RestartType switch
|
||||
{
|
||||
RestartType.None => Task.FromResult<(bool, string, string?)>((true, "Neustart übersprungen", "RestartType=None")),
|
||||
RestartType.Command => ExecuteCommandAsync(target, cancellationToken),
|
||||
RestartType.SonicContainer => ExecuteSonicRestartAsync(target, importXapi: false, cancellationToken),
|
||||
RestartType.SonicContainerWithXapi => ExecuteSonicRestartAsync(target, importXapi: true, cancellationToken),
|
||||
_ => Task.FromResult<(bool, string, string?)>((false, "Unbekannter RestartType", $"RestartType={target.RestartType}"))
|
||||
};
|
||||
|
||||
private async Task<(bool Success, string Status, string? Detail)> ExecuteSonicRestartAsync(
|
||||
DeploymentTarget target,
|
||||
bool importXapi,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(target.ContainerName))
|
||||
{
|
||||
return (false, "Sonic-Neustart fehlgeschlagen", $"Ziel '{target.Name}': ContainerName fehlt.");
|
||||
return (false, "Neustart fehlgeschlagen", $"Ziel '{target.Name}': ContainerName fehlt.");
|
||||
}
|
||||
|
||||
SonicConnection? connection = _sonicConnections
|
||||
@@ -40,111 +26,10 @@ public sealed class RestartExecutor
|
||||
if (connection is null)
|
||||
{
|
||||
return (false, "Sonic-Verbindung nicht gefunden",
|
||||
$"Ziel '{target.Name}': SonicConnection '{target.SonicConnectionName}' ist nicht in AppSettings konfiguriert.");
|
||||
$"Ziel '{target.Name}': SonicConnection '{target.SonicConnectionName}' fehlt in appsettings.");
|
||||
}
|
||||
|
||||
using SonicManagementClient client = new(connection);
|
||||
|
||||
if (importXapi)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(target.XapiSourcePath))
|
||||
{
|
||||
return (false, "XApi-Import fehlgeschlagen",
|
||||
$"Ziel '{target.Name}': XapiSourcePath fehlt bei RestartType=SonicContainerWithXapi.");
|
||||
}
|
||||
|
||||
return await client.ImportXapiAndRestartAsync(target.ContainerName, target.XapiSourcePath, cancellationToken);
|
||||
}
|
||||
|
||||
return await client.RestartContainerAsync(target.ContainerName, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<(bool Success, string Status, string? Detail)> ExecuteCommandAsync(
|
||||
DeploymentTarget target,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(target.RestartCommand))
|
||||
{
|
||||
return (true, "Neustart übersprungen", "RestartType=None");
|
||||
}
|
||||
|
||||
int timeoutSeconds = Math.Clamp(target.RestartTimeoutSeconds, 1, 600);
|
||||
|
||||
ProcessStartInfo startInfo = new()
|
||||
{
|
||||
FileName = target.RestartCommand,
|
||||
Arguments = target.RestartArguments ?? string.Empty,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
using Process process = new() { StartInfo = startInfo };
|
||||
if (!process.Start())
|
||||
{
|
||||
return (false, "Neustart fehlgeschlagen", "Prozess konnte nicht gestartet werden.");
|
||||
}
|
||||
|
||||
Task<string> stdoutTask = process.StandardOutput.ReadToEndAsync(cancellationToken);
|
||||
Task<string> stderrTask = process.StandardError.ReadToEndAsync(cancellationToken);
|
||||
|
||||
using CancellationTokenSource timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
timeoutCts.CancelAfter(TimeSpan.FromSeconds(timeoutSeconds));
|
||||
|
||||
try
|
||||
{
|
||||
await process.WaitForExitAsync(timeoutCts.Token);
|
||||
}
|
||||
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try { process.Kill(entireProcessTree: true); } catch { /* ignore */ }
|
||||
return (false, "Neustart Timeout", $"Timeout nach {timeoutSeconds}s.");
|
||||
}
|
||||
|
||||
string detail = BuildDetail(process.ExitCode, await stdoutTask, await stderrTask);
|
||||
return process.ExitCode == 0
|
||||
? (true, "Neustart ok", detail)
|
||||
: (false, "Neustart fehlgeschlagen", detail);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (false, "Neustart fehlgeschlagen", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildDetail(int exitCode, string stdout, string stderr)
|
||||
{
|
||||
string detail = $"ExitCode={exitCode}";
|
||||
|
||||
stdout = Truncate(stdout).Trim();
|
||||
if (!string.IsNullOrWhiteSpace(stdout))
|
||||
{
|
||||
detail += "; out=" + stdout;
|
||||
}
|
||||
|
||||
stderr = Truncate(stderr).Trim();
|
||||
if (!string.IsNullOrWhiteSpace(stderr))
|
||||
{
|
||||
detail += "; err=" + stderr;
|
||||
}
|
||||
|
||||
return detail;
|
||||
}
|
||||
|
||||
private static string Truncate(string value, int max = 400)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || value.Length <= max)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return value[..max] + "…";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user