Fixes input value conversion for New-IcingaCheck to properly handling different unit types

This commit is contained in:
Lord Hepipud 2025-03-27 15:11:00 +01:00
parent b35f0a77b9
commit 63c6c8e710
6 changed files with 130 additions and 17 deletions

View file

@ -11,9 +11,14 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
[Issues and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/38)
## 1.13.3 (tbd)
[Issues and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/39)
### Bugfixes
* [#787](https://github.com/Icinga/icinga-powershell-framework/pull/787) Fixes the return value in case the `Agent` component could not be installed from `$FALSE` to `null`
* [#796](https://github.com/Icinga/icinga-powershell-framework/issues/796) [#798](https://github.com/Icinga/icinga-powershell-framework/issues/798) Fixes an issue with the new check handling, which did not properly convert values from checks to the correct performance data values and base values in some cases
## 1.13.2 (2025-02-03)

View file

@ -0,0 +1,38 @@
<#
.SYNOPSIS
Converts a time string to a Unix timestamp.
.DESCRIPTION
Converts a given time string like "2025-04-10 20:00:00" to a Unix timestamp.
The function returns 0 if the input is null or empty.
If the input cannot be parsed, it returns -1.
The function uses the UTC time zone for the conversion.
.PARAMETER TimeString
The time string to convert. It should be in a format that can be parsed by [datetime]::Parse, like "2025-04-10 20:00:00"
.EXAMPLE
$UnixTime = ConvertTo-IcingaUnixTime -TimeString "2025-04-10 20:00:00"
$UnixTime
#>
function ConvertTo-IcingaUnixTime()
{
param (
[string]$TimeString = $null
);
if ([string]::IsNullOrEmpty($TimeString)) {
return 0;
}
try {
return [decimal][double]::Parse(
(Get-Date -UFormat %s -Date (Get-Date -Date $TimeString).ToUniversalTime())
);
} catch {
return -1;
}
return 0;
}

View file

@ -0,0 +1,51 @@
<#
.SYNOPSIS
Calculates the offset in seconds between the current Unix time and a specified Unix time or time string.
.DESCRIPTION
The `Get-IcingaUnixTimeOffsetNow` function computes the difference in seconds between the current Unix time and a provided Unix time or time string. If no valid input is provided, the function returns 0.
.PARAMETER TimeString
A string representing a specific time. This string will be converted to Unix time using the `ConvertTo-IcingaUnixTime` function.
.PARAMETER UnixTime
A decimal value representing a specific Unix time. If provided, the offset will be calculated using this value.
.RETURNS
The offset in seconds as a decimal value. If no valid input is provided or the conversion fails, the function returns 0.
.EXAMPLE
PS> Get-IcingaUnixTimeOffsetNow -TimeString "2025-04-20 10:00:00"
Calculates the offset in seconds between the current Unix time and the specified time string.
.EXAMPLE
PS> Get-IcingaUnixTimeOffsetNow -UnixTime 1672531200
Calculates the offset in seconds between the current Unix time and the specified Unix time.
.NOTES
This function depends on the `ConvertTo-IcingaUnixTime` and `Get-IcingaUnixTime` functions to perform time conversions and retrieve the current Unix time.
#>
function Get-IcingaUnixTimeOffsetNow()
{
param (
[string]$TimeString = '',
[decimal]$UnixTime = 0
);
if ([string]::IsNullOrEmpty($TimeString) -And $UnixTime -eq 0) {
return 0;
}
if ([string]::IsNullOrEmpty($TimeString) -eq $FALSE) {
$UnixTime = ConvertTo-IcingaUnixTime -TimeString $TimeString;
if ($UnixTime -le 0) {
return 0;
}
}
$CurrentUnixTime = Get-IcingaUnixTime;
return ($CurrentUnixTime - $UnixTime);
}

View file

@ -126,6 +126,24 @@ function Compare-IcingaPluginThresholds()
$IcingaThresholds | Add-Member -MemberType NoteProperty -Name 'Minimum' -Value (Convert-IcingaPluginThresholds -Threshold $Minium);
$IcingaThresholds | Add-Member -MemberType NoteProperty -Name 'Maximum' -Value (Convert-IcingaPluginThresholds -Threshold $Maximum);
if ($TestInput.Decimal) {
$ConvertedValue = Convert-IcingaPluginThresholds -Threshold ([string]::Format('{0}{1}', $InputValue, $Unit));
if ((Test-IcingaDecimal -Value $ConvertedValue.Value).Decimal) {
$InputValue = [decimal]$ConvertedValue.Value;
$IcingaThresholds.Value = [decimal]$ConvertedValue.Value;
$IcingaThresholds.Unit = $ConvertedValue.Unit;
}
}
if ($BaseInput.Decimal) {
$ConvertedBaseValue = Convert-IcingaPluginThresholds -Threshold ([string]::Format('{0}{1}', $BaseValue, $Unit));
if ((Test-IcingaDecimal -Value $ConvertedBaseValue.Value).Decimal) {
$BaseValue = [decimal]$ConvertedBaseValue.Value;
}
}
# In case we are using % values, we should set the BaseValue always to 100
if ($Unit -eq '%' -And $null -eq $BaseValue) {
$IcingaThresholds | Add-Member -MemberType NoteProperty -Name 'BaseValue' -Value 100;
@ -136,17 +154,17 @@ function Compare-IcingaPluginThresholds()
$CheckResult = $null;
if ($Matches) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.Matches -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.Matches -MetricsOverTime $MoTData;
} elseif ($NotMatches) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.NotMatches -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.NotMatches -MetricsOverTime $MoTData;
} elseif ($IsBetween) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.Between -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.Between -MetricsOverTime $MoTData;
} elseif ($IsLowerEqual) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.LowerEqual -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.LowerEqual -MetricsOverTime $MoTData;
} elseif ($IsGreaterEqual) {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.GreaterEqual -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -OverrideMode $IcingaEnums.IcingaThresholdMethod.GreaterEqual -MetricsOverTime $MoTData;
} else {
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $Unit -Translation $Translation -MetricsOverTime $MoTData;
$CheckResult = Compare-IcingaPluginValueToThreshold -Value $InputValue -BaseValue $IcingaThresholds.BaseValue -Threshold $IcingaThresholds.Threshold -Unit $IcingaThresholds.Unit -CheckUnit $Unit -Translation $Translation -MetricsOverTime $MoTData;
}
$IcingaThresholds.Message = $CheckResult.Message;

View file

@ -57,6 +57,7 @@ function Compare-IcingaPluginValueToThreshold()
$Value = $null,
$BaseValue = $null,
$Unit = $null,
$CheckUnit = $null,
$Translation = $null,
$Threshold = $null,
$OverrideMode = $null,
@ -94,7 +95,7 @@ function Compare-IcingaPluginValueToThreshold()
# Otherwise just convert the values to human readble values
$HumanReadableValue = ConvertTo-IcingaPluginOutputTranslation -Translation $Translation -Value $HumanReadableValue;
$HumanReadableValue = Convert-IcingaPluginValueToString -Value $HumanReadableValue -Unit $Unit;
$HumanReadableValue = Convert-IcingaPluginValueToString -Value $HumanReadableValue -Unit $Unit -OriginalUnit $CheckUnit;
if ($null -eq $Value -Or $null -eq $Threshold -Or [string]::IsNullOrEmpty($Threshold.Raw)) {
$RetValue.Message = $HumanReadableValue;
@ -139,7 +140,7 @@ function Compare-IcingaPluginValueToThreshold()
}
if ($Value -gt $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is greater than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is greater than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
}
@ -147,42 +148,42 @@ function Compare-IcingaPluginValueToThreshold()
};
$IcingaEnums.IcingaThresholdMethod.Lower {
if ($Value -lt $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is lower than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is lower than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.LowerEqual {
if ($Value -le $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is lower or equal than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is lower or equal than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.Greater {
if ($Value -gt $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is greater than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is greater than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.GreaterEqual {
if ($Value -gt $Threshold.Value) {
$RetValue.Message = [string]::Format('Value {0} is greater or equal than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is greater or equal than threshold {1}{2}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.Value -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.Between {
if ($Value -lt $Threshold.StartRange -Or $Value -gt $Threshold.EndRange) {
$RetValue.Message = [string]::Format('Value {0} is not between thresholds <{1} or >{2}{3}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.StartRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), (Convert-IcingaPluginValueToString -Value $Threshold.EndRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is not between thresholds <{1} or >{2}{3}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.StartRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), (Convert-IcingaPluginValueToString -Value $Threshold.EndRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;
};
$IcingaEnums.IcingaThresholdMethod.Outside {
if ($Value -ge $Threshold.StartRange -And $Value -le $Threshold.EndRange) {
$RetValue.Message = [string]::Format('Value {0} is between thresholds >={1} and <={2}{3}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.StartRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), (Convert-IcingaPluginValueToString -Value $Threshold.EndRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
$RetValue.Message = [string]::Format('Value {0} is between thresholds >={1} and <={2}{3}', $HumanReadableValue, (Convert-IcingaPluginValueToString -Value $Threshold.StartRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $CheckUnit -UsePercent:$UsePercent -IsThreshold), (Convert-IcingaPluginValueToString -Value $Threshold.EndRange -BaseValue $BaseValue -Unit $Threshold.Unit -OriginalUnit $Unit -UsePercent:$UsePercent -IsThreshold), $MoTMessage);
return $RetValue;
}
break;

View file

@ -258,9 +258,9 @@ function New-IcingaCheck()
[string]$PerfDataLabel = [string]::Format(
'{0}={1}{2};{3};{4};{5};{6}',
$PerfDataName,
$PerfDataName.ToLower(),
(Format-IcingaPerfDataValue $value),
$this.__ThresholdObject.PerfUnit,
$this.__ThresholdObject.Unit,
(Format-IcingaPerfDataValue $warning),
(Format-IcingaPerfDataValue $critical),
(Format-IcingaPerfDataValue $this.Minimum),
@ -289,7 +289,7 @@ function New-IcingaCheck()
}
}
$Global:Icinga.Private.Scheduler.PerfDataWriter.Storage.Append($PerfDataLabel.ToLower()) | Out-Null;
$Global:Icinga.Private.Scheduler.PerfDataWriter.Storage.Append($PerfDataLabel) | Out-Null;
}
$IcingaCheck | Add-Member -MemberType ScriptMethod -Name '__ValidateObject' -Value {