using ZA.CoreService.ESBCertificateManager.Models; namespace ZA.CoreService.ESBCertificateManager.Services; public sealed class PreflightValidator { public PreflightValidationResult Validate( string? certificatePath, CertificateInfo? certificateInfo, IReadOnlyList 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); } return result; } private static void ValidateTarget(PreflightValidationResult result, DeploymentTarget target) { 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 (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 }); } }