From 3b6153a5ba5f56f2caa44787af73a98eff4528c4 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 20 Feb 2023 18:06:30 +0100 Subject: [PATCH 1/8] Link to docs.microsoft.com/en-us, not docs.microsoft.com/de-de in an english documentation. --- doc/110-Installation/01-Getting-Started.md | 2 +- doc/130-JEA/01-JEA-Profiles.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/110-Installation/01-Getting-Started.md b/doc/110-Installation/01-Getting-Started.md index 724d8a6..bac7728 100644 --- a/doc/110-Installation/01-Getting-Started.md +++ b/doc/110-Installation/01-Getting-Started.md @@ -6,7 +6,7 @@ Icinga for Windows provides tools and functionality to entirely manage itself. T * Windows 2012 R2 or later * PowerShell Version 4.0 or later -* [Execution Policies](https://docs.microsoft.com/de-de/powershell/module/microsoft.powershell.core/about/about_execution_policies) allowing module/script execution +* [Execution Policies](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies) allowing module/script execution * Access to [packages.icinga.com](https://packages.icinga.com) at least from one location ## Installation Dependencies diff --git a/doc/130-JEA/01-JEA-Profiles.md b/doc/130-JEA/01-JEA-Profiles.md index 4947e11..f93fecb 100644 --- a/doc/130-JEA/01-JEA-Profiles.md +++ b/doc/130-JEA/01-JEA-Profiles.md @@ -2,7 +2,7 @@ Starting with Icinga for Windows v1.6.0, we are supporting JEA profiles and provide all required tools to build a profile based on installed Icinga for Windows components. -JEA stands for "Just Enough Administration" and you can read more about it on the [Microsoft Docs](https://docs.microsoft.com/de-de/powershell/scripting/learn/remoting/jea/overview). +JEA stands for "Just Enough Administration" and you can read more about it on the [Microsoft Docs](https://docs.microsoft.com/en-us/powershell/scripting/learn/remoting/jea/overview). In short, JEA allows you to limit the access to certain Cmdlets, Functions and Binaries on the system. In addition, you can grant additional privileges to users to perform tasks, which are permitted to Administrators only in general. From 5a5f08c1200c29773f75dc51d2a49048019c302a Mon Sep 17 00:00:00 2001 From: LordHepipud Date: Tue, 27 Jun 2023 15:59:39 +0200 Subject: [PATCH 2/8] Adds argument to allow Agent cipher list configuration --- doc/100-General/10-Changelog.md | 1 + .../icingaagent/writers/Write-IcingaAgentApiConfig.psm1 | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index 9e5a604..4e5062c 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -22,6 +22,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic ### Enhancements * [#623](https://github.com/Icinga/icinga-powershell-framework/issues/623) Adds support to provide the Icinga service user written as `user@domain` +* [#635](https://github.com/Icinga/icinga-powershell-framework/pull/635) Adds support for `Write-IcingaAgentApiConfig` function to configure the Icinga Agent TLS cipher list setting by new argument `-CipherList` ### Enhancements diff --git a/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 b/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 index 9099ecc..e77c25d 100644 --- a/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 +++ b/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 @@ -1,7 +1,8 @@ function Write-IcingaAgentApiConfig() { - param( - [int]$Port = 5665 + param ( + [int]$Port = 5665, + [string]$CipherList = $null ); [string]$ApiConf = ''; @@ -11,6 +12,9 @@ function Write-IcingaAgentApiConfig() $ApiConf = [string]::Format('{0} accept_config = true;{1}', $ApiConf, "`r`n"); $ApiConf = [string]::Format('{0} bind_host = "::";{1}', $ApiConf, "`r`n"); $ApiConf = [string]::Format('{0} bind_port = {1};{2}', $ApiConf, $Port, "`r`n"); + if ([string]::IsNullOrEmpty($CipherList) -eq $FALSE) { + $ApiConf = [string]::Format('{0} cipher_list = "{1}";{2}', $ApiConf, $CipherList, "`r`n"); + } $ApiConf = [string]::Format('{0}{1}{2}{2}', $ApiConf, '}', "`r`n"); $ApiConf = $ApiConf.Substring(0, $ApiConf.Length - 4); From 009a885e43283d8386c498b67fe0338f76d080c0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 6 Jul 2023 17:10:01 +0200 Subject: [PATCH 3/8] Updates README.md with badges --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index c1ae313..0f62bb3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ +[![PowerShell Version](https://img.shields.io/badge/PowerShell-5.1-777BB4?logo=PowerSHell)](https://learn.microsoft.com/en-US/powershell/scripting/install/installing-powershell-on-windows?view=powershell-5.1) +[![GitHub Tag](https://img.shields.io/github/tag/Icinga/icinga-powershell-framework.svg)](https://github.com/Icinga/icinga-powershell-framework/releases/latest) +[![GitHub Issues](https://img.shields.io/github/issues-search?query=repo%3Aicinga%2Ficinga-powershell-framework%20is%3Aopen%20is%3Aissue&label=Issues&color=red +)](https://github.com/Icinga/icinga-powershell-framework/issues) +[![GitHub Pull Requests](https://img.shields.io/github/issues-search?query=repo%3Aicinga%2Ficinga-powershell-framework%20is%3Aopen%20is%3Apr&label=Pull%20Requests&color=green +)](https://github.com/Icinga/icinga-powershell-framework/pulls) + Icinga PowerShell Framework ============== From 05653fea5a26e7298c0dfb055f95f62560751490 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 12 Jul 2023 13:24:52 +0200 Subject: [PATCH 4/8] Adds support to ignore SSL errors on IMC, Shell and Installer --- doc/100-General/10-Changelog.md | 6 ++-- icinga-powershell-framework.psm1 | 39 +++++++++++++++++--------- lib/core/installer/Install-Icinga.psm1 | 13 +++++++-- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index 4e5062c..375f592 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -21,12 +21,10 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic ### Enhancements +* [#619](https://github.com/Icinga/icinga-powershell-framework/pull/619) Adds feature to securely read enum provider values with new function `Get-IcingaProviderEnumData` * [#623](https://github.com/Icinga/icinga-powershell-framework/issues/623) Adds support to provide the Icinga service user written as `user@domain` * [#635](https://github.com/Icinga/icinga-powershell-framework/pull/635) Adds support for `Write-IcingaAgentApiConfig` function to configure the Icinga Agent TLS cipher list setting by new argument `-CipherList` - -### Enhancements - -* [#619](https://github.com/Icinga/icinga-powershell-framework/pull/619) Adds feature to securely read enum provider values with new function `Get-IcingaProviderEnumData` +* [#640](https://github.com/Icinga/icinga-powershell-framework/issues/640) Adds support to set the flag `-NoSSLValidation` for Cmdlets `icinga` and `Install-Icinga`, to ignore errors on self-signed certificates within the environment ## 1.10.1 (2022-12-20) diff --git a/icinga-powershell-framework.psm1 b/icinga-powershell-framework.psm1 index 69766ca..d800e19 100644 --- a/icinga-powershell-framework.psm1 +++ b/icinga-powershell-framework.psm1 @@ -243,12 +243,13 @@ function Invoke-IcingaCommand() [CmdletBinding()] param ( $ScriptBlock, - [switch]$SkipHeader = $FALSE, - [switch]$Manage = $FALSE, # Only for backwards compatibility, has no use at all - [switch]$Shell = $FALSE, - [switch]$RebuildCache = $FALSE, - [switch]$DeveloperMode = $FALSE, - [array]$ArgumentList = @() + [switch]$SkipHeader = $FALSE, + [switch]$Manage = $FALSE, # Only for backwards compatibility, has no use at all + [switch]$Shell = $FALSE, + [switch]$NoSSLValidation = $FALSE, + [switch]$RebuildCache = $FALSE, + [switch]$DeveloperMode = $FALSE, + [array]$ArgumentList = @() ); Import-LocalizedData ` @@ -304,10 +305,19 @@ function Invoke-IcingaCommand() $Shell = $args[3]; $IcingaShellArgs = $args[4]; $DeveloperMode = $args[5]; + $NoSSLValidation = $args[6]; # Load our Icinga Framework Use-Icinga; + # Always ensure we use the proper TLS Version + Set-IcingaTLSVersion; + + # Ignore SSL validation in case we set the flag + if ($NoSSLValidation) { + Enable-IcingaUntrustedCertificateValidation; + } + if ($DeveloperMode) { $Global:Icinga.Protected.DeveloperMode = $TRUE; Copy-IcingaFrameworkCacheTemplate; @@ -336,7 +346,7 @@ function Invoke-IcingaCommand() return "> " } - } -Args $ScriptBlock, $PSScriptRoot, $IcingaFrameworkData.PrivateData.Version, ([bool]$Shell), $ArgumentList, ([bool]$DeveloperMode); + } -Args $ScriptBlock, $PSScriptRoot, $IcingaFrameworkData.PrivateData.Version, ([bool]$Shell), $ArgumentList, ([bool]$DeveloperMode), ([bool]$NoSSLValidation); # In case we close the newly created PowerShell, ensure we set the script root back to the Framework folder if (Test-Path $PSScriptRoot) { @@ -349,13 +359,14 @@ function Invoke-IcingaCommand() # Use the same arguments again to open the IMC $IMCReopenArguments = @{ - 'ScriptBlock' = $ScriptBlock; - 'SkipHeader' = $SkipHeader; - 'Manage' = $Manage; - 'Shell' = $Shell; - 'RebuildCache' = $RebuildCache; - 'DeveloperMode' = $DeveloperMode; - 'ArgumentList' = $ArgumentList; + 'ScriptBlock' = $ScriptBlock; + 'SkipHeader' = $SkipHeader; + 'Manage' = $Manage; + 'Shell' = $Shell; + 'NoSSLValidation' = $NoSSLValidation; + 'RebuildCache' = $RebuildCache; + 'DeveloperMode' = $DeveloperMode; + 'ArgumentList' = $ArgumentList; }; Invoke-IcingaCommand @IMCReopenArguments; diff --git a/lib/core/installer/Install-Icinga.psm1 b/lib/core/installer/Install-Icinga.psm1 index 9e9cb24..2d9b3d5 100644 --- a/lib/core/installer/Install-Icinga.psm1 +++ b/lib/core/installer/Install-Icinga.psm1 @@ -1,14 +1,23 @@ function Install-Icinga() { param ( - [string]$InstallCommand = $null, - [string]$InstallFile = '' + [string]$InstallCommand = $null, + [string]$InstallFile = '', + [switch]$NoSSLValidation = $FALSE ); if ($null -eq $global:Icinga) { $global:Icinga = @{ }; } + # Always ensure we use the proper TLS Version + Set-IcingaTLSVersion; + + # Ignore SSL validation in case we set the flag + if ($NoSSLValidation) { + Enable-IcingaUntrustedCertificateValidation; + } + if ($global:Icinga.ContainsKey('InstallWizard') -eq $FALSE) { $global:Icinga.Add( 'InstallWizard', @{ From 100a666e0990910c3edc1e0cd3d799ef31de147b Mon Sep 17 00:00:00 2001 From: LordHepipud Date: Fri, 14 Jul 2023 10:09:30 +0200 Subject: [PATCH 5/8] Adds support to configure Director Self-Service config string --- doc/100-General/10-Changelog.md | 1 + ...egister-IcingaDirectorSelfServiceHost.psm1 | 22 ++++++- lib/core/installer/Install-Icinga.psm1 | 57 ++++++++-------- .../menu/installation/AdvancedEntries.psm1 | 1 + .../director/SelfServiceConfig.psm1 | 65 +++++++++++++++++++ lib/core/installer/tools/CustomConfig.psm1 | 2 +- .../installer/tools/SetValuesFromStep.psm1 | 20 ++++++ 7 files changed, 137 insertions(+), 31 deletions(-) create mode 100644 lib/core/installer/menu/installation/director/SelfServiceConfig.psm1 create mode 100644 lib/core/installer/tools/SetValuesFromStep.psm1 diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index 375f592..f64003a 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -21,6 +21,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic ### Enhancements +* [#544](https://github.com/Icinga/icinga-powershell-framework/issues/544) Adds support to configure the Icinga Director JSON string for registering hosts via self-service API * [#619](https://github.com/Icinga/icinga-powershell-framework/pull/619) Adds feature to securely read enum provider values with new function `Get-IcingaProviderEnumData` * [#623](https://github.com/Icinga/icinga-powershell-framework/issues/623) Adds support to provide the Icinga service user written as `user@domain` * [#635](https://github.com/Icinga/icinga-powershell-framework/pull/635) Adds support for `Write-IcingaAgentApiConfig` function to configure the Icinga Agent TLS cipher list setting by new argument `-CipherList` diff --git a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 index 980119d..3a9c567 100644 --- a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 +++ b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 @@ -61,8 +61,26 @@ function Register-IcingaDirectorSelfServiceHost() } } - $Interface = Get-IcingaNetworkInterface $Endpoint; - $DirectorConfigJson = [string]::Format('{0} "address":"{2}" {1}', '{', '}', $Interface); + $Interface = Get-IcingaNetworkInterface $Endpoint; + + if ($null -eq $Global:Icinga.InstallWizard.DirectorSelfServiceConfig) { + $DirectorConfigJson = [string]::Format('{{ "address": "{0}" }}', $Interface); + } else { + try { + $DirectorConfigJson = ConvertTo-Json -InputObject $Global:Icinga.InstallWizard.DirectorSelfServiceConfig -Compress -ErrorAction Stop; + $DirectorConfigJson = $DirectorConfigJson.Replace('$ifw.hostaddress$', $Interface); + $DirectorConfigJson = $DirectorConfigJson.Replace('$ifw.hostname.tolower$', (Get-IcingaHostname -AutoUseHostname 1 -LowerCase 1)); + $DirectorConfigJson = $DirectorConfigJson.Replace('$ifw.hostname.toupper$', (Get-IcingaHostname -AutoUseHostname 1 -UpperCase 1)); + $DirectorConfigJson = $DirectorConfigJson.Replace('$ifw.hostname$', (Get-IcingaHostname -AutoUseHostname 1)); + $DirectorConfigJson = $DirectorConfigJson.Replace('$ifw.hostfqdn.tolower$', (Get-IcingaHostname -AutoUseFQDN 1 -LowerCase 1)); + $DirectorConfigJson = $DirectorConfigJson.Replace('$ifw.hostfqdn.toupper$', (Get-IcingaHostname -AutoUseFQDN 1 -UpperCase 1)); + $DirectorConfigJson = $DirectorConfigJson.Replace('$ifw.hostfqdn$', (Get-IcingaHostname -AutoUseFQDN 1)); + } catch { + # Fallback to default + Write-IcingaConsosoleError 'Failed to deserialize your custom Icinga Director Self-Service configuration. Using Icinga for Windows defaults.' + $DirectorConfigJson = [string]::Format('{{ "address": "{0}" }}', $Interface); + } + } $EndpointUrl = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/register-host?name={0}&key={1}', $Hostname, $ApiKey)); diff --git a/lib/core/installer/Install-Icinga.psm1 b/lib/core/installer/Install-Icinga.psm1 index 2d9b3d5..4d6090c 100644 --- a/lib/core/installer/Install-Icinga.psm1 +++ b/lib/core/installer/Install-Icinga.psm1 @@ -21,34 +21,35 @@ function Install-Icinga() if ($global:Icinga.ContainsKey('InstallWizard') -eq $FALSE) { $global:Icinga.Add( 'InstallWizard', @{ - 'AdminShell' = (Test-AdministrativeShell); - 'LastInput' = ''; - 'LastNotice' = ''; - 'LastWarning' = @(); - 'LastError' = @(); - 'DirectorError' = ''; - 'HeaderPreview' = ''; - 'DirectorSelfService' = $FALSE; - 'DirectorRegisteredHost' = $FALSE; - 'DirectorInstallError' = $FALSE; - 'LastParent' = [System.Collections.ArrayList]@(); - 'LastValues' = @(); - 'DisabledEntries' = @{ }; - 'Config' = @{ }; - 'ConfigSwap' = @{ }; - 'ParentConfig' = $null; - 'Menu' = 'Install-Icinga'; - 'NextCommand' = ''; - 'NextArguments' = $null; - 'HeaderSelection' = $null; - 'DisplayAdvanced' = $FALSE; - 'ShowAdvanced' = $FALSE; - 'ShowHelp' = $FALSE; - 'ShowCommand' = $FALSE; - 'DeleteValues' = $FALSE; - 'HeaderPrint' = $FALSE; - 'JumpToSummary' = $FALSE; - 'Closing' = $FALSE; + 'AdminShell' = (Test-AdministrativeShell); + 'LastInput' = ''; + 'LastNotice' = ''; + 'LastWarning' = @(); + 'LastError' = @(); + 'DirectorError' = ''; + 'HeaderPreview' = ''; + 'DirectorSelfServiceConfig' = $null; + 'DirectorSelfService' = $FALSE; + 'DirectorRegisteredHost' = $FALSE; + 'DirectorInstallError' = $FALSE; + 'LastParent' = [System.Collections.ArrayList]@(); + 'LastValues' = @(); + 'DisabledEntries' = @{ }; + 'Config' = @{ }; + 'ConfigSwap' = @{ }; + 'ParentConfig' = $null; + 'Menu' = 'Install-Icinga'; + 'NextCommand' = ''; + 'NextArguments' = $null; + 'HeaderSelection' = $null; + 'DisplayAdvanced' = $FALSE; + 'ShowAdvanced' = $FALSE; + 'ShowHelp' = $FALSE; + 'ShowCommand' = $FALSE; + 'DeleteValues' = $FALSE; + 'HeaderPrint' = $FALSE; + 'JumpToSummary' = $FALSE; + 'Closing' = $FALSE; } ); } else { diff --git a/lib/core/installer/menu/installation/AdvancedEntries.psm1 b/lib/core/installer/menu/installation/AdvancedEntries.psm1 index cafdd7e..5a220d5 100644 --- a/lib/core/installer/menu/installation/AdvancedEntries.psm1 +++ b/lib/core/installer/menu/installation/AdvancedEntries.psm1 @@ -31,6 +31,7 @@ function Add-IcingaForWindowsInstallationAdvancedEntries() Show-IcingaForWindowsInstallationMenuEnterIcingaCAServer -Automated -Advanced; Show-IcingaForWindowsInstallerMenuSelectInstallApiChecks -Automated -Advanced; Show-IcingaForWindowsInstallerMenuSelectServiceRecovery -Automated -Advanced; + Show-IcingaForWindowsManagementConsoleInstallationEnterDirectorSelfServiceConfig -Automated -Advanced; Enable-IcingaFrameworkConsoleOutput; diff --git a/lib/core/installer/menu/installation/director/SelfServiceConfig.psm1 b/lib/core/installer/menu/installation/director/SelfServiceConfig.psm1 new file mode 100644 index 0000000..72c80fe --- /dev/null +++ b/lib/core/installer/menu/installation/director/SelfServiceConfig.psm1 @@ -0,0 +1,65 @@ +function Show-IcingaForWindowsManagementConsoleInstallationEnterDirectorSelfServiceConfig() +{ + param ( + [array]$Value = @(), + [string]$DefaultInput = 'c', + [switch]$JumpToSummary = $FALSE, + [switch]$Automated = $FALSE, + [switch]$Advanced = $FALSE + ); + + # Ensure we simply set the global variable for the Config in case we run in automation mode + if ($Automated) { + if ($null -ne $Value -And $null -ne $Value[0]) { + $Global:Icinga.InstallWizard.DirectorSelfServiceConfig = ConvertFrom-Json -InputObject $Value[0] -ErrorAction Stop; + return; + } + } + + # Set the default if no value ist set + if ($Value -IsNot [array] -Or $null -eq $Value -or $Value.Count -eq 0) { + $Value.Clear(); + if ($null -eq $Global:Icinga.InstallWizard.DirectorSelfServiceConfig) { + $Value += '{ "address": "$ifw.hostaddress$" }'; + } else { + $Value += ConvertTo-Json -InputObject $Global:Icinga.InstallWizard.DirectorSelfServiceConfig -Depth 100 -Compress; + } + } + + Show-IcingaForWindowsInstallerMenu ` + -Header 'You can update the Icinga Director Self-Service config in this section. USE WITH CARE!' ` + -Entries @( + @{ + 'Command' = 'Show-IcingaForWindowsInstallerConfigurationSummary'; + 'Help' = 'This is the configuration JSON-Object for the Icinga Director Self-Service API. You can set a custom IP-Address or define the display name of an object with "display_name" as key. Use this methid with caution! Not all configuration elements in general possible are accessible by using the Self-Service keys.'; + } + ) ` + -DefaultIndex $DefaultInput ` + -AddConfig ` + -ConfigLimit 1 ` + -DefaultValues @( $Value ) ` + -MandatoryValue ` + -JumpToSummary:$JumpToSummary ` + -ConfigElement ` + -Automated:$Automated ` + -Advanced:$Advanced; + + # Fetch the current JSON-String inserted by the user + [string]$ConfigString = Get-IcingaForWindowsInstallerValuesFromStep; + + if ([string]::IsNullOrEmpty($ConfigString) -eq $FALSE) { + try { + # Validate that our JSON is correct + $Global:Icinga.InstallWizard.DirectorSelfServiceConfig = ConvertFrom-Json -InputObject $ConfigString -ErrorAction Stop; + } catch { + # Set some defaults to ensure we don't break the installer + Write-IcingaConsoleError ([string]::Format('The provided Icinga Director Self Service configuration "{0}" does not appear to be a valid JSON-String. E.g.: {{ "address": "$ifw.hostaddress$" }} without leading and ending "" before and after {{ }}', $ConfigString)); + $Global:Icinga.InstallWizard.DirectorSelfServiceConfig = $null; + Set-IcingaForWindowsInstallerValuesFromStep -Values @( '{ }' ); + } + } else { + $Global:Icinga.InstallWizard.DirectorSelfServiceConfig = $null; + } +} + +Set-Alias -Name 'IfW-DirectorSelfServiceConfig' -Value 'Show-IcingaForWindowsManagementConsoleInstallationEnterDirectorSelfServiceConfig'; diff --git a/lib/core/installer/tools/CustomConfig.psm1 b/lib/core/installer/tools/CustomConfig.psm1 index 4dc52e2..de033e0 100644 --- a/lib/core/installer/tools/CustomConfig.psm1 +++ b/lib/core/installer/tools/CustomConfig.psm1 @@ -16,7 +16,7 @@ function Invoke-IcingaForWindowsManagementConsoleCustomConfig() } if ($cmdConfig.ContainsKey('Values') -And $null -ne $cmdConfig.Values) { - $cmdArguments.Add('Value', $cmdConfig.Values) + $cmdArguments.Add('Value', $cmdConfig.Values); } if ($cmdConfig.ContainsKey('Selection') -And $null -ne $cmdConfig.Selection) { $cmdArguments.Add('DefaultInput', $cmdConfig.Selection) diff --git a/lib/core/installer/tools/SetValuesFromStep.psm1 b/lib/core/installer/tools/SetValuesFromStep.psm1 new file mode 100644 index 0000000..d576aee --- /dev/null +++ b/lib/core/installer/tools/SetValuesFromStep.psm1 @@ -0,0 +1,20 @@ +function Set-IcingaForWindowsInstallerValuesFromStep() +{ + param ( + [string]$InstallerStep, + [string]$Parent, + [array]$Values = @() + ); + + $Step = Get-IcingaForWindowsManagementConsoleMenu; + + if ([string]::IsNullOrEmpty($InstallerStep) -eq $FALSE) { + $Step = Get-IcingaForWindowsManagementConsoleAlias -Command $InstallerStep; + + if ([string]::IsNullOrEmpty($Parent) -eq $FALSE) { + $Step = [string]::Format('{0}:{1}', $Step, $Parent); + } + } + + $global:Icinga.InstallWizard.Config[$Step].Values = $Values; +} From a1dff5b5ab0373c958a21a5986d8ceaa914038bd Mon Sep 17 00:00:00 2001 From: LordHepipud Date: Fri, 14 Jul 2023 19:23:44 +0200 Subject: [PATCH 6/8] Adds support for -RebuildCache flag on icinga cmd to rebuild component cache --- doc/100-General/10-Changelog.md | 1 + icinga-powershell-framework.psm1 | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index f64003a..6a1f80c 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -26,6 +26,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#623](https://github.com/Icinga/icinga-powershell-framework/issues/623) Adds support to provide the Icinga service user written as `user@domain` * [#635](https://github.com/Icinga/icinga-powershell-framework/pull/635) Adds support for `Write-IcingaAgentApiConfig` function to configure the Icinga Agent TLS cipher list setting by new argument `-CipherList` * [#640](https://github.com/Icinga/icinga-powershell-framework/issues/640) Adds support to set the flag `-NoSSLValidation` for Cmdlets `icinga` and `Install-Icinga`, to ignore errors on self-signed certificates within the environment +* [#643](https://github.com/Icinga/icinga-powershell-framework/pull/643) Adds support for `-RebuildCache` flag on `icinga` cmd to rebuild component cache as well ## 1.10.1 (2022-12-20) diff --git a/icinga-powershell-framework.psm1 b/icinga-powershell-framework.psm1 index d800e19..f09011e 100644 --- a/icinga-powershell-framework.psm1 +++ b/icinga-powershell-framework.psm1 @@ -281,6 +281,7 @@ function Invoke-IcingaCommand() } if ($RebuildCache -Or $DeveloperMode) { + Copy-IcingaFrameworkCacheTemplate; Write-IcingaFrameworkCodeCache -DeveloperMode:$DeveloperMode; } From 188f3caed5b886049e54b15972f51d561013d1f8 Mon Sep 17 00:00:00 2001 From: LordHepipud Date: Fri, 14 Jul 2023 20:10:07 +0200 Subject: [PATCH 7/8] Adds progress bar to repository interaction instead of text output --- doc/100-General/10-Changelog.md | 1 + lib/core/repository/New-IcingaRepository.psm1 | 2 +- lib/core/repository/New-IcingaRepositoryFile.psm1 | 9 ++++++++- lib/core/repository/Sync-IcingaRepository.psm1 | 10 ++++++++-- lib/core/repository/Update-IcingaRepository.psm1 | 4 ++-- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index 6a1f80c..a42bf17 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -27,6 +27,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#635](https://github.com/Icinga/icinga-powershell-framework/pull/635) Adds support for `Write-IcingaAgentApiConfig` function to configure the Icinga Agent TLS cipher list setting by new argument `-CipherList` * [#640](https://github.com/Icinga/icinga-powershell-framework/issues/640) Adds support to set the flag `-NoSSLValidation` for Cmdlets `icinga` and `Install-Icinga`, to ignore errors on self-signed certificates within the environment * [#643](https://github.com/Icinga/icinga-powershell-framework/pull/643) Adds support for `-RebuildCache` flag on `icinga` cmd to rebuild component cache as well +* [#644](https://github.com/Icinga/icinga-powershell-framework/pull/644) Adds progress bar output to repository interaction (sync, update, new) instead of plain text output ## 1.10.1 (2022-12-20) diff --git a/lib/core/repository/New-IcingaRepository.psm1 b/lib/core/repository/New-IcingaRepository.psm1 index 74e23cb..4668140 100644 --- a/lib/core/repository/New-IcingaRepository.psm1 +++ b/lib/core/repository/New-IcingaRepository.psm1 @@ -35,7 +35,7 @@ function New-IcingaRepository() return; } - $IcingaRepository = New-IcingaRepositoryFile -Path $Path -RemotePath $RemotePath; + $IcingaRepository = New-IcingaRepositoryFile -Path $Path -RemotePath $RemotePath -Name $Name; [array]$ConfigCount = $IcingaRepository.Packages.PSObject.Properties.Count; diff --git a/lib/core/repository/New-IcingaRepositoryFile.psm1 b/lib/core/repository/New-IcingaRepositoryFile.psm1 index f5f1763..2d6a013 100644 --- a/lib/core/repository/New-IcingaRepositoryFile.psm1 +++ b/lib/core/repository/New-IcingaRepositoryFile.psm1 @@ -2,7 +2,8 @@ function New-IcingaRepositoryFile() { param ( [string]$Path = $null, - [string]$RemotePath = $null + [string]$RemotePath = $null, + [string]$Name = '' ); $RepoFile = 'ifw.repo.json'; @@ -23,11 +24,15 @@ function New-IcingaRepositoryFile() $RepositoryFolder = Get-ChildItem -Path $Path -Recurse -Include '*.msi', '*.zip'; + New-IcingaProgressStatus -Name 'Updating Repository' -Message ([string]::Format('Update Icinga for Windows repository ({0}). Processed files', $Name)) -MaxValue $RepositoryFolder.Count -Details; + foreach ($entry in $RepositoryFolder) { $RepoFilePath = $entry.FullName.Replace($Path, ''); $FileHash = Get-FileHash -Path $entry.FullName -Algorithm SHA256; $ComponentName = ''; + Write-IcingaProgressStatus -Name 'Updating Repository'; + $IcingaForWindowsPackage = New-Object -TypeName PSObject; $IcingaForWindowsPackage | Add-Member -MemberType NoteProperty -Name 'Hash' -Value $FileHash.Hash; $IcingaForWindowsPackage | Add-Member -MemberType NoteProperty -Name 'Location' -Value $RepoFilePath; @@ -85,6 +90,8 @@ function New-IcingaRepositoryFile() $IcingaRepository.Info.RepoHash = Get-IcingaRepositoryHash -Path $Path; } + Complete-IcingaProgressStatus -Name 'Updating Repository'; + Write-IcingaFileSecure -File $RepoPath -Value (ConvertTo-Json -InputObject $IcingaRepository -Depth 100); return $IcingaRepository; diff --git a/lib/core/repository/Sync-IcingaRepository.psm1 b/lib/core/repository/Sync-IcingaRepository.psm1 index 59bf695..2995811 100644 --- a/lib/core/repository/Sync-IcingaRepository.psm1 +++ b/lib/core/repository/Sync-IcingaRepository.psm1 @@ -116,10 +116,14 @@ function Sync-IcingaRepository() foreach ($component in $JsonRepo.Packages.PSObject.Properties.Name) { $IfWPackage = $JsonRepo.Packages.$component + New-IcingaProgressStatus -Name 'Sync Repository' -Message ([string]::Format('Syncing Icinga for Windows repository {0} ({1}). Downloaded {2} packages', $Name, $JsonRepo.Info.RemoteSource, $component)) -MaxValue $IfWPackage.Count -Details; + foreach ($package in $IfWPackage) { $DownloadLink = $package.Location; $TargetLocation = $TmpDir; + Write-IcingaProgressStatus -Name 'Sync Repository'; + if ($package.RelativePath -eq $TRUE) { $DownloadLink = Join-WebPath -Path $JsonRepo.Info.RemoteSource -ChildPath $package.Location; $TargetLocation = Join-Path -Path $TmpDir -ChildPath $package.Location; @@ -146,13 +150,15 @@ function Sync-IcingaRepository() } try { - Write-IcingaConsoleNotice 'Syncing repository component "{0}" as file "{1}" into temp directory' -Objects $component, $package.Location; + Write-IcingaConsoleDebug 'Syncing repository component "{0}" as file "{1}" into temp directory' -Objects $component, $package.Location; Invoke-IcingaWebRequest -UseBasicParsing -Uri $DownloadLink -OutFile $TargetLocation | Out-Null; } catch { Write-IcingaConsoleError 'Failed to download repository component "{0}". Exception: "{1}"' -Objects $DownloadLink, $_.Exception.Message; continue; } } + + Complete-IcingaProgressStatus -Name 'Sync Repository'; } } @@ -187,7 +193,7 @@ function Sync-IcingaRepository() } if ($HasNonRelative) { - [void](New-IcingaRepositoryFile -Path $TmpDir -RemotePath $RemotePath); + [void](New-IcingaRepositoryFile -Path $TmpDir -RemotePath $RemotePath -Name $Name); $RepoContent = Get-Content -Path $RepoFile -Raw; $JsonRepo = ConvertFrom-Json -InputObject $RepoContent; Start-Sleep -Seconds 2; diff --git a/lib/core/repository/Update-IcingaRepository.psm1 b/lib/core/repository/Update-IcingaRepository.psm1 index 22836ab..945a86f 100644 --- a/lib/core/repository/Update-IcingaRepository.psm1 +++ b/lib/core/repository/Update-IcingaRepository.psm1 @@ -67,7 +67,7 @@ function Update-IcingaRepository() $SetRemotePath = $RemotePath; } - $IcingaRepository = New-IcingaRepositoryFile -Path $Path -RemotePath $SetRemotePath; + $IcingaRepository = New-IcingaRepositoryFile -Path $Path -RemotePath $SetRemotePath -Name $Name; if ($CreateNew) { return $IcingaRepository; @@ -97,7 +97,7 @@ function Update-IcingaRepository() $SetRemotePath = $RemotePath; } - Write-IcingaConsoleNotice 'Syncing repository "{0}"' -Objects $definedRepo.Name; + Write-IcingaConsoleDebug 'Syncing repository "{0}"' -Objects $definedRepo.Name; if ([string]::IsNullOrEmpty($definedRepo.Value.CloneSource) -eq $FALSE) { Sync-IcingaRepository ` From fa7947779019fc03b03647ad47009e7590dc5f12 Mon Sep 17 00:00:00 2001 From: LordHepipud Date: Wed, 19 Jul 2023 17:46:09 +0200 Subject: [PATCH 8/8] Fixes error and exception handling over API checks --- doc/100-General/10-Changelog.md | 1 + .../Invoke-IcingaApiChecksRESTCall.psm1 | 45 ++++++++++++++++--- .../exception/Exit-IcingaThrowException.psm1 | 2 + 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index a42bf17..9611040 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -18,6 +18,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#615](https://github.com/Icinga/icinga-powershell-framework/issues/615) Fixes the framework migration tasks which fails in case multiple versions of the framework are installed, printing warnings in case there is * [#617](https://github.com/Icinga/icinga-powershell-framework/issues/617) Fixes failing calls for plugins which use a switch argument like `-NoPerfData`, which is followed directly by the `-ThresholdInterval` argument * [#621](https://github.com/Icinga/icinga-powershell-framework/pull/621) Fixes `-ThresholdInterval` key detection on newer systems +* [#645](https://github.com/Icinga/icinga-powershell-framework/pull/645) Fixes error and exception handling while using API-Checks, which now will in most cases always return a proper check-result object and also abort while running into plugin execution errors, in case a server is not reachable by the time sync plugin for example ### Enhancements diff --git a/lib/daemons/modules/ApiChecks/Invoke-IcingaApiChecksRESTCall.psm1 b/lib/daemons/modules/ApiChecks/Invoke-IcingaApiChecksRESTCall.psm1 index 98878e3..8a2f604 100644 --- a/lib/daemons/modules/ApiChecks/Invoke-IcingaApiChecksRESTCall.psm1 +++ b/lib/daemons/modules/ApiChecks/Invoke-IcingaApiChecksRESTCall.psm1 @@ -9,9 +9,11 @@ function Invoke-IcingaApiChecksRESTCall() [Hashtable]$ContentResponse = @{ }; # Short our call - $CheckerAliases = $Global:Icinga.Public.Daemons.RESTApi.CommandAliases.checker; - $CheckConfig = $Request.Body; - [int]$ExitCode = 3; #Unknown + $CheckerAliases = $Global:Icinga.Public.Daemons.RESTApi.CommandAliases.checker; + $CheckConfig = $Request.Body; + [int]$ExitCode = 3; #Unknown + [string]$CheckResult = ''; + [string]$InternalError = ''; # Check if there are an inventory aliases configured # This should be maintained by the developer and not occur @@ -56,10 +58,20 @@ function Invoke-IcingaApiChecksRESTCall() } if ((Test-IcingaRESTApiCommand -Command $ExecuteCommand -Endpoint 'apichecks') -eq $FALSE) { + + Add-IcingaHashtableItem ` + -Hashtable $ContentResponse ` + -Key $ExecuteCommand ` + -Value @{ + 'exitcode' = 3; + 'checkresult' = [string]::Format('[UNKNOWN] Icinga Permission error was thrown: Permission denied for command "{0}"{1}{1}The command "{0}" you are trying to execute over the REST-Api endpoint "apichecks" is not whitelisted for remote execution.', $ExecuteCommand, (New-IcingaNewLine)); + 'perfdata' = @(); + } | Out-Null; + Send-IcingaTCPClientMessage -Message ( New-IcingaTCPClientRESTMessage ` -HTTPResponse ($IcingaHTTPEnums.HTTPResponseType.'Forbidden') ` - -ContentBody ([string]::Format('The command "{0}" you are trying to execute over this REST-Api endpoint "apichecks" is not whitelisted for remote execution.', $ExecuteCommand)) + -ContentBody $ContentResponse ) -Stream $Connection.Stream; return; @@ -100,9 +112,19 @@ function Invoke-IcingaApiChecksRESTCall() -Value $CmdArgValue | Out-Null; }; - [int]$ExitCode = & $ExecuteCommand @Arguments; + try { + [int]$ExitCode = & $ExecuteCommand @Arguments; + } catch { + [int]$ExitCode = 3; + $InternalError = $_.Exception.Message; + } } elseif ($Request.Method -eq 'GET') { - [int]$ExitCode = & $ExecuteCommand; + try { + [int]$ExitCode = & $ExecuteCommand; + } catch { + [int]$ExitCode = 3; + $InternalError = $_.Exception.Message; + } } else { Send-IcingaTCPClientMessage -Message ( New-IcingaTCPClientRESTMessage ` @@ -115,7 +137,16 @@ function Invoke-IcingaApiChecksRESTCall() # Once the check is executed, the plugin output and the performance data are stored # within a special cache map we can use for accessing - $CheckResult = Get-IcingaCheckSchedulerPluginOutput; + if ([string]::IsNullOrEmpty($InternalError)) { + $CheckResult = Get-IcingaCheckSchedulerPluginOutput; + } else { + if ($InternalError.Contains('[UNKNOWN]') -eq $FALSE) { + # Ensure we format the error message more user friendly + $CheckResult = [string]::Format('[UNKNOWN] Icinga Plugin execution error was thrown during API request:{0}{0}{1}', (New-IcingaNewLine), $InternalError); + } else { + $CheckResult = $InternalError; + } + } [array]$PerfData = Get-IcingaCheckSchedulerPerfData; # Ensure our PerfData variable is always an array diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 index 11aa8cd..e4e203d 100644 --- a/lib/icinga/exception/Exit-IcingaThrowException.psm1 +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -113,5 +113,7 @@ function Exit-IcingaThrowException() if ($Global:Icinga.Protected.RunAsDaemon -eq $FALSE -And $Global:Icinga.Protected.JEAContext -eq $FALSE) { Write-IcingaConsolePlain $OutputMessage; exit $IcingaEnums.IcingaExitCode.Unknown; + } else { + throw $OutputMessage; } }