icinga-powershell-framework/lib/daemons/RestAPI/daemon/New-IcingaForWindowsRESTApi.psm1

142 lines
5.7 KiB
PowerShell
Raw Normal View History

function New-IcingaForWindowsRESTApi()
{
# Allow us to parse the framework global data to this thread
param (
[string]$Address = '',
$Port,
$CertFile,
$CertThumbprint,
$RequireAuth
);
$RESTEndpoints = Invoke-IcingaNamespaceCmdlets -Command 'Register-IcingaRESTAPIEndpoint*';
Write-IcingaDebugMessage -Message (
[string]::Format(
'Loading configuration for REST-Endpoints{0}{1}',
(New-IcingaNewLine),
($RESTEndpoints | Out-String)
)
);
2021-12-09 11:42:06 -05:00
Write-IcingaDebugMessage -Message ($Global:Icinga.Public.Daemons.RESTApi | Out-String);
foreach ($entry in $RESTEndpoints.Values) {
2021-12-09 11:42:06 -05:00
[bool]$Success = Add-IcingaHashtableItem `
-Hashtable $Global:Icinga.Public.Daemons.RESTApi.RegisteredEndpoints `
-Key $entry.Alias `
-Value $entry.Command;
2021-11-17 13:06:09 -05:00
if ($Success -eq $FALSE) {
Write-IcingaEventMessage `
-EventId 2100 `
-Namespace 'RESTApi' `
-Objects ([string]::Format('Adding duplicated REST endpoint "{0}" with command "{1}', $entry.Alias, $entry.Command)), $RESTEndpoints;
}
}
$CommandAliases = Invoke-IcingaNamespaceCmdlets -Command 'Register-IcingaRESTApiCommandAliases*';
foreach ($entry in $CommandAliases.Values) {
foreach ($component in $entry.Keys) {
2021-12-09 11:42:06 -05:00
[bool]$Success = Add-IcingaHashtableItem `
-Hashtable $Global:Icinga.Public.Daemons.RESTApi.CommandAliases `
-Key $component `
-Value $entry[$component];
2021-11-17 13:06:09 -05:00
if ($Success -eq $FALSE) {
Write-IcingaEventMessage `
-EventId 2101 `
-Namespace 'RESTApi' `
-Objects ([string]::Format('Adding duplicated REST command aliases "{0}" for namespace "{1}', $entry[$component], $component)), $CommandAliases;
}
}
}
2021-12-09 11:42:06 -05:00
Write-IcingaDebugMessage -Message ($Global:Icinga.Public.Daemons.RESTApi.RegisteredEndpoints | Out-String);
$Global:Icinga.Public.SSL.CertFile = $CertFile;
$Global:Icinga.Public.SSL.CertThumbprint = $CertThumbprint;
while ($TRUE) {
if ($null -eq $Global:Icinga.Public.SSL.Certificate) {
# In case we are not inside a JEA context, use the SSLCertForSocket function to create the certificate file on the fly
# while maintaining the new wait feature. This fix is required, as the NetworkService user has no permssion
# to read the icingaforwindows.pfx file with the private key
if ([string]::IsNullOrEmpty((Get-IcingaJEAContext))) {
$Global:Icinga.Public.SSL.Certificate = Get-IcingaSSLCertForSocket `
-CertFile $Global:Icinga.Public.SSL.CertFile `
-CertThumbprint $Global:Icinga.Public.SSL.CertThumbprint;
} else {
$Global:Icinga.Public.SSL.Certificate = Get-IcingaForWindowsCertificate;
}
}
if ($null -ne $Global:Icinga.Public.SSL.Certificate) {
break;
}
# Wait 5 minutes and try again
Write-IcingaEventMessage -EventId 2002 -Namespace 'RESTApi' -Objects ($Global:Icinga.Public.SSL.Certificate | Out-String), $Global:Icinga.Public.SSL.CertFile, $Global:Icinga.Public.SSL.CertThumbprint;
Start-Sleep -Seconds (60 * 5);
}
# Create a background thread to renew the certificate on a regular basis
Start-IcingaForWindowsCertificateThreadTask;
$Socket = New-IcingaTCPSocket -Address $Address -Port $Port -Start;
# Keep our code executed as long as the PowerShell service is
# being executed. This is required to ensure we will execute
# the code frequently instead of only once
while ($TRUE) {
2021-11-17 13:06:09 -05:00
# Force Icinga for Windows Garbage Collection
Optimize-IcingaForWindowsMemory -ClearErrorStack -SmartGC;
2021-11-17 13:06:09 -05:00
$Connection = Open-IcingaTCPClientConnection `
-Client (New-IcingaTCPClient -Socket $Socket) `
-Certificate $Global:Icinga.Public.SSL.Certificate;
if ($Connection.Client -eq $null -Or $Connection.Stream -eq $null) {
Close-IcingaTCPConnection -Connection $Connection;
$Connection = $null;
continue;
}
2021-12-09 11:42:06 -05:00
if (Test-IcingaRESTClientBlacklisted -Client $Connection.Client -ClientList $Global:Icinga.Public.Daemons.RESTApi.ClientBlacklist) {
Write-IcingaDebugMessage -Message 'A remote client which is trying to connect was blacklisted' -Objects $Connection.Client.Client;
Close-IcingaTCPConnection -Connection $Connection;
2023-07-24 11:51:33 -04:00
$Connection = $null;
continue;
}
if ((Test-IcingaRESTClientConnection -Connection $Connection) -eq $FALSE) {
2023-07-24 11:51:33 -04:00
$Connection = $null;
continue;
}
# API not yet ready
2021-12-09 11:42:06 -05:00
if ($Global:Icinga.Public.Daemons.RESTApi.ApiRequests.Count -eq 0) {
Close-IcingaTCPConnection -Connection $Connection;
2023-07-24 11:51:33 -04:00
$Connection = $null;
continue;
}
try {
$NextRESTApiThreadId = (Get-IcingaNextRESTApiThreadId);
Write-IcingaDebugMessage -Message 'Scheduling Icinga for Windows API request' -Objects 'REST-Thread Id', $NextRESTApiThreadId;
2021-12-09 11:42:06 -05:00
if ($Global:Icinga.Public.Daemons.RESTApi.ApiRequests.ContainsKey($NextRESTApiThreadId) -eq $FALSE) {
Close-IcingaTCPConnection -Connection $Connection;
2023-07-24 11:51:33 -04:00
$Connection = $null;
continue;
}
$Global:Icinga.Public.Daemons.RESTApi.ApiRequests.$NextRESTApiThreadId.Add($Connection);
} catch {
2021-12-09 11:42:06 -05:00
Write-IcingaEventMessage -Namespace 'RESTApi' -EvenId 2050 -ExceptionObject $_;
}
}
}