diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index a42bf170..9611040e 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -18,6 +18,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#615](https://github.com/Icinga/icinga-powershell-framework/issues/615) Fixes the framework migration tasks which fails in case multiple versions of the framework are installed, printing warnings in case there is * [#617](https://github.com/Icinga/icinga-powershell-framework/issues/617) Fixes failing calls for plugins which use a switch argument like `-NoPerfData`, which is followed directly by the `-ThresholdInterval` argument * [#621](https://github.com/Icinga/icinga-powershell-framework/pull/621) Fixes `-ThresholdInterval` key detection on newer systems +* [#645](https://github.com/Icinga/icinga-powershell-framework/pull/645) Fixes error and exception handling while using API-Checks, which now will in most cases always return a proper check-result object and also abort while running into plugin execution errors, in case a server is not reachable by the time sync plugin for example ### Enhancements diff --git a/lib/daemons/modules/ApiChecks/Invoke-IcingaApiChecksRESTCall.psm1 b/lib/daemons/modules/ApiChecks/Invoke-IcingaApiChecksRESTCall.psm1 index 98878e3c..8a2f6045 100644 --- a/lib/daemons/modules/ApiChecks/Invoke-IcingaApiChecksRESTCall.psm1 +++ b/lib/daemons/modules/ApiChecks/Invoke-IcingaApiChecksRESTCall.psm1 @@ -9,9 +9,11 @@ function Invoke-IcingaApiChecksRESTCall() [Hashtable]$ContentResponse = @{ }; # Short our call - $CheckerAliases = $Global:Icinga.Public.Daemons.RESTApi.CommandAliases.checker; - $CheckConfig = $Request.Body; - [int]$ExitCode = 3; #Unknown + $CheckerAliases = $Global:Icinga.Public.Daemons.RESTApi.CommandAliases.checker; + $CheckConfig = $Request.Body; + [int]$ExitCode = 3; #Unknown + [string]$CheckResult = ''; + [string]$InternalError = ''; # Check if there are an inventory aliases configured # This should be maintained by the developer and not occur @@ -56,10 +58,20 @@ function Invoke-IcingaApiChecksRESTCall() } if ((Test-IcingaRESTApiCommand -Command $ExecuteCommand -Endpoint 'apichecks') -eq $FALSE) { + + Add-IcingaHashtableItem ` + -Hashtable $ContentResponse ` + -Key $ExecuteCommand ` + -Value @{ + 'exitcode' = 3; + 'checkresult' = [string]::Format('[UNKNOWN] Icinga Permission error was thrown: Permission denied for command "{0}"{1}{1}The command "{0}" you are trying to execute over the REST-Api endpoint "apichecks" is not whitelisted for remote execution.', $ExecuteCommand, (New-IcingaNewLine)); + 'perfdata' = @(); + } | Out-Null; + 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)) + -ContentBody $ContentResponse ) -Stream $Connection.Stream; return; @@ -100,9 +112,19 @@ function Invoke-IcingaApiChecksRESTCall() -Value $CmdArgValue | Out-Null; }; - [int]$ExitCode = & $ExecuteCommand @Arguments; + try { + [int]$ExitCode = & $ExecuteCommand @Arguments; + } catch { + [int]$ExitCode = 3; + $InternalError = $_.Exception.Message; + } } elseif ($Request.Method -eq 'GET') { - [int]$ExitCode = & $ExecuteCommand; + try { + [int]$ExitCode = & $ExecuteCommand; + } catch { + [int]$ExitCode = 3; + $InternalError = $_.Exception.Message; + } } else { Send-IcingaTCPClientMessage -Message ( New-IcingaTCPClientRESTMessage ` @@ -115,7 +137,16 @@ function Invoke-IcingaApiChecksRESTCall() # 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; + if ([string]::IsNullOrEmpty($InternalError)) { + $CheckResult = Get-IcingaCheckSchedulerPluginOutput; + } else { + if ($InternalError.Contains('[UNKNOWN]') -eq $FALSE) { + # Ensure we format the error message more user friendly + $CheckResult = [string]::Format('[UNKNOWN] Icinga Plugin execution error was thrown during API request:{0}{0}{1}', (New-IcingaNewLine), $InternalError); + } else { + $CheckResult = $InternalError; + } + } [array]$PerfData = Get-IcingaCheckSchedulerPerfData; # Ensure our PerfData variable is always an array diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 index 11aa8cd0..e4e203d9 100644 --- a/lib/icinga/exception/Exit-IcingaThrowException.psm1 +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -113,5 +113,7 @@ function Exit-IcingaThrowException() if ($Global:Icinga.Protected.RunAsDaemon -eq $FALSE -And $Global:Icinga.Protected.JEAContext -eq $FALSE) { Write-IcingaConsolePlain $OutputMessage; exit $IcingaEnums.IcingaExitCode.Unknown; + } else { + throw $OutputMessage; } }