From 96284f07a302b7068116be8686f15c5da0c5f57a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 14 Sep 2019 16:12:24 +0200 Subject: [PATCH] Improved exception handling on a more global state --- .../New-IcingaPerformanceCounter.psm1 | 7 +- .../Exit-IcingaMissingPermission.psm1 | 36 ---------- .../exception/Exit-IcingaThrowException.psm1 | 72 +++++++++++++++++++ lib/plugins/Invoke-IcingaCheckCPU.psm1 | 3 - 4 files changed, 78 insertions(+), 40 deletions(-) delete mode 100644 lib/icinga/exception/Exit-IcingaMissingPermission.psm1 create mode 100644 lib/icinga/exception/Exit-IcingaThrowException.psm1 diff --git a/lib/core/perfcounter/New-IcingaPerformanceCounter.psm1 b/lib/core/perfcounter/New-IcingaPerformanceCounter.psm1 index 83bebfe..ac50711 100644 --- a/lib/core/perfcounter/New-IcingaPerformanceCounter.psm1 +++ b/lib/core/perfcounter/New-IcingaPerformanceCounter.psm1 @@ -71,7 +71,12 @@ $AllCountersIntances += $NewCounter; } } catch { - return (New-IcingaPerformanceCounterNullObject -FullName $Counter -ErrorMessage ([string]::Format('Failed to deserialize instances for counter "{0}". Exception: "{1}".', $Counter, $_.Exception.Message))); + # Throw an exception in case our permissions are not enough to fetch performance counter + Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'System.UnauthorizedAccessException' -ExceptionType 'Permission' -ExceptionThrown $IcingaExceptions.Permission.PerformanceCounter; + Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'System.InvalidOperationException' -ExceptionType 'Input' -CustomMessage $Counter -ExceptionThrown $IcingaExceptions.Inputs.PerformanceCounter; + Exit-IcingaThrowException -InputString $_.Exception -StringPattern '' -ExceptionType 'Unhandled'; + # Shouldn't actually get down here anyways + return (New-IcingaPerformanceCounterNullObject -FullName $Counter -ErrorMessage ([string]::Format('Failed to deserialize instances for counter "{0}". Exception: "{1}".', $Counter, $_.Exception.Message))); } # If we load multiple instances, we should add a global wait here instead of a wait for each single instance diff --git a/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 b/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 deleted file mode 100644 index 425f984..0000000 --- a/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 +++ /dev/null @@ -1,36 +0,0 @@ -Import-IcingaLib icinga\enums; -Import-IcingaLib icinga\exception; - -function Exit-IcingaMissingPermission() -{ - param( - [string]$InputString, - [string]$StringPattern, - [string]$CustomMessage, - [string]$ExeptionType - ); - - if ($null -eq $InputString -Or [string]::IsNullOrEmpty($InputString)) { - return; - } - - if (-Not $InputString.Contains($StringPattern)) { - return; - } - - $OutputMessage = '{0}: Icinga Permission Error was thrown: {3}{1}{1}{2}'; - if ([string]::IsNullOrEmpty($CustomMessage) -eq $TRUE) { - $OutputMessage = '{0}: Icinga Permission Error was thrown {1}{1}{2}{3}'; - } - - $OutputMessage = [string]::Format( - $OutputMessage, - $IcingaEnums.IcingaExitCodeText.($IcingaEnums.IcingaExitCode.Unknown), - "`r`n", - $ExeptionType, - $CustomMessage - ); - - Write-Host $OutputMessage; - exit $IcingaEnums.IcingaExitCode.Unknown; -} diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 new file mode 100644 index 0000000..d4610ee --- /dev/null +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -0,0 +1,72 @@ +function Exit-IcingaThrowException() +{ + param( + [string]$InputString, + [string]$StringPattern, + [string]$CustomMessage, + [string]$ExceptionThrown, + [ValidateSet('Permission','Input','Unhandled')] + [string]$ExceptionType = 'Unhandled' + ); + + if ($null -eq $InputString -Or [string]::IsNullOrEmpty($InputString)) { + return; + } + + if (-Not $InputString.Contains($StringPattern)) { + return; + } + + $ExceptionMessageLib = $null; + $ExceptionTypeString = ''; + + switch ($ExceptionType) { + 'Permission' { + $ExceptionTypeString = 'Permission'; + $ExceptionMessageLib = $IcingaExceptions.Permission; + }; + 'Input' { + $ExceptionTypeString = 'Invalid Input'; + $ExceptionMessageLib = $IcingaExceptions.Inputs; + }; + 'Unhandled' { + $ExceptionTypeString = 'Unhandled'; + }; + } + + [string]$ExceptionName = ''; + + if ($null -ne $ExceptionMessageLib) { + foreach ($definedError in $ExceptionMessageLib.Keys) { + if ($ExceptionMessageLib.$definedError -eq $ExceptionThrown) { + $ExceptionName = $definedError; + break; + } + } + } else { + $ExceptionName = 'Unhandled Exception'; + $ExceptionThrown = [string]::Format( + 'Unhandled exception occured:{0}{1}', + "`r`n", + $InputString + ); + } + + $OutputMessage = '{0}: Icinga {5} Error was thrown: {3}: {4}{1}{1}{2}'; + if ([string]::IsNullOrEmpty($CustomMessage) -eq $TRUE) { + $OutputMessage = '{0}: Icinga {5} Error was thrown: {3}{1}{1}{2}{4}'; + } + + $OutputMessage = [string]::Format( + $OutputMessage, + $IcingaEnums.IcingaExitCodeText.($IcingaEnums.IcingaExitCode.Unknown), + "`r`n", + $ExceptionThrown, + $ExceptionName, + $CustomMessage, + $ExceptionTypeString + ); + + Write-Host $OutputMessage; + exit $IcingaEnums.IcingaExitCode.Unknown; +} diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index defd00b..0df4075 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -1,6 +1,5 @@ Import-IcingaLib core\perfcounter; Import-IcingaLib icinga\plugin; -Import-IcingaLib icinga\exception; function Invoke-IcingaCheckCPU() { @@ -15,8 +14,6 @@ function Invoke-IcingaCheckCPU() $CpuCounter = New-IcingaPerformanceCounter -Counter ([string]::Format('\Processor({0})\% processor time', $Core)); $CpuPackage = New-IcingaCheckPackage -Name 'CPU Load' -OperatorAnd -Verbos $Verbose; - Exit-IcingaMissingPermission -InputString $CpuCounter.ErrorMessage -StringPattern '"Global"' -ExeptionType $IcingaExceptions.Throw.PerformanceCounter; - if ($CpuCounter.Counters.Count -ne 0) { foreach ($counter in $CpuCounter.Counters) { $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}', $counter.Instance)) -Value $counter.Value().Value -Unit '%';