From 9de78c622293b9d00e9c18c19da2a013a7d55f95 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 9 Sep 2021 18:53:48 +0200 Subject: [PATCH] Improves error handling on IMC for Diretor --- doc/100-General/10-Changelog.md | 1 + .../Get-IcingaDirectorSelfServiceConfig.psm1 | 25 +++++++++++++-- .../Get-IcingaDirectorSelfServiceTicket.psm1 | 25 +++++++++++++-- ...egister-IcingaDirectorSelfServiceHost.psm1 | 25 +++++++++++++-- .../misc/Start-IcingaAgentDirectorWizard.psm1 | 12 ++++++- lib/core/installer/Install-Icinga.psm1 | 3 ++ .../Start-IcingaForWindowsInstallation.psm1 | 8 ++++- .../director/DirectorTemplate.psm1 | 20 ++++++++++-- .../installer/tools/ShowInstallerMenu.psm1 | 2 +- .../logging/Write-IcingaConsoleDebug.psm1 | 6 ++-- .../logging/Write-IcingaConsoleError.psm1 | 6 ++-- .../logging/Write-IcingaConsoleNotice.psm1 | 6 ++-- .../logging/Write-IcingaConsoleOutput.psm1 | 16 ++++++++-- .../logging/Write-IcingaConsolePlain.psm1 | 6 ++-- .../logging/Write-IcingaConsoleWarning.psm1 | 6 ++-- lib/web/Invoke-IcingaWebRequest.psm1 | 32 +++++++++++++++---- 16 files changed, 168 insertions(+), 31 deletions(-) diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index a08906c..5f28e97 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -17,6 +17,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#362](https://github.com/Icinga/icinga-powershell-framework/issues/362) Fixes repository component installation from file share locations * [#363](https://github.com/Icinga/icinga-powershell-framework/issues/363) Fixes unneeded continue for JEA process lookup, in case no JEA pid is present * [#365](https://github.com/Icinga/icinga-powershell-framework/issues/365) Fixes Icinga environment corruption on Icinga Agent installation failure +* [#366](https://github.com/Icinga/icinga-powershell-framework/issues/366) Fixes error handling with Icinga Director over IMC, by printing more detailed and user-friendly error messages ### Enhancements diff --git a/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 b/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 index e844645..ac59a9e 100644 --- a/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 +++ b/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 @@ -42,10 +42,31 @@ function Get-IcingaDirectorSelfServiceConfig() $EndpointUrl = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/powershell-parameters?key={0}', $ApiKey)); - $response = Invoke-IcingaWebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; + $response = Invoke-IcingaWebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST' -NoErrorMessage; if ($response.StatusCode -ne 200) { - throw $response.Content; + $ErrorMessage = ''; + switch ($response.StatusCode) { + 403 { + $ErrorMessage = 'Failed to fetch configuration for host over Self-Service API with key "{0}". This error mostly occurs in case the host object itself is not defined as "Icinga2 Agent" object inside the Icinga Director.'; + break; + }; + 404 { + $ErrorMessage = 'Failed to fetch configuration for host over Self-Service API with key "{0}". Probably the assigned host/template key is not valid or your Icinga Director Url is invalid "{1}".'; + break; + }; + 901 { + $ErrorMessage = 'Failed to fetch host/template configuration from Icinga Director Self-Service API because of SSL/TLS error. Please ensure the certificate is valid and use "Enable-IcingaUntrustedCertificateValidation" for self-signed certificates or install the certificate on this machine.'; + break; + } + Default { + $ErrorMessage = ([string]::Format('Failed to fetch host/template configuration from Icinga Director Self-Service API because of unhandled exception: {0}', $response.StatusCode)); + break; + }; + } + + Write-IcingaConsoleError $ErrorMessage -Objects $ApiKey, $DirectorUrl; + throw $ErrorMessage; } $JsonContent = ConvertFrom-Json -InputObject $response.Content; diff --git a/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 b/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 index 3a96905..8561ea1 100644 --- a/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 +++ b/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 @@ -42,10 +42,31 @@ function Get-IcingaDirectorSelfServiceTicket() [string]$url = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/ticket?key={0}', $ApiKey)); - $response = Invoke-IcingaWebRequest -Uri $url -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; + $response = Invoke-IcingaWebRequest -Uri $url -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST' -NoErrorMessage; if ($response.StatusCode -ne 200) { - throw $response.Content; + $ErrorMessage = ''; + switch ($response.StatusCode) { + 404 { + $ErrorMessage = 'Failed to fetch certificate ticket for this host over Self-Service API. Please check that your Icinga Director Url "{1}" is valid and the provided API key "{0}" belongs to a Icinga host object.'; + break; + }; + 500 { + $ErrorMessage = 'Failed to fetch certificate ticket for this host over Self-Service API. Please check that your Icinga CA is running, you have configured a Ticketsalt and that your Icinga Director has enough permissions to communicate with the Icinga 2 API for generating tickets.'; + break; + }; + 901 { + $ErrorMessage = 'Failed to fetch certificate ticket for this host over Self-Service API because of SSL/TLS error. Please ensure the certificate is valid and use "Enable-IcingaUntrustedCertificateValidation" for self-signed certificates or install the certificate on this machine.'; + break; + } + Default { + $ErrorMessage = ([string]::Format('Failed to fetch certificate ticket from Icinga Director because of unhandled exception: {0}', $response.StatusCode)); + break; + }; + } + + Write-IcingaConsoleError $ErrorMessage -Objects $ApiKey, $DirectorUrl; + throw $ErrorMessage; } $JsonContent = ConvertFrom-Json -InputObject $response.Content; diff --git a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 index a59bbb9..0814af4 100644 --- a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 +++ b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 @@ -66,10 +66,31 @@ function Register-IcingaDirectorSelfServiceHost() $EndpointUrl = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/register-host?name={0}&key={1}', $Hostname, $ApiKey)); - $response = Invoke-IcingaWebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST' -Body $DirectorConfigJson; + $response = Invoke-IcingaWebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST' -Body $DirectorConfigJson -NoErrorMessage; if ($response.StatusCode -ne 200) { - throw $response.Content; + $ErrorMessage = ''; + switch ($response.StatusCode) { + 400 { + Write-IcingaConsoleWarning 'Failed to register host inside Icinga Director. The host is probably already registered.' + return $null; + }; + 404 { + $ErrorMessage = 'Failed to register host with the given API key "{0}" inside Icinga Director. Please ensure the template key you are using is correct and the template is set as "Icinga2 Agent" object. Non-Agent templates will not work over the Self-Service API.'; + break; + }; + 901 { + $ErrorMessage = 'Failed to register host over Self-Service API inside Icinga Director because of SSL/TLS error. Please ensure the certificate is valid and use "Enable-IcingaUntrustedCertificateValidation" for self-signed certificates or install the certificate on this machine.'; + break; + } + Default { + $ErrorMessage = ([string]::Format('Failed to register host inside Icinga Director because of unhandled exception: {0}', $response.StatusCode)); + break; + }; + } + + Write-IcingaConsoleError $ErrorMessage -Objects $ApiKey; + throw $ErrorMessage; } $JsonContent = ConvertFrom-Json -InputObject $response.Content; diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 index 2ec1ddf..abf9713 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 @@ -91,10 +91,20 @@ function Start-IcingaAgentDirectorWizard() if ($HostKnown -eq $FALSE) { while ($TRUE) { + [bool]$RegisterFailed = $FALSE; try { $SelfServiceAPIKey = Register-IcingaDirectorSelfServiceHost -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey -Hostname (Get-IcingaHostname @Arguments) -Endpoint $Arguments.IcingaMaster; - break; + + if ([string]::IsNullOrEmpty($SelfServiceAPIKey) -eq $FALSE) { + break; + } else { + $RegisterFailed = $TRUE; + } } catch { + $RegisterFailed = $TRUE; + } + + if ($RegisterFailed) { $SelfServiceAPIKey = (Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Failed to register host within Icinga Director. Full error: "{0}". Please re-enter your SelfService API Key. If this prompt continues ensure you are using an Agent template or drop your host key at "Hosts -> {1} -> Agent"', $_.Exception.Message, (Get-IcingaHostname @Arguments))) -Default 'v' -DefaultInput $SelfServiceAPIKey).answer; } } diff --git a/lib/core/installer/Install-Icinga.psm1 b/lib/core/installer/Install-Icinga.psm1 index 203f34c..672e750 100644 --- a/lib/core/installer/Install-Icinga.psm1 +++ b/lib/core/installer/Install-Icinga.psm1 @@ -16,9 +16,11 @@ function Install-Icinga() 'LastInput' = ''; 'LastNotice' = ''; 'LastError' = ''; + 'DirectorError' = ''; 'HeaderPreview' = ''; 'DirectorSelfService' = $FALSE; 'DirectorRegisteredHost' = $FALSE; + 'DirectorInstallError' = $FALSE; 'LastParent' = [System.Collections.ArrayList]@(); 'LastValues' = @(); 'DisabledEntries' = @{ }; @@ -61,6 +63,7 @@ function Install-Icinga() # In case we use the director, we require to first fetch all basic values from the Self-Service API then # require to register the host to fet the remaining content if ($IcingaConfiguration.ContainsKey('IfW-DirectorSelfServiceKey') -And $IcingaConfiguration.ContainsKey('IfW-DirectorUrl')) { + Enable-IcingaFrameworkConsoleOutput; Resolve-IcingaForWindowsManagementConsoleInstallationDirectorTemplate; Resolve-IcingaForWindowsManagementConsoleInstallationDirectorTemplate -Register; Disable-IcingaFrameworkConsoleOutput; diff --git a/lib/core/installer/Start-IcingaForWindowsInstallation.psm1 b/lib/core/installer/Start-IcingaForWindowsInstallation.psm1 index 87c53a2..90a715d 100644 --- a/lib/core/installer/Start-IcingaForWindowsInstallation.psm1 +++ b/lib/core/installer/Start-IcingaForWindowsInstallation.psm1 @@ -4,12 +4,18 @@ function Start-IcingaForWindowsInstallation() [switch]$Automated ); - if ((Get-IcingaFrameworkDebugMode) -eq $FALSE) { + if ($global:Icinga.InstallWizard.DirectorInstallError -eq $FALSE -And (Get-IcingaFrameworkDebugMode) -eq $FALSE) { Clear-Host; } Write-IcingaConsoleNotice 'Starting Icinga for Windows installation'; + if ($global:Icinga.InstallWizard.DirectorInstallError) { + Write-IcingaConsoleError 'Failed to start Icinga for Windows installation, caused by an error while communicating with Icinga Director: {0}' -Objects $global:Icinga.InstallWizard.DirectorError; + throw $global:Icinga.InstallWizard.DirectorError; + return; + } + $ConnectionType = Get-IcingaForWindowsInstallerStepSelection -InstallerStep 'Show-IcingaForWindowsInstallerMenuSelectConnection'; $HostnameType = Get-IcingaForWindowsInstallerStepSelection -InstallerStep 'Show-IcingaForWindowsInstallerMenuSelectHostname'; $FirewallType = Get-IcingaForWindowsInstallerStepSelection -InstallerStep 'Show-IcingaForWindowsInstallerMenuSelectOpenWindowsFirewall'; diff --git a/lib/core/installer/menu/installation/director/DirectorTemplate.psm1 b/lib/core/installer/menu/installation/director/DirectorTemplate.psm1 index 7c0779d..68850e1 100644 --- a/lib/core/installer/menu/installation/director/DirectorTemplate.psm1 +++ b/lib/core/installer/menu/installation/director/DirectorTemplate.psm1 @@ -46,10 +46,20 @@ function Resolve-IcingaForWindowsManagementConsoleInstallationDirectorTemplate() }; } + [bool]$RegisterFailed = $FALSE; + try { $SelfServiceKey = Register-IcingaDirectorSelfServiceHost -DirectorUrl $DirectorUrl -ApiKey $SelfServiceKey -Hostname $Hostname; - $UsedEnteredKey = $SelfServiceKey; + if ([string]::IsNullOrEmpty($SelfServiceKey) -eq $FALSE) { + $UsedEnteredKey = $SelfServiceKey; + } else { + $RegisterFailed = $TRUE; + } } catch { + $RegisterFailed = $TRUE; + } + + if ($RegisterFailed) { Write-IcingaConsoleNotice 'Host seems already to be registered within Icinga Director. Trying local Api key if present' $SelfServiceKey = Get-IcingaPowerShellConfig -Path 'IcingaDirector.SelfService.ApiKey'; @@ -57,6 +67,7 @@ function Resolve-IcingaForWindowsManagementConsoleInstallationDirectorTemplate() Write-IcingaConsoleNotice 'No local Api key was found and using your provided template key failed. Please ensure the host is not already registered and drop the set Self-Service key within the Icinga Director for this host.' } } + Add-IcingaForWindowsInstallerConfigEntry -Selection 'c' -Values $UsedEnteredKey -OverwriteValues -OverwriteMenu 'Show-IcingaForWindowsManagementConsoleInstallationEnterDirectorSelfServiceKey'; } @@ -64,10 +75,15 @@ function Resolve-IcingaForWindowsManagementConsoleInstallationDirectorTemplate() $DirectorConfig = Get-IcingaDirectorSelfServiceConfig -DirectorUrl $DirectorUrl -ApiKey $SelfServiceKey; } catch { Set-IcingaForWindowsManagementConsoleMenu 'Show-IcingaForWindowsInstallerConfigurationSummary'; - $global:Icinga.InstallWizard.LastError = 'Failed to fetch host configuration with the given Director Url and Self-Service key. Please ensure the template key is correct and in case a previous host key was used, that it matches the one configured within the Icinga Director. In case this form was loaded previously with a key, it might be that the host key is no longer valid and requires to be dropped. In addition please ensure that this host can connect to the Icinga Director and the SSL certificate is trusted. Otherwise run "Enable-IcingaUntrustedCertificateValidation" before starting the management console. Otherwise modify the "DirectorSelfServiceKey" configuration element above with the correct key and try again.'; + $global:Icinga.InstallWizard.LastError = 'Failed to fetch host configuration with the given Director Url and Self-Service key. Please ensure the template key is correct and in case a previous host key was used, that it matches the one configured within the Icinga Director. In case this form was loaded previously with a key, it might be that the host key is no longer valid and requires to be dropped. In addition please ensure that this host can connect to the Icinga Director and the SSL certificate is trusted. Otherwise run "Enable-IcingaUntrustedCertificateValidation" before starting the management console. Otherwise modify the "DirectorSelfServiceKey" configuration element above with the correct key and try again.'; + $global:Icinga.InstallWizard.DirectorError = $global:Icinga.InstallWizard.LastError; + $global:Icinga.InstallWizard.DirectorInstallError = $TRUE; return; } + $global:Icinga.InstallWizard.DirectorInstallError = $FALSE; + $global:Icinga.InstallWizard.DirectorError = ''; + # No we need to identify which host selection is matching our config $HostnameSelection = 1; $InstallPluginsSelection = 0; diff --git a/lib/core/installer/tools/ShowInstallerMenu.psm1 b/lib/core/installer/tools/ShowInstallerMenu.psm1 index 28187ed..ba18c57 100644 --- a/lib/core/installer/tools/ShowInstallerMenu.psm1 +++ b/lib/core/installer/tools/ShowInstallerMenu.psm1 @@ -22,7 +22,7 @@ function Show-IcingaForWindowsInstallerMenu() [switch]$NoConfigSwap = $FALSE ); - if ((Test-IcingaForWindowsInstallationHeaderPrint) -eq $FALSE -And (Get-IcingaFrameworkDebugMode) -eq $FALSE) { + if ($global:Icinga.InstallWizard.DirectorInstallError -eq $FALSE -And (Test-IcingaForWindowsInstallationHeaderPrint) -eq $FALSE -And (Get-IcingaFrameworkDebugMode) -eq $FALSE) { Clear-Host; } diff --git a/lib/core/logging/Write-IcingaConsoleDebug.psm1 b/lib/core/logging/Write-IcingaConsoleDebug.psm1 index 2656379..b0f5fdc 100644 --- a/lib/core/logging/Write-IcingaConsoleDebug.psm1 +++ b/lib/core/logging/Write-IcingaConsoleDebug.psm1 @@ -23,7 +23,8 @@ function Write-IcingaConsoleDebug() { param ( [string]$Message, - [array]$Objects + [array]$Objects, + [switch]$DropMessage = $FALSE ); if ((Get-IcingaFrameworkDebugMode) -eq $FALSE) { @@ -34,5 +35,6 @@ function Write-IcingaConsoleDebug() -Message $Message ` -Objects $Objects ` -ForeColor 'Blue' ` - -Severity 'Debug'; + -Severity 'Debug' ` + -DropMessage:$DropMessage; } diff --git a/lib/core/logging/Write-IcingaConsoleError.psm1 b/lib/core/logging/Write-IcingaConsoleError.psm1 index 895a6b1..91c77fb 100644 --- a/lib/core/logging/Write-IcingaConsoleError.psm1 +++ b/lib/core/logging/Write-IcingaConsoleError.psm1 @@ -23,12 +23,14 @@ function Write-IcingaConsoleError() { param ( [string]$Message, - [array]$Objects + [array]$Objects, + [switch]$DropMessage = $FALSE ); Write-IcingaConsoleOutput ` -Message $Message ` -Objects $Objects ` -ForeColor 'Red' ` - -Severity 'Error'; + -Severity 'Error' ` + -DropMessage:$DropMessage; } diff --git a/lib/core/logging/Write-IcingaConsoleNotice.psm1 b/lib/core/logging/Write-IcingaConsoleNotice.psm1 index 44939fa..7aec872 100644 --- a/lib/core/logging/Write-IcingaConsoleNotice.psm1 +++ b/lib/core/logging/Write-IcingaConsoleNotice.psm1 @@ -23,12 +23,14 @@ function Write-IcingaConsoleNotice() { param ( [string]$Message, - [array]$Objects + [array]$Objects, + [switch]$DropMessage = $FALSE ); Write-IcingaConsoleOutput ` -Message $Message ` -Objects $Objects ` -ForeColor 'Green' ` - -Severity 'Notice'; + -Severity 'Notice' ` + -DropMessage:$DropMessage; } diff --git a/lib/core/logging/Write-IcingaConsoleOutput.psm1 b/lib/core/logging/Write-IcingaConsoleOutput.psm1 index c21430c..d9988f7 100644 --- a/lib/core/logging/Write-IcingaConsoleOutput.psm1 +++ b/lib/core/logging/Write-IcingaConsoleOutput.psm1 @@ -20,6 +20,11 @@ The color the severity name will be displayed in .PARAMETER Severity The severity being displayed before the actual message. Leave empty to skip. +.PARAMETER NoNewLine + Will ensure that no new line is added at the end of the message, allowing to + write different messages with different function calls without line breaks +.PARAMETER DropMessage + Will not write the message to the console and simply drop it .INPUTS System.String .LINK @@ -32,11 +37,16 @@ function Write-IcingaConsoleOutput() [string]$Message, [array]$Objects, [ValidateSet('Default', 'Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')] - [string]$ForeColor = 'Default', - [string]$Severity = 'Notice', - [switch]$NoNewLine = $FALSE + [string]$ForeColor = 'Default', + [string]$Severity = 'Notice', + [switch]$NoNewLine = $FALSE, + [switch]$DropMessage = $FALSE ); + if ($DropMessage) { + return; + } + if ((Test-IcingaFrameworkConsoleOutput) -eq $FALSE) { return; } diff --git a/lib/core/logging/Write-IcingaConsolePlain.psm1 b/lib/core/logging/Write-IcingaConsolePlain.psm1 index 1cb29b4..331cd77 100644 --- a/lib/core/logging/Write-IcingaConsolePlain.psm1 +++ b/lib/core/logging/Write-IcingaConsolePlain.psm1 @@ -26,7 +26,8 @@ function Write-IcingaConsolePlain() [array]$Objects, [ValidateSet('Default', 'Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')] [string]$ForeColor = 'Default', - [switch]$NoNewLine = $FALSE + [switch]$NoNewLine = $FALSE, + [switch]$DropMessage = $FALSE ); Write-IcingaConsoleOutput ` @@ -34,5 +35,6 @@ function Write-IcingaConsolePlain() -Objects $Objects ` -ForeColor $ForeColor ` -Severity $null ` - -NoNewLine:$NoNewLine; + -NoNewLine:$NoNewLine ` + -DropMessage:$DropMessage; } diff --git a/lib/core/logging/Write-IcingaConsoleWarning.psm1 b/lib/core/logging/Write-IcingaConsoleWarning.psm1 index 2dc3554..432cf86 100644 --- a/lib/core/logging/Write-IcingaConsoleWarning.psm1 +++ b/lib/core/logging/Write-IcingaConsoleWarning.psm1 @@ -23,12 +23,14 @@ function Write-IcingaConsoleWarning() { param ( [string]$Message, - [array]$Objects + [array]$Objects, + [switch]$DropMessage = $FALSE ); Write-IcingaConsoleOutput ` -Message $Message ` -Objects $Objects ` -ForeColor 'DarkYellow' ` - -Severity 'Warning'; + -Severity 'Warning' ` + -DropMessage:$DropMessage; } diff --git a/lib/web/Invoke-IcingaWebRequest.psm1 b/lib/web/Invoke-IcingaWebRequest.psm1 index 96e182e..380c168 100644 --- a/lib/web/Invoke-IcingaWebRequest.psm1 +++ b/lib/web/Invoke-IcingaWebRequest.psm1 @@ -46,6 +46,8 @@ .PARAMETER Objects Use placeholders within the `-Uri` argument, like {0} and replace them with array elements of this argument. The index entry of {0} has to match the order of this argument. +.PARAMETER NoErrorMessage + Will not print any error message caused by invalid requests or errors .INPUTS System.String .OUTPUTS @@ -64,7 +66,8 @@ function Invoke-IcingaWebRequest() [string]$Method = 'Get', [string]$OutFile, [switch]$UseBasicParsing, - [array]$Objects = @() + [array]$Objects = @(), + [switch]$NoErrorMessage = $FALSE ); [int]$Index = 0; @@ -109,27 +112,42 @@ function Invoke-IcingaWebRequest() Set-IcingaTLSVersion; Disable-IcingaProgressPreference; + $ErrorStatus = 900; + try { - $Response = Invoke-WebRequest -UseBasicParsing:$UseBasicParsing @WebArguments -ErrorAction Stop; + $Response = Invoke-WebRequest -UseBasicParsing:$UseBasicParsing @WebArguments; } catch { [string]$ErrorId = ([string]$_.FullyQualifiedErrorId).Split(',')[0]; [string]$Message = $_.Exception.Message; + if ([string]::IsNullOrEmpty($_.Exception.Response.StatusCode.Value__) -eq $FALSE) { + $ErrorStatus = $_.Exception.Response.StatusCode.Value__; + } + + if ($_.Exception.ToString().Contains('TlsStream')) { + $ErrorId = 'System.Net.TlsStream.Exception'; + } + switch ($ErrorId) { 'System.UriFormatException' { - Write-IcingaConsoleError 'The provided Url "{0}" is not a valid format' -Objects $Uri; + Write-IcingaConsoleError 'The provided Url "{0}" is not a valid format. Response: "{1}"' -Objects $Uri, $Message -DropMessage:$NoErrorMessage; break; }; 'WebCmdletWebResponseException' { - Write-IcingaConsoleError 'The remote host for address "{0}" could not be resolved' -Objects $Uri; + Write-IcingaConsoleError 'The remote host "{0}" send an exception response "{1}": "{2}"' -Objects $Uri, $ErrorStatus, $Message -DropMessage:$NoErrorMessage; break; }; 'System.InvalidOperationException' { - Write-IcingaConsoleError 'Failed to query host "{0}". Possible this is caused by an invalid Proxy Server configuration: "{1}".' -Objects $Uri, $ProxyServer; + Write-IcingaConsoleError 'Failed to query host "{0}". Possible this is caused by an invalid Proxy Server configuration: "{1}". Response: "{2}"' -Objects $Uri, $ProxyServer, $Message -DropMessage:$NoErrorMessage; break; }; + 'System.Net.TlsStream.Exception' { + Write-IcingaConsoleError 'Failed to establish secure SSL/TLS connection to "{0}". Please ensure the certificate is valid and trusted and use "Set-IcingaTLSVersion" on older Windows machines. If you are using self-signed certificates, install them locally or use "Enable-IcingaUntrustedCertitifacateValidation". Error Message: "{1}"' -Objects $Uri, $Message -DropMessage:$NoErrorMessage; + $ErrorStatus = 901; + break; + } Default { - Write-IcingaConsoleError 'Unhandled exception for Url "{0}" with error id "{1}":{2}{2}{3}' -Objects $Uri, $ErrorId, (New-IcingaNewLine), $Message; + Write-IcingaConsoleError 'Unhandled exception for Url "{0}" with error id "{1}":{2}{2}{3}{2}Response: "{4}"' -Objects $Uri, $ErrorId, (New-IcingaNewLine), $Message -DropMessage:$NoErrorMessage; break; }; } @@ -142,7 +160,7 @@ function Invoke-IcingaWebRequest() 'AbsoluteUri' = $Uri; }; }; - 'StatusCode' = 900; + 'StatusCode' = $ErrorStatus; }; }