src/public/Pain/Add-PainPoint.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Adds or updates a pain point configuration in AitherPulse. .DESCRIPTION Creates a new pain point or updates an existing one with specified properties. This allows defining custom pain signals for specific monitoring needs. .PARAMETER PulseUrl URL of the AitherPulse server. Defaults to http://localhost:8081. .PARAMETER Id Unique identifier for the pain point. .PARAMETER Name Display name for the pain point. .PARAMETER Description Description of what this pain point detects. .PARAMETER Category Category for grouping (resource, quality, cost, etc.). .PARAMETER Weight Weight multiplier for severity (0.0 - 10.0). .PARAMETER Threshold Threshold value that triggers the pain. .PARAMETER ThresholdType Comparison type: gt, gte, lt, lte, eq, neq. .PARAMETER AutoInterrupt Whether to interrupt agents when triggered. .PARAMETER HaltOnCritical Whether to halt all operations when severity > 0.9. .PARAMETER InterruptMessage Message to display when interrupting. .PARAMETER CooldownSeconds Minimum seconds between triggers. .PARAMETER DecayRate How fast pain decays per minute. .PARAMETER Enabled Whether the pain point is enabled. .EXAMPLE Add-PainPoint -Id "custom_build_slow" -Name "Slow Build" -Description "Build taking too long" ` -Category performance -Weight 2.0 -Threshold 300 -ThresholdType gt ` -InterruptMessage "Build is taking over 5 minutes!" Adds a custom pain point for slow builds. .EXAMPLE Add-PainPoint -Id "test_failure" -Weight 5.0 Updates the weight of an existing pain point. .NOTES Author: AitherZero Domain: Pain #> function Add-PainPoint { [CmdletBinding()] param( [Parameter()] [string]$PulseUrl = $env:AITHERPULSE_URL ?? 'http://localhost:8081', [Parameter(Mandatory)] [string]$Id, [Parameter()] [string]$Name, [Parameter()] [string]$Description, [Parameter()] [ValidateSet('resource', 'quality', 'cost', 'reliability', 'security', 'performance', 'loop', 'infrastructure', 'development', 'git')] [string]$Category, [Parameter()] [ValidateRange(0.0, 10.0)] [float]$Weight, [Parameter()] [float]$Threshold, [Parameter()] [ValidateSet('gt', 'gte', 'lt', 'lte', 'eq', 'neq')] [string]$ThresholdType = 'gt', [Parameter()] [switch]$AutoInterrupt, [Parameter()] [switch]$HaltOnCritical, [Parameter()] [string]$InterruptMessage, [Parameter()] [int]$CooldownSeconds = 60, [Parameter()] [ValidateRange(0.0, 1.0)] [float]$DecayRate = 0.1, [Parameter()] [bool]$Enabled = $true ) $ErrorActionPreference = 'Stop' try { # Try to get existing pain point $existing = $null try { $existing = Invoke-RestMethod -Uri "$PulseUrl/pain-points/$Id" -Method Get -TimeoutSec 10 -ErrorAction SilentlyContinue } catch { # Pain point doesn't exist, we'll create new } # Build pain point config if ($existing) { # Update existing - only override provided parameters $painPoint = $existing if ($PSBoundParameters.ContainsKey('Name')) { $painPoint.name = $Name } if ($PSBoundParameters.ContainsKey('Description')) { $painPoint.description = $Description } if ($PSBoundParameters.ContainsKey('Category')) { $painPoint.category = $Category } if ($PSBoundParameters.ContainsKey('Weight')) { $painPoint.weight = $Weight } if ($PSBoundParameters.ContainsKey('Threshold')) { $painPoint.threshold = $Threshold } if ($PSBoundParameters.ContainsKey('ThresholdType')) { $painPoint.threshold_type = $ThresholdType } if ($PSBoundParameters.ContainsKey('AutoInterrupt')) { $painPoint.auto_interrupt = $AutoInterrupt.IsPresent } if ($PSBoundParameters.ContainsKey('HaltOnCritical')) { $painPoint.halt_on_critical = $HaltOnCritical.IsPresent } if ($PSBoundParameters.ContainsKey('InterruptMessage')) { $painPoint.interrupt_message = $InterruptMessage } if ($PSBoundParameters.ContainsKey('CooldownSeconds')) { $painPoint.cooldown_seconds = $CooldownSeconds } if ($PSBoundParameters.ContainsKey('DecayRate')) { $painPoint.decay_rate = $DecayRate } if ($PSBoundParameters.ContainsKey('Enabled')) { $painPoint.enabled = $Enabled } Write-AitherLog -Level Information -Message "Updating existing pain point '$Id'..." -Source 'Add-PainPoint' } else { # Create new - validate required parameters if (-not $Name) { throw "Name is required for new pain points" } if (-not $Description) { throw "Description is required for new pain points" } if (-not $Category) { throw "Category is required for new pain points" } if ($null -eq $Threshold) { throw "Threshold is required for new pain points" } $painPoint = @{ id = $Id name = $Name description = $Description category = $Category weight = if ($PSBoundParameters.ContainsKey('Weight')) { $Weight } else { 1.0 } threshold = $Threshold threshold_type = $ThresholdType auto_interrupt = $AutoInterrupt.IsPresent halt_on_critical = $HaltOnCritical.IsPresent interrupt_message = if ($InterruptMessage) { $InterruptMessage } else { "" } cooldown_seconds = $CooldownSeconds decay_rate = $DecayRate enabled = $Enabled } Write-AitherLog -Level Information -Message "Creating new pain point '$Id'..." -Source 'Add-PainPoint' } # Send to API $response = Invoke-RestMethod -Uri "$PulseUrl/pain-points" -Method Post ` -Body ($painPoint | ConvertTo-Json -Depth 10) ` -ContentType "application/json" -TimeoutSec 10 if ($response.created) { Write-AitherLog -Level Information -Message "✓ Pain point '$Id' saved successfully" -Source 'Add-PainPoint' # Show the saved config $saved = Invoke-RestMethod -Uri "$PulseUrl/pain-points/$Id" -Method Get -TimeoutSec 10 Write-AitherLog -Level Information -Message " Name: $($saved.name)" -Source 'Add-PainPoint' Write-AitherLog -Level Information -Message " Category: $($saved.category)" -Source 'Add-PainPoint' Write-AitherLog -Level Information -Message " Weight: $($saved.weight)" -Source 'Add-PainPoint' Write-AitherLog -Level Information -Message " Threshold: $($saved.threshold) ($($saved.threshold_type))" -Source 'Add-PainPoint' Write-AitherLog -Level Information -Message " Auto-Interrupt: $($saved.auto_interrupt)" -Source 'Add-PainPoint' Write-AitherLog -Level Information -Message " Enabled: $($saved.enabled)" -Source 'Add-PainPoint' } return $response } catch { if ($_.Exception.Message -like "*Unable to connect*") { Write-AitherLog -Level Warning -Message "AitherPulse is not running at $PulseUrl" -Source 'Add-PainPoint' } else { throw $_ } } } |