Public/cloud-hook.ps1
|
function Get-CloudHook { <# .SYNOPSIS Gets hooks from the Cloud Server. .DESCRIPTION Retrieves a list of hooks. Automatically handles token refresh. .PARAMETER Name Optional. Filter by hook name. .PARAMETER ID Optional. Filter by hook ID .EXAMPLE # Get all hooks Get-CloudHook .EXAMPLE # Get a hook by ID Get-CloudHook -ID 5 .EXAMPLE # Get a hook by name Get-CloudHook -Name "vm-creation" #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$Name, [Parameter(Mandatory = $false)] [int]$ID ) $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook" if ($PSBoundParameters.ContainsKey('ID')) { $hookuri = "$uri/${ID}" $response = Invoke-CloudApiRequest -Uri $hookuri -Method Get $hook = $response.hook return $hook } else { $response = Invoke-CloudApiRequest -Uri $uri -Method Get $hooks = $response.hook if ($Name) { $hooks = $hooks | Where-Object { $_.name -like "*$Name*" } } return $hooks } } function Get-CloudHookLogs { <# .SYNOPSIS Gets hook logs from the Cloud Server. .DESCRIPTION Retrieves hook logs for a specific hook. Automatically handles token refresh. .PARAMETER HookID Hook ID to retrieve logs for .PARAMETER MinDate Minimum date filter (as DateTime object or string) .PARAMETER MaxDate Maximum date filter (as DateTime object or string) .EXAMPLE # Get logs for a hook with a date range Get-CloudHookLog -HookID 5 -MinDate "2025-01-01" -MaxDate "2025-01-31" .EXAMPLE # Get logs for a hook for the past 7 days Get-CloudHookLog -HookID 5 -MinDate (Get-Date).AddDays(-7) -MaxDate (Get-Date) .EXAMPLE # Get logs for a hook for the past 24 hours Get-CloudHookLog -HookID 14 -MinDate (Get-Date).AddDays(-1) -MaxDate (Get-Date) #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [int]$HookID, [Parameter(Mandatory = $true)] [DateTime]$MinDate, [Parameter(Mandatory = $true)] [DateTime]$MaxDate ) # Convert dates to YYYY-MM-DD format (Go's date format) $minDateStr = $MinDate.ToString("yyyy-MM-dd") $maxDateStr = $MaxDate.ToString("yyyy-MM-dd") # Build the URI with query parameters $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook/$HookID/log" $uri += "?min=$minDateStr&max=$maxDateStr" write-host $uri Write-Verbose "Request URI: $uri" Write-Verbose "Min Date: $MinDate -> $minDateStr" Write-Verbose "Max Date: $MaxDate -> $maxDateStr" # Use the helper function which handles token refresh automatically $response = Invoke-CloudApiRequest -Uri $uri -Method Get return $response } #function New-CloudHook { # <# # .SYNOPSIS # Creates a new hook in the Cloud Server. # # .DESCRIPTION # Creates a hook that triggers on specific events. Automatically handles token refresh. # # .PARAMETER Name # Name of the hook # # .PARAMETER Type # Hook type (e.g., 'api' for API hooks, 'state' for state hooks) # # .PARAMETER Command # Command to execute when hook triggers # # .PARAMETER Template # Full hook template as a string # # .EXAMPLE # # Create a simple logging hook that triggers on VM creation - writes "OpenNebula hook test - VM operation" to the system log (syslog) # $template = @" # NAME="simple-test-hook" # TYPE="api" # COMMAND="/usr/bin/logger" # ARGUMENTS="OpenNebula hook test - VM operation" # CALL="one.vm.allocate" # "@ # New-CloudHook -Template $template # #> # # [CmdletBinding()] # param( # [Parameter(Mandatory = $true)] # [string]$Template # ) # # $hookData = @{ # template = $Template # } # # $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook" # # Write-Verbose "Request URI: $uri" # Write-Verbose "Hook Template:`n$Template" # # $response = Invoke-CloudApiRequest -Uri $uri -Method Post -Body $hookData # # return $response #} # function Remove-CloudHook { <# .SYNOPSIS Removes a hook from the Cloud Server. .DESCRIPTION Removes a hook. Automatically handles token refresh. .PARAMETER Name Required. Hook ID. .EXAMPLE # Remove hook with confirmation prompt (default behavior): Remove-CloudHook -ID 3 Confirm Are you sure you want to perform this action? Performing the operation "Remove Hook" on target "Hook ID 3 (MyHook)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y .EXAMPLE # Remove hook without confirmation prompt: Remove-CloudHook -ID 3 -Confirm:$false #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID ) process { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook/${ID}" Invoke-CloudResourceRemoval ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Hook" ` -ID $ID ` -Uri $uri ` -GetResourceScript { Get-CloudHook -ID $ID } } } function Rename-CloudHook { <# .SYNOPSIS Rename a hook in the Cloud Server. .DESCRIPTION Renames a hook. Automatically handles token refresh. .PARAMETER Name New name of the hook .PARAMETER ID ID of the hook .EXAMPLE # Rename a hook Rename-CloudHook -Name "new-name" -ID 5 #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [int]$ID ) $newname = @{ name = $Name } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook/${ID}/name" $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $newname return $response } function Lock-CloudHook { <# .SYNOPSIS Lock a hook in the Cloud Server. .DESCRIPTION Lock a hook. Automatically handles token refresh. .PARAMETER ID ID of the hook .PARAMETER Level Lock level (USE, MANAGE, ADMIN, ALL) .PARAMETER Test When set, performs a test lock instead of a real one. .EXAMPLE # Lock a hook to restrict administrative operations Lock-CloudHook -ID 5 -Level ADMIN .EXAMPLE # Test locking a hook Lock-CloudHook -ID 5 -Level USE -Test #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [int]$ID, [Parameter(Mandatory = $true)] [ValidateSet('USE','MANAGE','ADMIN','ALL')] [string]$Level, [switch]$Test ) $lockdata = @{ level = $Level test = [bool]$Test } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook/${ID}/lock" $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $lockdata return $response } function Unlock-CloudHook { <# .SYNOPSIS Unlock a hook in the Cloud Server. .DESCRIPTION Unlock a hook. Automatically handles token refresh. .PARAMETER ID ID of the hook .EXAMPLE # Unlock a hook Unlock-CloudHook -ID 5 #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [int]$ID ) $unlockdata = @{ lock = 0 } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook/${ID}/unlock" $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $unlockdata return $response } function New-CloudHook { <# .SYNOPSIS Creates a new hook in the Cloud Server. .DESCRIPTION Creates a hook that triggers on specific OpenNebula events. Hooks can execute commands, scripts, or send notifications when specific API calls are made or resource states change. Automatically handles token refresh. .PARAMETER Template Required. Hook template in OpenNebula format. Must include NAME, TYPE, COMMAND, and trigger conditions. Common template attributes: - NAME: Hook identifier - TYPE: Hook type ('api' or 'state') - COMMAND: Command/script to execute - ARGUMENTS: Arguments passed to the command ($TEMPLATE for full XML, $ID for resource ID) - CALL: API method that triggers the hook (for TYPE=api) - ON: State change that triggers the hook (for TYPE=state) - RESOURCE: Resource type (VM, HOST, VNET, IMAGE, etc.) .EXAMPLE # Create an API Hook: Log when VMs are created $template = @" NAME="vm-creation-logger" TYPE="api" COMMAND="/usr/bin/logger" ARGUMENTS="VM Created - ID: `$ID" CALL="one.vm.allocate" "@ New-CloudHook -Template $template .EXAMPLE # Create a n API Hook: Send email notification when VM is deleted $template = @" NAME="vm-deletion-alert" TYPE="api" COMMAND="/usr/local/bin/send-alert.sh" ARGUMENTS="`$TEMPLATE" CALL="one.vm.delete" "@ New-CloudHook -Template $template .EXAMPLE # Create a State Hook: Execute script when VM goes to RUNNING state $template = @" NAME="vm-running-webhook" TYPE="state" COMMAND="/usr/local/bin/vm-started.sh" ARGUMENTS="`$ID `$TEMPLATE" ON="RUNNING" RESOURCE="VM" "@ New-CloudHook -Template $template .EXAMPLE # Create a State Hook: Trigger on VM failure states $template = @" NAME="vm-failure-alert" TYPE="state" COMMAND="/usr/local/bin/alert-admin.sh" ARGUMENTS="VM `$ID failed - `$PREV_STATE to `$CUR_STATE" ON="FAILED" RESOURCE="VM" "@ New-CloudHook -Template $template .EXAMPLE # Create an API Hook: Monitor host operations $template = @" NAME="host-monitor" TYPE="api" COMMAND="/var/lib/one/hooks/host-change.py" ARGUMENTS="`$ID `$TEMPLATE" CALL="one.host.update" "@ New-CloudHook -Template $template .EXAMPLE # Create a State Hook: Network monitoring $template = @" NAME="network-state-monitor" TYPE="state" COMMAND="/usr/local/bin/network-alert.sh" ARGUMENTS="`$ID" ON="ERROR" RESOURCE="VNET" REMOTE="no" "@ New-CloudHook -Template $template .EXAMPLE # Create an API Hook: Image creation tracking with multiple arguments $template = @" NAME="image-creation-tracker" TYPE="api" COMMAND="/opt/monitoring/track-image.py" ARGUMENTS="--image-id `$ID --timestamp `$(date +%s) --user `$UNAME" CALL="one.image.allocate" "@ New-CloudHook -Template $template #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Low')] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string]$Template ) process { $hookData = @{ template = $Template } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook" if ($PSCmdlet.ShouldProcess("Hook", "Create new hook")) { Write-Verbose "Request URI: $uri" Write-Verbose "Hook Template:`n$Template" try { $response = Invoke-CloudApiRequest -Uri $uri -Method Post -Body $hookData Write-Verbose "Successfully created hook: $($response.hook.name)" return $response.hook } catch { Write-Error "Failed to create hook: $_" throw } } } } #function Update-CloudHook1 { # <# # .SYNOPSIS # Updates a hook in the Cloud Server. # # .PARAMETER Template # Required. Hook template in OpenNebula format. Must include NAME, TYPE, COMMAND, and trigger conditions. # # .PARAMETER Merge # Optional. Boolean. Whether or not to merge the config, defaults to true. -Merge:$true or -Merge:$false # # .PARAMETER ID # Required. Hook ID # # Common template attributes: # - NAME: Hook identifier # - TYPE: Hook type ('api' or 'state') # - COMMAND: Command/script to execute # - ARGUMENTS: Arguments passed to the command ($TEMPLATE for full XML, $ID for resource ID) # - CALL: API method that triggers the hook (for TYPE=api) # - ON: State change that triggers the hook (for TYPE=state) # - RESOURCE: Resource type (VM, HOST, VNET, IMAGE, etc.) # # .EXAMPLE # # API Hook: Log when VMs are created # $template = @" #NAME="vm-creation-logger" #TYPE="api" #COMMAND="/usr/bin/logger" #ARGUMENTS="VM Created - ID: `$ID" #CALL="one.vm.allocate" #"@ # Update-CloudHook -ID 5 -Template $template # # .EXAMPLE # # API Hook: Send email notification when VM is deleted # $template = @" #NAME="vm-deletion-alert" #TYPE="api" #COMMAND="/usr/local/bin/send-alert.sh" #ARGUMENTS="`$TEMPLATE" #CALL="one.vm.delete" #"@ # Update-CloudHook -ID 5 -Template $template # # .EXAMPLE # # State Hook: Execute script when VM goes to RUNNING state # $template = @" #NAME="vm-running-webhook" #TYPE="state" #COMMAND="/usr/local/bin/vm-started.sh" #ARGUMENTS="`$ID `$TEMPLATE" #ON="RUNNING" #RESOURCE="VM" #"@ # Update-CloudHook -ID 5 -Template $template # # .EXAMPLE # # State Hook: Trigger on VM failure states # $template = @" #NAME="vm-failure-alert" #TYPE="state" #COMMAND="/usr/local/bin/alert-admin.sh" #ARGUMENTS="VM `$ID failed - `$PREV_STATE to `$CUR_STATE" #ON="FAILED" #RESOURCE="VM" #"@ # Update-CloudHook -ID 5 -Template $template # # .EXAMPLE # # API Hook: Monitor host operations # $template = @" #NAME="host-monitor" #TYPE="api" #COMMAND="/var/lib/one/hooks/host-change.py" #ARGUMENTS="`$ID `$TEMPLATE" #CALL="one.host.update" #"@ # Update-CloudHook -ID 5 -Template $template # # .EXAMPLE # # State Hook: Network monitoring # $template = @" #NAME="network-state-monitor" #TYPE="state" #COMMAND="/usr/local/bin/network-alert.sh" #ARGUMENTS="`$ID" #ON="ERROR" #RESOURCE="VNET" #REMOTE="no" #"@ # Update-CloudHook -ID 5 -Template $template # # .EXAMPLE # # API Hook: Image creation tracking with multiple arguments and will not merge the config # $template = @" #NAME="image-creation-tracker" #TYPE="api" #COMMAND="/opt/monitoring/track-image.py" #ARGUMENTS="--image-id `$ID --timestamp `$(date +%s) --user `$UNAME" #CALL="one.image.allocate" #"@ # Update-CloudHook -ID 5 -Template $template -Merge:$false # #> # #[CmdletBinding(SupportsShouldProcess, ConfirmImpact='Low')] #param( # [Parameter(Mandatory = $true)] # [int]$ID, # # [Parameter(Mandatory = $true, ValueFromPipeline = $true)] # [string]$Template, # # [Parameter()] # [bool]$Merge = $true #) # #process { # $hookData = @{ # merge = $Merge # template = $Template # } # # $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook/${ID}" # Write-Host "DEBUG - Body being sent:" #$hookData | ConvertTo-Json -Depth 5 | Write-Host # # if ($PSCmdlet.ShouldProcess("Hook ID $ID", "Update hook")) { # Write-Verbose "Request URI: $uri" # Write-Verbose "Hook Template:`n$Template" # Write-Verbose "Merge: $Merge" # # try { # $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $hookData # # Write-Verbose "Successfully updated hook $ID" # return $response.hook # } # catch { # Write-Error "Failed to update hook: $_" # throw # } # } #} #} # function Update-CloudHook { <# .SYNOPSIS Updates a hook in the Cloud Server. .PARAMETER ID Required. Hook ID to update .PARAMETER Template Required. Hook template in OpenNebula format. .PARAMETER Merge Optional. If specified, merges with existing template. If not specified, replaces the template entirely. .EXAMPLE # Update a hook replacing the entire hook configuration (default behavior) $template = @" NAME="new-hook-name" TYPE="api" COMMAND="/usr/bin/logger" ARGUMENTS="Test" CALL="one.vm.allocate" "@ Update-CloudHook -ID 17 -Template $template .EXAMPLE # Update a book merging the new configuration with the existing configuration $template = 'ARGUMENTS="New arguments"' Update-CloudHook -ID 17 -Template $template -Merge #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Low')] param( [Parameter(Mandatory = $true)] [int]$ID, [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string]$Template, [Parameter()] [switch]$Merge ) process { # Build the request body $hookData = @{ template = $Template } if ($Merge) { $hookData['merge'] = $true } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook/${ID}" if ($PSCmdlet.ShouldProcess("Hook ID $ID", "Update hook")) { Write-Verbose "Request URI: $uri" Write-Verbose "Hook Template:`n$Template" Write-Verbose "Merge: $Merge" try { $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $hookData Write-Verbose "Successfully updated hook $ID" return $response.hook } catch { Write-Error "Failed to update hook: $_" throw } } } } function Redo-CloudHook { <# .SYNOPSIS Attempt to retry a hook in the Cloud Server. .DESCRIPTION Retries a hook. Automatically handles token refresh. .PARAMETER ID Required. ID of the hook .PARAMETER Time Required. Time in seconds to wait before retrying the hook .EXAMPLE # Retries hook 5 in 10 seconds Redo-CloudHook -ID 5 -Time 10 #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [int]$Time, [Parameter(Mandatory = $true)] [int]$ID ) $hooktime = @{ execution = $Time } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/hook/${ID}/retry" $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $hooktime return $response } |