Added new functionality: checking HIP hosts for TCP connectivity and whether they can be reached via RDP.
This commit is contained in:
@@ -25,6 +25,9 @@ _ReSharper*/
|
||||
artifacts/
|
||||
publish/
|
||||
|
||||
HIP-VMs.txt
|
||||
hostcheck.ps
|
||||
|
||||
logs/
|
||||
state/
|
||||
|
||||
|
||||
+40
-2
@@ -12,6 +12,7 @@ The monitor checks technical reachability and writes:
|
||||
- Windows Application Event Log
|
||||
- email notifications for failures, recoveries, and a daily status summary
|
||||
- a state file for transition detection, cooldown handling, and once-per-day summary tracking
|
||||
- optional static HIP VM checks from `hip-vms.json` for network/ping and RDP/TCP 3389
|
||||
|
||||
### 2. BizTalkMonitorConfigGenerator
|
||||
|
||||
@@ -60,7 +61,8 @@ The goal is to avoid manually maintaining the target list and instead derive it
|
||||
├── App.config
|
||||
├── HostAvailabilityMonitor.csproj
|
||||
├── Program.cs
|
||||
└── appsettings.json
|
||||
├── appsettings.json
|
||||
└── hip-vms.json
|
||||
```
|
||||
|
||||
This layout is intentionally simple so it can be committed to **Gitea**, built on Windows, and deployed to BizTalk or application servers with minimal friction.
|
||||
@@ -95,6 +97,7 @@ The generator tries to transform BizTalk addresses into monitor-compatible endpo
|
||||
- `sftp://...`
|
||||
- `tcp://...`
|
||||
- `icmp://...`
|
||||
- `rdp://...`
|
||||
- plain host / host:port values on a best-effort basis
|
||||
|
||||
### Special handling
|
||||
@@ -139,6 +142,7 @@ File: `src\HostAvailabilityMonitor\appsettings.json`
|
||||
- `Logging`: file logging configuration
|
||||
- `EventLog`: Windows Event Log configuration
|
||||
- `Email`: SMTP and notification configuration
|
||||
- `HipVirtualMachines`: optional static VM checks
|
||||
- `Targets`: endpoints to probe
|
||||
|
||||
### Email section
|
||||
@@ -233,6 +237,7 @@ The daily status email contains:
|
||||
- status
|
||||
- detail
|
||||
- host/port/HTTP status when available
|
||||
- a HIP VM snapshot with network and RDP status per VM when `HipVirtualMachines.Enabled=true`
|
||||
|
||||
Note:
|
||||
|
||||
@@ -240,6 +245,39 @@ The daily counters are derived from the **current day's rolling log file**. If t
|
||||
|
||||
---
|
||||
|
||||
## HIP VM Monitoring
|
||||
|
||||
The HIP VMs are kept in a dedicated file:
|
||||
|
||||
```text
|
||||
src\HostAvailabilityMonitor\hip-vms.json
|
||||
```
|
||||
|
||||
This keeps them independent from the `Targets` regenerated by the BizTalk generator. Changes to BizTalk send ports or receive locations do not overwrite the static VM list.
|
||||
|
||||
Enable the feature in `appsettings.json`:
|
||||
|
||||
```json
|
||||
"HipVirtualMachines": {
|
||||
"Enabled": true,
|
||||
"ConfigPath": "hip-vms.json",
|
||||
"ApplicationName": "HIP Virtual Machines",
|
||||
"TimeoutSeconds": 5,
|
||||
"RdpPort": 3389,
|
||||
"CheckNetwork": true,
|
||||
"CheckRdp": true
|
||||
}
|
||||
```
|
||||
|
||||
The `hip-vms.json` file contains group, name, address, description, and enabled state for each VM. At startup, the monitor turns every enabled VM into normal monitor targets:
|
||||
|
||||
- `Network`: `icmp://<address>` for ping/network connectivity
|
||||
- `RDP`: `rdp://<address>:3389` for TCP connectivity to the RDP service
|
||||
|
||||
These targets use the same state file as all other checks. Lost network or RDP reachability and later recoveries are therefore reported through the normal failure/recovery emails. File logs and Windows Event Log entries include source, group, machine, and check type.
|
||||
|
||||
---
|
||||
|
||||
## Generator configuration details
|
||||
|
||||
File: `generator-settings.json`
|
||||
@@ -297,7 +335,7 @@ It contains:
|
||||
|
||||
Important:
|
||||
|
||||
When the generator writes the monitor JSON, the daily summary options are also copied into the generated target file. That means `GeneratedMonitorConfig.Email.SendDailySummary`, `DailySummaryHourLocal`, and `DailySummaryMinuteLocal` flow directly into the output monitor configuration.
|
||||
When the generator writes the monitor JSON, the daily summary options and static HIP VM settings are also copied into the generated target file. That means `GeneratedMonitorConfig.Email.SendDailySummary`, `DailySummaryHourLocal`, `DailySummaryMinuteLocal`, and `GeneratedMonitorConfig.HipVirtualMachines` flow directly into the output monitor configuration.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+40
-2
@@ -12,6 +12,7 @@ Der Monitor prüft technische Erreichbarkeit und schreibt:
|
||||
- Windows Application Event Log
|
||||
- E-Mail-Benachrichtigungen bei Ausfall, Recovery und täglichem Status
|
||||
- Statusdatei für Zustandswechsel, Cooldown-Logik und die tägliche Summary-Mail
|
||||
- optional statische HIP-VM-Prüfungen aus `hip-vms.json` für Netzwerk/Ping und RDP/TCP 3389
|
||||
|
||||
### 2. BizTalkMonitorConfigGenerator
|
||||
|
||||
@@ -60,7 +61,8 @@ Ziel ist, dass die Ziel-Liste nicht manuell gepflegt werden muss, sondern direkt
|
||||
├── App.config
|
||||
├── HostAvailabilityMonitor.csproj
|
||||
├── Program.cs
|
||||
└── appsettings.json
|
||||
├── appsettings.json
|
||||
└── hip-vms.json
|
||||
```
|
||||
|
||||
Diese Struktur ist für ein normales Gitea-Repository ausgelegt. Build und Deployment können aus der Solution oder projektweise erfolgen.
|
||||
@@ -95,6 +97,7 @@ Der Generator versucht, BizTalk-Adressen in Monitor-kompatible Endpunkte zu übe
|
||||
- `sftp://...`
|
||||
- `tcp://...`
|
||||
- `icmp://...`
|
||||
- `rdp://...`
|
||||
- Plain Host / Host:Port (best effort)
|
||||
|
||||
### Spezielle Behandlung
|
||||
@@ -139,6 +142,7 @@ Datei: `src\HostAvailabilityMonitor\appsettings.json`
|
||||
- `Logging`: Dateilog-Konfiguration
|
||||
- `EventLog`: Windows Event Log Konfiguration
|
||||
- `Email`: SMTP- und Benachrichtigungskonfiguration
|
||||
- `HipVirtualMachines`: optionale statische VM-Prüfungen
|
||||
- `Targets`: die zu prüfenden Endpunkte
|
||||
|
||||
### Email
|
||||
@@ -233,6 +237,7 @@ Die Tagesstatus-Mail enthält:
|
||||
- Status
|
||||
- Detail
|
||||
- Host/Port/HTTP-Status, soweit vorhanden
|
||||
- HIP-VM-Snapshot mit Netzwerk- und RDP-Status pro VM, wenn `HipVirtualMachines.Enabled=true`
|
||||
|
||||
Hinweis:
|
||||
|
||||
@@ -240,6 +245,39 @@ Die Tageszähler werden aus dem **heutigen Rolling-Log** ausgewertet. Sollte die
|
||||
|
||||
---
|
||||
|
||||
## HIP-VM-Monitoring
|
||||
|
||||
Die HIP-VMs werden bewusst in einer eigenen Datei gepflegt:
|
||||
|
||||
```text
|
||||
src\HostAvailabilityMonitor\hip-vms.json
|
||||
```
|
||||
|
||||
Damit bleiben sie unabhängig von den durch den BizTalk-Generator neu erzeugten `Targets`. Änderungen an BizTalk-Sendports oder Receive Locations überschreiben diese statische VM-Liste nicht.
|
||||
|
||||
Aktiviert wird die Erweiterung in `appsettings.json`:
|
||||
|
||||
```json
|
||||
"HipVirtualMachines": {
|
||||
"Enabled": true,
|
||||
"ConfigPath": "hip-vms.json",
|
||||
"ApplicationName": "HIP Virtual Machines",
|
||||
"TimeoutSeconds": 5,
|
||||
"RdpPort": 3389,
|
||||
"CheckNetwork": true,
|
||||
"CheckRdp": true
|
||||
}
|
||||
```
|
||||
|
||||
Die Datei `hip-vms.json` enthält pro VM Gruppe, Namen, Adresse, Beschreibung und Aktivstatus. Beim Start erzeugt der Monitor daraus normale Targets:
|
||||
|
||||
- `Network`: `icmp://<adresse>` für Ping/Netzwerk-Konnektivität
|
||||
- `RDP`: `rdp://<adresse>:3389` für TCP-Konnektivität zum RDP-Dienst
|
||||
|
||||
Diese Targets nutzen dieselbe State-Datei wie alle anderen Checks. Dadurch werden verlorene Netzwerk- oder RDP-Erreichbarkeit und spätere Recoveries automatisch in den normalen Failure-/Recovery-Mails gemeldet. Im Dateilog und Event Log werden zusätzlich Quelle, Gruppe, Maschine und Check-Typ geschrieben.
|
||||
|
||||
---
|
||||
|
||||
## Generator-Konfiguration im Detail
|
||||
|
||||
Datei: `generator-settings.json`
|
||||
@@ -297,7 +335,7 @@ Hier werden gepflegt:
|
||||
|
||||
Wichtig:
|
||||
|
||||
Wenn der Generator die Monitor-JSON erzeugt, werden auch die Felder für die Tagesstatus-Mail mit erzeugt. Das heißt: `GeneratedMonitorConfig.Email.SendDailySummary`, `DailySummaryHourLocal` und `DailySummaryMinuteLocal` werden direkt in die Zielkonfiguration übernommen.
|
||||
Wenn der Generator die Monitor-JSON erzeugt, werden auch die Felder für die Tagesstatus-Mail und die statische HIP-VM-Prüfung mit erzeugt. Das heißt: `GeneratedMonitorConfig.Email.SendDailySummary`, `DailySummaryHourLocal`, `DailySummaryMinuteLocal` und `GeneratedMonitorConfig.HipVirtualMachines` werden direkt in die Zielkonfiguration übernommen.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
Dieses Repository ist für eine **Gitea-kompatible Repo-Struktur** aufgebaut und enthält zwei Konsolenanwendungen für **Windows Server 2019 / BizTalk Server 2019** auf **.NET Framework 4.7.2**:
|
||||
|
||||
1. **HostAvailabilityMonitor**
|
||||
- prüft Endpunkte wie UNC/SMB, `file://`, HTTP/HTTPS, SFTP, FTP, TCP und ICMP
|
||||
- prüft Endpunkte wie UNC/SMB, `file://`, HTTP/HTTPS, SFTP, FTP, TCP, ICMP und RDP
|
||||
- lädt optional eine statische HIP-VM-Liste aus `hip-vms.json` und prüft pro VM Netzwerk/Ping sowie RDP/TCP 3389
|
||||
- schreibt Rolling-Logs, Windows Application Event Log und E-Mails bei DOWN, Recovery und täglichem Status
|
||||
|
||||
2. **BizTalkMonitorConfigGenerator**
|
||||
@@ -61,7 +62,8 @@ Der typische Betrieb auf einer BizTalk-Maschine ist:
|
||||
├── App.config
|
||||
├── HostAvailabilityMonitor.csproj
|
||||
├── Program.cs
|
||||
└── appsettings.json
|
||||
├── appsettings.json
|
||||
└── hip-vms.json
|
||||
```
|
||||
|
||||
Diese Struktur ist bewusst einfach gehalten, damit das Repository sauber in **Gitea** eingecheckt, gebaut und auf Windows-Servern ausgerollt werden kann.
|
||||
@@ -88,6 +90,8 @@ Diese Struktur ist bewusst einfach gehalten, damit das Repository sauber in **Gi
|
||||
- Windows Application Event Log
|
||||
- SMTP-Mails bei DOWN, Recovery (`DOWN -> UP`) und täglichem Status
|
||||
- SMTP-Sendports bzw. reine E-Mail-Empfaengerlisten werden vom Generator uebersprungen und vom Monitor defensiv nur als `Skipped` protokolliert, nicht alarmiert
|
||||
- statische HIP-VM-Prüfung über separate `hip-vms.json`, damit durch BizTalk neu erzeugte Endpunktlisten nicht mit der VM-Liste kollidieren
|
||||
- pro HIP-VM werden zwei normale Monitor-Targets erzeugt: `icmp://<ip>` für Netzwerk-Konnektivität und `rdp://<ip>:3389` für RDP
|
||||
- tägliche Status-Mail auf Basis des **ersten Laufs ab der konfigurierten Uhrzeit**
|
||||
- State-Datei gegen Mail-Spam und für die Einmal-pro-Tag-Logik der Status-Mail
|
||||
- `ApplicationName` pro Target
|
||||
@@ -257,6 +261,36 @@ Inhalt der Tagesstatus-Mail:
|
||||
- Anzahl heutiger erfolgreicher und fehlgeschlagener Checks
|
||||
- aktueller Snapshot des letzten Laufs
|
||||
- Liste der aktuell DOWN befindlichen Endpunkte mit Anwendung und Umgebung
|
||||
- HIP-VM-Snapshot mit Netzwerk- und RDP-Status pro VM
|
||||
|
||||
## HIP-VM-Monitoring
|
||||
|
||||
Die statischen HIP-VMs liegen getrennt von den BizTalk-Endpunkten in:
|
||||
|
||||
```text
|
||||
src\HostAvailabilityMonitor\hip-vms.json
|
||||
```
|
||||
|
||||
Aktiviert wird die Erweiterung in `appsettings.json`:
|
||||
|
||||
```json
|
||||
"HipVirtualMachines": {
|
||||
"Enabled": true,
|
||||
"ConfigPath": "hip-vms.json",
|
||||
"ApplicationName": "HIP Virtual Machines",
|
||||
"TimeoutSeconds": 5,
|
||||
"RdpPort": 3389,
|
||||
"CheckNetwork": true,
|
||||
"CheckRdp": true
|
||||
}
|
||||
```
|
||||
|
||||
Pro VM erzeugt der Monitor beim Start zwei normale Checks:
|
||||
|
||||
- `Network`: Ping/ICMP gegen die konfigurierte Adresse
|
||||
- `RDP`: TCP-Verbindung auf den konfigurierten RDP-Port, standardmäßig `3389`
|
||||
|
||||
Ausfälle und Recoveries laufen über dieselbe State-Datei und dieselbe Mail-Logik wie alle anderen Targets. Die tägliche Status-Mail enthält zusätzlich eine kompakte HIP-VM-Übersicht je Gruppe, Maschine und Beschreibung.
|
||||
|
||||
## Mehrere Mail-Empfaenger konfigurieren
|
||||
|
||||
@@ -307,6 +341,7 @@ Wichtige Felder:
|
||||
- `BizTalk.ApplicationMappings`: Mapping von BizTalk-Anwendungsnamen auf fachliche App-Namen
|
||||
- `Output.Path`: Pfad der zu erzeugenden Monitor-JSON
|
||||
- `GeneratedMonitorConfig`: Vorlage für Logging, Runtime, Event Log und Mail des Monitors
|
||||
- `GeneratedMonitorConfig.HipVirtualMachines`: statische HIP-VM-Prüfung in der generierten Monitor-JSON einschalten
|
||||
- `GeneratedMonitorConfig.Email.SendDailySummary`: tägliche Status-Mail in der generierten Monitor-JSON einschalten
|
||||
- `GeneratedMonitorConfig.Email.DailySummaryHourLocal`: lokale Uhrzeit der Tageszusammenfassung
|
||||
- `GeneratedMonitorConfig.Email.DailySummaryMinuteLocal`: lokale Minute der Tageszusammenfassung
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace BizTalkMonitorConfigGenerator.Configuration
|
||||
config.GeneratedMonitorConfig.Logging = config.GeneratedMonitorConfig.Logging ?? new LoggingOptions();
|
||||
config.GeneratedMonitorConfig.EventLog = config.GeneratedMonitorConfig.EventLog ?? new EventLogOptions();
|
||||
config.GeneratedMonitorConfig.Email = config.GeneratedMonitorConfig.Email ?? new EmailOptions();
|
||||
config.GeneratedMonitorConfig.HipVirtualMachines = config.GeneratedMonitorConfig.HipVirtualMachines ?? new HipVirtualMachineOptions();
|
||||
config.GeneratedMonitorConfig.Email.To = RecipientListHelper.SanitizeRecipientList(config.GeneratedMonitorConfig.Email.To);
|
||||
config.GeneratedMonitorConfig.Email.Cc = RecipientListHelper.SanitizeRecipientList(config.GeneratedMonitorConfig.Email.Cc);
|
||||
config.GeneratedMonitorConfig.Email.Bcc = RecipientListHelper.SanitizeRecipientList(config.GeneratedMonitorConfig.Email.Bcc);
|
||||
@@ -213,6 +214,7 @@ namespace BizTalkMonitorConfigGenerator.Configuration
|
||||
configuration.Logging = configuration.Logging ?? new LoggingOptions();
|
||||
configuration.EventLog = configuration.EventLog ?? new EventLogOptions();
|
||||
configuration.Email = configuration.Email ?? new EmailOptions();
|
||||
configuration.HipVirtualMachines = configuration.HipVirtualMachines ?? new HipVirtualMachineOptions();
|
||||
configuration.Targets = configuration.Targets ?? new List<TargetOptions>();
|
||||
|
||||
if (configuration.Runtime.MaxConcurrency <= 0)
|
||||
@@ -225,6 +227,24 @@ namespace BizTalkMonitorConfigGenerator.Configuration
|
||||
throw new InvalidOperationException("GeneratedMonitorConfig.Logging.RetentionDays darf nicht negativ sein.");
|
||||
}
|
||||
|
||||
if (configuration.HipVirtualMachines.Enabled)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(configuration.HipVirtualMachines.ConfigPath))
|
||||
{
|
||||
throw new InvalidOperationException("GeneratedMonitorConfig.HipVirtualMachines.Enabled=true, aber ConfigPath ist leer.");
|
||||
}
|
||||
|
||||
if (configuration.HipVirtualMachines.TimeoutSeconds <= 0)
|
||||
{
|
||||
configuration.HipVirtualMachines.TimeoutSeconds = 5;
|
||||
}
|
||||
|
||||
if (configuration.HipVirtualMachines.RdpPort <= 0 || configuration.HipVirtualMachines.RdpPort > 65535)
|
||||
{
|
||||
throw new InvalidOperationException("GeneratedMonitorConfig.HipVirtualMachines.RdpPort muss zwischen 1 und 65535 liegen.");
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration.Email.Enabled)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(configuration.Email.SmtpHost))
|
||||
@@ -306,6 +326,16 @@ namespace BizTalkMonitorConfigGenerator.Configuration
|
||||
CooldownMinutes = configuration.Email.CooldownMinutes,
|
||||
TimeoutSeconds = configuration.Email.TimeoutSeconds
|
||||
},
|
||||
HipVirtualMachines = new HipVirtualMachineOptions
|
||||
{
|
||||
Enabled = configuration.HipVirtualMachines.Enabled,
|
||||
ConfigPath = configuration.HipVirtualMachines.ConfigPath,
|
||||
ApplicationName = configuration.HipVirtualMachines.ApplicationName,
|
||||
TimeoutSeconds = configuration.HipVirtualMachines.TimeoutSeconds,
|
||||
RdpPort = configuration.HipVirtualMachines.RdpPort,
|
||||
CheckNetwork = configuration.HipVirtualMachines.CheckNetwork,
|
||||
CheckRdp = configuration.HipVirtualMachines.CheckRdp
|
||||
},
|
||||
Targets = new List<TargetOptions>()
|
||||
};
|
||||
|
||||
|
||||
@@ -94,6 +94,15 @@
|
||||
"CooldownMinutes": 0,
|
||||
"TimeoutSeconds": 30
|
||||
},
|
||||
"HipVirtualMachines": {
|
||||
"Enabled": true,
|
||||
"ConfigPath": "hip-vms.json",
|
||||
"ApplicationName": "HIP Virtual Machines",
|
||||
"TimeoutSeconds": 5,
|
||||
"RdpPort": 3389,
|
||||
"CheckNetwork": true,
|
||||
"CheckRdp": true
|
||||
},
|
||||
"Targets": []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Web.Script.Serialization;
|
||||
|
||||
namespace HostAvailabilityMonitor.Configuration
|
||||
{
|
||||
public sealed class HipVirtualMachineConfiguration
|
||||
{
|
||||
public List<HipVirtualMachine> VirtualMachines { get; set; } = new List<HipVirtualMachine>();
|
||||
|
||||
public static HipVirtualMachineConfiguration Load(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
throw new ArgumentException("Der Pfad zur HIP-VM-Konfiguration ist leer.", nameof(path));
|
||||
}
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
throw new FileNotFoundException("HIP-VM-Konfiguration wurde nicht gefunden: " + path, path);
|
||||
}
|
||||
|
||||
var json = File.ReadAllText(path);
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var config = serializer.Deserialize<HipVirtualMachineConfiguration>(json);
|
||||
if (config == null)
|
||||
{
|
||||
throw new InvalidOperationException("HIP-VM-Konfiguration konnte nicht deserialisiert werden.");
|
||||
}
|
||||
|
||||
config.VirtualMachines = config.VirtualMachines ?? new List<HipVirtualMachine>();
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class HipVirtualMachine
|
||||
{
|
||||
public string Group { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Address { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public bool Enabled { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ namespace HostAvailabilityMonitor.Configuration
|
||||
public LoggingOptions Logging { get; set; } = new LoggingOptions();
|
||||
public EventLogOptions EventLog { get; set; } = new EventLogOptions();
|
||||
public EmailOptions Email { get; set; } = new EmailOptions();
|
||||
public HipVirtualMachineOptions HipVirtualMachines { get; set; } = new HipVirtualMachineOptions();
|
||||
public List<TargetOptions> Targets { get; set; } = new List<TargetOptions>();
|
||||
|
||||
public static MonitorConfiguration Load(string path)
|
||||
@@ -36,6 +37,7 @@ namespace HostAvailabilityMonitor.Configuration
|
||||
config.Logging = config.Logging ?? new LoggingOptions();
|
||||
config.EventLog = config.EventLog ?? new EventLogOptions();
|
||||
config.Email = config.Email ?? new EmailOptions();
|
||||
config.HipVirtualMachines = config.HipVirtualMachines ?? new HipVirtualMachineOptions();
|
||||
config.Email.To = SanitizeRecipientList(config.Email.To);
|
||||
config.Email.Cc = SanitizeRecipientList(config.Email.Cc);
|
||||
config.Email.Bcc = SanitizeRecipientList(config.Email.Bcc);
|
||||
@@ -84,7 +86,9 @@ namespace HostAvailabilityMonitor.Configuration
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (Targets == null || Targets.Count == 0)
|
||||
Targets = Targets ?? new List<TargetOptions>();
|
||||
|
||||
if ((Targets == null || Targets.Count == 0) && (HipVirtualMachines == null || !HipVirtualMachines.Enabled))
|
||||
{
|
||||
throw new InvalidOperationException("Es wurde kein Ziel in der Konfiguration definiert.");
|
||||
}
|
||||
@@ -112,6 +116,29 @@ namespace HostAvailabilityMonitor.Configuration
|
||||
Runtime.MaxConcurrency = 1;
|
||||
}
|
||||
|
||||
if (HipVirtualMachines == null)
|
||||
{
|
||||
HipVirtualMachines = new HipVirtualMachineOptions();
|
||||
}
|
||||
|
||||
if (HipVirtualMachines.Enabled)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(HipVirtualMachines.ConfigPath))
|
||||
{
|
||||
throw new InvalidOperationException("HipVirtualMachines.Enabled=true, aber ConfigPath ist leer.");
|
||||
}
|
||||
|
||||
if (HipVirtualMachines.TimeoutSeconds <= 0)
|
||||
{
|
||||
HipVirtualMachines.TimeoutSeconds = 5;
|
||||
}
|
||||
|
||||
if (HipVirtualMachines.RdpPort <= 0 || HipVirtualMachines.RdpPort > 65535)
|
||||
{
|
||||
throw new InvalidOperationException("HipVirtualMachines.RdpPort muss zwischen 1 und 65535 liegen.");
|
||||
}
|
||||
}
|
||||
|
||||
if (Logging.RetentionDays < 0)
|
||||
{
|
||||
throw new InvalidOperationException("Logging.RetentionDays darf nicht negativ sein.");
|
||||
@@ -227,6 +254,17 @@ namespace HostAvailabilityMonitor.Configuration
|
||||
public int TimeoutSeconds { get; set; } = 30;
|
||||
}
|
||||
|
||||
public sealed class HipVirtualMachineOptions
|
||||
{
|
||||
public bool Enabled { get; set; } = false;
|
||||
public string ConfigPath { get; set; } = "hip-vms.json";
|
||||
public string ApplicationName { get; set; } = "HIP Virtual Machines";
|
||||
public int TimeoutSeconds { get; set; } = 5;
|
||||
public int RdpPort { get; set; } = 3389;
|
||||
public bool CheckNetwork { get; set; } = true;
|
||||
public bool CheckRdp { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class TargetOptions
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
@@ -236,6 +274,11 @@ namespace HostAvailabilityMonitor.Configuration
|
||||
public int? Port { get; set; }
|
||||
public bool? ValidateUncPathAccess { get; set; }
|
||||
public string HttpMethod { get; set; }
|
||||
public string Source { get; set; }
|
||||
public string Group { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string MachineName { get; set; }
|
||||
public string CheckName { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
public string DisplayName
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Configuration\HipVirtualMachineConfiguration.cs" />
|
||||
<Compile Include="Configuration\MonitorConfiguration.cs" />
|
||||
<Compile Include="Logging\FileLogger.cs" />
|
||||
<Compile Include="Logging\WindowsEventLogger.cs" />
|
||||
@@ -56,6 +57,9 @@
|
||||
<Content Include="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="hip-vms.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
|
||||
@@ -104,6 +104,26 @@ namespace HostAvailabilityMonitor.Logging
|
||||
parts.Add("Port=" + result.Port.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(result.Source))
|
||||
{
|
||||
parts.Add("Source=" + Escape(result.Source));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(result.Group))
|
||||
{
|
||||
parts.Add("Group=" + Escape(result.Group));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(result.MachineName))
|
||||
{
|
||||
parts.Add("Machine=" + Escape(result.MachineName));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(result.CheckName))
|
||||
{
|
||||
parts.Add("Check=" + Escape(result.CheckName));
|
||||
}
|
||||
|
||||
if (result.HttpStatusCode.HasValue)
|
||||
{
|
||||
parts.Add("HttpStatus=" + result.HttpStatusCode.Value);
|
||||
|
||||
@@ -65,12 +65,14 @@ namespace HostAvailabilityMonitor.Monitoring
|
||||
return await CheckTcpAsync(target, uri.Host, target.Port ?? ResolvePort(uri, null), startedAt, TargetKind.Tcp, endpoint, cancellationToken).ConfigureAwait(false);
|
||||
case "icmp":
|
||||
return await CheckIcmpAsync(target, uri.Host, startedAt, endpoint, cancellationToken).ConfigureAwait(false);
|
||||
case "rdp":
|
||||
return await CheckTcpAsync(target, uri.Host, target.Port ?? ResolvePort(uri, 3389), startedAt, TargetKind.Rdp, endpoint, cancellationToken).ConfigureAwait(false);
|
||||
case "ftp":
|
||||
return await CheckTcpAsync(target, uri.Host, target.Port ?? ResolvePort(uri, 21), startedAt, TargetKind.Ftp, endpoint, cancellationToken).ConfigureAwait(false);
|
||||
case "file":
|
||||
return await CheckFileUriAsync(target, uri, startedAt, cancellationToken).ConfigureAwait(false);
|
||||
default:
|
||||
return Fail(target, TargetKind.Unknown, endpoint, startedAt, "Nicht unterstütztes Schema '" + uri.Scheme + "'. Unterstützt: UNC, file, http, https, sftp, ftp, tcp, icmp.", null, uri.Host, uri.IsDefaultPort ? (int?)null : uri.Port);
|
||||
return Fail(target, TargetKind.Unknown, endpoint, startedAt, "Nicht unterstütztes Schema '" + uri.Scheme + "'. Unterstützt: UNC, file, http, https, sftp, ftp, tcp, icmp, rdp.", null, uri.Host, uri.IsDefaultPort ? (int?)null : uri.Port);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,6 +397,11 @@ namespace HostAvailabilityMonitor.Monitoring
|
||||
Detail = detail,
|
||||
Host = host,
|
||||
Port = port,
|
||||
Source = target.Source,
|
||||
Group = target.Group,
|
||||
Description = target.Description,
|
||||
MachineName = target.MachineName,
|
||||
CheckName = target.CheckName,
|
||||
HttpStatusCode = httpStatusCode,
|
||||
ErrorType = errorType,
|
||||
StartedAtLocal = startedAt,
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace HostAvailabilityMonitor.Monitoring
|
||||
Icmp = 6,
|
||||
Host = 7,
|
||||
Ftp = 8,
|
||||
File = 9
|
||||
File = 9,
|
||||
Rdp = 10
|
||||
}
|
||||
|
||||
public sealed class ProbeResult
|
||||
@@ -29,6 +30,11 @@ namespace HostAvailabilityMonitor.Monitoring
|
||||
public string Detail { get; set; }
|
||||
public string Host { get; set; }
|
||||
public int? Port { get; set; }
|
||||
public string Source { get; set; }
|
||||
public string Group { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string MachineName { get; set; }
|
||||
public string CheckName { get; set; }
|
||||
public int? HttpStatusCode { get; set; }
|
||||
public string ErrorType { get; set; }
|
||||
public DateTimeOffset StartedAtLocal { get; set; }
|
||||
|
||||
@@ -276,6 +276,8 @@ namespace HostAvailabilityMonitor.Notifications
|
||||
sb.AppendLine("Aktuell sind keine Endpunkte down / There are currently no unavailable endpoints.");
|
||||
}
|
||||
|
||||
AppendHipVirtualMachineSnapshot(sb, summary.CurrentResults);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -296,6 +298,22 @@ namespace HostAvailabilityMonitor.Notifications
|
||||
{
|
||||
sb.AppendLine(" Port: " + result.Port.Value);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(result.Group))
|
||||
{
|
||||
sb.AppendLine(" Gruppe / Group: " + result.Group);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(result.MachineName))
|
||||
{
|
||||
sb.AppendLine(" Maschine / Machine: " + result.MachineName);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(result.CheckName))
|
||||
{
|
||||
sb.AppendLine(" Check: " + result.CheckName);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(result.Description))
|
||||
{
|
||||
sb.AppendLine(" Beschreibung / Description: " + result.Description);
|
||||
}
|
||||
if (result.HttpStatusCode.HasValue)
|
||||
{
|
||||
sb.AppendLine(" HTTP Status: " + result.HttpStatusCode.Value);
|
||||
@@ -310,6 +328,84 @@ namespace HostAvailabilityMonitor.Notifications
|
||||
}
|
||||
}
|
||||
|
||||
private static void AppendHipVirtualMachineSnapshot(StringBuilder sb, IReadOnlyCollection<ProbeResult> results)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var vmResults = results
|
||||
.Where(r => r != null && string.Equals(r.Source, "HipVirtualMachines", StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
if (vmResults.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("HIP-VM Snapshot / HIP VM snapshot:");
|
||||
|
||||
var networkUp = vmResults.Count(r => string.Equals(r.CheckName, "Network", StringComparison.OrdinalIgnoreCase) && r.IsSuccess);
|
||||
var networkDown = vmResults.Count(r => string.Equals(r.CheckName, "Network", StringComparison.OrdinalIgnoreCase) && !r.IsSkipped && !r.IsSuccess);
|
||||
var rdpUp = vmResults.Count(r => string.Equals(r.CheckName, "RDP", StringComparison.OrdinalIgnoreCase) && r.IsSuccess);
|
||||
var rdpDown = vmResults.Count(r => string.Equals(r.CheckName, "RDP", StringComparison.OrdinalIgnoreCase) && !r.IsSkipped && !r.IsSuccess);
|
||||
sb.AppendLine("- Netzwerk / Network UP: " + networkUp + ", DOWN: " + networkDown);
|
||||
sb.AppendLine("- RDP UP: " + rdpUp + ", DOWN: " + rdpDown);
|
||||
|
||||
var groups = vmResults
|
||||
.GroupBy(r => BuildVmSnapshotKey(r), StringComparer.OrdinalIgnoreCase)
|
||||
.OrderBy(g => FirstNonEmpty(g.Select(r => r.Group)), StringComparer.OrdinalIgnoreCase)
|
||||
.ThenBy(g => FirstNonEmpty(g.Select(r => r.MachineName)), StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
var entries = group.ToList();
|
||||
var first = entries[0];
|
||||
var network = entries.FirstOrDefault(r => string.Equals(r.CheckName, "Network", StringComparison.OrdinalIgnoreCase));
|
||||
var rdp = entries.FirstOrDefault(r => string.Equals(r.CheckName, "RDP", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
sb.AppendLine("- " + Safe(first.Group) + " | " + Safe(first.MachineName) + " | " + Safe(first.Description));
|
||||
sb.AppendLine(" Netzwerk / Network: " + FormatCompactStatus(network));
|
||||
sb.AppendLine(" RDP: " + FormatCompactStatus(rdp));
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildVmSnapshotKey(ProbeResult result)
|
||||
{
|
||||
return string.Join("|", new[]
|
||||
{
|
||||
Safe(result.Group),
|
||||
Safe(result.MachineName),
|
||||
Safe(result.Description)
|
||||
});
|
||||
}
|
||||
|
||||
private static string FormatCompactStatus(ProbeResult result)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
return "n/a";
|
||||
}
|
||||
|
||||
if (result.IsSkipped)
|
||||
{
|
||||
return "SKIPPED - " + Safe(result.Detail);
|
||||
}
|
||||
|
||||
return (result.IsSuccess ? "UP" : "DOWN") + " - " + Safe(result.Detail);
|
||||
}
|
||||
|
||||
private static string FirstNonEmpty(IEnumerable<string> values)
|
||||
{
|
||||
if (values == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return values.FirstOrDefault(v => !string.IsNullOrWhiteSpace(v)) ?? string.Empty;
|
||||
}
|
||||
|
||||
private static string Safe(string value)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(value) ? "n/a" : value;
|
||||
@@ -329,6 +425,7 @@ namespace HostAvailabilityMonitor.Notifications
|
||||
public int CurrentTargetsDown { get; set; }
|
||||
public int CurrentTargetsSkipped { get; set; }
|
||||
public List<ProbeResult> CurrentFailures { get; set; } = new List<ProbeResult>();
|
||||
public List<ProbeResult> CurrentResults { get; set; } = new List<ProbeResult>();
|
||||
public IDictionary<string, TargetState> CurrentState { get; set; } = new Dictionary<string, TargetState>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace HostAvailabilityMonitor
|
||||
var configPath = args != null && args.Length > 0 && !string.IsNullOrWhiteSpace(args[0])
|
||||
? args[0]
|
||||
: Path.Combine(baseDirectory, "appsettings.json");
|
||||
var fullConfigPath = Path.GetFullPath(configPath);
|
||||
|
||||
var config = MonitorConfiguration.Load(configPath);
|
||||
config.Validate();
|
||||
@@ -43,7 +44,7 @@ namespace HostAvailabilityMonitor
|
||||
logger = new FileLogger(logDirectory, config.Logging.FilePrefix, config.Logging.RetentionDays, config.ApplicationName, config.EnvironmentName);
|
||||
logger.CleanupOldFiles();
|
||||
logger.Info(config.ApplicationName + " gestartet. Umgebung=" + config.EnvironmentName + ", Server=" + Environment.MachineName + ".");
|
||||
logger.Info("Konfiguration geladen: " + Path.GetFullPath(configPath));
|
||||
logger.Info("Konfiguration geladen: " + fullConfigPath);
|
||||
|
||||
eventLogger = new WindowsEventLogger(config.EventLog, logger);
|
||||
eventLogger.TryInitialize();
|
||||
@@ -67,7 +68,7 @@ namespace HostAvailabilityMonitor
|
||||
|
||||
var currentState = new Dictionary<string, TargetState>(previousState, StringComparer.OrdinalIgnoreCase);
|
||||
var probeService = new EndpointProbeService(config.Runtime);
|
||||
var enabledTargets = config.Targets.Where(t => t != null && t.Enabled).ToList();
|
||||
var enabledTargets = BuildEnabledTargets(config, fullConfigPath, baseDirectory, logger);
|
||||
|
||||
if (enabledTargets.Count == 0)
|
||||
{
|
||||
@@ -219,6 +220,126 @@ namespace HostAvailabilityMonitor
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<TargetOptions> BuildEnabledTargets(MonitorConfiguration config, string configPath, string baseDirectory, FileLogger logger)
|
||||
{
|
||||
var targets = config.Targets == null
|
||||
? new List<TargetOptions>()
|
||||
: config.Targets.Where(t => t != null && t.Enabled).ToList();
|
||||
|
||||
if (config.HipVirtualMachines == null || !config.HipVirtualMachines.Enabled)
|
||||
{
|
||||
return targets;
|
||||
}
|
||||
|
||||
var vmConfigPath = ResolveConfigurationPath(configPath, baseDirectory, config.HipVirtualMachines.ConfigPath);
|
||||
logger.Info("HIP-VM-Konfiguration wird geladen: " + vmConfigPath);
|
||||
|
||||
var vmConfig = HipVirtualMachineConfiguration.Load(vmConfigPath);
|
||||
var vmTargets = CreateHipVirtualMachineTargets(vmConfig, config.HipVirtualMachines, logger);
|
||||
targets.AddRange(vmTargets);
|
||||
|
||||
logger.Info("HIP-VM-Konfiguration geladen. VMs=" + vmConfig.VirtualMachines.Count + ", generierte Targets=" + vmTargets.Count + ".");
|
||||
return targets;
|
||||
}
|
||||
|
||||
private static List<TargetOptions> CreateHipVirtualMachineTargets(HipVirtualMachineConfiguration vmConfig, HipVirtualMachineOptions options, FileLogger logger)
|
||||
{
|
||||
var targets = new List<TargetOptions>();
|
||||
var machines = vmConfig == null || vmConfig.VirtualMachines == null
|
||||
? new List<HipVirtualMachine>()
|
||||
: vmConfig.VirtualMachines;
|
||||
|
||||
foreach (var vm in machines)
|
||||
{
|
||||
if (vm == null || !vm.Enabled)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var address = (vm.Address ?? string.Empty).Trim();
|
||||
if (string.IsNullOrWhiteSpace(address))
|
||||
{
|
||||
logger.Warn("HIP-VM ohne Adresse wurde uebersprungen. Name=" + (vm.Name ?? string.Empty) + ".");
|
||||
continue;
|
||||
}
|
||||
|
||||
var machineName = string.IsNullOrWhiteSpace(vm.Name) ? address : vm.Name.Trim();
|
||||
var applicationName = string.IsNullOrWhiteSpace(options.ApplicationName) ? "HIP Virtual Machines" : options.ApplicationName.Trim();
|
||||
var timeoutSeconds = Math.Max(1, options.TimeoutSeconds);
|
||||
|
||||
if (options.CheckNetwork)
|
||||
{
|
||||
targets.Add(CreateHipVirtualMachineTarget(
|
||||
vm,
|
||||
machineName,
|
||||
applicationName,
|
||||
"Network",
|
||||
"Netzwerk",
|
||||
"icmp://" + address,
|
||||
null,
|
||||
timeoutSeconds));
|
||||
}
|
||||
|
||||
if (options.CheckRdp)
|
||||
{
|
||||
targets.Add(CreateHipVirtualMachineTarget(
|
||||
vm,
|
||||
machineName,
|
||||
applicationName,
|
||||
"RDP",
|
||||
"RDP",
|
||||
"rdp://" + address + ":" + Math.Max(1, options.RdpPort),
|
||||
Math.Max(1, options.RdpPort),
|
||||
timeoutSeconds));
|
||||
}
|
||||
}
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
private static TargetOptions CreateHipVirtualMachineTarget(
|
||||
HipVirtualMachine vm,
|
||||
string machineName,
|
||||
string applicationName,
|
||||
string checkName,
|
||||
string displayCheckName,
|
||||
string endpoint,
|
||||
int? port,
|
||||
int timeoutSeconds)
|
||||
{
|
||||
return new TargetOptions
|
||||
{
|
||||
Name = machineName + " - " + displayCheckName,
|
||||
ApplicationName = applicationName,
|
||||
Endpoint = endpoint,
|
||||
Port = port,
|
||||
TimeoutSeconds = timeoutSeconds,
|
||||
Enabled = true,
|
||||
Source = "HipVirtualMachines",
|
||||
Group = vm.Group,
|
||||
Description = vm.Description,
|
||||
MachineName = machineName,
|
||||
CheckName = checkName
|
||||
};
|
||||
}
|
||||
|
||||
private static string ResolveConfigurationPath(string configPath, string baseDirectory, string configuredPath)
|
||||
{
|
||||
if (Path.IsPathRooted(configuredPath))
|
||||
{
|
||||
return configuredPath;
|
||||
}
|
||||
|
||||
var configDirectory = Path.GetDirectoryName(Path.GetFullPath(configPath));
|
||||
var configRelativePath = Path.GetFullPath(Path.Combine(configDirectory, configuredPath));
|
||||
if (File.Exists(configRelativePath))
|
||||
{
|
||||
return configRelativePath;
|
||||
}
|
||||
|
||||
return Path.GetFullPath(Path.Combine(baseDirectory, configuredPath));
|
||||
}
|
||||
|
||||
private static async Task TrySendDailySummaryAsync(
|
||||
MonitorConfiguration config,
|
||||
EmailNotifier notifier,
|
||||
@@ -258,6 +379,7 @@ namespace HostAvailabilityMonitor
|
||||
CurrentTargetsDown = latestResults.Count(r => !r.IsSkipped && !r.IsSuccess),
|
||||
CurrentTargetsSkipped = latestResults.Count(r => r.IsSkipped),
|
||||
CurrentFailures = currentFailures,
|
||||
CurrentResults = latestResults,
|
||||
CurrentState = currentState
|
||||
};
|
||||
|
||||
@@ -368,11 +490,16 @@ namespace HostAvailabilityMonitor
|
||||
private static string BuildEventMessage(MonitorConfiguration config, ProbeResult result)
|
||||
{
|
||||
return string.Format(
|
||||
"Umgebung={0} | Anwendung={1} | Name={2} | Endpoint={3} | Status={4} | Detail={5}",
|
||||
"Umgebung={0} | Anwendung={1} | Name={2} | Endpoint={3} | Typ={4} | Quelle={5} | Gruppe={6} | Maschine={7} | Check={8} | Status={9} | Detail={10}",
|
||||
config.EnvironmentName,
|
||||
result.ApplicationName,
|
||||
result.Name,
|
||||
result.Endpoint,
|
||||
result.Kind,
|
||||
result.Source,
|
||||
result.Group,
|
||||
result.MachineName,
|
||||
result.CheckName,
|
||||
result.StatusText,
|
||||
result.Detail);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,15 @@
|
||||
"CooldownMinutes": 0,
|
||||
"TimeoutSeconds": 30
|
||||
},
|
||||
"HipVirtualMachines": {
|
||||
"Enabled": true,
|
||||
"ConfigPath": "hip-vms.json",
|
||||
"ApplicationName": "HIP Virtual Machines",
|
||||
"TimeoutSeconds": 5,
|
||||
"RdpPort": 3389,
|
||||
"CheckNetwork": true,
|
||||
"CheckRdp": true
|
||||
},
|
||||
"Targets": [
|
||||
{
|
||||
"Name": "Internes Fileshare 1",
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
{
|
||||
"VirtualMachines": [
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23aasw0001",
|
||||
"Address": "10.121.157.21",
|
||||
"Description": "Developer Machine (Steffen R.)",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23aasw0006",
|
||||
"Address": "10.121.157.27",
|
||||
"Description": "Developer Machine (Johannes Rest)",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23aasw0007",
|
||||
"Address": "10.121.157.28",
|
||||
"Description": "Developer Machine (Reza Takhsha)",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23aasw0002",
|
||||
"Address": "10.121.157.22",
|
||||
"Description": "Developer Machine (Chris Schild)",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23agpwbi01",
|
||||
"Address": "10.121.157.8",
|
||||
"Description": "Developer Machine (Ronny)",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23agpwbi02",
|
||||
"Address": "10.121.157.9",
|
||||
"Description": "Developer Machine (Lars)",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23agpwbi03",
|
||||
"Address": "10.121.157.10",
|
||||
"Description": "BizTalk Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23agpwbi04",
|
||||
"Address": "10.121.157.7",
|
||||
"Description": "Monitoring/Administration Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23adbwbi01",
|
||||
"Address": "10.121.157.6",
|
||||
"Description": "BizTalk DB Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Entwickermaschinen",
|
||||
"Name": "dv23wgpwbi01",
|
||||
"Address": "10.123.49.100",
|
||||
"Description": "IIS Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "TST",
|
||||
"Name": "tv23agpwbi01",
|
||||
"Address": "10.121.157.11",
|
||||
"Description": "BizTalk Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "TST",
|
||||
"Name": "tv23agpwbi02",
|
||||
"Address": "10.121.157.12",
|
||||
"Description": "Monitoring/Administration Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "TST",
|
||||
"Name": "tv23adbwbi01",
|
||||
"Address": "10.121.157.13",
|
||||
"Description": "BizTalk DB Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "TST",
|
||||
"Name": "tv23wgpwbi01",
|
||||
"Address": "10.123.49.228",
|
||||
"Description": "IIS Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "ACC",
|
||||
"Name": "av23agpwbi01",
|
||||
"Address": "10.121.145.6",
|
||||
"Description": "BizTalk Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "ACC",
|
||||
"Name": "av23agpwbi02",
|
||||
"Address": "10.121.145.7",
|
||||
"Description": "Monitoring/Administration Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "ACC",
|
||||
"Name": "av23adbwbi01",
|
||||
"Address": "10.121.145.8",
|
||||
"Description": "BizTalk DB Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "ACC",
|
||||
"Name": "acc-lbi-23-agw-bewintegration0001",
|
||||
"Address": "10.123.47.198",
|
||||
"Description": "Load Balancer",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "ACC",
|
||||
"Name": "av23wgpwbi01",
|
||||
"Address": "10.123.47.196",
|
||||
"Description": "IIS Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "ACC",
|
||||
"Name": "av23wgpwbi02",
|
||||
"Address": "10.123.47.197",
|
||||
"Description": "IIS Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Produktion",
|
||||
"Name": "pv23agpwbi01",
|
||||
"Address": "10.121.145.9",
|
||||
"Description": "BizTalk Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Produktion",
|
||||
"Name": "pv23agpwbi02",
|
||||
"Address": "10.121.145.10",
|
||||
"Description": "Monitoring/Administration Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Produktion",
|
||||
"Name": "pv23adbwbi01",
|
||||
"Address": "10.121.145.11",
|
||||
"Description": "BizTalk DB Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Produktion",
|
||||
"Name": "pv23wgpwbi01",
|
||||
"Address": "10.123.48.196",
|
||||
"Description": "IIS Server",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Group": "Produktion",
|
||||
"Name": "pv23wgpwbi02",
|
||||
"Address": "10.123.48.197",
|
||||
"Description": "IIS Server",
|
||||
"Enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user