From 2268d9658c8ea93d53b3538c228f899562c3e7ce Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 16 Jul 2021 11:31:41 +0200 Subject: [PATCH] Adds critical exception cmdlet and exit code catch --- doc/31-Changelog.md | 1 + .../exception/Exit-IcingaThrowCritical.psm1 | 32 +++++++++++++++++++ .../exception/Exit-IcingaThrowException.psm1 | 3 ++ lib/icinga/plugin/New-IcingaCheckResult.psm1 | 6 +++- .../Set-IcingaInternalPluginException.psm1 | 29 +++++++++++++++++ .../Set-IcingaInternalPluginExitCode.psm1 | 29 +++++++++++++++++ 6 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 lib/icinga/exception/Exit-IcingaThrowCritical.psm1 create mode 100644 lib/icinga/plugin/Set-IcingaInternalPluginException.psm1 create mode 100644 lib/icinga/plugin/Set-IcingaInternalPluginExitCode.psm1 diff --git a/doc/31-Changelog.md b/doc/31-Changelog.md index 742f5ed..b920c8e 100644 --- a/doc/31-Changelog.md +++ b/doc/31-Changelog.md @@ -12,6 +12,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic [Issue and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/15?closed=1) * [#305](https://github.com/Icinga/icinga-powershell-framework/pull/305) Adds a new Cmdlet to test if functions with `Add-Type` are already present inside the current scope of the shell +* [#306](https://github.com/Icinga/icinga-powershell-framework/pull/306) Adds new Cmdlet `Exit-IcingaThrowCritical` to throw critical exit with a custom message, either by force or by using string filtering and adds storing of plugin exit codes internally ## 1.5.2 (2021-07-09) diff --git a/lib/icinga/exception/Exit-IcingaThrowCritical.psm1 b/lib/icinga/exception/Exit-IcingaThrowCritical.psm1 new file mode 100644 index 0000000..7abd875 --- /dev/null +++ b/lib/icinga/exception/Exit-IcingaThrowCritical.psm1 @@ -0,0 +1,32 @@ +function Exit-IcingaThrowCritical() +{ + param ( + [string]$Message = '', + [string]$FilterString = $null, + [string]$SearchString = $null, + [switch]$Force = $FALSE + ); + + if ($Force -eq $FALSE) { + if ([string]::IsNullOrEmpty($FilterString) -Or [string]::IsNullOrEmpty($SearchString)) { + return; + } + + if ($FilterString -NotLike "*$SearchString*") { + return; + } + } + + [string]$OutputMessage = [string]::Format( + '[CRITICAL] {0}', + $Message + ); + + Set-IcingaInternalPluginExitCode -ExitCode $IcingaEnums.IcingaExitCode.Critical; + Set-IcingaInternalPluginException -PluginException $OutputMessage; + + if ($null -eq $global:IcingaDaemonData -Or $global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { + Write-IcingaConsolePlain $OutputMessage; + exit $IcingaEnums.IcingaExitCode.Critical; + } +} diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 index 60457e2..86dfbc4 100644 --- a/lib/icinga/exception/Exit-IcingaThrowException.psm1 +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -107,6 +107,9 @@ function Exit-IcingaThrowException() $ExceptionTypeString ); + Set-IcingaInternalPluginExitCode -ExitCode $IcingaEnums.IcingaExitCode.Unknown; + Set-IcingaInternalPluginException -PluginException $OutputMessage; + if ($null -eq $global:IcingaDaemonData -Or $global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { Write-IcingaConsolePlain $OutputMessage; exit $IcingaEnums.IcingaExitCode.Unknown; diff --git a/lib/icinga/plugin/New-IcingaCheckResult.psm1 b/lib/icinga/plugin/New-IcingaCheckResult.psm1 index 621de95..a353b16 100644 --- a/lib/icinga/plugin/New-IcingaCheckResult.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckResult.psm1 @@ -27,7 +27,11 @@ function New-IcingaCheckResult() # Ensure we reset our internal cache once the plugin was executed $Global:Icinga.ThresholdCache[$this.Check.__GetCheckCommand()] = $null; - return $this.Check.__GetCheckState(); + $ExitCode = $this.Check.__GetCheckState(); + + Set-IcingaInternalPluginExitCode -ExitCode $ExitCode; + + return $ExitCode; } if ($Compile) { diff --git a/lib/icinga/plugin/Set-IcingaInternalPluginException.psm1 b/lib/icinga/plugin/Set-IcingaInternalPluginException.psm1 new file mode 100644 index 0000000..906e5f2 --- /dev/null +++ b/lib/icinga/plugin/Set-IcingaInternalPluginException.psm1 @@ -0,0 +1,29 @@ +function Set-IcingaInternalPluginException() +{ + param ( + [string]$PluginException = '' + ); + + if ($null -eq $Global:Icinga) { + $Global:Icinga = @{ }; + } + + if ($Global:Icinga.ContainsKey('PluginExecution') -eq $FALSE) { + $Global:Icinga.Add( + 'PluginExecution', + @{ + 'PluginException' = $PluginException; + } + ) + } else { + if ($Global:Icinga.PluginExecution.ContainsKey('PluginException') -eq $FALSE) { + $Global:Icinga.PluginExecution.Add('PluginException', $PluginException); + return; + } + + # Only catch the first exception + if ([string]::IsNullOrEmpty($Global:Icinga.PluginExecution.PluginException)) { + $Global:Icinga.PluginExecution.PluginException = $PluginException; + } + } +} diff --git a/lib/icinga/plugin/Set-IcingaInternalPluginExitCode.psm1 b/lib/icinga/plugin/Set-IcingaInternalPluginExitCode.psm1 new file mode 100644 index 0000000..6e20468 --- /dev/null +++ b/lib/icinga/plugin/Set-IcingaInternalPluginExitCode.psm1 @@ -0,0 +1,29 @@ +function Set-IcingaInternalPluginExitCode() +{ + param ( + $ExitCode = 0 + ); + + if ($null -eq $Global:Icinga) { + $Global:Icinga = @{ }; + } + + if ($Global:Icinga.ContainsKey('PluginExecution') -eq $FALSE) { + $Global:Icinga.Add( + 'PluginExecution', + @{ + 'LastExitCode' = $ExitCode; + } + ) + } else { + if ($Global:Icinga.PluginExecution.ContainsKey('LastExitCode') -eq $FALSE) { + $Global:Icinga.PluginExecution.Add('LastExitCode', $ExitCode); + return; + } + + # Only add the first exit code we should cover during one runtime + if ($null -eq $Global:Icinga.PluginExecution.LastExitCode) { + $Global:Icinga.PluginExecution.LastExitCode = $ExitCode; + } + } +}