diff --git a/lib/icinga/checkresult.psm1 b/lib/icinga/checkresult.psm1 new file mode 100644 index 0000000..4ce1716 --- /dev/null +++ b/lib/icinga/checkresult.psm1 @@ -0,0 +1 @@ +Import-IcingaDirectoryModules -LibDirectory (Join-Path -Path $PSScriptRoot -ChildPath $MyInvocation.MyCommand.Name); diff --git a/lib/icinga/checkresult/New-IcingaCheck.psm1 b/lib/icinga/checkresult/New-IcingaCheck.psm1 new file mode 100644 index 0000000..28ce500 --- /dev/null +++ b/lib/icinga/checkresult/New-IcingaCheck.psm1 @@ -0,0 +1,311 @@ +Import-IcingaLib icinga\enums; + +function New-IcingaCheck() +{ + param( + [string]$Name = '', + $Value = $null, + $Unit = $null + ); + + $Check = New-Object -TypeName PSObject; + $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; + $Check | Add-Member -membertype NoteProperty -name 'messages' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'value' -value $Value; + $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; + $Check | Add-Member -membertype NoteProperty -name 'unit' -value $Unit; + + $Check | Add-Member -membertype ScriptMethod -name 'WarnIfLike' -value { + param($warning); + + if ($this.value -Like $warning) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $warning, + 'like' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'WarnIfNotLike' -value { + param($warning); + + if (-Not ($this.value -Like $warning)) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $warning, + 'not like' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'WarnIfMatch' -value { + param($warning); + + if ($this.value -eq $warning) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $warning, + 'matching' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'WarnIfNotMatch' -value { + param($warning); + + if ($this.value -ne $warning) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $warning, + 'not matching' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'WarnIfLowerThan' -value { + param($warning); + + if ($this.value -lt $warning) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $warning, + 'lower than' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'WarnIfLowerEqualThan' -value { + param($warning); + + if ($this.value -le $warning) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $warning, + 'lower or equal than' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'WarnIfGreaterThan' -value { + param($warning); + + if ($this.value -gt $warning) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $warning, + 'greater than' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'WarnIfGreaterEqualThan' -value { + param($warning); + + if ($this.value -ge $warning) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $warning, + 'greater or equal than' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CritIfLike' -value { + param($critical); + + if ($this.value -Like $critical) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $critical, + 'like' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CritIfNotLike' -value { + param($critical); + + if (-Not ($this.value -Like $critical)) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $critical, + 'not like' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CritIfMatch' -value { + param($critical); + + if ($this.value -eq $critical) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $critical, + 'matching' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CritIfNotMatch' -value { + param($critical); + + if ($this.value -ne $critical) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $critical, + 'not matching' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CritIfLowerThan' -value { + param($critical); + + if ($this.value -lt $critical) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $critical, + 'lower than' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CritIfLowerEqualThan' -value { + param($critical); + + if ($this.value -le $critical) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $critical, + 'lower or equal than' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CritIfGreaterThan' -value { + param($critical); + + if ($this.value -gt $critical) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $critical, + 'greater than' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CritIfGreaterEqualThan' -value { + param($critical); + + if ($this.value -ge $critical) { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $critical, + 'greater or equal than' + ); + } + + return $this; + } + + $Check | Add-Member -membertype ScriptMethod -name 'AddInternalCheckMessage' -value { + param($state, $value, $type); + + $this.SetExitCode($state); + $this.AddMessage([string]::Format( + '{0} {1}{4} is {2} {3}{4}', $this.name, $this.value, $type, $value, $this.unit + ), $state); + } + + $Check | Add-Member -membertype ScriptMethod -name 'AddMessage' -value { + param($message, $exitcode); + + $this.messages += [string]::Format( + '{0}: {1}', + $IcingaEnums.IcingaExitCodeText[$exitcode], + $message + ); + } + + $Check | Add-Member -membertype ScriptMethod -name 'SetExitCode' -value { + param([int]$code); + + # Only overwrite the exit code in case our new value is greater then + # the current one Ok > Warning > Critical + if ([int]$this.exitcode -gt $code) { + return $this; + } + + $this.exitcode = $code; + } + + $Check | Add-Member -membertype ScriptMethod -name 'WriteUnitError' -value { + if ($null -ne $this.unit -And (-Not $IcingaEnums.IcingaMeasurementUnits.ContainsKey($this.unit))) { + Write-Host ( + [string]::Format( + 'Error: Usage of invalid plugin unit "{0}". Allowed units are: {1}', + $this.unit, + (($IcingaEnums.IcingaMeasurementUnits.Keys | Sort-Object name) -Join ', ') + ) + ); + } + } + + $Check | Add-Member -membertype ScriptMethod -name 'AddOkOutput' -value { + if ([int]$this.exitcode -eq -1) { + $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; + $this.AddMessage([string]::Format('{0} is {1}{2}', $this.name, $this.value, $this.unit), $IcingaEnums.IcingaExitCode.Ok); + } + } + + $Check | Add-Member -membertype ScriptMethod -name 'SilentCompile' -value { + $this.WriteUnitError(); + $this.AddOkOutput(); + } + + $Check | Add-Member -membertype ScriptMethod -name 'Compile' -value { + param([bool]$Verbose = $FALSE); + + if ($Verbose) { + Write-Host ($this.messages | Out-String); + } + + $this.WriteUnitError(); + $this.AddOkOutput(); + + return $this.exitcode; + } + + return $Check; +} diff --git a/lib/icinga/checkresult/New-IcingaCheckPackage.psm1 b/lib/icinga/checkresult/New-IcingaCheckPackage.psm1 new file mode 100644 index 0000000..cbd3db9 --- /dev/null +++ b/lib/icinga/checkresult/New-IcingaCheckPackage.psm1 @@ -0,0 +1,176 @@ +Import-IcingaLib icinga\enums; + +function New-IcingaCheckPackage() +{ + param( + [string]$Name, + [switch]$OperatorAnd, + [switch]$OperatorOr, + [switch]$OperatorNone, + [int]$OperatorMin = -1, + [int]$OperatorMax = -1, + [array]$Checks = @() + ); + + $Check = New-Object -TypeName PSObject; + $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; + $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; + $Check | Add-Member -membertype NoteProperty -name 'checks' -value $Checks; + $Check | Add-Member -membertype NoteProperty -name 'opand' -value $OperatorAnd; + $Check | Add-Member -membertype NoteProperty -name 'opor' -value $OperatorOr; + $Check | Add-Member -membertype NoteProperty -name 'opnone' -value $OperatorNone; + $Check | Add-Member -membertype NoteProperty -name 'opmin' -value $OperatorMin; + $Check | Add-Member -membertype NoteProperty -name 'opmax' -value $OperatorMax; + $Check | Add-Member -membertype NoteProperty -name 'hasoutput' -value $TRUE; + + $Check | Add-Member -membertype ScriptMethod -name 'Compile' -value { + + Write-Host ([string]::Format('Check result for package {0} ({1}):{2}', $this.name, $this.GetPackageConfigMessage(), "`r`n")); + + if ($this.opand) { + if ($this.CheckAllOk() -eq $FALSE) { + $this.GetWorstExitCode(); + } + } elseif($this.opor) { + if ($this.CheckOneOk() -eq $FALSE) { + $this.GetWorstExitCode(); + } + } elseif($this.opnone) { + if ($this.CheckOneOk() -eq $TRUE) { + $this.GetWorstExitCode(); + $this.exitcode = $IcingaEnums.IcingaExitCode.Critical; + } else { + $this.WriteAllOutput(); + $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + } elseif([int]$this.opmin -ne -1) { + if ($this.CheckMinimumOk() -eq $FALSE) { + $this.GetWorstExitCode(); + } else { + $this.WriteAllOutput(); + $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + } elseif([int]$this.opmax -ne -1) { + if ($this.CheckMaximumOk() -eq $FALSE) { + $this.GetWorstExitCode(); + } else { + $this.WriteAllOutput(); + $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + } + + if ($this.hasoutput -eq $FALSE) { + Write-Host $IcingaEnums.IcingaExitCodeText.($this.exitcode); + } + + return $this.exitcode; + } + + $Check | Add-Member -membertype ScriptMethod -name 'SilentCompile' -value { + $this.Compile() | Out-Null; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetOkCount' -value { + [int]$okCount = 0; + foreach ($check in $this.checks) { + if ([int]$check.exitcode -eq [int]$IcingaEnums.IcingaExitCode.Ok) { + $okCount += 1; + } + } + + return $okCount; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CheckMinimumOk' -value { + [int]$okCount = $this.GetOkCount(); + + if ($this.opmin -le $okCount) { + return $TRUE; + } + + return $FALSE; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CheckMaximumOk' -value { + [int]$okCount = $this.GetOkCount(); + + if ($this.opmax -ge $okCount) { + return $TRUE; + } + + return $FALSE; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CheckAllOk' -value { + foreach ($check in $this.checks) { + if ([int]$check.exitcode -ne [int]$IcingaEnums.IcingaExitCode.Ok) { + return $FALSE; + } + } + + return $TRUE; + } + + $Check | Add-Member -membertype ScriptMethod -name 'CheckOneOk' -value { + foreach ($check in $this.checks) { + if ([int]$check.exitcode -eq [int]$IcingaEnums.IcingaExitCode.Ok) { + if ($check.messages.Count -ne 0) { + Write-Host ($check.messages | Out-String); + } else { + $this.hasoutput = $FALSE; + } + $this.exitcode = $check.exitcode; + return $TRUE; + } + } + + return $FALSE; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetPackageConfigMessage' -value { + if ($this.opand) { + return 'Match All'; + } elseif ($this.opor) { + return 'Match Any'; + } elseif ($this.opnone) { + return 'Match None'; + } elseif ([int]$this.opmin -ne -1) { + return [string]::Format('Minimum {0}', $this.opmin) + } elseif ([int]$this.opmax -ne -1) { + return [string]::Format('Maximum {0}', $this.opmax) + } + } + + $Check | Add-Member -membertype ScriptMethod -name 'WriteAllOutput' -value { + $printedOutput = $FALSE; + foreach ($check in $this.checks) { + if ($check.messages.Count -ne 0) { + Write-Host ($check.messages | Out-String); + $printedOutput = $TRUE; + } + } + if ($printedOutput -eq $FALSE) { + $this.hasoutput = $FALSE; + } + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetWorstExitCode' -value { + $worstCheck = $null; + foreach ($check in $this.checks) { + if ([int]$this.exitcode -lt $check.exitcode) { + $this.exitcode = $check.exitcode; + $worstCheck = $check; + } + } + + if ($null -ne $worstCheck) { + if ($worstCheck.messages.Count -ne 0) { + Write-Host ($worstCheck.messages | Out-String); + } else { + $this.hasoutput = $FALSE; + } + } + } + + return $Check; +} diff --git a/lib/icinga/checkresult/New-IcingaCheckResult.psm1 b/lib/icinga/checkresult/New-IcingaCheckResult.psm1 new file mode 100644 index 0000000..f5084cc --- /dev/null +++ b/lib/icinga/checkresult/New-IcingaCheckResult.psm1 @@ -0,0 +1,131 @@ +Import-IcingaLib icinga\enums; + +function New-IcingaCheckresult() +{ + $CheckResult = New-Object -TypeName PSObject; + $CheckResult | Add-Member -membertype NoteProperty -name 'HasResult' -value $FALSE; + $CheckResult | Add-Member -membertype NoteProperty -name 'ExitCode' -value -1; + $CheckResult | Add-Member -membertype NoteProperty -name 'OutputMessage' -value @(); + $CheckResult | Add-Member -membertype NoteProperty -name 'PerfData' -value @(); + + $CheckResult | Add-Member -membertype ScriptMethod -name 'Matches' -value { + param($match, $value, $message, [bool]$negate = $FALSE); + + [string]$phrase = 'IS'; + [int]$exitcode = $IcingaEnums.IcingaExitCode.Unknown; + + if ($negate) { + if ($value -ne $match) { + $phrase = 'IS'; + $exitcode = $IcingaEnums.IcingaExitCode.Ok; + } else { + $phrase = 'is NOT'; + $exitcode = $IcingaEnums.IcingaExitCode.Critical; + } + } else { + if ($value -ne $match) { + $phrase = 'is NOT'; + $exitcode = $IcingaEnums.IcingaExitCode.Critical; + } else { + $phrase = 'IS'; + $exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + } + + $message = [string]::Format('{0} (Input value "{1}" {3} matching "{2}")', $message, $value, $match, $phrase); + $this.SetExitCode($exitcode); + $this.AddOutputMessage($message, $exitcode); + } + + $CheckResult | Add-Member -membertype ScriptMethod -name 'Lower' -value { + param($warning, $critical, $value, $message); + + [int]$exitcode = $IcingaEnums.IcingaExitCode.Unknown; + + if ($value -ge $critical) { + $exitcode = $IcingaEnums.IcingaExitCode.Critical; + } elseif ($value -ge $warning) { + $exitcode = $IcingaEnums.IcingaExitCode.Warning; + } else { + $exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + + $this.SetExitCode($exitcode); + $this.AddOutputMessage($message, $exitcode); + } + + $CheckResult | Add-Member -membertype ScriptMethod -name 'LowerEqual' -value { + param($warning, $critical, $value, $message); + + [int]$exitcode = $IcingaEnums.IcingaExitCode.Unknown; + + if ($value -gt $critical) { + $exitcode = $IcingaEnums.IcingaExitCode.Critical; + } elseif ($value -gt $warning) { + $exitcode = $IcingaEnums.IcingaExitCode.Warning; + } else { + $exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + + $this.SetExitCode($exitcode); + $this.AddOutputMessage($message, $exitcode); + } + + $CheckResult | Add-Member -membertype ScriptMethod -name 'Greater' -value { + param($warning, $critical, $value, $message); + + [int]$exitcode = $IcingaEnums.IcingaExitCode.Unknown; + + if ($value -le $critical) { + $exitcode = $IcingaEnums.IcingaExitCode.Critical; + } elseif ($value -le $warning) { + $exitcode = $IcingaEnums.IcingaExitCode.Warning; + } else { + $exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + + $this.SetExitCode($exitcode); + $this.AddOutputMessage($message, $exitcode); + } + + $CheckResult | Add-Member -membertype ScriptMethod -name 'GreaterEqual' -value { + param($warning, $critical, $value, $message); + + [int]$exitcode = $IcingaEnums.IcingaExitCode.Unknown; + + if ($value -lt $critical) { + $exitcode = $IcingaEnums.IcingaExitCode.Critical; + } elseif ($value -lt $warning) { + $exitcode = $IcingaEnums.IcingaExitCode.Warning; + } else { + $exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + + $this.SetExitCode($exitcode); + $this.AddOutputMessage($message, $exitcode); + } + + $CheckResult | Add-Member -membertype ScriptMethod -name 'SetExitCode' -value { + param($exitcode); + + # Only overwrite the exit code in case our new value is greater then + # the current one Ok > Warning > Critical + if ($this.ExitCode -gt $exitcode) { + return; + } + + $this.ExitCode = $exitcode; + } + + $CheckResult | Add-Member -membertype ScriptMethod -name 'AddOutputMessage' -value { + param($exitcode, $message); + + $this.OutputMessage.Add( + [string]::Format( + '{0}: {1}', + $IcingaEnums.IcingaExitCodeText[$exitcode], + $message + ) + ) + } +} diff --git a/lib/icinga/enums.psm1 b/lib/icinga/enums.psm1 new file mode 100644 index 0000000..098cb80 --- /dev/null +++ b/lib/icinga/enums.psm1 @@ -0,0 +1,46 @@ +<# + # This script will provide 'Enums' we can use within our module to + # easier access constants and to maintain a better overview of the + # entire components + #> + +[hashtable]$IcingaExitCode = @{ + Ok = 0; + Warning = 1; + Critical = 2; + Unknown = 3; +}; + +[hashtable]$IcingaExitCodeText = @{ + 0 = 'Ok'; + 1 = 'Warning'; + 2 = 'Critical'; + 3 = 'Unknown'; +}; + +[hashtable]$IcingaMeasurementUnits = @{ + 's' = 'seconds'; + 'ms' = 'milliseconds'; + 'us' = 'microseconds'; + '%' = 'percent'; + 'B' = 'bytes'; + 'KB' = 'kilobytes'; + 'MB' = 'megabytes'; + 'TB' = 'terabytes'; + 'c' = 'counter'; +}; + +<# + # Once we defined a new enum hashtable above, simply add it to this list + # to make it available within the entire module. + # + # Example usage: + # $IcingaEnums.IcingaExitCode.Ok + #> +[hashtable]$IcingaEnums = @{ + IcingaExitCode = $IcingaExitCode; + IcingaExitCodeText = $IcingaExitCodeText; + IcingaMeasurementUnits = $IcingaMeasurementUnits; +} + +Export-ModuleMember -Variable @( 'IcingaEnums' );