211 lines
8.3 KiB
C#
211 lines
8.3 KiB
C#
namespace ZA.CoreService.ESBCertificateManager.Models;
|
||
|
||
/// <summary>
|
||
/// Verbindungskonfiguration für eine Progress Sonic ESB Management Instanz.
|
||
/// </summary>
|
||
public sealed class SonicConnection
|
||
{
|
||
/// <summary>
|
||
/// Eindeutiger Bezeichner; wird in <see cref="DeploymentTarget.SonicConnectionName"/> referenziert.
|
||
/// </summary>
|
||
public required string Name { get; init; }
|
||
|
||
/// <summary>Sonic-Domain-Name, z.B. "proalpha-test".</summary>
|
||
public required string DomainName { get; init; }
|
||
|
||
/// <summary>
|
||
/// Sonic-Broker-/Management-URL im Sonic-Format, z.B. "tcp://dekun-painwbdet:13070".
|
||
/// Der Hostname wird daraus extrahiert (WinRM-Ziel / HTTP-Basis).
|
||
/// </summary>
|
||
public required string ConnectionUrl { get; init; }
|
||
|
||
/// <summary>Benutzername für WinRM / Management-Konsole.</summary>
|
||
public required string Username { get; init; }
|
||
|
||
/// <summary>Passwort für WinRM / Management-Konsole.</summary>
|
||
public required string Password { get; init; }
|
||
|
||
/// <summary>
|
||
/// Management-Modus:
|
||
/// - WinRm: PowerShell Remoting auf dem Sonic-Server (Standard)
|
||
/// - LocalCmd: CMD/PowerShell lokal (zum Testen direkt auf dem Sonic-PC)
|
||
/// - HttpApi: REST, falls vorhanden
|
||
/// </summary>
|
||
public SonicManagementMode ManagementMode { get; init; } = SonicManagementMode.WinRm;
|
||
|
||
/// <summary>
|
||
/// Installationsroot von Sonic MQ / Management Console, z.B. "C:\Sonic\MQ10.0".
|
||
/// Wird für Default-Scripts (stopcontainer/startcontainer) benötigt.
|
||
/// </summary>
|
||
public string SonicHome { get; init; } = @"C:\Sonic\MQ10.0";
|
||
|
||
/// <summary>
|
||
/// Bekannte Container-Namen dieser Domain (Fallback, wenn Remote-Discovery nichts findet).
|
||
/// z.B. [ "ESB", "DomainManager" ] oder vollqualifiziert [ "proalpha-test.ESB" ].
|
||
/// </summary>
|
||
public List<string> KnownContainers { get; init; } = [];
|
||
|
||
// ---------------------------------------------------------------
|
||
// HTTP REST API (ManagementMode = HttpApi)
|
||
// ---------------------------------------------------------------
|
||
|
||
public int ManagementHttpPort { get; init; } = 8080;
|
||
public string ApiBasePath { get; init; } = "/api/v1";
|
||
public string ContainerListPath { get; init; } = string.Empty;
|
||
public string ContainerRestartPath { get; init; } = string.Empty;
|
||
public string ContainerStopPath { get; init; } = string.Empty;
|
||
public string ContainerStartPath { get; init; } = string.Empty;
|
||
|
||
// ---------------------------------------------------------------
|
||
// WinRM / LocalCmd
|
||
// ---------------------------------------------------------------
|
||
|
||
public int WinRmPort { get; init; } = 5985;
|
||
|
||
/// <summary>
|
||
/// PowerShell-Script zum Neustarten. Leer = Default über Sonic bin\stop/startcontainer.bat.
|
||
/// Platzhalter: {container}, {domain}, {sonicHome}
|
||
/// </summary>
|
||
public string WinRmRestartScript { get; init; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// PowerShell-Script zum Auflisten der Container. Leer = Default (Services + SonicHome).
|
||
/// </summary>
|
||
public string WinRmContainerListScript { get; init; } = string.Empty;
|
||
|
||
public string WinRmXapiImportScript { get; init; } = string.Empty;
|
||
|
||
public int TimeoutSeconds { get; init; } = 60;
|
||
public int PostRestartDelaySeconds { get; init; } = 15;
|
||
|
||
/// <summary>Effektives Restart-Script inkl. Default, wenn leer.</summary>
|
||
public string ResolveRestartScript()
|
||
=> string.IsNullOrWhiteSpace(WinRmRestartScript)
|
||
? DefaultRestartScript
|
||
: WinRmRestartScript;
|
||
|
||
/// <summary>Effektives List-Script inkl. Default, wenn leer.</summary>
|
||
public string ResolveContainerListScript()
|
||
=> string.IsNullOrWhiteSpace(WinRmContainerListScript)
|
||
? DefaultContainerListScript
|
||
: WinRmContainerListScript;
|
||
|
||
/// <summary>
|
||
/// Default: Sonic Management Console Tools per CMD auf dem Ziel-PC.
|
||
/// stopcontainer.bat / startcontainer.bat unter SonicHome\bin.
|
||
/// </summary>
|
||
public const string DefaultRestartScript =
|
||
"""
|
||
$ErrorActionPreference = 'Stop'
|
||
$sonicHome = '{sonicHome}'
|
||
$domain = '{domain}'
|
||
$container = '{container}'
|
||
$bin = Join-Path $sonicHome 'bin'
|
||
$stop = Join-Path $bin 'stopcontainer.bat'
|
||
$start = Join-Path $bin 'startcontainer.bat'
|
||
$fullName = if ($container -like '*.*') { $container } else { "$domain.$container" }
|
||
|
||
if (-not (Test-Path -LiteralPath $stop)) {
|
||
throw "Sonic stopcontainer.bat nicht gefunden: $stop (SonicHome prüfen)"
|
||
}
|
||
if (-not (Test-Path -LiteralPath $start)) {
|
||
throw "Sonic startcontainer.bat nicht gefunden: $start (SonicHome prüfen)"
|
||
}
|
||
|
||
Write-Output "STOP $fullName via $stop"
|
||
$stopProc = Start-Process -FilePath 'cmd.exe' -ArgumentList @('/c', "`"$stop`" `"$fullName`"") -Wait -PassThru -NoNewWindow
|
||
if ($stopProc.ExitCode -ne 0) {
|
||
Write-Warning "stopcontainer ExitCode=$($stopProc.ExitCode) – starte trotzdem neu"
|
||
}
|
||
|
||
Start-Sleep -Seconds 5
|
||
|
||
Write-Output "START $fullName via $start"
|
||
$startProc = Start-Process -FilePath 'cmd.exe' -ArgumentList @('/c', "`"$start`" `"$fullName`"") -Wait -PassThru -NoNewWindow
|
||
if ($startProc.ExitCode -ne 0) {
|
||
throw "startcontainer fehlgeschlagen, ExitCode=$($startProc.ExitCode)"
|
||
}
|
||
|
||
Write-Output "Neustart ok: $fullName"
|
||
""";
|
||
|
||
public const string DefaultContainerListScript =
|
||
"""
|
||
$ErrorActionPreference = 'Continue'
|
||
$sonicHome = '{sonicHome}'
|
||
$domain = '{domain}'
|
||
$names = New-Object System.Collections.Generic.List[string]
|
||
|
||
function Add-Name([string]$n) {
|
||
if ([string]::IsNullOrWhiteSpace($n)) { return }
|
||
$n = $n.Trim()
|
||
if (-not $names.Contains($n)) { [void]$names.Add($n) }
|
||
}
|
||
|
||
if (-not (Test-Path -LiteralPath $sonicHome)) {
|
||
Write-Output "WARN:SonicHomeNichtGefunden:$sonicHome"
|
||
}
|
||
else {
|
||
Write-Output "INFO:SonicHomeOk:$sonicHome"
|
||
|
||
# *.cache Ordner (Domain.Container.cache) – 1–2 Ebenen
|
||
Get-ChildItem -LiteralPath $sonicHome -Directory -ErrorAction SilentlyContinue |
|
||
ForEach-Object {
|
||
if ($_.Name -like '*.cache') {
|
||
Add-Name ($_.Name -replace '\.cache$', '')
|
||
}
|
||
Get-ChildItem -LiteralPath $_.FullName -Directory -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.Name -like '*.cache' } |
|
||
ForEach-Object { Add-Name ($_.Name -replace '\.cache$', '') }
|
||
}
|
||
|
||
# container.xml / Containers-Verzeichnisse
|
||
Get-ChildItem -LiteralPath $sonicHome -Recurse -Filter 'container.xml' -File -ErrorAction SilentlyContinue |
|
||
Select-Object -First 40 |
|
||
ForEach-Object {
|
||
$parent = Split-Path $_.DirectoryName -Leaf
|
||
Add-Name $parent
|
||
}
|
||
}
|
||
|
||
# Windows-Dienste
|
||
Get-Service -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.DisplayName -match 'Sonic|ESB|MQ|Aurea' -or $_.Name -match 'Sonic|ESB|MQ|Aurea' } |
|
||
ForEach-Object {
|
||
Add-Name $_.Name
|
||
Add-Name $_.DisplayName
|
||
}
|
||
|
||
# Prozess-Hinweise (laufende Container)
|
||
Get-CimInstance Win32_Process -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.CommandLine -match 'sonic|mf\.framework|container\.xml' } |
|
||
ForEach-Object {
|
||
if ($_.CommandLine -match '([A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+)\.cache') {
|
||
Add-Name $Matches[1]
|
||
}
|
||
}
|
||
|
||
if ($names.Count -eq 0 -and -not [string]::IsNullOrWhiteSpace($domain)) {
|
||
Write-Output "WARN:KeineContainerGefunden Domain=$domain SonicHome=$sonicHome"
|
||
}
|
||
|
||
$names | Sort-Object -Unique
|
||
""";
|
||
}
|
||
|
||
public enum SonicManagementMode
|
||
{
|
||
/// <summary>HTTP REST API (wenn vom Sonic-Server bereitgestellt).</summary>
|
||
HttpApi = 0,
|
||
|
||
/// <summary>
|
||
/// PowerShell Remoting (WinRM) – führt Scripts auf dem Sonic-Server aus.
|
||
/// </summary>
|
||
WinRm = 1,
|
||
|
||
/// <summary>
|
||
/// CMD/PowerShell lokal auf diesem PC – zum Testen direkt auf dem Sonic-Rechner.
|
||
/// </summary>
|
||
LocalCmd = 2
|
||
}
|