Files
123123/ZA.CoreService.ESBCertificateManager/Services/SonicManagementClient.cs
T
GizzlerandCursor d1b95bcb9d Keep original UI; drop unused deploy/XApi/WinRM/TLS/SQL paths.
Form1 design unchanged; only MfApi restart and certificate recognition remain active.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 11:09:46 +02:00

105 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using ZA.CoreService.ESBCertificateManager.Models;
namespace ZA.CoreService.ESBCertificateManager.Services;
/// <summary>
/// Sonic MfApi (wie SMC-Neustart) ohne WinRM/HTTP/XApi.
/// </summary>
public sealed class SonicManagementClient : IDisposable
{
private readonly SonicConnection _connection;
private readonly SonicMfApiExecutor _mfApi;
public SonicManagementClient(SonicConnection connection)
{
_connection = connection;
_mfApi = new SonicMfApiExecutor(connection);
}
public async Task<(bool Success, string? Error, string? ResolvedPath)> CheckConnectionAsync(
CancellationToken cancellationToken = default)
{
(bool ok, string? error) = await _mfApi.TestConnectionAsync(cancellationToken);
if (ok)
{
return (true, null, $"MfApi {_connection.ConnectionUrl} Domain={_connection.DomainName}");
}
if (_connection.KnownContainers.Count > 0
&& await IsTcpReachableAsync(_connection.ConnectionUrl, cancellationToken))
{
return (true, null,
$"MfApi-Ping fehlgeschlagen, KnownContainers/TCP ok. Hinweis: {Truncate(error)}");
}
return (false, error ?? "MfApi-Verbindung fehlgeschlagen", null);
}
public async Task<(bool Success, IReadOnlyList<string> ContainerNames, string? Error)> GetContainersAsync(
CancellationToken cancellationToken = default)
{
(bool ok, IReadOnlyList<string> names, string? error) =
await _mfApi.ListContainersAsync(cancellationToken);
if (ok && names.Count > 0)
{
return (true, names, null);
}
if (_connection.KnownContainers.Count > 0)
{
return (true, _connection.KnownContainers,
ok ? null : $"Liste leer/fehlerhaft KnownContainers. {error}");
}
return (false, [], error ?? "Keine Container gefunden.");
}
public async Task<(bool Success, string Status, string? Detail)> RestartContainerAsync(
string containerName,
CancellationToken cancellationToken = default)
{
(bool ok, string? output, string? error) =
await _mfApi.RestartAsync(containerName, cancellationToken);
if (ok)
{
await Task.Delay(
TimeSpan.FromSeconds(Math.Clamp(_connection.PostRestartDelaySeconds, 0, 120)),
cancellationToken);
return (true, $"Container '{containerName}' neugestartet (MfApi)",
$"Domain={_connection.DomainName}; URL={_connection.ConnectionUrl}\n{output}");
}
return (false, "Neustart fehlgeschlagen (MfApi)",
$"Container '{containerName}', Domain '{_connection.DomainName}', URL {_connection.ConnectionUrl}\n" +
$"Fehler: {error}\n\n{output}");
}
private static async Task<bool> IsTcpReachableAsync(string connectionUrl, CancellationToken cancellationToken)
{
try
{
Uri uri = new(connectionUrl);
using System.Net.Sockets.TcpClient tcp = new();
using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(TimeSpan.FromSeconds(5));
await tcp.ConnectAsync(uri.Host, uri.Port > 0 ? uri.Port : 2506, cts.Token);
return true;
}
catch
{
return false;
}
}
private static string Truncate(string? s, int max = 180)
=> string.IsNullOrWhiteSpace(s) ? string.Empty
: s.Length <= max ? s : s[..max] + "…";
public void Dispose()
{
}
}