140 lines
4.5 KiB
C#
140 lines
4.5 KiB
C#
using ZA.CoreService.ESBCertificateManager.Models;
|
||
|
||
namespace ZA.CoreService.ESBCertificateManager.Services;
|
||
|
||
public sealed class PreflightValidator
|
||
{
|
||
public PreflightValidationResult Validate(
|
||
string? certificatePath,
|
||
CertificateInfo? certificateInfo,
|
||
IReadOnlyList<DeploymentTarget> selectedTargets)
|
||
{
|
||
PreflightValidationResult result = new();
|
||
|
||
if (string.IsNullOrWhiteSpace(certificatePath) || !File.Exists(certificatePath))
|
||
{
|
||
AddIssue(result, "Es ist keine gültige Zertifikatsdatei ausgewählt.");
|
||
}
|
||
|
||
if (certificateInfo is null)
|
||
{
|
||
AddIssue(result, "Zertifikatsmetadaten sind nicht geladen.");
|
||
}
|
||
else if (!certificateInfo.IsCurrentlyValid)
|
||
{
|
||
AddIssue(result, "Das geladene Zertifikat ist abgelaufen oder ungültig.");
|
||
}
|
||
|
||
if (selectedTargets.Count == 0)
|
||
{
|
||
AddIssue(result, "Bitte mindestens ein Ziel anhaken.");
|
||
}
|
||
|
||
foreach (DeploymentTarget target in selectedTargets)
|
||
{
|
||
ValidateTarget(result, target, requireDeployPaths: true);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Vorabprüfung nur für ESB-Neustart (ohne Zertifikat / Kopierpfade).
|
||
/// </summary>
|
||
public PreflightValidationResult ValidateRestartOnly(IReadOnlyList<DeploymentTarget> selectedTargets)
|
||
{
|
||
PreflightValidationResult result = new();
|
||
|
||
if (selectedTargets.Count == 0)
|
||
{
|
||
AddIssue(result, "Bitte mindestens ein Ziel anhaken.");
|
||
return result;
|
||
}
|
||
|
||
foreach (DeploymentTarget target in selectedTargets)
|
||
{
|
||
if (target.RestartType is RestartType.None)
|
||
{
|
||
AddIssue(result, $"Ziel '{target.Name}': RestartType=None – kein Neustart konfiguriert.", target.Id);
|
||
continue;
|
||
}
|
||
|
||
ValidateTarget(result, target, requireDeployPaths: false);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
private static void ValidateTarget(
|
||
PreflightValidationResult result,
|
||
DeploymentTarget target,
|
||
bool requireDeployPaths)
|
||
{
|
||
if (requireDeployPaths)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(target.TargetDirectory))
|
||
{
|
||
AddIssue(result, $"Ziel '{target.Name}': TargetDirectory fehlt.", target.Id);
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(target.CertificateFileName))
|
||
{
|
||
AddIssue(result, $"Ziel '{target.Name}': CertificateFileName fehlt.", target.Id);
|
||
}
|
||
}
|
||
|
||
if (target.RestartType == RestartType.Command
|
||
&& string.IsNullOrWhiteSpace(target.RestartCommand))
|
||
{
|
||
AddIssue(result, $"Ziel '{target.Name}': RestartCommand fehlt bei RestartType=Command.", target.Id);
|
||
}
|
||
|
||
if (target.RestartType is RestartType.SonicContainer or RestartType.SonicContainerWithXapi)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(target.ContainerName))
|
||
{
|
||
AddIssue(result, $"Ziel '{target.Name}': ContainerName fehlt bei RestartType={target.RestartType}.", target.Id);
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(target.SonicConnectionName))
|
||
{
|
||
AddIssue(result, $"Ziel '{target.Name}': SonicConnectionName fehlt bei RestartType={target.RestartType}.", target.Id);
|
||
}
|
||
}
|
||
|
||
if (target.RestartType == RestartType.SonicContainerWithXapi
|
||
&& string.IsNullOrWhiteSpace(target.XapiSourcePath))
|
||
{
|
||
AddIssue(result, $"Ziel '{target.Name}': XapiSourcePath fehlt bei RestartType=SonicContainerWithXapi.", target.Id);
|
||
}
|
||
|
||
if (!requireDeployPaths || string.IsNullOrWhiteSpace(target.TargetDirectory))
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
string directory = PathResolver.ResolvePath(target.TargetDirectory);
|
||
Directory.CreateDirectory(directory);
|
||
|
||
string probeFile = Path.Combine(directory, $".write-probe-{Guid.NewGuid():N}");
|
||
File.WriteAllText(probeFile, "ok");
|
||
File.Delete(probeFile);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
AddIssue(result, $"Ziel '{target.Name}': Verzeichnis nicht beschreibbar ({ex.Message}).", target.Id);
|
||
}
|
||
}
|
||
|
||
private static void AddIssue(PreflightValidationResult result, string message, int? targetId = null)
|
||
{
|
||
result.Issues.Add(new ValidationIssue
|
||
{
|
||
TargetId = targetId,
|
||
Message = message
|
||
});
|
||
}
|
||
}
|