mirror of
https://github.com/Icinga/icinga-powershell-framework.git
synced 2025-12-20 23:00:35 -05:00
164 lines
6 KiB
PowerShell
164 lines
6 KiB
PowerShell
function New-IcingaForWindowsRESTApi()
|
|
{
|
|
# Allow us to parse the framework global data to this thread
|
|
param (
|
|
$IcingaDaemonData,
|
|
$Port,
|
|
$RootFolder,
|
|
$CertFile,
|
|
$CertThumbprint,
|
|
$RequireAuth
|
|
);
|
|
|
|
# Import the framework library components and initialise it
|
|
# as daemon
|
|
Use-Icinga -LibOnly -Daemon;
|
|
|
|
$Global:IcingaDaemonData = $IcingaDaemonData;
|
|
|
|
# Add a synchronized hashtable to the global data background
|
|
# daemon hashtable to write data to. In addition it will
|
|
# allow to share data collected from this daemon with others
|
|
$IcingaDaemonData.BackgroundDaemon.Add(
|
|
'IcingaPowerShellRestApi',
|
|
[hashtable]::Synchronized(@{})
|
|
);
|
|
|
|
# Map our Icinga globals to a shorter variable
|
|
$RestDaemon = $IcingaDaemonData.BackgroundDaemon.IcingaPowerShellRestApi;
|
|
|
|
# This will add another hashtable to our previous
|
|
# IcingaPowerShellRestApi hashtable to store actual
|
|
# endpoint configurations for the API
|
|
$RestDaemon.Add(
|
|
'RegisteredEndpoints',
|
|
[hashtable]::Synchronized(@{})
|
|
);
|
|
|
|
# This will add another hashtable to our previous
|
|
# IcingaPowerShellRestApi hashtable to store actual
|
|
# command aliases for execution for the API
|
|
$RestDaemon.Add(
|
|
'CommandAliases',
|
|
[hashtable]::Synchronized(@{})
|
|
);
|
|
|
|
# This will add another hashtable to our previous
|
|
# IcingaPowerShellRestApi hashtable to store actual
|
|
# command aliases for execution for the API
|
|
$RestDaemon.Add(
|
|
'ClientBlacklist',
|
|
[hashtable]::Synchronized(@{})
|
|
);
|
|
|
|
# Make the root folder of our rest daemon module available
|
|
# for every possible thread we require
|
|
$RestDaemon.Add(
|
|
'RootFolder', $RootFolder
|
|
);
|
|
|
|
$RESTEndpoints = Invoke-IcingaNamespaceCmdlets -Command 'Register-IcingaRESTAPIEndpoint*';
|
|
Write-IcingaDebugMessage -Message (
|
|
[string]::Format(
|
|
'Loading configuration for REST-Endpoints{0}{1}',
|
|
(New-IcingaNewLine),
|
|
($RESTEndpoints | Out-String)
|
|
)
|
|
);
|
|
|
|
Write-IcingaDebugMessage -Message ($RestDaemon | Out-String);
|
|
|
|
foreach ($entry in $RESTEndpoints.Values) {
|
|
[bool]$Success = Add-IcingaHashtableItem -Hashtable $RestDaemon.RegisteredEndpoints `
|
|
-Key $entry.Alias `
|
|
-Value $entry.Command;
|
|
|
|
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) {
|
|
[bool]$Success = Add-IcingaHashtableItem -Hashtable $RestDaemon.CommandAliases `
|
|
-Key $component `
|
|
-Value $entry[$component];
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-IcingaDebugMessage -Message ($RestDaemon.RegisteredEndpoints | Out-String);
|
|
|
|
if ($Global:IcingaDaemonData.JEAContext) {
|
|
if ($global:IcingaDaemonData.ContainsKey('SSLCertificate') -eq $FALSE -Or $null -eq $global:IcingaDaemonData.SSLCertificate) {
|
|
Write-IcingaEventMessage -EventId 2001 -Namespace 'RESTApi';
|
|
return;
|
|
}
|
|
|
|
$Certificate = $global:IcingaDaemonData.SSLCertificate;
|
|
} else {
|
|
$Certificate = Get-IcingaSSLCertForSocket -CertFile $CertFile -CertThumbprint $CertThumbprint;
|
|
}
|
|
|
|
if ($null -eq $Certificate) {
|
|
Write-IcingaEventMessage -EventId 2000 -Namespace 'RESTApi';
|
|
return;
|
|
}
|
|
|
|
$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) {
|
|
$Connection = Open-IcingaTCPClientConnection `
|
|
-Client (New-IcingaTCPClient -Socket $Socket) `
|
|
-Certificate $Certificate;
|
|
|
|
if (Test-IcingaRESTClientBlacklisted -Client $Connection.Client -ClientList $RestDaemon.ClientBlacklist) {
|
|
Write-IcingaDebugMessage -Message 'A remote client which is trying to connect was blacklisted' -Objects $Connection.Client.Client;
|
|
Close-IcingaTCPConnection -Client $Connection.Client;
|
|
continue;
|
|
}
|
|
|
|
if ((Test-IcingaRESTClientConnection -Connection $Connection) -eq $FALSE) {
|
|
continue;
|
|
}
|
|
|
|
# API not yet ready
|
|
if ($IcingaDaemonData.IcingaThreadContent.RESTApi.ApiRequests.Count -eq 0) {
|
|
Close-IcingaTCPConnection -Client $Connection.Client;
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
$NextRESTApiThreadId = (Get-IcingaNextRESTApiThreadId);
|
|
|
|
if ($IcingaDaemonData.IcingaThreadContent.RESTApi.ApiRequests.ContainsKey($NextRESTApiThreadId) -eq $FALSE) {
|
|
Close-IcingaTCPConnection -Client $Connection.Client;
|
|
continue;
|
|
}
|
|
|
|
$IcingaDaemonData.IcingaThreadContent.RESTApi.ApiRequests.$NextRESTApiThreadId.Enqueue($Connection);
|
|
} catch {
|
|
$ExMsg = $_.Exception.Message;
|
|
Write-IcingaEventMessage -Namespace 'RESTApi' -EvenId 2050 -Objects $ExMsg;
|
|
}
|
|
|
|
# Cleanup the error stack and remove not required data
|
|
$Error.Clear();
|
|
# Force PowerShell to call the garbage collector to free memory
|
|
[System.GC]::Collect();
|
|
}
|
|
}
|