mirror of
https://github.com/Icinga/icinga-powershell-framework.git
synced 2025-12-20 23:00:35 -05:00
225 lines
7.1 KiB
PowerShell
225 lines
7.1 KiB
PowerShell
|
|
$ClientProtocol = New-Object -TypeName PSObject;
|
||
|
|
|
||
|
|
$ClientProtocol | Add-Member -membertype NoteProperty -name 'fqdn' -value '';
|
||
|
|
|
||
|
|
$ClientProtocol | Add-Member -membertype ScriptMethod -name 'setFQDN' -value {
|
||
|
|
param([string]$fqdn);
|
||
|
|
|
||
|
|
$this.fqdn = $fqdn;
|
||
|
|
}
|
||
|
|
|
||
|
|
$ClientProtocol | Add-Member -membertype ScriptMethod -name 'SetConnectionState' -value {
|
||
|
|
param([string]$remoteAddress, [bool]$reachable);
|
||
|
|
|
||
|
|
if ($Icinga2.Cache.Checker.RemoteServices -eq $null) {
|
||
|
|
$Icinga2.Cache.Checker.RemoteServices = @{ };
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($Icinga2.Cache.Checker.RemoteServices.ContainsKey($remoteAddress) -eq $FALSE) {
|
||
|
|
$Icinga2.Cache.Checker.RemoteServices.Add($remoteAddress, $reachable);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$Icinga2.Cache.Checker.RemoteServices[$remoteAddress] = $reachable;
|
||
|
|
}
|
||
|
|
|
||
|
|
$ClientProtocol | Add-Member -membertype ScriptMethod -name 'GetConnectionState' -value {
|
||
|
|
param([string]$remoteAddress);
|
||
|
|
|
||
|
|
if ($Icinga2.Cache.Checker.RemoteServices.ContainsKey($remoteAddress) -eq $FALSE) {
|
||
|
|
return $TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $Icinga2.Cache.Checker.RemoteServices[$remoteAddress];
|
||
|
|
}
|
||
|
|
|
||
|
|
$ClientProtocol | Add-Member -membertype ScriptMethod -name 'NewRequest' -value {
|
||
|
|
param([array]$headers, [string]$content, [string]$remoteAddress, [string]$url);
|
||
|
|
|
||
|
|
$url = [string]::Format(
|
||
|
|
'{0}{1}',
|
||
|
|
$remoteAddress,
|
||
|
|
$url
|
||
|
|
);
|
||
|
|
|
||
|
|
$httpRequest = [System.Net.HttpWebRequest]::Create(
|
||
|
|
$url
|
||
|
|
);
|
||
|
|
$httpRequest.Method = 'POST';
|
||
|
|
$httpRequest.Accept = 'application/json';
|
||
|
|
$httpRequest.ContentType = 'application/json';
|
||
|
|
$httpRequest.Headers.Add(
|
||
|
|
[string]::Format(
|
||
|
|
'X-Windows-CheckResult: {0}',
|
||
|
|
$this.fqdn
|
||
|
|
)
|
||
|
|
);
|
||
|
|
|
||
|
|
# Add possible custom header
|
||
|
|
foreach ($header in $headers) {
|
||
|
|
$httpRequest.Headers.Add($header);
|
||
|
|
}
|
||
|
|
$httpRequest.TimeOut = 60000;
|
||
|
|
|
||
|
|
# If we are using self-signed certificates for example, the HTTP request will
|
||
|
|
# fail caused by the SSL certificate. With this we can allow even faulty
|
||
|
|
# certificates. This should be used with caution
|
||
|
|
if (-Not $Icinga2.Config.'checker.ssl.verify') {
|
||
|
|
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
# Only send data in case we want to send some data
|
||
|
|
if ($content -ne '') {
|
||
|
|
$transmitBytes = [System.Text.Encoding]::UTF8.GetBytes($content);
|
||
|
|
$httpRequest.ContentLength = $transmitBytes.Length;
|
||
|
|
[System.IO.Stream]$httpOutput = [System.IO.Stream]$httpRequest.GetRequestStream()
|
||
|
|
$httpOutput.Write($transmitBytes, 0, $transmitBytes.Length)
|
||
|
|
$httpOutput.Close()
|
||
|
|
}
|
||
|
|
} catch [System.Net.WebException] {
|
||
|
|
$this.SetConnectionState($remoteAddress, $FALSE);
|
||
|
|
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Exception,
|
||
|
|
[string]::Format('Exception while trying to connect to "{0}". Possible a connection error. Message: {1}',
|
||
|
|
$url,
|
||
|
|
$_.Exception.Message
|
||
|
|
)
|
||
|
|
);
|
||
|
|
return $null;
|
||
|
|
} catch {
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Exception,
|
||
|
|
$_.Exception.Message
|
||
|
|
);
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Exception,
|
||
|
|
$_.Exception.StackTrace
|
||
|
|
);
|
||
|
|
return $null;
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
|
||
|
|
$this.SetConnectionState($remoteAddress, $TRUE);
|
||
|
|
return $this.readResponseStream($httpRequest.GetResponse());
|
||
|
|
|
||
|
|
} catch [System.Net.WebException] {
|
||
|
|
# Print an exception message and the possible body in case we received one
|
||
|
|
# to make troubleshooting easier
|
||
|
|
[string]$errorResponse = $this.readResponseStream($_.Exception.Response);
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Debug,
|
||
|
|
$_.Exception.Message
|
||
|
|
);
|
||
|
|
if ($errorResponse -ne '') {
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Debug,
|
||
|
|
$errorResponse
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
$exceptionMessage = $_.Exception.Response;
|
||
|
|
if ($exceptionMessage.StatusCode) {
|
||
|
|
return [int][System.Net.HttpStatusCode]$exceptionMessage.StatusCode;
|
||
|
|
} else {
|
||
|
|
return 900;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $null;
|
||
|
|
}
|
||
|
|
|
||
|
|
$ClientProtocol | Add-Member -membertype ScriptMethod -name 'readResponseStream' -value {
|
||
|
|
param([System.Object]$response);
|
||
|
|
|
||
|
|
try {
|
||
|
|
if ($response) {
|
||
|
|
$responseStream = $response.getResponseStream();
|
||
|
|
$streamReader = New-Object IO.StreamReader($responseStream);
|
||
|
|
$result = $streamReader.ReadToEnd();
|
||
|
|
$response.close()
|
||
|
|
$streamReader.close()
|
||
|
|
|
||
|
|
return $result;
|
||
|
|
}
|
||
|
|
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Exception,
|
||
|
|
'The received response from the remote server is NULL. This might be caused by SSL errors or wrong Webserver configuration.'
|
||
|
|
);
|
||
|
|
} catch {
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Exception,
|
||
|
|
$_.Exception.Message
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $null;
|
||
|
|
}
|
||
|
|
|
||
|
|
$ClientProtocol | Add-Member -membertype ScriptMethod -name 'parseWindowsHelloResponse' -value {
|
||
|
|
param($json);
|
||
|
|
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Debug,
|
||
|
|
[string]::Format(
|
||
|
|
'Remote Server Output: {0}',
|
||
|
|
$json
|
||
|
|
)
|
||
|
|
);
|
||
|
|
|
||
|
|
$Icinga2.Cache.Checker.AuthToken = $json.token;
|
||
|
|
if ($Icinga2.Cache.Checker.ModuleConfig -eq $null) {
|
||
|
|
$Icinga2.Cache.Checker.ModuleConfig = @{};
|
||
|
|
}
|
||
|
|
|
||
|
|
$Icinga2.Cache.Checker.ModuleArguments = $json.module_arguments;
|
||
|
|
|
||
|
|
[hashtable]$activeModules = @{};
|
||
|
|
|
||
|
|
foreach ($module in $json.modules) {
|
||
|
|
if ($Icinga2.Cache.Checker.ModuleConfig.ContainsKey($module.name)) {
|
||
|
|
$Icinga2.Cache.Checker.ModuleConfig[$module.name] = $module.check_interval;
|
||
|
|
} else {
|
||
|
|
$Icinga2.Cache.Checker.ModuleConfig.Add($module.name, $module.check_interval);
|
||
|
|
}
|
||
|
|
$activeModules.Add($module.name, $TRUE);
|
||
|
|
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Debug,
|
||
|
|
[string]::Format(
|
||
|
|
'Adding module {0} with check intervall {1}',
|
||
|
|
$module.name,
|
||
|
|
$module.check_interval
|
||
|
|
)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
# We might have disabled some modules. Lets handle this by setting the
|
||
|
|
# execution timer to -1
|
||
|
|
foreach ($module in $Icinga2.Cache.Checker.ModuleConfig.Keys) {
|
||
|
|
if ($activeModules.ContainsKey($module) -eq $FALSE) {
|
||
|
|
$activeModules.Add($module, $FALSE);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# We require a second loop to ensure we won't crash because of a changed hashtable
|
||
|
|
foreach($module in $activeModules.Keys) {
|
||
|
|
if ($activeModules[$module] -eq $FALSE) {
|
||
|
|
if ($Icinga2.Cache.Checker.ModuleConfig.ContainsKey($module)) {
|
||
|
|
$Icinga2.Cache.Checker.ModuleConfig.Remove($module);
|
||
|
|
$Icinga2.Log.Write(
|
||
|
|
$Icinga2.Enums.LogState.Debug,
|
||
|
|
[string]::Format(
|
||
|
|
'Disabling module {0}',
|
||
|
|
$module
|
||
|
|
)
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $ClientProtocol;
|