lib/Invoke-IcingaApiChecksRESTCall.psm1
function Invoke-IcingaApiChecksRESTCall() { param ( [Hashtable]$Request = @{}, [Hashtable]$Connection = @{}, $IcingaGlobals, [string]$ApiVersion = $null ); $Global:IcingaDaemonData = $IcingaGlobals; # Initialise some global variables we use to actually store check result data from # plugins properly. This is doable from each thread instance as this part isn't # shared between daemons New-IcingaCheckSchedulerEnvironment; [Hashtable]$ContentResponse = @{}; # Short our call $CheckerAliases = $IcingaGlobals.BackgroundDaemon.IcingaPowerShellRestApi.CommandAliases.checker; $CheckConfig = $Request.Body; [int]$ExitCode = 3; #Unknown # Check if there are an inventory aliases configured # This should be maintained by the developer and not occur # anyway if ($null -eq $CheckerAliases) { $CheckerAliases = @{ }; } if ((Get-IcingaRESTHeaderValue -Request $Request -Header 'Content-Type') -ne 'application/json' -And $Request.Method -eq 'POST') { Send-IcingaTCPClientMessage -Message ( New-IcingaTCPClientRESTMessage ` -HTTPResponse ($IcingaHTTPEnums.HTTPResponseType.'Bad Request') ` -ContentBody 'This API endpoint does only accept "application/json" as content type over POST.' ) -Stream $Connection.Stream; return; } # Our namespace to include inventory packages is 'include' over the api # Everything else will be dropped for the moment if ($Request.RequestArguments.ContainsKey('list')) { Add-IcingaHashtableItem ` -Hashtable $ContentResponse ` -Key 'Commands' ` -Value $CheckerAliases | Out-Null; } elseif ($Request.RequestArguments.ContainsKey('command')) { [string]$ExecuteCommand = $null; foreach ($element in $CheckerAliases.Keys) { if ($Request.RequestArguments.command -Contains $element) { $ExecuteCommand = $CheckerAliases[$element]; # We only support to execute one check per call # No need to loop through everything break; } } if ([string]::IsNullOrEmpty($ExecuteCommand)) { [string]$ExecuteCommand = $Request.RequestArguments.command; } if ((Test-IcingaRESTApiCommand -Command $ExecuteCommand -Endpoint 'apichecks') -eq $FALSE) { Send-IcingaTCPClientMessage -Message ( New-IcingaTCPClientRESTMessage ` -HTTPResponse ($IcingaHTTPEnums.HTTPResponseType.'Forbidden') ` -ContentBody ([string]::Format('The command "{0}" you are trying to execute over this REST-Api endpoint "apichecks" is not whitelisted for remote execution.', $ExecuteCommand)) ) -Stream $Connection.Stream; return; } Write-IcingaDebugMessage -Message ('Executing API check for command: ' + $ExecuteCommand); if ([string]::IsNullOrEmpty($CheckConfig) -eq $FALSE -And $Request.Method -eq 'POST') { # Convert our JSON config for checks to a PSCustomObject $PSArguments = ConvertFrom-Json -InputObject $CheckConfig; # For executing the checks, we will require the data as # hashtable, so declare it here [hashtable]$Arguments = @{}; # Now convert our custom object by Key<->Value to # a valid hashtable, allowing us to parse arguments # to our check command $PSArguments.PSObject.Properties | ForEach-Object { Add-IcingaHashtableItem ` -Hashtable $Arguments ` -Key $_.Name ` -Value $_.Value | Out-Null; }; [int]$ExitCode = & $ExecuteCommand @Arguments; } elseif ($Request.Method -eq 'GET') { [int]$ExitCode = & $ExecuteCommand; } else { Send-IcingaTCPClientMessage -Message ( New-IcingaTCPClientRESTMessage ` -HTTPResponse ($IcingaHTTPEnums.HTTPResponseType.Ok) ` -ContentBody @{ 'message' = 'This API endpoint does only accept GET and POST methods for requests.' } ) -Stream $Connection.Stream; return; } # Once the check is executed, the plugin output and the performance data are stored # within a special cache map we can use for accessing $CheckResult = Get-IcingaCheckSchedulerPluginOutput; [array]$PerfData = Get-IcingaCheckSchedulerPerfData; # Ensure our PerfData variable is always an array if ($null -eq $PerfData -Or $PerfData.Count -eq 0) { [array]$PerfData = @(); } # Free our memory again Clear-IcingaCheckSchedulerEnvironment; Write-IcingaDebugMessage -Message 'Check Executed. Result below' -Objects $ExecuteCommand, $CheckResult, $PerfData, $ExitCode; Add-IcingaHashtableItem ` -Hashtable $ContentResponse ` -Key $ExecuteCommand ` -Value @{ 'exitcode' = $ExitCode; 'checkresult' = $CheckResult; 'perfdata' = $PerfData; } | Out-Null; } if ($ContentResponse.Count -eq 0) { $ContentResponse.Add( 'message', 'Welcome to the Icinga for Windows API checker. To execute checks, please use the command parameter. For providing arguments, you will have to submit a post with JSON encoded arguments. Example: /v1/checker?command=Invoke-IcingaCheckCPU' ); } # Send the response to the client Send-IcingaTCPClientMessage -Message ( New-IcingaTCPClientRESTMessage ` -HTTPResponse ($IcingaHTTPEnums.HTTPResponseType.Ok) ` -ContentBody $ContentResponse ) -Stream $Connection.Stream; } |