From 7bd61a16d2e44f01568ab42f7734032b13965c48 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 31 Mar 2020 17:45:41 +0200 Subject: [PATCH 01/34] Adds custom plugin developer guide --- doc/04-Developer-Guide.md | 1 + doc/developerguide/11-Custom-Plugins.md | 592 ++++++++++++++++++++++++ 2 files changed, 593 insertions(+) create mode 100644 doc/developerguide/11-Custom-Plugins.md diff --git a/doc/04-Developer-Guide.md b/doc/04-Developer-Guide.md index 1338a7d..384ed81 100644 --- a/doc/04-Developer-Guide.md +++ b/doc/04-Developer-Guide.md @@ -13,3 +13,4 @@ A detailed overview of functions can be found below * [New-IcingaCheck](developerguide/01-New-IcingaCheck.md) * [New-IcingaCheckPackage](developerguide/02-New-IcingaCheckPackage.md) * [Custom Daemons](developerguide/10-Custom-Daemons.md) +* [Custom Plugins](developerguide/11-Custom-Plugins.md) diff --git a/doc/developerguide/11-Custom-Plugins.md b/doc/developerguide/11-Custom-Plugins.md new file mode 100644 index 0000000..1254e97 --- /dev/null +++ b/doc/developerguide/11-Custom-Plugins.md @@ -0,0 +1,592 @@ +# Developer Guide: Custom Plugins + +With the [Icinga PowerShell Framework](https://icinga.com/docs/windows/latest) you have the possibility to create new check plugins with very small effort. Below you will find a step-by-step tutorial for writing an example one. + +## Creating A New Module + +The best approach for creating a custom plugin is by creating an independent module which is installed in your PowerShell modules directly. This will ensure you are not overwriting your custom data with possible framework updates. + +In this guide, we will assume the name of the module is `icinga-powershell-plugintutorial`. + +At first we will have to create a new module. Navigate to the PowerShell modules folder the Framework itself is installed to. In this tutorial we will assume the location is + +```powershell +C:\Program Files\WindowsPowerShell\Modules +``` + +Now create a new folder with the name `icinga-powershell-plugintutorial` and navigate into it. + +As we require a `psm1` file which contains our code, we will create a new file with the name `icinga-powershell-plugintutorial.psm1`. This will allow the PowerShell autoloader to load the module automaticly. + +**Note:** It could be possible, depending on your [execution policies](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6), that your module is not loaded properly. If this is the case, you can try to unblock the file by opening a PowerShell and use the `Unblock-File` Cmdelet + +```powershell +Unblock-File -Path 'C:\Program Files\WindowsPowerShell\Modules\icinga-powershell-plugintutorial\icinga-powershell-plugintutorial.psm1' +``` + +## Testing The Module + +Once the module files are created and unblocked, we can start testing if the autoloader is properly working and our module is detected. + +For this open the file `icinga-powershell-plugintutorial.psm1` in your prefered editor and add the following code snippet + +```powershell +function Test-MyIcingaPluginTutorialCommand() +{ + Write-Host 'Module was loaded'; +} +``` + +Now open a **new** PowerShell terminal or write `powershell` into an already open PowerShell prompt and execute the command `Test-MyIcingaPluginTutorialCommand`. + +If everything went properly, you should now read the output `Module was loaded` in our prompt. If not, you can try to import the module by using + +```powershell +Import-Module 'C:\Program Files\WindowsPowerShell\Modules\icinga-powershell-plugintutorial\icinga-powershell-plugintutorial.psm1'; +``` + +inside your console prompt. After that try again to execute the command `Test-MyIcingaPluginTutorialCommand` and check if it works this time. If not, you might check the naming of your module to ensure `folder name` and `.psm1 file name` is identical. + +Once this is working, we can remove the function again as we no longer require it. + +## Create A New Plugin + +Once everything is working properly we can create our starting function we later use to execute our plugin. + +For naming guidelines we will have to begin with the `Invoke-IcingaCheck` naming and an identifier of what are going to achieve with our plugin. This is `mandatory` to ensure all auto-generation Cmdlets are still working. In our example we will simply name it `Tutorial`. + +So lets get started with the function + +```powershell +function Invoke-IcingaCheckTutorial() +{ + # Our code belongs here +} +``` + +### Basic Plugin Architecture + +A basic plugin contains of multiple parts. At first we general `arguments` to parse thresholds through. In addition to that we will make use of several functions to create our check and check results. The functions [New-IcingaCheck](01-New-IcingaCheck), [New-IcingaCheckPackage](02-New-IcingaCheckPackage) and `New-IcingaCheckResult` will do the work for us. + +### Writing Our Base-Skeleton + +For our plugin we will start with `param()` to parse arguments to our module, create a check objects and return the result. + +At first we will create a variable inside our `Start-IcingaAgentServiceTest` function. + +```powershell +function Invoke-IcingaCheckTutorial() +{ + # Create our arguments we can use to parese thresholds + # Example: Invoke-IcingaCheckTutorial -Warning 10 -Critical 30 + param ( + $Warning = $null, + $Critical = $null + ); + + # Create a new object we can check on. This will include + # comparing values and checking if they are between a + # range is Unknown + $Check = New-IcingaCheck ` + -Name 'Tutorial'; + + # Return our checkresult for the provided check and compile it + # This function will take care to write the plugin output and + # with return we will return the exit code to determine if our + # check is Ok, Warning, Critical or Unknown + return (New-IcingaCheckResult -Check $Check -Compile) +} +``` + +To test this module, we can call another PowerShell instance within our current session and execute the code. This will ensure, we are always loading changes we are making: + +```powershell +powershell -C { Use-Icinga; Invoke-IcingaCheckTutorial; } +``` + +Our tutorial plugin will now output the current status, the name, performance data and the exit. + +```text +[OK] Tutorial: +| 'tutorial'=;; +0 +``` + +### Optional Performance Data + +To make performance data optional on user input, we can now add another argument to our paramter list and update our check result object to use this argument + +```powershell +function Invoke-IcingaCheckTutorial() +{ + # Create our arguments we can use to parese thresholds + # Example: Invoke-IcingaCheckTutorial -Warning 10 -Critical 30 + param ( + $Warning = $null, + $Critical = $null, + [switch]$NoPerfData = $FALSE + ); + + # Create a new object we can check on. This will include + # comparing values and checking if they are between a + # range is Unknown + $Check = New-IcingaCheck ` + -Name 'Tutorial'; + + # Return our checkresult for the provided check and compile it + # This function will take care to write the plugin output and + # with return we will return the exit code to determine if our + # check is Ok, Warning, Critical or Unknown + return (New-IcingaCheckResult -Check $Check -NoPerfData $NoPerfData -Compile) +} +``` + +Once we call the module with the `NoPerfData` argument, performance data is no longer printed + +```powershell +powershell -C { Use-Icinga; Invoke-IcingaCheckTutorial -NoPerfData; } +``` + +```text +[OK] Tutorial: +0 +``` + +### Add Value to Check-Object + +Now as the basic skeleton is ready, we can dive into the actual check object. In our example we will use a `random value`, but feel free to add any other related PowerShell value fetched by WMI, APIs or other components here. + +```powershell +function Invoke-IcingaCheckTutorial() +{ + # Create our arguments we can use to parese thresholds + # Example: Invoke-IcingaCheckTutorial -Warning 10 -Critical 30 + param ( + $Warning = $null, + $Critical = $null, + [switch]$NoPerfData = $FALSE + ); + + # Create a new object we can check on. This will include + # comparing values and checking if they are between a + # range is Unknown + $Check = New-IcingaCheck ` + -Name 'Tutorial' ` + -Value ( + Get-Random -Minimum 10 -Maximum 100 + ); + + # Return our checkresult for the provided check and compile it + # This function will take care to write the plugin output and + # with return we will return the exit code to determine if our + # check is Ok, Warning, Critical or Unknown + return (New-IcingaCheckResult -Check $Check -NoPerfData $NoPerfData -Compile) +} +``` + +By doing so, nothing will change from the plugin output in general, besides the performance data in case we wish to output them and the value the object is now holding. + +```powershell +powershell -C { Use-Icinga; Invoke-IcingaCheckTutorial } +``` + +```text +[OK] Tutorial: 79 +| 'tutorial'=79;; +0 +``` + +### Compare Value with Tresholds + +Now as we are holding a value inside our check object, we can start to compare it with our `Warning` and `Critical` tresholds. There are a bunch of functions inside the check object avaialble for this which can be found in the [check object documentation](01-New-IcingaCheck.md). + +For most plugins the generic approach will do just fine. This one will ensure we can use the Nagios/Icinga treshold syntax to compare values more dynamicly and add ranges support. (See also [Icinga Plugins](https://icinga.com/docs/windows/latest/plugins/doc/10-Icinga-Plugins/)) + +The two functions we will use for this are `WarnOutOfRange` and `CritOutOfRange`. + +```powershell +function Invoke-IcingaCheckTutorial() +{ + # Create our arguments we can use to parese thresholds + # Example: Invoke-IcingaCheckTutorial -Warning 10 -Critical 30 + param ( + $Warning = $null, + $Critical = $null, + [switch]$NoPerfData = $FALSE + ); + + # Create a new object we can check on. This will include + # comparing values and checking if they are between a + # range is Unknown + $Check = New-IcingaCheck ` + -Name 'Tutorial' ` + -Value ( + Get-Random -Minimum 10 -Maximum 100 + ); + # Each compare function within our check object will return the + # object itself, allowing us to write a nested call like below + # to compare multiple values at once. + # IMPORTANT: We have to output the last call either to Out-Null + # or store the result inside a variable, as the check + # object is otherwise written into our plugin output + $Check.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + + # Return our checkresult for the provided check and compile it + # This function will take care to write the plugin output and + # with return we will return the exit code to determine if our + # check is Ok, Warning, Critical or Unknown + return (New-IcingaCheckResult -Check $Check -NoPerfData $NoPerfData -Compile) +} +``` + +**NOTE:** It is very important to output the function calls either to `Out-Null` or assign a variable to store the content, as otherwise we will spam our check object into our plugin output + +```powershell +$dump = $Check.WarnOutOfRange($Warning).CritOutOfRange($Critical); +``` + +As we have now added comparing functions to our plugin, we can execute the plugin again and check if everything works as intended + +```powershell +powershell -C { Use-Icinga; Invoke-IcingaCheckTutorial -Warning 20 -Critical 30 } +``` + +```text +[CRITICAL] Tutorial: Value "76" is greater than threshold "30" +| 'tutorial'=76;20;30 +2 +``` + +### Using Check Packages + +Now it is time to combine multiple check objects into one check package. Our basic plugin works just fine, but maybe we wish to compare multiple values for multiple checks. To do so, we will create another `check object` and one `check package object`. + +Dont forget to add the compare functions `WarnOutOfRange` and `CritOutOfRange` for the new `check object`! + +Last but not least we will modify our `New-IcingaCheckResult` fuction to use the `check package` instead of our old `check object` + +```powershell +function Invoke-IcingaCheckTutorial() +{ + # Create our arguments we can use to parese thresholds + # Example: Invoke-IcingaCheckTutorial -Warning 10 -Critical 30 + param ( + $Warning = $null, + $Critical = $null, + [switch]$NoPerfData = $FALSE + ); + + # Create a new object we can check on. This will include + # comparing values and checking if they are between a + # range is Unknown + $Check = New-IcingaCheck ` + -Name 'Tutorial' ` + -Value ( + Get-Random -Minimum 10 -Maximum 100 + ); + # Add another check objects with a different name for identifying + # which check is holding which value + $Check2 = New-IcingaCheck ` + -Name 'Tutorial 2' ` + -Value ( + Get-Random -Minimum 10 -Maximum 100 + ); + # Each compare function within our check object will return the + # object itself, allowing us to write a nested call like below + # to compare multiple values at once. + # IMPORTANT: We have to output the last call either to Out-Null + # or store the result inside a variable, as the check + # object is otherwise written into our plugin output + $Check.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + # Dont forget to add our comparison for the second check with + # the identical tresholds. If you want to, you could compare + # them to different arguments + $Check2.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + + # Now lets define a check package we can combine our checks into. + # Check packages have names themself and provide a function to + # add checks into. We can either add them directly during creation + # or later + $CheckPackage = New-IcingaCheckPackage ` + -Name 'Tutorial Package' ` + -Checks @( + $Check, + $Check2 + ); + + # Alternatively we can also call the method AddCheck + # $CheckPackage.AddCheck($Check); + # $CheckPackage.AddCheck($Check2); + + # Return our checkresult for the provided check and compile it + # This function will take care to write the plugin output and + # with return we will return the exit code to determine if our + # check is Ok, Warning, Critical or Unknown + return (New-IcingaCheckResult -Check $CheckPackage -NoPerfData $NoPerfData -Compile) +} +``` + +If we now call our script plugin again, we will see two output for performance data + +```powershell +powershell -C { Use-Icinga; Invoke-IcingaCheckTutorial -Warning 20 -Critical 30 } +``` + +```test +[OK] Check package "Tutorial Package" +| 'tutorial'=63;20;30 'tutorial_2'=37;20;30 +0 +``` + +### Package Operators + +As you see, the plugin output is `Ok` while clearly it should throw `Critical`. What we are missing is a comparing operator, telling the package how to count each assiged check. We have several operators on our hand: + +* `-OperatorMin ` with `` amount of checks require to be ok for the package to be ok +* `-OperatorMax ` with `` amount of checks require to be ok for the package to be ok +* `-OperatorAnd` for all checks requiring to be ok for the package to be ok +* `-OperatorOr` for atleast one check requiring to be ok for the package to be ok +* `-OperatorNone` for all checks to be `not` ok for the package to be ok + +You can only use one operator per check package, a combination is not possible. + +On our example we will use the `-OperatorAnd` to ensure all checks have to be ok for the package to be ok + +```powershell +function Invoke-IcingaCheckTutorial() +{ + # Create our arguments we can use to parese thresholds + # Example: Invoke-IcingaCheckTutorial -Warning 10 -Critical 30 + param ( + $Warning = $null, + $Critical = $null, + [switch]$NoPerfData = $FALSE + ); + + # Create a new object we can check on. This will include + # comparing values and checking if they are between a + # range is Unknown + $Check = New-IcingaCheck ` + -Name 'Tutorial' ` + -Value ( + Get-Random -Minimum 10 -Maximum 100 + ); + # Add another check objects with a different name for identifying + # which check is holding which value + $Check2 = New-IcingaCheck ` + -Name 'Tutorial 2' ` + -Value ( + Get-Random -Minimum 10 -Maximum 100 + ); + # Each compare function within our check object will return the + # object itself, allowing us to write a nested call like below + # to compare multiple values at once. + # IMPORTANT: We have to output the last call either to Out-Null + # or store the result inside a variable, as the check + # object is otherwise written into our plugin output + $Check.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + # Dont forget to add our comparison for the second check with + # the identical tresholds. If you want to, you could compare + # them to different arguments + $Check2.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + + # Now lets define a check package we can combine our checks into. + # Check packages have names themself and provide a function to + # add checks into. We can either add them directly during creation + # or later + $CheckPackage = New-IcingaCheckPackage ` + -Name 'Tutorial Package' ` + -Checks @( + $Check, + $Check2 + ) ` + -OperatorAnd; + + # Alternatively we can also call the method AddCheck + # $CheckPackage.AddCheck($Check); + # $CheckPackage.AddCheck($Check2); + + # Return our checkresult for the provided check and compile it + # This function will take care to write the plugin output and + # with return we will return the exit code to determine if our + # check is Ok, Warning, Critical or Unknown + return (New-IcingaCheckResult -Check $CheckPackage -NoPerfData $NoPerfData -Compile) +} +``` + +Now lets see how the output changes + +```powershell +powershell -C { Use-Icinga; Invoke-IcingaCheckTutorial -Warning 20 -Critical 30 } +``` + +```text +[CRITICAL] Check package "Tutorial Package" - [CRITICAL] Tutorial, Tutorial 2 +\_ [CRITICAL] Tutorial: Value "52" is greater than threshold "30" +\_ [CRITICAL] Tutorial 2: Value "60" is greater than threshold "30" +| 'tutorial'=52;20;30 'tutorial_2'=60;20;30 +2 +``` + +As you can see our package is now critical, outputting each check which is `not` Ok. In addition the functions will add + +```text +[CRITICAL] Tutorial, Tutorial 2 +``` + +inside the short plugin output to ensure we have a quick overview within Icinga Web 2, telling us which checks are failling. + +### Increasing Verbosity + +In case our checks are ok, they are not printed by default to keep the view as little as possible. We can test this by executing the plugin without tresholds + +```powershell +powershell -C { Use-Icinga; Invoke-IcingaCheckTutorial } +``` + +```text +[OK] Check package "Tutorial Package" +| 'tutorial'=63;; 'tutorial_2'=51;; +0 +``` + +In case we want to make it configurable if every single `check object` and `check package` is printed, we can add a `Verbosity` flag. This will also introduce another method for the `params` of the module, as we will only allow certain input values for the `Verbosity` argument. + +In addition, we will parse the new `$Verbosity` as argument to our `check package` + +```powershell +function Invoke-IcingaCheckTutorial() +{ + # Create our arguments we can use to parese thresholds + # Example: Invoke-IcingaCheckTutorial -Warning 10 -Critical 30 + param ( + $Warning = $null, + $Critical = $null, + [switch]$NoPerfData = $FALSE, + # Ensure only 0-2 values are allowed for Verbosity + [ValidateSet(0, 1, 2)] + [int]$Verbosity = 0 + ); + + # Create a new object we can check on. This will include + # comparing values and checking if they are between a + # range is Unknown + $Check = New-IcingaCheck ` + -Name 'Tutorial' ` + -Value ( + Get-Random -Minimum 10 -Maximum 100 + ); + # Add another check objects with a different name for identifying + # which check is holding which value + $Check2 = New-IcingaCheck ` + -Name 'Tutorial 2' ` + -Value ( + Get-Random -Minimum 10 -Maximum 100 + ); + # Each compare function within our check object will return the + # object itself, allowing us to write a nested call like below + # to compare multiple values at once. + # IMPORTANT: We have to output the last call either to Out-Null + # or store the result inside a variable, as the check + # object is otherwise written into our plugin output + $Check.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + # Dont forget to add our comparison for the second check with + # the identical tresholds. If you want to, you could compare + # them to different arguments + $Check2.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + + # Now lets define a check package we can combine our checks into. + # Check packages have names themself and provide a function to + # add checks into. We can either add them directly during creation + # or later + $CheckPackage = New-IcingaCheckPackage ` + -Name 'Tutorial Package' ` + -Checks @( + $Check, + $Check2 + ) ` + -OperatorAnd ` + -Verbose $Verbosity; + + # Alternatively we can also call the method AddCheck + # $CheckPackage.AddCheck($Check); + # $CheckPackage.AddCheck($Check2); + + # Return our checkresult for the provided check and compile it + # This function will take care to write the plugin output and + # with return we will return the exit code to determine if our + # check is Ok, Warning, Critical or Unknown + return (New-IcingaCheckResult -Check $CheckPackage -NoPerfData $NoPerfData -Compile) +} +``` + +If we now exectue the plugin with `Verbosity` and the value `2`, every single check will be printed, even when the check itself is Ok + +```powershell +powershell -C { Use-Icinga; Invoke-IcingaCheckTutorial -Verbosity 2 } +``` + +```text +[OK] Check package "Tutorial Package" (Match All) +\_ [OK] Tutorial: 70 +\_ [OK] Tutorial 2: 36 +| 'tutorial'=70;; 'tutorial_2'=36;; +0 +``` + +The following `Verbose` options are available + +* `0`: Default - only `not` Ok values will be printed +* `1`: Only `not` Ok values will be printed including package `operator` config +* `2`: Everything will be printed + +### More Complex Checks + +We will not provide an example in this guide, but we would like to add that this is not the final complexity level of plugins. Each `check package` for example could contain multiple `check packages` with `checks` and even more `check packages`. + +You simply have to ensure you are adding `checks` and `check packages` correctly into each object and parse your primary `check package` to the `check result Cmdlet`. The Framework will then deal with the entire operation and calculation itself + +### Plugin Providers + +In addition we would like you keep the plugin and possible data providers separated. If you for example write plugins for your application monitoring and you require different functions to collect these information, the guided way is to separate the collector functions from the plugin itself. + +The file structure will look like this + +```text +plugin folder + |_ plugin.psm1 + |_ provider_folder + |_ your_plugin_provider.psm1 +``` + +This will ensure these functions can be called separately from the plugin itself and make re-using them a lot easier. + +### Icinga Configuration + +Now as we are done with writing our plugin, it is time to test it inside Icinga 2. Instead of having to write an `Icinga Director` command configuration yourself, we can use an integrated Framework Cmdlet to generate a `Basket` file for us which can be imorted into the `Icinga Director`. + +```powershell +Get-IcingaCheckCommandConfig -CheckName 'Invoke-IcingaCheckTutorial' -OutDirectory 'C:\users\public'; +``` + +```text +The following commands have been exported: +- 'Invoke-IcingaCheckTutorial' +JSON export created in 'C:\users\public\PowerShell_CheckCommands_03-31-2020-17-34-5367.json' +``` + +This is the reason why it is `mandatory` to place plugin Cmdlets within the `Invoke-IcingaCheck` "namespace". Calling `Get-IcingaCheckCommandConfig` without the `CheckName` argument will automatically lookup every command with this naming schema and export all of them inside the `Basket` file. + +### General Guidelines + +To ensure the later import into the `Icinga Director` and usage within Icinga 2 is as easy as possible, it is recommended to write a proper plugin documentation which is understood by the `Get-Help` Cmdlet of Windows. By doing so, arguments are described directly inside the `Icinga Director`. + +Another important note are correct `data types` for values. Each `data type` is translated properly into `Icinga Director` language, resulting in the following behaviour: + +* `[string]` will be translated to text values on check input fields +* `[int]` will be translated to numeric values on check input fields +* `[bool]` will be translated to yes/no values on check input fields +* `[switch]` will be translated to yes/no values on check input fields +* `[array]` will be translated to array values on check input fields + +By using the `ValidateSet` feature of PowerShell (as we did for our `Verbosity`) we will automatically generate a `custom variable` as `datalist`, only allowing the valid input values in a `drop down list` From 3c06a287c12bb0897b5b7473785122514f93562c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 1 Apr 2020 08:41:02 +0200 Subject: [PATCH 02/34] Updates documentation on plugin file structure and moves it on top --- doc/developerguide/11-Custom-Plugins.md | 33 ++++++++++++++----------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/doc/developerguide/11-Custom-Plugins.md b/doc/developerguide/11-Custom-Plugins.md index 1254e97..1fa5488 100644 --- a/doc/developerguide/11-Custom-Plugins.md +++ b/doc/developerguide/11-Custom-Plugins.md @@ -2,6 +2,24 @@ With the [Icinga PowerShell Framework](https://icinga.com/docs/windows/latest) you have the possibility to create new check plugins with very small effort. Below you will find a step-by-step tutorial for writing an example one. +## File Structure + +For plugins we will have to distinguish between general components. The plugin file itself with the Cmdlet and the general check/treshold comparison and possible data providers, delivery the content for our modules. If you for example write plugins for your application monitoring and you require different functions to collect these information, the way to gois to separate the collector functions from the plugin itself. + +This will result in the following file structure + +```text +module + |_ plugin.psd1 + |_ plugin.psm1 + |_ provider + |_ your_plugin_provider.psm1 +``` + +This will ensure these functions can be called separately from the plugin itself and make re-using them a lot easier. In addition, it will help other developers to build dependencies based on your module and data collectors to allow an easier re-usage of already existing components. + +Additional required files within the `provider` folder can be included by using the `NestedModules` array within your `psd1` file. This will ensure these files are automatically loaded once a new PowerShell session is started. + ## Creating A New Module The best approach for creating a custom plugin is by creating an independent module which is installed in your PowerShell modules directly. This will ensure you are not overwriting your custom data with possible framework updates. @@ -546,21 +564,6 @@ We will not provide an example in this guide, but we would like to add that this You simply have to ensure you are adding `checks` and `check packages` correctly into each object and parse your primary `check package` to the `check result Cmdlet`. The Framework will then deal with the entire operation and calculation itself -### Plugin Providers - -In addition we would like you keep the plugin and possible data providers separated. If you for example write plugins for your application monitoring and you require different functions to collect these information, the guided way is to separate the collector functions from the plugin itself. - -The file structure will look like this - -```text -plugin folder - |_ plugin.psm1 - |_ provider_folder - |_ your_plugin_provider.psm1 -``` - -This will ensure these functions can be called separately from the plugin itself and make re-using them a lot easier. - ### Icinga Configuration Now as we are done with writing our plugin, it is time to test it inside Icinga 2. Instead of having to write an `Icinga Director` command configuration yourself, we can use an integrated Framework Cmdlet to generate a `Basket` file for us which can be imorted into the `Icinga Director`. From a4dfee6f8be7ceb9309d45b2a216e461ec04a07e Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 1 Apr 2020 09:07:42 +0200 Subject: [PATCH 03/34] Improves plugin creation Cmdlet, releasing plugins as separate modules --- lib/core/tools/New-IcingaCheckCommand.psm1 | 34 ++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/core/tools/New-IcingaCheckCommand.psm1 b/lib/core/tools/New-IcingaCheckCommand.psm1 index f3a1787..ddee00c 100644 --- a/lib/core/tools/New-IcingaCheckCommand.psm1 +++ b/lib/core/tools/New-IcingaCheckCommand.psm1 @@ -25,16 +25,30 @@ function New-IcingaCheckCommand() ); [string]$CommandFile = [string]::Format( - '{0}.psm1', - $CommandName + 'icinga-powershell-{0}.psm1', + $Name.ToLower() + ); + [string]$PSDFile = [string]::Format( + 'icinga-powershell-{0}.psd1', + $Name.ToLower() ); - [string]$ScriptFile = Join-Path -Path (Get-IcingaCustomPluginDir) -ChildPath $CommandFile; + [string]$ModuleFolder = Join-Path -Path (Get-IcingaFrameworkRootPath) -ChildPath ( + [string]::Format('icinga-powershell-{0}', $Name.ToLower()) + ); + [string]$ScriptFile = Join-Path -Path $ModuleFolder -ChildPath $CommandFile; + [string]$PSDFile = Join-Path -Path $ModuleFolder -ChildPath $PSDFile; + + if ((Test-Path $ModuleFolder) -eq $TRUE) { + throw 'This module folder does already exist.'; + } if ((Test-Path $ScriptFile) -eq $TRUE) { - throw 'This Check-Command does already exist.'; + throw 'This check command does already exist.'; } + New-Item -Path $ModuleFolder -ItemType Directory | Out-Null; + Add-Content -Path $ScriptFile -Value 'Import-IcingaLib icinga\plugin;'; foreach ($Library in $ImportLib) { @@ -88,9 +102,19 @@ function New-IcingaCheckCommand() $DefaultEditor = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.psm1\OpenWithList' -Name a).a; $DefaultEditor = $DefaultEditor.Replace('.exe', ''); + New-ModuleManifest ` + -Path $PSDFile ` + -ModuleToProcess $CommandFile ` + -RequiredModules @('icinga-powershell-framework') ` + -FunctionsToExport @('*') ` + -CmdletsToExport @('*') ` + -VariablesToExport '*' | Out-Null; + + Unblock-IcingaPowerShellFiles -Path $ModuleFolder; + Import-Module $ScriptFile -Global; - if ([string]::IsNullOrEmpty($DefaultEditor) -eq $FALSE -And ((Get-Command $DefaultEditor -ErrorAction SilentlyContinue) -eq $null) -And ((Test-Path $DefaultEditor) -eq $FALSE)) { + if ([string]::IsNullOrEmpty($DefaultEditor) -eq $FALSE -And ($null -eq (Get-Command $DefaultEditor -ErrorAction SilentlyContinue)) -And ((Test-Path $DefaultEditor) -eq $FALSE)) { Write-Host 'No default editor for .psm1 files found. Specify a default editor to automaticly open the newly generated check plugin.'; return; } From bde0005203d672f7a3064b4634c92906a1288450 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 13 Apr 2020 16:31:55 +0200 Subject: [PATCH 04/34] Fixes Icinga Agent MSI package fetching by ignoring RC packages Fixes #58 --- lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 index 5a48b7d..ed86911 100644 --- a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 +++ b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 @@ -25,7 +25,6 @@ function Get-IcingaAgentMSIPackage() foreach ($line in $Content) { if ($line -like '*.msi*' -And $line -like "*$Architecture*") { - #Write-Host '#####' $line $MSIPackage = $line.SubString( $line.IndexOf('Icinga2-'), $line.IndexOf('.msi') - $line.IndexOf('Icinga2-') @@ -43,7 +42,7 @@ function Get-IcingaAgentMSIPackage() break; } } elseif ($Version -eq 'latest') { - if ($line -like '*snapshot*') { + if ($line -like '*snapshot*' -Or $line -like '*-rc*') { continue; } $UsePackage = $MSIPackage; From 858a45bf3072ba63bfc056ce15a5c71162365547 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 15 Apr 2020 10:32:20 +0200 Subject: [PATCH 05/34] Adds documentation for Icinga checkresult --- doc/04-Developer-Guide.md | 1 + .../03-New-IcingaCheckResult.md | 83 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 doc/developerguide/03-New-IcingaCheckResult.md diff --git a/doc/04-Developer-Guide.md b/doc/04-Developer-Guide.md index 384ed81..6702cae 100644 --- a/doc/04-Developer-Guide.md +++ b/doc/04-Developer-Guide.md @@ -12,5 +12,6 @@ A detailed overview of functions can be found below * [New-IcingaCheck](developerguide/01-New-IcingaCheck.md) * [New-IcingaCheckPackage](developerguide/02-New-IcingaCheckPackage.md) +* [New-IcingaCheckResult](developerguide/03-New-IcingaCheckResult.md) * [Custom Daemons](developerguide/10-Custom-Daemons.md) * [Custom Plugins](developerguide/11-Custom-Plugins.md) diff --git a/doc/developerguide/03-New-IcingaCheckResult.md b/doc/developerguide/03-New-IcingaCheckResult.md new file mode 100644 index 0000000..aa24bc3 --- /dev/null +++ b/doc/developerguide/03-New-IcingaCheckResult.md @@ -0,0 +1,83 @@ +# Developer Guide: New-IcingaCheckResult + +Below you will find a list of functions and detailed descriptions including use cases for Cmdlets and features the PowerShell Framework provides. + +| Type | Return Value | Description | +| --- | --- | --- | +| Cmdlet | Integer | Compiles [Icinga Check](01-New-IcingaCheck.md)/[Check Package](02-New-IcingaCheckPackage.md) objects for valid Icinga Plugin output including performance data and returns the Icinga exit code as Integer | + +The `IcingaCheckResult` is the final step to finalyse a Icinga Plugin with the Powershell Framework. The checkresult Cmdlet will process either an [Icinga Check](01-New-IcingaCheck.md) or [Check Package](02-New-IcingaCheckPackage.md) object and `compile` the stored details within to write the plugin output, performance data and return the exit code for Icinga as integer. + +It will be used like in this example: + +```powershell +return New-IcingaCheckresult -Check $MyCheckObject -Compile; +``` + +## Arguments + +| Argument | Input | Mandatory | Description | +| --- | --- | --- | --- | +| Check | PSObject | * | [Icinga Check](01-New-IcingaCheck.md) or [Check Package](02-New-IcingaCheckPackage.md) object | +| NoPerfData | Bool | | Bool value with `true` or `false` to print performance metrics for the plugin or to drop them | +| Compile | Switch | | Will directly compile the checkresult, print the output to console and return the exit code as Integer | + +### Examples + +Please note that within the plugin output on console you will see a number at the end, which is the actual exit code of the plugin which is returned. If you are calling `Cmdlets` from within Icinga, you can simply use `exit` for the plugin call with PowerShell to tell Icinga the correct status. + +```powershell +exit Invoke-IcingaCheckCPU; +``` + +#### Simple Check Output + +```powershell +$IcingaCheck = New-IcingaCheck -Name 'My Check 1' -Value 37 -Unit '%'; +$IcingaCheck.WarnOutOfRange(20).CritOutOfRange(35) | Out-Null; + +return New-IcingaCheckresult -Check $IcingaCheck -Compile; +``` + +```text +[CRITICAL] My Check 1: Value "37%" is greater than threshold "35%" +| 'my_check_1'=37%;20;35;0;100 +2 +``` + +#### Simple Check Output without PerfData + +```powershell +$IcingaCheck = New-IcingaCheck -Name 'My Check 1' -Value 37 -Unit '%'; +$IcingaCheck.WarnOutOfRange(20).CritOutOfRange(35) | Out-Null; + +return New-IcingaCheckresult -Check $IcingaCheck -NoPerfData $TRUE -Compile; +``` + +```text +[CRITICAL] My Check 1: Value "37%" is greater than threshold "35%" +2 +``` + +#### Checkresult with check package + +```powershell +$IcingaCheck1 = New-IcingaCheck -Name 'My Check 1' -Value 37 -Unit '%'; +$IcingaCheck1.WarnOutOfRange(20).CritOutOfRange(35) | Out-Null; + +$IcingaCheck2 = New-IcingaCheck -Name 'My Check 2' -Value 18 -Unit '%'; +$IcingaCheck2.WarnOutOfRange(20).CritOutOfRange(35) | Out-Null; + +$IcingaPackage = New-IcingaCheckPackage -Name 'My Package' -OperatorAnd; +$IcingaPackage.AddCheck($IcingaCheck1); +$IcingaPackage.AddCheck($IcingaCheck2); + +return New-IcingaCheckresult -Check $IcingaPackage -Compile; +``` + +```text +[CRITICAL] Check package "My Package" - [CRITICAL] My Check 1 +\_ [CRITICAL] My Check 1: Value "37%" is greater than threshold "35%" +| 'my_check_1'=37%;20;35;0;100 'my_check_2'=18%;20;35;0;100 +2 +``` From 4f8b51ce7894341cca977b0909c1e5a70833c2ce Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 28 Apr 2020 13:48:15 +0200 Subject: [PATCH 06/34] Handle deprecated argument --key for Icinga Agent save-cert cmd Fixes #62 --- .../Install-IcingaAgentCertificates.psm1 | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 index eeb16c5..71699de 100644 --- a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 +++ b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 @@ -48,11 +48,19 @@ function Install-IcingaAgentCertificates() Write-Host ([string]::Format('Fetching trusted master certificate from "{0}"', $Endpoint)); - $arguments = [string]::Format('pki save-cert --key {0}{1}.key --trustedcert {0}trusted-parent.crt --host {2}', - $CertificateDirectory, - $Hostname, - $Endpoint - ); + # Argument --key for save-cert is deprecated starting with Icinga 2.12.0 + if (Compare-IcingaVersions -RequiredVersion '2.12.0') { + $arguments = [string]::Format('pki save-cert --trustedcert {0}trusted-parent.crt --host {1}', + $CertificateDirectory, + $Endpoint + ); + } else { + $arguments = [string]::Format('pki save-cert --key {0}{1}.key --trustedcert {0}trusted-parent.crt --host {2}', + $CertificateDirectory, + $Hostname, + $Endpoint + ); + } if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) { Write-Host 'Unable to connect to your provided Icinga CA. Please verify the entered configuration is correct.' ` From 09d7bf9050fe10bc317fe12e5c27b9eee445dc82 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 28 Apr 2020 14:04:34 +0200 Subject: [PATCH 07/34] Fixes missing port argument for save-cert Icinga 2 command Fixes #63 --- .../installer/Install-IcingaAgentCertificates.psm1 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 index 71699de..5a13f55 100644 --- a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 +++ b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 @@ -50,15 +50,17 @@ function Install-IcingaAgentCertificates() # Argument --key for save-cert is deprecated starting with Icinga 2.12.0 if (Compare-IcingaVersions -RequiredVersion '2.12.0') { - $arguments = [string]::Format('pki save-cert --trustedcert {0}trusted-parent.crt --host {1}', + $arguments = [string]::Format('pki save-cert --trustedcert {0}trusted-parent.crt --host {1} --port {2}', $CertificateDirectory, - $Endpoint + $Endpoint, + $Port ); } else { - $arguments = [string]::Format('pki save-cert --key {0}{1}.key --trustedcert {0}trusted-parent.crt --host {2}', + $arguments = [string]::Format('pki save-cert --key {0}{1}.key --trustedcert {0}trusted-parent.crt --host {2} --port {3}', $CertificateDirectory, $Hostname, - $Endpoint + $Endpoint, + $Port ); } From 00990c52e1f9e32a18cbdfb1f98ec04cc25180eb Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 28 Apr 2020 14:06:43 +0200 Subject: [PATCH 08/34] Adds documentation for several Cmdlets --- lib/core/cache/Get-IcingaCacheData.psm1 | 26 ++++++++++++++ lib/core/cache/Set-IcingaCacheData.psm1 | 27 ++++++++++++++ lib/core/framework/Copy-ItemSecure.psm1 | 27 ++++++++++++++ .../framework/Expand-IcingaZipArchive.psm1 | 21 +++++++++++ .../Get-IcingaFrameworkServiceBinary.psm1 | 26 ++++++++++++++ .../Get-IcingaPowerShellModuleArchive.psm1 | 36 +++++++++++++++++++ .../Get-IcingaPowerShellModuleVersion.psm1 | 21 +++++++++++ 7 files changed, 184 insertions(+) diff --git a/lib/core/cache/Get-IcingaCacheData.psm1 b/lib/core/cache/Get-IcingaCacheData.psm1 index 27b09d9..19225a2 100644 --- a/lib/core/cache/Get-IcingaCacheData.psm1 +++ b/lib/core/cache/Get-IcingaCacheData.psm1 @@ -1,3 +1,29 @@ +<# +.SYNOPSIS + Reads data from a cache file of the Framework and returns its content +.DESCRIPTION + Allows a developer to read data from certain cache files to either speed up + loading procedures, to store content to not lose data on restarts of a daemon + or to build data tables over time +.FUNCTIONALITY + Returns cached data for specific content +.EXAMPLE + PS>Get-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult_store' -KeyName 'Invoke-IcingaCheckCPU'; +.PARAMETER Space + The individual space to read from. This is targeted to a folder the cache data is written to under icinga-powershell-framework/cache/ +.PARAMETER CacheStore + This is targeted to a sub-folder under icinga-powershell-framework/cache// +.PARAMETER KeyName + This is the actual cache file located under icinga-powershell-framework/cache///.json + Please note to only provide the name without the '.json' apendix. This is done by the module itself +.INPUTS + System.String +.OUTPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +.NOTES +#> function Get-IcingaCacheData() { param( diff --git a/lib/core/cache/Set-IcingaCacheData.psm1 b/lib/core/cache/Set-IcingaCacheData.psm1 index bdf3a36..bb6c81b 100644 --- a/lib/core/cache/Set-IcingaCacheData.psm1 +++ b/lib/core/cache/Set-IcingaCacheData.psm1 @@ -1,3 +1,30 @@ +<# +.SYNOPSIS + Writes data to a cache file for the Framework +.DESCRIPTION + Allows a developer to write data to certain cache files to either speed up + loading procedures, to store content to not lose data on restarts of a daemon + or to build data tables over time +.FUNCTIONALITY + Writes data for specific value to a cache file +.EXAMPLE + PS>Set-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult_store' -KeyName 'Invoke-IcingaCheckCPU' -Value @{ 'CachedData' = 'MyValue' }; +.PARAMETER Space + The individual space to write to. This is targeted to a folder the cache data is written to under icinga-powershell-framework/cache/ +.PARAMETER CacheStore + This is targeted to a sub-folder under icinga-powershell-framework/cache// +.PARAMETER KeyName + This is the actual cache file located under icinga-powershell-framework/cache///.json + Please note to only provide the name without the '.json' apendix. This is done by the module itself +.PARAMETER Value + The actual value to store within the cache file. This can be any kind of value, as long as it is convertable to JSON +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +.NOTES +#> + function Set-IcingaCacheData() { param( diff --git a/lib/core/framework/Copy-ItemSecure.psm1 b/lib/core/framework/Copy-ItemSecure.psm1 index 9641a29..3085785 100644 --- a/lib/core/framework/Copy-ItemSecure.psm1 +++ b/lib/core/framework/Copy-ItemSecure.psm1 @@ -1,3 +1,30 @@ +<# +.SYNOPSIS + A more secure way to copy items from one location to another including error handling +.DESCRIPTION + Wrapper for the Copy-Item Cmdlet to more securely copy items with error + handling to prevent interuptions during actions +.FUNCTIONALITY + Copies items from a source to a destination location +.EXAMPLE + PS>Copy-ItemSecure -Path 'C:\users\public\test.txt' -Destination 'C:\users\public\text2.txt'; +.EXAMPLE + PS>Copy-ItemSecure -Path 'C:\users\public\testfolder\' -Destination 'C:\users\public\testfolder2\' -Recurse; +.PARAMETER Path + The location you wish to copy from. Can either be a file or a directory +.PARAMETER Destination + The target destination to copy to. Can either be a file or a directory +.PARAMETER Recurse + Include possible sub-folders +.PARAMETER Force + Overwrite already existing files/folders +.INPUTS + System.String +.OUTPUTS + System.Boolean +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> function Copy-ItemSecure() { param( diff --git a/lib/core/framework/Expand-IcingaZipArchive.psm1 b/lib/core/framework/Expand-IcingaZipArchive.psm1 index 658e63a..dfde53a 100644 --- a/lib/core/framework/Expand-IcingaZipArchive.psm1 +++ b/lib/core/framework/Expand-IcingaZipArchive.psm1 @@ -1,3 +1,24 @@ +<# +.SYNOPSIS + Extracts a ZIP-Archive to a certain location +.DESCRIPTION + Unzips a ZIP-Archive on to a certain location +.FUNCTIONALITY + Unzips a ZIP-Archive on to a certain location +.EXAMPLE + PS>Expand-IcingaZipArchive -Path 'C:\users\public\test.zip' -Destination 'C:\users\public\'; +.PARAMETER Path + The location of your ZIP-Archive +.PARAMETER Destination + The target destination to extract the ZIP-Archive to +.INPUTS + System.String +.OUTPUTS + System.Boolean +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Expand-IcingaZipArchive() { param( diff --git a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 index 96552b8..cdc34f1 100644 --- a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 +++ b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 @@ -1,3 +1,29 @@ +<# +.SYNOPSIS + Downloads a ZIP-Archive for the Icinga for Windows Service Binary + and installs it into a specified directory +.DESCRIPTION + Wizard function to download the Icinga for Windows Service binary from + a public ressource or from a local webstore / webshare and extract + the ZIP-Archive into a target destination +.FUNCTIONALITY + Downloads and unzips the Icinga for Windows service binary ZIP-Archive +.EXAMPLE + PS>Get-IcingaFrameworkServiceBinary -FrameworkServiceUrl 'https://github.com/Icinga/icinga-powershell-service/releases/download/v1.0.0/icinga-service-v1.0.0.zip' -ServiceDirectory 'C:\Program Files\icinga-framework-service'; +.EXAMPLE + PS>Get-IcingaFrameworkServiceBinary -FrameworkServiceUrl 'C:/users/public/icinga-service-v1.0.0.zip' -ServiceDirectory 'C:\Program Files\icinga-framework-service'; +.PARAMETER FrameworkServiceUrl + The URL / Source for downloading the ZIP-Archive from. +.PARAMETER Destination + The target destination to extract the ZIP-Archive to and to place the service binary +.INPUTS + System.String +.OUTPUTS + System.Hashtable +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Get-IcingaFrameworkServiceBinary() { param( diff --git a/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 b/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 index 4f6025d..221aefd 100644 --- a/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 +++ b/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 @@ -1,3 +1,39 @@ +<# +.SYNOPSIS + Download a PowerShell Module from a custom source or from GitHub + by providing a repository and the user space +.DESCRIPTION + Download a PowerShell Module from a custom source or from GitHub + by providing a repository and the user space +.FUNCTIONALITY + Download and install a PowerShell module from a custom or GitHub source +.EXAMPLE + PS>Get-IcingaPowerShellModuleArchive -ModuleName 'Plugins' -Repository 'icinga-powershell-plugins' -Stable 1; +.EXAMPLE + PS>Get-IcingaPowerShellModuleArchive -ModuleName 'Plugins' -Repository 'icinga-powershell-plugins' -Stable 1 -DryRun 1; +.PARAMETER DownloadUrl + The Url to a ZIP-Archive to download from (skips the wizard) +.PARAMETER ModuleName + The name which is used inside output messages +.PARAMETER Repository + The repository to download the ZIP-Archive from +.PARAMETER GitHubUser + The user from which a repository is downloaded from +.PARAMETER Stable + Download the latest stable release +.PARAMETER Snapshot + Download the latest package from the master branch +.PARAMETER DryRun + Only return the finished build Url including the version to install but + do not modify the system in any way +.INPUTS + System.String +.OUTPUTS + System.Hashtable +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Get-IcingaPowerShellModuleArchive() { param( diff --git a/lib/core/framework/Get-IcingaPowerShellModuleVersion.psm1 b/lib/core/framework/Get-IcingaPowerShellModuleVersion.psm1 index 14d9d4c..7a9e74e 100644 --- a/lib/core/framework/Get-IcingaPowerShellModuleVersion.psm1 +++ b/lib/core/framework/Get-IcingaPowerShellModuleVersion.psm1 @@ -1,3 +1,24 @@ +<# +.SYNOPSIS + Get the version of an installed PowerShell Module +.DESCRIPTION + Get the version of an installed PowerShell Module +.FUNCTIONALITY + Get the version of an installed PowerShell Module +.EXAMPLE + PS>Get-IcingaPowerShellModuleVersion -ModuleName 'icinga-powershell-framework'; +.EXAMPLE + PS>Get-IcingaPowerShellModuleVersion -ModuleName 'icinga-powershell-plugins'; +.PARAMETER ModuleName + The PowerShell module to fetch the installed version from +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Get-IcingaPowerShellModuleVersion() { param( From 7fa21a8f86da29599c7179ba73c061f781e1307d Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 28 Apr 2020 15:24:57 +0200 Subject: [PATCH 09/34] Adds help for several Cmdlets --- .../Get-IcingaDirectorSelfServiceConfig.psm1 | 24 +++++++++++++++ .../Get-IcingaDirectorSelfServiceTicket.psm1 | 23 ++++++++++++++ ...egister-IcingaDirectorSelfServiceHost.psm1 | 30 +++++++++++++++++++ lib/config/Get-IcingaConfigTreeCount.psm1 | 19 ++++++++++++ lib/config/Get-IcingaPowerShellConfig.psm1 | 19 ++++++++++++ .../New-IcingaPowerShellConfigItem.psm1 | 21 +++++++++++++ lib/config/Read-IcingaPowerShellConfig.psm1 | 15 ++++++++++ lib/config/Remove-IcingaPowerShellConfig.psm1 | 17 +++++++++++ lib/config/Set-IcingaPowerShellConfig.psm1 | 19 ++++++++++++ .../Test-IcingaPowerShellConfigItem.psm1 | 21 +++++++++++++ lib/config/Write-IcingaPowerShellConfig.psm1 | 17 +++++++++++ 11 files changed, 225 insertions(+) diff --git a/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 b/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 index f934f26..e6614c4 100644 --- a/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 +++ b/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 @@ -1,3 +1,27 @@ +<# +.SYNOPSIS + Will fetch the current host configuration or general configuration depending + if a host or template key is specified from the Icinga Director Self-Service API +.DESCRIPTION + Use the Self-Service API of the Icinga Director to connect to it and fetch the + configuration to apply for this host. The configuration itself is differentiated + if a template or the specific host key is used +.FUNCTIONALITY + Fetches host or general configuration form the Icinga Director Self-Service API +.EXAMPLE + PS>Get-IcingaDirectorSelfServiceConfig -DirectorUrl 'https://example.com/icingaweb2/director -ApiKey 457g6b98054v76vb5490ß276bv0457v6054b76; +.PARAMETER DirectorUrl + The URL pointing directly to the Icinga Web 2 Director module +.PARAMETER ApiKey + Either the template or host key to authenticate against the Self-Service API +.INPUTS + System.String +.OUTPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Get-IcingaDirectorSelfServiceConfig() { param( diff --git a/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 b/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 index 48fca58..2e2bfaa 100644 --- a/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 +++ b/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 @@ -1,3 +1,26 @@ +<# +.SYNOPSIS + Will fetch the ticket for certificate signing by using the Icinga Director + Self-Service API +.DESCRIPTION + Use the Self-Service API of the Icinga Director to connect to it and fetch the + ticket to sign Icinga 2 certificate requests +.FUNCTIONALITY + Fetches the ticket for certificate signing form the Icinga Director Self-Service API +.EXAMPLE + PS>Get-IcingaDirectorSelfServiceTicket -DirectorUrl 'https://example.com/icingaweb2/director -ApiKey 457g6b98054v76vb5490ß276bv0457v6054b76; +.PARAMETER DirectorUrl + The URL pointing directly to the Icinga Web 2 Director module +.PARAMETER ApiKey + The host key to authenticate against the Self-Service API +.INPUTS + System.String +.OUTPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Get-IcingaDirectorSelfServiceTicket() { param( diff --git a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 index f5503d5..633a954 100644 --- a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 +++ b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 @@ -1,3 +1,33 @@ +<# +.SYNOPSIS + Register the current host wihtin the Icinga Director by using the + Self-Service API and return the host key +.DESCRIPTION + This function will register the current host within the Icinga Director in case + it is not already registered and returns the host key for storing it on disk + to allow the host to fetch detailed configurations like zones and endppoints +.FUNCTIONALITY + Register a host within the Icinga Director by using the Self-Service API +.EXAMPLE + PS>Register-IcingaDirectorSelfServiceHost -DirectorUrl 'https://example.com/icingaweb2/director -Hostname 'examplehost' -ApiKey 457g6b98054v76vb5490ß276bv0457v6054b76 -Endpoint 'icinga.example.com'; +.PARAMETER DirectorUrl + The URL pointing directly to the Icinga Web 2 Director module +.PARAMETER Hostname + The name of the current host to register within the Icinga Director +.PARAMETER ApiKey + The template key to authenticate against the Self-Service API +.PARAMETER Endpoint + The IP or FQDN to one of the parent Icinga 2 nodes this Agent will connect to + for determining which network interface shall be used by Icinga for connecting + and to apply hostalive/ping checks to +.INPUTS + System.String +.OUTPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Register-IcingaDirectorSelfServiceHost() { param( diff --git a/lib/config/Get-IcingaConfigTreeCount.psm1 b/lib/config/Get-IcingaConfigTreeCount.psm1 index a295d52..67f76a9 100644 --- a/lib/config/Get-IcingaConfigTreeCount.psm1 +++ b/lib/config/Get-IcingaConfigTreeCount.psm1 @@ -1,3 +1,22 @@ +<# +.SYNOPSIS + Returns the amount of items for a config item +.DESCRIPTION + Returns the amount of items for a config item +.FUNCTIONALITY + Returns the amount of items for a config item +.EXAMPLE + PS>Get-IcingaConfigTreeCount -Path 'framework.daemons'; +.PARAMETER Path + The path to the config item to check for +.INPUTS + System.String +.OUTPUTS + System.Integer +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Get-IcingaConfigTreeCount() { param( diff --git a/lib/config/Get-IcingaPowerShellConfig.psm1 b/lib/config/Get-IcingaPowerShellConfig.psm1 index 65abd70..4aed09d 100644 --- a/lib/config/Get-IcingaPowerShellConfig.psm1 +++ b/lib/config/Get-IcingaPowerShellConfig.psm1 @@ -1,3 +1,22 @@ +<# +.SYNOPSIS + Returns the configuration for a provided config path +.DESCRIPTION + Returns the configuration for a provided config path +.FUNCTIONALITY + Returns the configuration for a provided config path +.EXAMPLE + PS>Get-IcingaPowerShellConfig -Path 'framework.daemons'; +.PARAMETER Path + The path to the config item to check for +.INPUTS + System.String +.OUTPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Get-IcingaPowerShellConfig() { param( diff --git a/lib/config/New-IcingaPowerShellConfigItem.psm1 b/lib/config/New-IcingaPowerShellConfigItem.psm1 index ddff776..2de7a6a 100644 --- a/lib/config/New-IcingaPowerShellConfigItem.psm1 +++ b/lib/config/New-IcingaPowerShellConfigItem.psm1 @@ -1,3 +1,24 @@ +<# +.SYNOPSIS + Creates a new config entry with given arguments +.DESCRIPTION + Creates a new config entry with given arguments +.FUNCTIONALITY + Creates a new config entry with given arguments +.EXAMPLE + PS>New-IcingaPowerShellConfigItem -ConfigObject $PSObject -ConfigKey 'keyname' -ConfigValue 'keyvalue'; +.PARAMETER ConfigObject + The custom config object to modify +.PARAMETER ConfigKey + The key which is added to the config object +.PARAMETER ConfigValue + The value written for the ConfigKey +.INPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function New-IcingaPowerShellConfigItem() { param( diff --git a/lib/config/Read-IcingaPowerShellConfig.psm1 b/lib/config/Read-IcingaPowerShellConfig.psm1 index cf989f2..84d74af 100644 --- a/lib/config/Read-IcingaPowerShellConfig.psm1 +++ b/lib/config/Read-IcingaPowerShellConfig.psm1 @@ -1,3 +1,18 @@ +<# +.SYNOPSIS + Reads the entire configuration and returns it as custom object +.DESCRIPTION + Reads the entire configuration and returns it as custom object +.FUNCTIONALITY + Reads the entire configuration and returns it as custom object +.EXAMPLE + PS>Read-IcingaPowerShellConfig; +.OUTPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Read-IcingaPowerShellConfig() { $ConfigDir = Get-IcingaPowerShellConfigDir; diff --git a/lib/config/Remove-IcingaPowerShellConfig.psm1 b/lib/config/Remove-IcingaPowerShellConfig.psm1 index a6c0dfd..a9a9ab6 100644 --- a/lib/config/Remove-IcingaPowerShellConfig.psm1 +++ b/lib/config/Remove-IcingaPowerShellConfig.psm1 @@ -1,3 +1,20 @@ +<# +.SYNOPSIS + Removes a config entry from a given path +.DESCRIPTION + Removes a config entry from a given path +.FUNCTIONALITY + Removes a config entry from a given path +.EXAMPLE + PS>Remove-IcingaPowerShellConfig -Path 'framework.daemons'; +.PARAMETER Path + The path to the config item to remove +.INPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Remove-IcingaPowerShellConfig() { param( diff --git a/lib/config/Set-IcingaPowerShellConfig.psm1 b/lib/config/Set-IcingaPowerShellConfig.psm1 index 195d6e1..c5b6069 100644 --- a/lib/config/Set-IcingaPowerShellConfig.psm1 +++ b/lib/config/Set-IcingaPowerShellConfig.psm1 @@ -1,3 +1,22 @@ +<# +.SYNOPSIS + Sets a config entry for a given path to a certain value +.DESCRIPTION + Sets a config entry for a given path to a certain value +.FUNCTIONALITY + Sets a config entry for a given path to a certain value +.EXAMPLE + PS>Set-IcingaPowerShellConfig -Path 'framework.daemons.servicecheck' -Value $DaemonConfig; +.PARAMETER Path + The path to the config item to be set +.PARAMETER Value + The value to be set for a specific config path +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Set-IcingaPowerShellConfig() { param( diff --git a/lib/config/Test-IcingaPowerShellConfigItem.psm1 b/lib/config/Test-IcingaPowerShellConfigItem.psm1 index 95c3fe4..e910ef1 100644 --- a/lib/config/Test-IcingaPowerShellConfigItem.psm1 +++ b/lib/config/Test-IcingaPowerShellConfigItem.psm1 @@ -1,3 +1,24 @@ +<# +.SYNOPSIS + Test if a config entry on an object is already present +.DESCRIPTION + Test if a config entry on an object is already present +.FUNCTIONALITY + Test if a config entry on an object is already present +.EXAMPLE + PS>Test-IcingaPowerShellConfigItem -ConfigObject $PSObject -ConfigKey 'keyname'; +.PARAMETER ConfigObject + The custom config object to check for +.PARAMETER ConfigKey + The key which is checked +.INPUTS + System.String +.OUTPUTS + System.Boolean +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Test-IcingaPowerShellConfigItem() { param( diff --git a/lib/config/Write-IcingaPowerShellConfig.psm1 b/lib/config/Write-IcingaPowerShellConfig.psm1 index 3dfbdda..5375c8d 100644 --- a/lib/config/Write-IcingaPowerShellConfig.psm1 +++ b/lib/config/Write-IcingaPowerShellConfig.psm1 @@ -1,3 +1,20 @@ +<# +.SYNOPSIS + Writes a given config object to disk +.DESCRIPTION + Writes a given config object to disk +.FUNCTIONALITY + Writes a given config object to disk +.EXAMPLE + PS>Write-IcingaPowerShellConfig -Config $PSObject; +.PARAMETER Config + A PSObject containing the entire configuration to write +.INPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Write-IcingaPowerShellConfig() { param( From 96733eb7911d649e78f87461b591b81af957bd40 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 28 Apr 2020 16:39:38 +0200 Subject: [PATCH 10/34] Fix URL building for Agent MSI packages Fixes #64 --- lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 index ed86911..132bfeb 100644 --- a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 +++ b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 @@ -66,7 +66,7 @@ function Get-IcingaAgentMSIPackage() return @{ 'InstallerPath' = $DownloadPath; - 'Version' = ($UsePackage).Replace('Icinga2-v', '').Replace($Architecture, '').Replace('.msi', '').Replace('-', ''); + 'Version' = ($UsePackage).Replace('Icinga2-v', '').Replace([string]::Format('-{0}.msi', $Architecture), '') 'LastUpdate' = $LastUpdate; } } From c0e006640aeb6d6d92074b31372a033c7aa50980 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 28 Apr 2020 17:05:57 +0200 Subject: [PATCH 11/34] Adds support to restore original config after using old PS module Fixes #65 --- .../misc/Reset-IcingaAgentConfigFile.psm1 | 30 +++++++++++++++++++ .../misc/Start-IcingaAgentInstallWizard.psm1 | 1 + 2 files changed, 31 insertions(+) create mode 100644 lib/core/icingaagent/misc/Reset-IcingaAgentConfigFile.psm1 diff --git a/lib/core/icingaagent/misc/Reset-IcingaAgentConfigFile.psm1 b/lib/core/icingaagent/misc/Reset-IcingaAgentConfigFile.psm1 new file mode 100644 index 0000000..a51a005 --- /dev/null +++ b/lib/core/icingaagent/misc/Reset-IcingaAgentConfigFile.psm1 @@ -0,0 +1,30 @@ +<# +.SYNOPSIS + Checks for old configurations provided by the old PowerShell module + and restores the original configuration file +.DESCRIPTION + Restores the original Icinga 2 configuration by replacing the existing + configuration created by the old PowerShell module with the plain one + from the Icinga 2 backup file +.FUNCTIONALITY + Restores original Icinga 2 configuration icinga2.conf +.EXAMPLE + PS>Reset-IcingaAgentConfigFile; +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Reset-IcingaAgentConfigFile() +{ + $ConfigDir = Get-IcingaAgentConfigDirectory; + $OldConfig = Join-Path -Path $ConfigDir -ChildPath 'icinga2.conf'; + $OldConfigBackup = Join-Path -Path $ConfigDir -ChildPath 'icinga2.conf.old.module'; + $OriginalConfig = Join-Path -Path $ConfigDir -ChildPath 'icinga2.confdirector.bak'; + + if ((Test-Path $OriginalConfig)) { + Write-Host 'Found icinga2.conf backup file created by old PowerShell module. Restoring original configuration'; + + Move-Item -Path $OldConfig -Destination $OldConfigBackup; + Move-Item -Path $OriginalConfig -Destination $OldConfig; + } +} diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 1984232..27cf33f 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -474,6 +474,7 @@ function Start-IcingaAgentInstallWizard() if ($RunInstaller) { if ((Install-IcingaAgent -Version $AgentVersion -Source $PackageSource -AllowUpdates $AllowVersionChanges) -Or $Reconfigure) { + Reset-IcingaAgentConfigFile; Move-IcingaAgentDefaultConfig; Set-IcingaAgentNodeName -Hostname $Hostname; Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass -SetPermission | Out-Null; From 3809806472c29bcc7184f834ad77f4af1acfcb01 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 29 Apr 2020 13:54:50 +0200 Subject: [PATCH 12/34] Updates docs to refer to the service installation guide --- doc/service/01-Install-Service.md | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/doc/service/01-Install-Service.md b/doc/service/01-Install-Service.md index aebcb6e..a6d4e57 100644 --- a/doc/service/01-Install-Service.md +++ b/doc/service/01-Install-Service.md @@ -11,36 +11,12 @@ In order to make this work, you will require the Icinga Windows Service which ca Benefits --- -Running the PowerShell Framework as background service will add the possibility to register certain functions which are executed depending on their configuration / coding. One example would be to frequently collect monitoring metrics from the installed plugins, allowing you to receice an average of time for the CPU load for example. +Running the PowerShell Framework as background service will add the possibility to register certain functions which are executed depending on their configuration / coding. One example would be to frequently collect monitoring metrics from the installed plugins, allowing you to receive an average of time for the CPU load for example. Install the Service --- -At first you will require the Service Binary from the [Icinga Windows Service GitHub Repository](https://github.com/Icinga/icinga-powershell-service) and copy the binary locally to your system. A recommended path would be your Program Files / Program Files (x86) directory. - -Any other custom location is fully supported, has to be however accessible from the Windows Service Environment. - -Once you have found a location, the PowerShell Module will assist you with setting up the service itself. In this documentation we will assume the path you have chosen to copy the binary to is - -```powershell -C:\Program Files\Icinga-Framework-Service -``` - -and the binary name is - -```powershell -icinga-service.exe -``` - -Now lets install the service with the help of the PowerShell Module: - -```powershell -Install-IcingaFrameworkService -Path 'C:\Program Files\Icinga-Framework-Service\icinga-service.exe' -``` - -You can validate if the service has been installed properly by using the Get Service Cmdlet: - -Each enabled background daemon component is afterwards being started and executed. +A detailed documentation on how to download and install the service and be found directly on the services [installation guide](https://icinga.com/docs/windows/latest/service/doc/02-Installation/). Register Functions --- From 084e57504db9c11a7a44a16da9ba6167e111d83a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 30 Apr 2020 12:21:10 +0200 Subject: [PATCH 13/34] Improves check package operator docs --- doc/developerguide/02-New-IcingaCheckPackage.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/developerguide/02-New-IcingaCheckPackage.md b/doc/developerguide/02-New-IcingaCheckPackage.md index 68a9507..e900780 100644 --- a/doc/developerguide/02-New-IcingaCheckPackage.md +++ b/doc/developerguide/02-New-IcingaCheckPackage.md @@ -20,11 +20,11 @@ $IcingaPackage = New-IcingaCheckPackage -Name 'My Package' -OperatorAnd; | Argument | Input | Mandatory | Description | | --- | --- | --- | --- | | Name | String | * | The unique name of each package within a plugin. Will be displayed in the check output. | -| OperatorAnd | Switch | | Logical relation of the check within the package becomes an AND | -| OperatorOr | Switch | | Logical relation of the check within the package becomes an Or | -| OperatorNone | Switch | | - | -| OperatorMin | Int | | - | -| OperatorMax | Int | | - | +| OperatorAnd | Switch | | Every added check/package requires to return Ok for this package to be Ok | +| OperatorOr | Switch | | One added check/package requires to return Ok for this package to be Ok | +| OperatorNone | Switch | | None of added check/package has to return Ok for this package to be Ok | +| OperatorMin | Int | | Minimum of `n` added checks/packages requires to return Ok for this package to be Ok | +| OperatorMax | Int | | Maximum of `n` added checks/packages requires to return Ok for this package to be Ok | | Checks | Array | | Array of checks to be added to the check package | | Verbose | int | | Defines the level of output detail from 0 lowest to 3 highest detail | | Hidden | Switch | | If set, the check package doesn't generate output | From cac7e941f05c08ddb5420a3372e017937ae54658 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 6 May 2020 09:36:52 +0200 Subject: [PATCH 14/34] Fixes doc for custom daemon module naming --- doc/developerguide/10-Custom-Daemons.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/developerguide/10-Custom-Daemons.md b/doc/developerguide/10-Custom-Daemons.md index ea89c0e..e9e71df 100644 --- a/doc/developerguide/10-Custom-Daemons.md +++ b/doc/developerguide/10-Custom-Daemons.md @@ -8,7 +8,7 @@ Creating A New Module The best approach for creating a custom daemon is by creating an independent module which is installed in your PowerShell modules directly. This will ensure you are not overwriting your custom data with possible framework updates. -In this guide, we will assume the name of the module is `icinga-psdaemon-agentservice`. +In this guide, we will assume the name of the module is `icinga-powershell-agentservice`. At first we will have to create a new module. Navigate to the PowerShell modules folder the Framework itself is installed to. In this tutorial we will assume the location is @@ -16,14 +16,14 @@ At first we will have to create a new module. Navigate to the PowerShell modules C:\Program Files\WindowsPowerShell\Modules ``` -Now create a new folder with the name `icinga-psdaemon-agentservice` and navigate into it. +Now create a new folder with the name `icinga-powershell-agentservice` and navigate into it. -As we require a `psm1` file which contains our code, we will create a new file with the name `icinga-psdaemon-agentservice.psm1`. This will allow the PowerShell autoloader to load the module automaticly. +As we require a `psm1` file which contains our code, we will create a new file with the name `icinga-powershell-agentservice.psm1`. This will allow the PowerShell autoloader to load the module automaticly. **Note:** It could be possible, depending on your [execution policies](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6), that your module is not loaded properly. If this is the case, you can try to unblock the file by opening a PowerShell and use the `Unblock-File` Cmdelet ```powershell -Unblock-File -Path 'C:\Program Files\WindowsPowerShell\Modules\icinga-psdaemon-agentservice\icinga-psdaemon-agentservice.psm1' +Unblock-File -Path 'C:\Program Files\WindowsPowerShell\Modules\icinga-powershell-agentservice\icinga-powershell-agentservice.psm1' ``` Testing The Module @@ -31,7 +31,7 @@ Testing The Module Once the modules files are created and unblocked, we can start testing if the autoloader is properly working and our module is detected. -For this open the file `icinga-psdaemon-agentservice.psm1` in your prefered editor and add the following code snippet +For this open the file `icinga-powershell-agentservice.psm1` in your prefered editor and add the following code snippet ```powershell function Test-MyIcingaAgentServiceCommand() @@ -45,7 +45,7 @@ Now open a **new** PowerShell terminal or write `powershell` into an already ope If everything went properly, you should now read the output `Module was loaded` in our prompt. If not, you can try to import the module by using ```powershell -Import-Module 'C:\Program Files\WindowsPowerShell\Modules\icinga-psdaemon-agentservice\icinga-psdaemon-agentservice.psm1'; +Import-Module 'C:\Program Files\WindowsPowerShell\Modules\icinga-powershell-agentservice\icinga-powershell-agentservice.psm1'; ``` inside your console prompt. After that try again to execute the command `Test-MyIcingaAgentServiceCommand` and check if it works this time. If not, you might check the naming of your module to ensure `folder name` and `.psm1 file name` is identical. From 10c9add973d79bec575c137fe431758033a19877 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 6 May 2020 11:36:15 +0200 Subject: [PATCH 15/34] Fixes custom daemon example for restart_error counter --- doc/developerguide/10-Custom-Daemons.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/doc/developerguide/10-Custom-Daemons.md b/doc/developerguide/10-Custom-Daemons.md index e9e71df..05883f3 100644 --- a/doc/developerguide/10-Custom-Daemons.md +++ b/doc/developerguide/10-Custom-Daemons.md @@ -296,7 +296,13 @@ function Start-IcingaAgentServiceTest() if ($ServiceState.Status -ne 'Running') { try { # Try to restart the service - Restart-Service 'icinga2'; + Restart-Service 'icinga2' -ErrorAction Stop; + + Add-IcingaHashtableItem ` + -Hashtable $IcingaDaemonData.BackgroundDaemon.TestIcingaAgentService.ServiceState ` + -Key 'restart_error' ` + -Value 0 ` + -Override | Out-Null; } catch { # Add an error counter in case we failed $RestartErrors += 1; @@ -378,7 +384,13 @@ function Start-IcingaAgentServiceTest() if ($ServiceState.Status -ne 'Running') { try { # Try to restart the service - Restart-Service 'icinga2'; + Restart-Service 'icinga2' -ErrorAction Stop; + + Add-IcingaHashtableItem ` + -Hashtable $IcingaDaemonData.BackgroundDaemon.TestIcingaAgentService.ServiceState ` + -Key 'restart_error' ` + -Value 0 ` + -Override | Out-Null; } catch { # Add an error counter in case we failed $RestartErrors += 1; From d2059890075a474c009db266dc5f8ccb13b3c984 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 12 May 2020 16:37:08 +0200 Subject: [PATCH 16/34] Fixes performance data by converting boolean to integer Fixes #66 --- lib/core/tools/ConvertTo-Integer.psm1 | 65 ++++++++++++++++++++++++++ lib/icinga/plugin/New-IcingaCheck.psm1 | 49 +++++++++++++++++-- 2 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 lib/core/tools/ConvertTo-Integer.psm1 diff --git a/lib/core/tools/ConvertTo-Integer.psm1 b/lib/core/tools/ConvertTo-Integer.psm1 new file mode 100644 index 0000000..8c195b8 --- /dev/null +++ b/lib/core/tools/ConvertTo-Integer.psm1 @@ -0,0 +1,65 @@ +<# +.SYNOPSIS + Helper function to convert values to integer if possible +.DESCRIPTION + Converts an input value to integer if possible in any way. Otherwise it will return the object unmodified + + More Information on https://github.com/Icinga/icinga-powershell-framework +.FUNCTIONALITY + Converts an input value to integer if possible in any way. Otherwise it will return the object unmodified +.PARAMETER Value + Any value/object is analysed and if possible converted to an integer +.INPUTS + System.Object +.OUTPUTS + System.Integer + +.LINK + https://github.com/Icinga/icinga-powershell-framework +.NOTES +#> + +function ConvertTo-Integer() +{ + param ( + $Value, + [switch]$NullAsEmpty + ); + + if ($null -eq $Value) { + if ($NullAsEmpty) { + return ''; + } + + return 0; + } + + if ([string]::IsNullOrEmpty($Value)) { + if ($NullAsEmpty) { + return ''; + } + + return 0; + } + + if ((Test-Numeric $Value)) { + return $Value; + } + + $Type = $value.GetType().Name; + + if ($Type -eq 'GpoBoolean' -Or $Type -eq 'Boolean' -Or $Type -eq 'SwitchParameter') { + return [int]$Value; + } + + if ($Type -eq 'String') { + if ($Value.ToLower() -eq 'true' -Or $Value.ToLower() -eq 'yes' -Or $Value.ToLower() -eq 'y') { + return 1; + } + if ($Value.ToLower() -eq 'false' -Or $Value.ToLower() -eq 'no' -Or $Value.ToLower() -eq 'n') { + return 0; + } + } + + return $Value; +} diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 89d8bf7..b7be7a9 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -147,6 +147,8 @@ function New-IcingaCheck() ); } + $this.warning = $warning; + return $this; } @@ -161,6 +163,8 @@ function New-IcingaCheck() ); } + $this.warning = $warning; + return $this; } @@ -175,6 +179,8 @@ function New-IcingaCheck() ); } + $this.warning = $warning; + return $this; } @@ -189,6 +195,8 @@ function New-IcingaCheck() ); } + $this.warning = $warning; + return $this; } @@ -203,6 +211,8 @@ function New-IcingaCheck() ); } + $this.warning = [string]::Format('{0}:{1}', $min, $max); + return $this; } @@ -217,6 +227,8 @@ function New-IcingaCheck() ); } + $this.warning = [string]::Format('{0}:{1}', $min, $max); + return $this; } @@ -231,6 +243,8 @@ function New-IcingaCheck() ); } + $this.warning = $warning; + return $this; } @@ -245,6 +259,8 @@ function New-IcingaCheck() ); } + $this.warning = $warning; + return $this; } @@ -259,6 +275,8 @@ function New-IcingaCheck() ); } + $this.warning = $warning; + return $this; } @@ -273,6 +291,8 @@ function New-IcingaCheck() ); } + $this.warning = $warning; + return $this; } @@ -329,6 +349,8 @@ function New-IcingaCheck() ); } + $this.critical = $critical; + return $this; } @@ -343,6 +365,8 @@ function New-IcingaCheck() ); } + $this.critical = $critical; + return $this; } @@ -357,6 +381,8 @@ function New-IcingaCheck() ); } + $this.critical = $critical; + return $this; } @@ -371,6 +397,8 @@ function New-IcingaCheck() ); } + $this.critical = $critical; + return $this; } @@ -385,6 +413,8 @@ function New-IcingaCheck() ); } + $this.critical = [string]::Format('{0}:{1}', $min, $max); + return $this; } @@ -399,6 +429,8 @@ function New-IcingaCheck() ); } + $this.critical = [string]::Format('{0}:{1}', $min, $max); + return $this; } @@ -413,6 +445,8 @@ function New-IcingaCheck() ); } + $this.critical = $critical; + return $this; } @@ -427,6 +461,8 @@ function New-IcingaCheck() ); } + $this.critical = $critical; + return $this; } @@ -441,6 +477,8 @@ function New-IcingaCheck() ); } + $this.critical = $critical; + return $this; } @@ -455,6 +493,8 @@ function New-IcingaCheck() ); } + $this.critical = $critical; + return $this; } @@ -721,14 +761,17 @@ function New-IcingaCheck() $this.completed = $TRUE; [string]$LabelName = (Format-IcingaPerfDataLabel $this.name); + $value = ConvertTo-Integer -Value $this.value -NullAsEmpty; + $warning = ConvertTo-Integer -Value $this.warning -NullAsEmpty; + $critical = ConvertTo-Integer -Value $this.critical -NullAsEmpty; $perfdata = @{ 'label' = $LabelName; 'perfdata' = ''; 'unit' = $this.unit; - 'value' = (Format-IcingaPerfDataValue $this.value); - 'warning' = (Format-IcingaPerfDataValue $this.warning); - 'critical' = (Format-IcingaPerfDataValue $this.critical); + 'value' = (Format-IcingaPerfDataValue $value); + 'warning' = (Format-IcingaPerfDataValue $warning); + 'critical' = (Format-IcingaPerfDataValue $critical); 'minimum' = (Format-IcingaPerfDataValue $this.minimum); 'maximum' = (Format-IcingaPerfDataValue $this.maximum); 'package' = $FALSE; From efdca87b7e1107399115d618642f96ff8ea9ae38 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 12 May 2020 18:33:50 +0200 Subject: [PATCH 17/34] Improves wizard argument escaping, duplicates and arg conversion Fix #61 --- .../misc/Start-IcingaAgentDirectorWizard.psm1 | 13 +- .../misc/Start-IcingaAgentInstallWizard.psm1 | 265 ++++++++++++------ 2 files changed, 197 insertions(+), 81 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 index c7f6c51..e7cb29f 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 @@ -112,6 +112,10 @@ function Start-IcingaAgentDirectorWizard() $DirectorOverrideArgs.Add( 'Ticket', $IcingaTicket ); + $DirectorOverrideArgs.Add( + 'OverrideDirectorVars', 0 + ); + if ([string]::IsNullOrEmpty($TemplateKey) -eq $FALSE) { $DirectorOverrideArgs.Add( 'SelfServiceAPIKey', $TemplateKey @@ -136,13 +140,16 @@ function Start-IcingaDirectorAPIArgumentOverride() foreach ($entry in $Arguments.Keys) { $value = (Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Please enter the new value for the argument "{0}"', $entry)) -Default 'v' -DefaultInput $Arguments[$entry]).answer; - if ($Arguments[$entry] -is [array]) { - if ([string]::IsNullOrEmpty($value) -eq $FALSE) { + if ($Arguments[$entry] -is [array] -Or ($value -is [string] -And $value.Contains(','))) { + if ([string]::IsNullOrEmpty($value) -eq $FALSE) { + while ($value.Contains(', ')) { + $value = $value.Replace(', ', ','); + } [array]$tmpArray = $value.Split(','); if ($null -ne (Compare-Object -ReferenceObject $Arguments[$entry] -DifferenceObject $tmpArray)) { $NewArguments.Add( $entry, - ([string]::Join(',', $tmpArray)) + $tmpArray ); } } diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 27cf33f..81e3551 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -70,68 +70,68 @@ function Start-IcingaAgentInstallWizard() $SelfServiceAPIKey = $Result.Value; $InstallerArguments = $Result.Args; } - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'Ticket' -Value $Ticket -InstallerArguments $InstallerArguments; - $Ticket = $Result.Value; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'PackageSource' -Value $PackageSource -InstallerArguments $InstallerArguments; - $PackageSource = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AgentVersion' -Value $AgentVersion -InstallerArguments $InstallerArguments; - $AgentVersion = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'CAPort' -Value $CAPort -InstallerArguments $InstallerArguments; - $CAPort = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AllowVersionChanges' -Value $AllowVersionChanges -InstallerArguments $InstallerArguments; - $AllowVersionChanges = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'GlobalZones' -Value $GlobalZones -InstallerArguments $InstallerArguments; - $GlobalZones = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'ParentZone' -Value $ParentZone -InstallerArguments $InstallerArguments; - $ParentZone = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'CAEndpoint' -Value $CAEndpoint -InstallerArguments $InstallerArguments; - $CAEndpoint = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'Endpoints' -Value $Endpoints -InstallerArguments $InstallerArguments; - $Endpoints = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddFirewallRule' -Value $AddFirewallRule -InstallerArguments $InstallerArguments; - $AddFirewallRule = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AcceptConnections' -Value $AcceptConnections -InstallerArguments $InstallerArguments; - $AcceptConnections = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddFirewallRule' -Value $AddFirewallRule -InstallerArguments $InstallerArguments; - $AddFirewallRule = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'ServiceUser' -Value $ServiceUser -InstallerArguments $InstallerArguments; - $ServiceUser = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'UpdateAgent' -Value $UpdateAgent -InstallerArguments $InstallerArguments; - $UpdateAgent = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddDirectorGlobal' -Value $AddDirectorGlobal -InstallerArguments $InstallerArguments; - $AddDirectorGlobal = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddGlobalTemplates' -Value $AddGlobalTemplates -InstallerArguments $InstallerArguments; - $AddGlobalTemplates = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'LowerCase' -Value $LowerCase -Default $FALSE -InstallerArguments $InstallerArguments; - $LowerCase = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'UpperCase' -Value $UpperCase -Default $FALSE -InstallerArguments $InstallerArguments; - $UpperCase = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AutoUseFQDN' -Value $AutoUseFQDN -Default $FALSE -InstallerArguments $InstallerArguments; - $AutoUseFQDN = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AutoUseHostname' -Value $AutoUseHostname -Default $FALSE -InstallerArguments $InstallerArguments; - $AutoUseHostname = $Result.Value; - $InstallerArguments = $Result.Args; - $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'EndpointConnections' -Value $EndpointConnections -InstallerArguments $InstallerArguments; - $EndpointConnections = $Result.Value; - $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'Ticket' -Value $Ticket -InstallerArguments $InstallerArguments; + $Ticket = $Result.Value; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'PackageSource' -Value $PackageSource -InstallerArguments $InstallerArguments; + $PackageSource = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AgentVersion' -Value $AgentVersion -InstallerArguments $InstallerArguments; + $AgentVersion = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'CAPort' -Value $CAPort -InstallerArguments $InstallerArguments; + $CAPort = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AllowVersionChanges' -Value $AllowVersionChanges -InstallerArguments $InstallerArguments; + $AllowVersionChanges = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'GlobalZones' -Value $GlobalZones -InstallerArguments $InstallerArguments; + $GlobalZones = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'ParentZone' -Value $ParentZone -InstallerArguments $InstallerArguments; + $ParentZone = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'CAEndpoint' -Value $CAEndpoint -InstallerArguments $InstallerArguments; + $CAEndpoint = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'Endpoints' -Value $Endpoints -InstallerArguments $InstallerArguments; + $Endpoints = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddFirewallRule' -Value $AddFirewallRule -InstallerArguments $InstallerArguments; + $AddFirewallRule = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AcceptConnections' -Value $AcceptConnections -InstallerArguments $InstallerArguments; + $AcceptConnections = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'ServiceUser' -Value $ServiceUser -InstallerArguments $InstallerArguments; + $ServiceUser = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'UpdateAgent' -Value $UpdateAgent -InstallerArguments $InstallerArguments; + $UpdateAgent = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddDirectorGlobal' -Value $AddDirectorGlobal -InstallerArguments $InstallerArguments; + $AddDirectorGlobal = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddGlobalTemplates' -Value $AddGlobalTemplates -InstallerArguments $InstallerArguments; + $AddGlobalTemplates = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'LowerCase' -Value $LowerCase -Default $FALSE -InstallerArguments $InstallerArguments; + $LowerCase = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'UpperCase' -Value $UpperCase -Default $FALSE -InstallerArguments $InstallerArguments; + $UpperCase = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AutoUseFQDN' -Value $AutoUseFQDN -Default $FALSE -InstallerArguments $InstallerArguments; + $AutoUseFQDN = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AutoUseHostname' -Value $AutoUseHostname -Default $FALSE -InstallerArguments $InstallerArguments; + $AutoUseHostname = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'EndpointConnections' -Value $EndpointConnections -InstallerArguments $InstallerArguments; + $EndpointConnections = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'OverrideDirectorVars' -Value $OverrideDirectorVars -InstallerArguments $InstallerArguments; + $OverrideDirectorVars = $Result.Value; + $InstallerArguments = $Result.Args; } } @@ -265,7 +265,9 @@ function Start-IcingaAgentInstallWizard() } } elseif ($AcceptConnections) { $CanConnectToParent = $TRUE; - $InstallerArguments += ("-AcceptConnections $AcceptConnections"); + if ((Test-IcingaWizardArgument -Argument 'AcceptConnections') -eq $FALSE) { + $InstallerArguments += ([string]::Format('-AcceptConnections {0}', [int]$AcceptConnections)); + } } if ($null -eq $AddFirewallRule) { @@ -428,6 +430,10 @@ function Start-IcingaAgentInstallWizard() $result = Install-IcingaFrameworkPlugins -PluginsUrl $PluginsUrl; $InstallerArguments += "-InstallFrameworkPlugins 1"; $InstallerArguments += "-PluginsUrl '$PluginsUrl'"; + } else { + if ((Test-IcingaWizardArgument -Argument 'InstallFrameworkPlugins') -eq $FALSE) { + $InstallerArguments += "-InstallFrameworkPlugins 0"; + } } if ($null -eq $InstallFrameworkService) { @@ -495,6 +501,106 @@ function Start-IcingaAgentInstallWizard() } } +function Add-InstallerArgument() +{ + param( + $InstallerArguments, + [string]$Key, + $Value, + [switch]$ReturnValue + ); + + [bool]$IsArray = $Value -is [array]; + + # Check for arrays + if ($IsArray) { + [array]$NewArray = @(); + foreach ($entry in $Value) { + $NewArray += Add-InstallerArgument -Value $entry -ReturnValue; + } + + if ($ReturnValue) { + return ([string]::Join(',', $NewArray)); + } + + $InstallerArguments += [string]::Format( + '-{0} {1}', + $Key, + [string]::Join(',', $NewArray) + ); + + return $InstallerArguments; + } + + # Check for integers + if (Test-Numeric $Value) { + if ($ReturnValue) { + return $Value; + } + + $InstallerArguments += [string]::Format( + '-{0} {1}', + $Key, + $Value + ); + + return $InstallerArguments; + } + + # Check for integer conversion + $IntValue = ConvertTo-Integer -Value $Value; + if ([string]$Value -ne [string]$IntValue) { + if ($ReturnValue) { + return $IntValue; + } + + $InstallerArguments += [string]::Format( + '-{0} {1}', + $Key, + $IntValue + ); + + return $InstallerArguments; + } + + $Type = $Value.GetType().Name; + $NewValue = $null; + + if ($Type -eq 'String') { + $NewValue = [string]::Format( + "'{0}'", + $Value + ); + + if ($ReturnValue) { + return $NewValue; + } + + $InstallerArguments += [string]::Format( + '-{0} {1}', + $Key, + $NewValue + ); + + return $InstallerArguments; + } +} + +function Test-IcingaWizardArgument() +{ + param( + [string]$Argument + ); + + foreach ($entry in $InstallerArguments) { + if ($entry -like [string]::Format('-{0} *', $Argument)) { + return $TRUE; + } + } + + return $FALSE; +} + function Set-IcingaWizardArgument() { param( @@ -506,11 +612,12 @@ function Set-IcingaWizardArgument() ); if ($DirectorArgs.Overrides.ContainsKey($WizardArg)) { - $Override = $DirectorArgs.Overrides[$WizardArg]; - if ($Value -is [array]) { - $Override = [string]::Join(',', $Override); - } - $InstallerArguments += "-$WizardArg $Override"; + + $InstallerArguments = Add-InstallerArgument ` + -InstallerArguments $InstallerArguments ` + -Key $WizardArg ` + -Value $DirectorArgs.Overrides[$WizardArg]; + return @{ 'Value' = $DirectorArgs.Overrides[$WizardArg]; 'Args' = $InstallerArguments; @@ -523,11 +630,12 @@ function Set-IcingaWizardArgument() $RetValue = $DirectorArgs.Arguments[$WizardArg]; } else { if ($null -ne $Value -Or [string]::IsNullOrEmpty($Value) -eq $FALSE) { - $TmpValue = $Value; - if ($Value -is [array]) { - $TmpValue = [string]::Join(',', $TmpValue); - } - $InstallerArguments += "-$WizardArg $TmpValue"; + + $InstallerArguments = Add-InstallerArgument ` + -InstallerArguments $InstallerArguments ` + -Key $WizardArg ` + -Value $Value; + return @{ 'Value' = $Value; 'Args' = $InstallerArguments; @@ -541,11 +649,12 @@ function Set-IcingaWizardArgument() } if ([string]::IsNullOrEmpty($Value) -eq $FALSE) { - $TmpValue = $Value; - if ($Value -is [array]) { - $TmpValue = [string]::Join(',', $Value); - } - $InstallerArguments += "-$WizardArg $TmpValue"; + + $InstallerArguments = Add-InstallerArgument ` + -InstallerArguments $InstallerArguments ` + -Key $WizardArg ` + -Value $Value; + return @{ 'Value' = $Value; 'Args' = $InstallerArguments; From 224a1b56595f114e0a62e79332eb5bd850f5d5a3 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 13 May 2020 14:50:11 +0200 Subject: [PATCH 18/34] Adds defaults to certain steps and FQDN to IP conversion --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 35 +++++++++-- .../tools/Convert-IcingaEndpointsToIP.psm1 | 60 +++++++++++++++++++ 2 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 lib/core/tools/Convert-IcingaEndpointsToIP.psm1 diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 81e3551..c9777e8 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -16,6 +16,7 @@ function Start-IcingaAgentInstallWizard() $AcceptConnections = $null, [array]$Endpoints = @(), [array]$EndpointConnections = @(), + $ConvertEndpointIPConfig = $null, [string]$ParentZone, [array]$GlobalZones = $null, [string]$CAEndpoint, @@ -218,7 +219,7 @@ function Start-IcingaAgentInstallWizard() if ($UpdateAgent -eq 1) { if ([string]::IsNullOrEmpty($AgentVersion)) { - $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v').answer; + $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v' -DefaultInput 'latest').answer; $InstallerArguments += "-AgentVersion '$AgentVersion'"; Write-Host ([string]::Format('Updating/Downgrading Icinga 2 Agent to version: "{0}"', $AgentVersion)); @@ -237,7 +238,7 @@ function Start-IcingaAgentInstallWizard() } if ($Endpoints.Count -eq 0) { - $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify all endpoints this Agent will report to (separated by ",")' -Default 'v').answer; + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify all Icinga endpoints this Agent will report to separated by "," (Example: master-icinga2a, master-icinga2b)' -Default 'v').answer; $Endpoints = ($ArrayString.Replace(' ', '')).Split(','); $InstallerArguments += ("-Endpoints " + ([string]::Join(',', $Endpoints))); } @@ -255,7 +256,7 @@ function Start-IcingaAgentInstallWizard() [bool]$CanConnectToParent = $FALSE; if ($null -eq $AcceptConnections) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this Agent able to connect to its parent node for certificate generation and general communication?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt "Is this Agent able to connect to it's parent node for certificate requests and general communication?" -Default 'y').result -eq 1) { $CanConnectToParent = $TRUE; $AcceptConnections = 1; $InstallerArguments += ("-AcceptConnections 1"); @@ -280,6 +281,21 @@ function Start-IcingaAgentInstallWizard() } } + if ($null -eq $ConvertEndpointIPConfig) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to convert all possible provided FQDN address for endpoint/network configuration for Icinga 2 to plain IP-Address?', $CAPort)) -Default 'y').result -eq 1) { + $InstallerArguments += "-ConvertEndpointIPConfig 1"; + $ConvertEndpointIPConfig = $TRUE; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; + if ($EndpointsConversion.HasErrors) { + Write-Host 'Not all of your endpoints configuration could be converted and was therefor dropped'; + } + $Endpoints = $EndpointsConversion.Network; + } else { + $InstallerArguments += "-ConvertEndpointIPConfig 0"; + $ConvertEndpointIPConfig = $FALSE; + } + } + if ($EndpointConnections.Count -eq 0 -And $AcceptConnections -eq 1) { $NetworkDefault = ''; foreach ($Endpoint in $Endpoints) { @@ -288,8 +304,15 @@ function Start-IcingaAgentInstallWizard() if ([string]::IsNullOrEmpty($NetworkDefault) -eq $FALSE) { $NetworkDefault = $NetworkDefault.Substring(0, $NetworkDefault.Length - 1); } - $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this agent will connect to, separated by ","' -Default 'v' -DefaultInput $NetworkDefault).answer; + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this Agent will connect to separated by "," (Example: 192.168.0.1, [192.168.0.2]:5665, [icinga2.example.com]:5665)' -Default 'v' -DefaultInput $NetworkDefault).answer; $EndpointConnections = ($ArrayString.Replace(' ', '')).Split(','); + + if ($ConvertEndpointIPConfig) { + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; + if ($EndpointsConversion.HasErrors -eq $FALSE) { + $EndpointConnections = $EndpointsConversion.Network; + } + } $InstallerArguments += ("-EndpointConnections " + ([string]::Join(',', $EndpointConnections))); } @@ -342,7 +365,7 @@ function Start-IcingaAgentInstallWizard() if ($CanConnectToParent) { if ([string]::IsNullOrEmpty($CAEndpoint)) { - $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the IP/FQDN for either ONE of your Icinga parent nodes or your Icinga 2 CA master' -Default 'v' -DefaultInput (Get-IPConfigFromString $EndpointConnections[0]).address).answer; + $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the IP/FQDN for either ONE of your Icinga parent nodes or your Icinga 2 CA master for requesting certificates' -Default 'v' -DefaultInput (Get-IPConfigFromString $EndpointConnections[0]).address).answer; $InstallerArguments += "-CAEndpoint $CAEndpoint"; } if ([string]::IsNullOrEmpty($Ticket) -And $null -eq $EmptyTicket) { @@ -400,7 +423,7 @@ function Start-IcingaAgentInstallWizard() if ([string]::IsNullOrEmpty($ServiceUser)) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to change the user the Icinga Agent service is running with (Default: "NT Authority\NetworkService")?' -Default 'n').result -eq 0) { - $ServiceUser = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the user you wish the Icinga Agent service to run with' -Default 'v').answer; + $ServiceUser = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the user you wish the Icinga Agent service to run with' -Default 'v' -DefaultInput 'NT Authority\NetworkService').answer; $InstallerArguments += "-ServiceUser $ServiceUser"; if ($null -eq $ServicePass) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Does your Icinga Service user require a password to login (not required for System users)?' -Default 'y').result -eq 1) { diff --git a/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 new file mode 100644 index 0000000..9305b88 --- /dev/null +++ b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 @@ -0,0 +1,60 @@ +<# +.SYNOPSIS + Converts Icinga Network configuration from FQDN to IP +.DESCRIPTION + This Cmdlet will convert a given Icinga Endpoint configuration based + on a FQDN to a IPv4 based configuration and returns nothing of the + FQDN could not be resolved +.FUNCTIONALITY + Converts Icinga Network configuration from FQDN to IP +.EXAMPLE + PS>Convert-IcingaEndpointsToIPv4 -NetworkConfig @( '[icinga2.example.com]:5665' ); +.PARAMETER NetworkConfig + An array of Icinga endpoint or single network configuration, like '[icinga2.example.com]:5665' + which will be converted to IP based configuration +.INPUTS + System.Array +.OUTPUTS + System.Hashtable +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> +function Convert-IcingaEndpointsToIPv4() +{ + param ( + [array]$NetworkConfig + ); + + [array]$ResolvedNetwork = @(); + [bool]$HasUnresolved = $FALSE; + [string]$Domain = $ENV:UserDNSDomain; + + foreach ($entry in $NetworkConfig) { + $Network = Get-IPConfigFromString -IPConfig $entry; + try { + $ResolvedIP = [System.Net.Dns]::GetHostAddresses($Network.address); + $ResolvedNetwork += $entry.Replace($Network.address, $ResolvedIP); + } catch { + # Once we failed in first place, try to lookup the "FQDN" with our host domain + # we are in. Might resolve some issues if our DNS is not knowing the plain + # hostname and untable to resolve it + try { + $ResolvedIP = [System.Net.Dns]::GetHostAddresses( + [string]::Format( + '{0}.{1}', + $Network.address, + $Domain + ) + ); + $ResolvedNetwork += $entry.Replace($Network.address, $ResolvedIP); + } catch { + $HasUnresolved = $TRUE; + } + } + } + + return @{ + 'Network' = $ResolvedNetwork; + 'HasErrors' = $HasUnresolved; + }; +} From 2b740785fec9a8b67211fb70c3b621be32de3d95 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 13 May 2020 16:53:15 +0200 Subject: [PATCH 19/34] Replaces Write-Host calls with custom console writes --- .../Get-IcingaDirectorSelfServiceTicket.psm1 | 38 ++++++------ ...egister-IcingaDirectorSelfServiceHost.psm1 | 2 +- lib/core/framework/Copy-ItemSecure.psm1 | 2 +- .../framework/Expand-IcingaZipArchive.psm1 | 2 +- .../Get-IcingaFrameworkServiceBinary.psm1 | 4 +- .../Get-IcingaPowerShellModuleArchive.psm1 | 8 +-- .../Install-IcingaFrameworkPlugins.psm1 | 12 ++-- .../Install-IcingaFrameworkService.psm1 | 10 ++-- .../Install-IcingaFrameworkUpdate.psm1 | 18 +++--- lib/core/framework/Remove-ItemSecure.psm1 | 2 +- lib/core/framework/Restart-IcingaService.psm1 | 2 +- .../Unblock-IcingaPowerShellFiles.psm1 | 4 +- .../Uninstall-IcingaFrameworkService.psm1 | 4 +- .../firewall/Disable-IcingaFirewall.psm1 | 8 +-- .../firewall/Enable-IcingaFirewall.psm1 | 6 +- .../firewall/Get-IcingaFirewallConfig.psm1 | 6 +- .../getters/Get-IcingaAgentMSIPackage.psm1 | 2 +- .../installer/Install-IcingaAgent.psm1 | 14 ++--- .../Install-IcingaAgentCertificates.psm1 | 36 ++++++------ .../installer/Uninstall-IcingaAgent.psm1 | 8 +-- .../misc/Disable-IcingaAgentFeature.psm1 | 4 +- .../misc/Enable-IcingaAgentFeature.psm1 | 4 +- .../misc/Move-IcingaAgentDefaultConfig.psm1 | 4 +- .../misc/Reset-IcingaAgentConfigFile.psm1 | 2 +- .../misc/Show-IcingaAgentObjects.psm1 | 2 +- .../misc/Start-IcingaAgentDirectorWizard.psm1 | 8 +-- .../misc/Start-IcingaAgentInstallWizard.psm1 | 28 ++++----- .../readers/Read-IcingaAgentDebugLogFile.psm1 | 2 +- .../readers/Read-IcingaAgentLogFile.psm1 | 2 +- .../setters/Set-IcingaAgentNodeName.psm1 | 2 +- .../Set-IcingaAgentServicePermission.psm1 | 2 +- .../setters/Set-IcingaAgentServiceUser.psm1 | 4 +- .../icingaagent/tests/Test-IcingaAcl.psm1 | 4 +- .../tests/Test-IcingaAgentConfig.psm1 | 2 +- .../writers/Write-IcingaAgentApiConfig.psm1 | 2 +- .../writers/Write-IcingaAgentZonesConfig.psm1 | 2 +- .../logging/Write-IcingaConsoleDebug.psm1 | 34 +++++++++++ .../logging/Write-IcingaConsoleError.psm1 | 34 +++++++++++ .../logging/Write-IcingaConsoleNotice.psm1 | 34 +++++++++++ .../logging/Write-IcingaConsoleOutput.psm1 | 58 +++++++++++++++++++ .../logging/Write-IcingaConsolePlain.psm1 | 34 +++++++++++ .../logging/Write-IcingaConsoleWarning.psm1 | 34 +++++++++++ lib/core/tools/Expand-IcingaIPv6String.psm1 | 2 +- .../tools/Get-IcingaCheckCommandConfig.psm1 | 12 ++-- .../tools/Get-IcingaNetworkInterface.psm1 | 4 +- lib/core/tools/New-IcingaCheckCommand.psm1 | 4 +- .../Remove-IcingaDirectorSelfServiceKey.psm1 | 4 +- .../Show-IcingaDirectorSelfServiceKey.psm1 | 4 +- .../Register-IcingaBackgroundDaemon.psm1 | 2 +- .../Unregister-IcingaBackgroundDaemon.psm1 | 2 +- .../Register-IcingaServiceCheck.psm1 | 2 +- ...et-IcingaRegisteredServiceCheckConfig.psm1 | 6 +- .../Show-IcingaRegisteredServiceChecks.psm1 | 4 +- .../Unregister-IcingaServiceCheck.psm1 | 2 +- lib/help/help/Get-IcingaHelpThresholds.psm1 | 2 +- lib/icinga/enums/Icinga_IcingaEnums.psm1 | 8 +++ .../exception/Exit-IcingaThrowException.psm1 | 2 +- .../plugin/Write-IcingaPluginOutput.psm1 | 2 +- .../plugin/Write-IcingaPluginPerfData.psm1 | 2 +- 59 files changed, 395 insertions(+), 159 deletions(-) create mode 100644 lib/core/logging/Write-IcingaConsoleDebug.psm1 create mode 100644 lib/core/logging/Write-IcingaConsoleError.psm1 create mode 100644 lib/core/logging/Write-IcingaConsoleNotice.psm1 create mode 100644 lib/core/logging/Write-IcingaConsoleOutput.psm1 create mode 100644 lib/core/logging/Write-IcingaConsolePlain.psm1 create mode 100644 lib/core/logging/Write-IcingaConsoleWarning.psm1 diff --git a/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 b/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 index 2e2bfaa..f4c1b85 100644 --- a/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 +++ b/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 @@ -23,30 +23,30 @@ function Get-IcingaDirectorSelfServiceTicket() { - param( - $DirectorUrl, - $ApiKey = $null - ); + param( + $DirectorUrl, + $ApiKey = $null + ); - if ([string]::IsNullOrEmpty($DirectorUrl)) { - Write-Host 'Unable to fetch host ticket. No Director url has been specified'; - return; - } + if ([string]::IsNullOrEmpty($DirectorUrl)) { + Write-IcingaConsoleError 'Unable to fetch host ticket. No Director url has been specified'; + return; + } - if ([string]::IsNullOrEmpty($ApiKey)) { - Write-Host 'Unable to fetch host ticket. No API key has been specified'; - return; - } + if ([string]::IsNullOrEmpty($ApiKey)) { + Write-IcingaConsoleError 'Unable to fetch host ticket. No API key has been specified'; + return; + } - [string]$url = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/ticket?key={0}', $ApiKey)); + [string]$url = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/ticket?key={0}', $ApiKey)); - $response = Invoke-WebRequest -Uri $url -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; + $response = Invoke-WebRequest -Uri $url -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; - if ($response.StatusCode -ne 200) { - throw $response.Content; - } + if ($response.StatusCode -ne 200) { + throw $response.Content; + } - $JsonContent = ConvertFrom-Json -InputObject $response.Content; + $JsonContent = ConvertFrom-Json -InputObject $response.Content; - return $JsonContent; + return $JsonContent; } diff --git a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 index 633a954..adcee02 100644 --- a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 +++ b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 @@ -77,7 +77,7 @@ function Register-IcingaDirectorSelfServiceHost() Set-IcingaPowerShellConfig -Path 'IcingaDirector.SelfService.ApiKey' -Value $JsonContent; - Write-Host 'Host was successfully registered within Icinga Director'; + Write-IcingaConsoleNotice 'Host was successfully registered within Icinga Director'; return $JsonContent; } diff --git a/lib/core/framework/Copy-ItemSecure.psm1 b/lib/core/framework/Copy-ItemSecure.psm1 index 3085785..f5ccb96 100644 --- a/lib/core/framework/Copy-ItemSecure.psm1 +++ b/lib/core/framework/Copy-ItemSecure.psm1 @@ -50,7 +50,7 @@ function Copy-ItemSecure() } return $TRUE; } catch { - Write-Host ([string]::Format('Failed to copy items from path "{0}" to "{1}": {2}', $Path, $Destination, $_.Exception)) -ForegroundColor Red; + Write-IcingaConsoleError -Message 'Failed to copy items from path "{0}" to "{1}": {2}' -Objects $Path, $Destination, $_.Exception; } return $FALSE; } diff --git a/lib/core/framework/Expand-IcingaZipArchive.psm1 b/lib/core/framework/Expand-IcingaZipArchive.psm1 index dfde53a..5359971 100644 --- a/lib/core/framework/Expand-IcingaZipArchive.psm1 +++ b/lib/core/framework/Expand-IcingaZipArchive.psm1 @@ -27,7 +27,7 @@ function Expand-IcingaZipArchive() ); if ((Test-Path $Path) -eq $FALSE -Or (Test-Path $Destination) -eq $FALSE) { - Write-Host 'The path to the zip archive or the destination path do not exist'; + Write-IcingaConsoleError 'The path to the zip archive or the destination path do not exist'; return $FALSE; } diff --git a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 index cdc34f1..0274a00 100644 --- a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 +++ b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 @@ -45,7 +45,7 @@ function Get-IcingaFrameworkServiceBinary() } if ([string]::IsNullOrEmpty($FrameworkServiceUrl)) { - Write-Host 'No Url to download the Icinga Service Binary from has been specified. Please try again.'; + Write-IcingaConsoleError 'No Url to download the Icinga Service Binary from has been specified. Please try again.'; return Get-IcingaFrameworkServiceBinary; } @@ -66,7 +66,7 @@ function Get-IcingaFrameworkServiceBinary() try { Invoke-WebRequest -Uri $FrameworkServiceUrl -UseBasicParsing -OutFile $ZipArchive; } catch { - Write-Host ([string]::Format('Failed to download the Icinga Service Binary from "{0}". Please try again.', $FrameworkServiceUrl)); + Write-IcingaConsoleError -Message 'Failed to download the Icinga Service Binary from "{0}". Please try again.' -Objects $FrameworkServiceUrl; return Get-IcingaFrameworkServiceBinary; } diff --git a/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 b/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 index 221aefd..bbcc6fb 100644 --- a/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 +++ b/lib/core/framework/Get-IcingaPowerShellModuleArchive.psm1 @@ -61,7 +61,7 @@ function Get-IcingaPowerShellModuleArchive() $CurrentVersion = Get-IcingaPowerShellModuleVersion $Repository; if ($null -ne $CurrentVersion -And $CurrentVersion -eq $Tag) { - Write-Host ([string]::Format('Your "{0}" is already up-to-date', $ModuleName)); + Write-IcingaConsoleNotice -Message 'Your "{0}" is already up-to-date' -Objects $ModuleName; return @{ 'DownloadUrl' = $DownloadUrl; 'Version' = $Tag; @@ -80,15 +80,15 @@ function Get-IcingaPowerShellModuleArchive() try { $DownloadDirectory = New-IcingaTemporaryDirectory; $DownloadDestination = (Join-Path -Path $DownloadDirectory -ChildPath ([string]::Format('{0}.zip', $Repository))); - Write-Host ([string]::Format('Downloading "{0}" into "{1}"', $ModuleName, $DownloadDirectory)); + Write-IcingaConsoleNotice ([string]::Format('Downloading "{0}" into "{1}"', $ModuleName, $DownloadDirectory)); Invoke-WebRequest -UseBasicParsing -Uri $DownloadUrl -OutFile $DownloadDestination; } catch { - Write-Host ([string]::Format('Failed to download "{0}" into "{1}". Starting cleanup process', $ModuleName, $DownloadDirectory)); + Write-IcingaConsoleError ([string]::Format('Failed to download "{0}" into "{1}". Starting cleanup process', $ModuleName, $DownloadDirectory)); Start-Sleep -Seconds 2; Remove-Item -Path $DownloadDirectory -Recurse -Force; - Write-Host 'Starting to re-run the download wizard'; + Write-IcingaConsoleNotice 'Starting to re-run the download wizard'; return Get-IcingaPowerShellModuleArchive -ModuleName $ModuleName -Repository $Repository; } diff --git a/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 b/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 index 7d11b40..d281c63 100644 --- a/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 @@ -13,7 +13,7 @@ function Install-IcingaFrameworkPlugins() }; } - Write-Host ([string]::Format('Installing module into "{0}"', ($Archive.Directory))); + Write-IcingaConsoleNotice ([string]::Format('Installing module into "{0}"', ($Archive.Directory))); Expand-IcingaZipArchive -Path $Archive.Archive -Destination $Archive.Directory | Out-Null; $FolderContent = Get-ChildItem -Path $Archive.Directory; @@ -26,19 +26,19 @@ function Install-IcingaFrameworkPlugins() } } - Write-Host ([string]::Format('Using content of folder "{0}" for updates', $ModuleContent)); + Write-IcingaConsoleNotice ([string]::Format('Using content of folder "{0}" for updates', $ModuleContent)); $PluginDirectory = (Join-Path -Path $Archive.ModuleRoot -ChildPath $RepositoryName); if ((Test-Path $PluginDirectory) -eq $FALSE) { - Write-Host ([string]::Format('Plugin Module Directory "{0}" is not present. Creating Directory', $PluginDirectory)); + Write-IcingaConsoleNotice ([string]::Format('Plugin Module Directory "{0}" is not present. Creating Directory', $PluginDirectory)); New-Item -Path $PluginDirectory -ItemType Directory | Out-Null; } - Write-Host 'Copying files to plugins'; + Write-IcingaConsoleNotice 'Copying files to plugins'; Copy-ItemSecure -Path (Join-Path -Path $ModuleContent -ChildPath '/*') -Destination $PluginDirectory -Recurse -Force | Out-Null; - Write-Host 'Cleaning temporary content'; + Write-IcingaConsoleNotice 'Cleaning temporary content'; Start-Sleep -Seconds 1; Remove-ItemSecure -Path $Archive.Directory -Recurse -Force | Out-Null; @@ -47,7 +47,7 @@ function Install-IcingaFrameworkPlugins() # include the plugins Use-Icinga; - Write-Host 'Icinga Plugin update has been completed'; + Write-IcingaConsoleNotice 'Icinga Plugin update has been completed'; return @{ 'PluginUrl' = $Archive.DownloadUrl diff --git a/lib/core/framework/Install-IcingaFrameworkService.psm1 b/lib/core/framework/Install-IcingaFrameworkService.psm1 index dd67ec1..1263c0f 100644 --- a/lib/core/framework/Install-IcingaFrameworkService.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkService.psm1 @@ -7,7 +7,7 @@ function Install-IcingaFrameworkService() ); if ([string]::IsNullOrEmpty($Path)) { - Write-Host 'No path specified for Framework service. Service will not be installed'; + Write-IcingaConsoleError 'No path specified for Framework service. Service will not be installed'; return; } @@ -17,10 +17,10 @@ function Install-IcingaFrameworkService() if ((Test-Path $UpdateFile)) { - Write-Host 'Updating Icinga PowerShell Service binary'; + Write-IcingaConsoleNotice 'Updating Icinga PowerShell Service binary'; if ($ServiceStatus -eq 'Running') { - Write-Host 'Stopping Icinga PowerShell service'; + Write-IcingaConsoleNotice 'Stopping Icinga PowerShell service'; Stop-IcingaService 'icingapowershell'; Start-Sleep -Seconds 1; } @@ -47,7 +47,7 @@ function Install-IcingaFrameworkService() throw ([string]::Format('Failed to install Icinga PowerShell Service: {0}{1}', $ServiceCreation.Message, $ServiceCreation.Error)); } } else { - Write-Host 'The Icinga PowerShell Service is already installed'; + Write-IcingaConsoleWarning 'The Icinga PowerShell Service is already installed'; } # This is just a hotfix to ensure we setup the service properly before assigning it to @@ -60,7 +60,7 @@ function Install-IcingaFrameworkService() Stop-IcingaService 'icingapowershell'; if ($ServiceStatus -eq 'Running') { - Write-Host 'Starting Icinga PowerShell service'; + Write-IcingaConsoleNotice 'Starting Icinga PowerShell service'; Start-IcingaService 'icingapowershell'; Start-Sleep -Seconds 1; } diff --git a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 index b2cb4ba..327efab 100644 --- a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 @@ -13,7 +13,7 @@ function Install-IcingaFrameworkUpdate() }; } - Write-Host ([string]::Format('Installing module into "{0}"', ($Archive.Directory))); + Write-IcingaConsoleNotice ([string]::Format('Installing module into "{0}"', ($Archive.Directory))); Expand-IcingaZipArchive -Path $Archive.Archive -Destination $Archive.Directory | Out-Null; $FolderContent = Get-ChildItem -Path $Archive.Directory; @@ -26,12 +26,12 @@ function Install-IcingaFrameworkUpdate() } } - Write-Host ([string]::Format('Using content of folder "{0}" for updates', $ModuleContent)); + Write-IcingaConsoleNotice ([string]::Format('Using content of folder "{0}" for updates', $ModuleContent)); $ServiceStatus = (Get-Service 'icingapowershell' -ErrorAction SilentlyContinue).Status; if ($ServiceStatus -eq 'Running') { - Write-Host 'Stopping Icinga PowerShell service'; + Write-IcingaConsoleNotice 'Stopping Icinga PowerShell service'; Stop-IcingaService 'icingapowershell'; Start-Sleep -Seconds 1; } @@ -39,13 +39,13 @@ function Install-IcingaFrameworkUpdate() $ModuleDirectory = (Join-Path -Path $Archive.ModuleRoot -ChildPath $RepositoryName); if ((Test-Path $ModuleDirectory) -eq $FALSE) { - Write-Host 'Failed to update the component. Module Root-Directory was not found'; + Write-IcingaConsoleError 'Failed to update the component. Module Root-Directory was not found'; return; } $Files = Get-ChildItem $ModuleDirectory -File '*'; - Write-Host 'Removing files from framework'; + Write-IcingaConsoleNotice 'Removing files from framework'; foreach ($ModuleFile in $Files) { Remove-ItemSecure -Path $ModuleFile -Force | Out-Null; @@ -55,7 +55,7 @@ function Install-IcingaFrameworkUpdate() Remove-ItemSecure -Path (Join-Path $ModuleDirectory -ChildPath 'lib') -Recurse -Force | Out-Null; Remove-ItemSecure -Path (Join-Path $ModuleDirectory -ChildPath 'manifests') -Recurse -Force | Out-Null; - Write-Host 'Copying new files to framework'; + Write-IcingaConsoleNotice 'Copying new files to framework'; Copy-ItemSecure -Path (Join-Path $ModuleContent -ChildPath 'doc') -Destination $ModuleDirectory -Recurse -Force | Out-Null; Copy-ItemSecure -Path (Join-Path $ModuleContent -ChildPath 'lib') -Destination $ModuleDirectory -Recurse -Force | Out-Null; Copy-ItemSecure -Path (Join-Path $ModuleContent -ChildPath 'manifests') -Destination $ModuleDirectory -Recurse -Force | Out-Null; @@ -63,16 +63,16 @@ function Install-IcingaFrameworkUpdate() Unblock-IcingaPowerShellFiles -Path $ModuleDirectory; - Write-Host 'Cleaning temporary content'; + Write-IcingaConsoleNotice 'Cleaning temporary content'; Start-Sleep -Seconds 1; Remove-ItemSecure -Path $Archive.Directory -Recurse -Force | Out-Null; - Write-Host 'Framework update has been completed. Please start a new PowerShell instance now to complete the update'; + Write-IcingaConsoleNotice 'Framework update has been completed. Please start a new PowerShell instance now to complete the update'; Test-IcingaAgent; if ($ServiceStatus -eq 'Running') { - Write-Host 'Starting Icinga PowerShell service'; + Write-IcingaConsoleNotice 'Starting Icinga PowerShell service'; Start-IcingaService 'icingapowershell'; } } diff --git a/lib/core/framework/Remove-ItemSecure.psm1 b/lib/core/framework/Remove-ItemSecure.psm1 index 6c97c90..f284c1e 100644 --- a/lib/core/framework/Remove-ItemSecure.psm1 +++ b/lib/core/framework/Remove-ItemSecure.psm1 @@ -22,7 +22,7 @@ function Remove-ItemSecure() } return $TRUE; } catch { - Write-Host ([string]::Format('Failed to remove items from path "{0}": {1}', $Path, $_.Exception)) -ForegroundColor Red; + Write-IcingaConsoleError ([string]::Format('Failed to remove items from path "{0}": {1}', $Path, $_.Exception)); } return $FALSE; } diff --git a/lib/core/framework/Restart-IcingaService.psm1 b/lib/core/framework/Restart-IcingaService.psm1 index 4fc26e7..b6166e9 100644 --- a/lib/core/framework/Restart-IcingaService.psm1 +++ b/lib/core/framework/Restart-IcingaService.psm1 @@ -5,7 +5,7 @@ function Restart-IcingaService() ); if (Get-Service $Service -ErrorAction SilentlyContinue) { - Write-Host ([string]::Format('Restarting service "{0}"', $Service)); + Write-IcingaConsoleNotice ([string]::Format('Restarting service "{0}"', $Service)); Restart-Service $Service; } } diff --git a/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 b/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 index 9f6ef5c..afa6269 100644 --- a/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 +++ b/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 @@ -5,10 +5,10 @@ function Unblock-IcingaPowerShellFiles() ); if ([string]::IsNullOrEmpty($Path)) { - Write-Host 'The specified directory was not found'; + Write-IcingaConsoleError 'The specified directory was not found'; return; } - Write-Host 'Unblocking Icinga PowerShell Files'; + Write-IcingaConsoleNotice 'Unblocking Icinga PowerShell Files'; Get-ChildItem -Path $Path -Recurse | Unblock-File; } diff --git a/lib/core/framework/Uninstall-IcingaFrameworkService.psm1 b/lib/core/framework/Uninstall-IcingaFrameworkService.psm1 index 5c703b2..8c2c689 100644 --- a/lib/core/framework/Uninstall-IcingaFrameworkService.psm1 +++ b/lib/core/framework/Uninstall-IcingaFrameworkService.psm1 @@ -7,10 +7,10 @@ function Uninstall-IcingaFrameworkService() switch ($ServiceCreation.ExitCode) { 0 { - Write-Host 'Icinga PowerShell Service was successfully removed'; + Write-IcingaConsoleNotice 'Icinga PowerShell Service was successfully removed'; } 1060 { - Write-Host 'The Icinga PowerShell Service is not installed'; + Write-IcingaConsoleWarning 'The Icinga PowerShell Service is not installed'; } Default { throw ([string]::Format('Failed to install Icinga PowerShell Service: {0}{1}', $ServiceCreation.Message, $ServiceCreation.Error)); diff --git a/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 b/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 index 749d17c..d2cafe0 100644 --- a/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 +++ b/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 @@ -9,9 +9,9 @@ function Disable-IcingaFirewall() if ($FirewallConfig.LegacyFirewall) { $Firewall = Start-IcingaProcess -Executable 'netsh' -Arguments 'advfirewall firewall delete rule name="Icinga 2 Agent Inbound by PS-Module"'; if ($Firewall.ExitCode -ne 0) { - Write-Host ([string]::Format('Failed to remove legacy firewall: {0}{1}', $Firewall.Message, $Firewall.Error)); + Write-IcingaConsoleError ([string]::Format('Failed to remove legacy firewall: {0}{1}', $Firewall.Message, $Firewall.Error)); } else { - Write-Host 'Successfully removed legacy Firewall rule'; + Write-IcingaConsoleNotice 'Successfully removed legacy Firewall rule'; } } @@ -22,9 +22,9 @@ function Disable-IcingaFirewall() if ($FirewallConfig.IcingaFirewall) { $Firewall = Start-IcingaProcess -Executable 'netsh' -Arguments 'advfirewall firewall delete rule name="Icinga Agent Inbound"'; if ($Firewall.ExitCode -ne 0) { - Write-Host ([string]::Format('Failed to remove Icinga firewall: {0}{1}', $Firewall.Message, $Firewall.Error)); + Write-IcingaConsoleError ([string]::Format('Failed to remove Icinga firewall: {0}{1}', $Firewall.Message, $Firewall.Error)); } else { - Write-Host 'Successfully removed Icinga Firewall rule'; + Write-IcingaConsoleNotice 'Successfully removed Icinga Firewall rule'; } } } diff --git a/lib/core/icingaagent/firewall/Enable-IcingaFirewall.psm1 b/lib/core/icingaagent/firewall/Enable-IcingaFirewall.psm1 index 88b353c..1f8a18c 100644 --- a/lib/core/icingaagent/firewall/Enable-IcingaFirewall.psm1 +++ b/lib/core/icingaagent/firewall/Enable-IcingaFirewall.psm1 @@ -8,7 +8,7 @@ function Enable-IcingaFirewall() $FirewallConfig = Get-IcingaFirewallConfig -NoOutput; if ($FirewallConfig.IcingaFirewall -And $Force -eq $FALSE) { - Write-Host 'Icinga Firewall is already enabled' + Write-IcingaConsoleNotice 'Icinga Firewall is already enabled' return; } @@ -28,8 +28,8 @@ function Enable-IcingaFirewall() $FirewallResult = Start-IcingaProcess -Executable 'netsh' -Arguments $FirewallRule; if ($FirewallResult.ExitCode -ne 0) { - Write-Host ([string]::Format('Failed to open Icinga firewall for port "{0}": {1}[2}', $IcingaPort, $FirewallResult.Message, $FirewallResult.Error)); + Write-IcingaConsoleError ([string]::Format('Failed to open Icinga firewall for port "{0}": {1}[2}', $IcingaPort, $FirewallResult.Message, $FirewallResult.Error)); } else { - Write-Host ([string]::Format('Successfully enabled firewall for port "{0}"', $IcingaPort)); + Write-IcingaConsoleNotice ([string]::Format('Successfully enabled firewall for port "{0}"', $IcingaPort)); } } diff --git a/lib/core/icingaagent/firewall/Get-IcingaFirewallConfig.psm1 b/lib/core/icingaagent/firewall/Get-IcingaFirewallConfig.psm1 index 6caa144..1048b88 100644 --- a/lib/core/icingaagent/firewall/Get-IcingaFirewallConfig.psm1 +++ b/lib/core/icingaagent/firewall/Get-IcingaFirewallConfig.psm1 @@ -11,7 +11,7 @@ function Get-IcingaFirewallConfig() if ($LegacyFirewall.ExitCode -eq 0) { if ($NoOutput -eq $FALSE) { - Write-Host 'Legacy firewall configuration has been detected.'; + Write-IcingaConsoleWarning 'Legacy firewall configuration has been detected.'; } $LegacyFirewallPresent = $TRUE; } @@ -20,12 +20,12 @@ function Get-IcingaFirewallConfig() if ($IcingaFirewall.ExitCode -eq 0) { if ($NoOutput -eq $FALSE) { - Write-Host 'Icinga firewall is present.'; + Write-IcingaConsoleNotice 'Icinga firewall is present.'; } $IcingaFirewallPresent = $TRUE; } else { if ($NoOutput -eq $FALSE) { - Write-Host 'Icinga firewall is not present'; + Write-IcingaConsoleError 'Icinga firewall is not present'; } } diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 index 132bfeb..580c6ff 100644 --- a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 +++ b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 @@ -60,7 +60,7 @@ function Get-IcingaAgentMSIPackage() if ($SkipDownload -eq $FALSE) { $DownloadPath = Join-Path $Env:TEMP -ChildPath $UsePackage; - Write-Host ([string]::Format('Downloading Icinga 2 Agent installer "{0}" into temp directory "{1}"', $UsePackage, $DownloadPath)); + Write-IcingaConsoleNotice ([string]::Format('Downloading Icinga 2 Agent installer "{0}" into temp directory "{1}"', $UsePackage, $DownloadPath)); Invoke-WebRequest -Uri (Join-WebPath -Path $Source -ChildPath $UsePackage) -OutFile $DownloadPath; } diff --git a/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 index 7490a12..613faa6 100644 --- a/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 +++ b/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 @@ -8,12 +8,12 @@ function Install-IcingaAgent() ); if ([string]::IsNullOrEmpty($Version)) { - Write-Host 'No Icinga Agent version specified. Skipping installation.'; + Write-IcingaConsoleError 'No Icinga Agent version specified. Skipping installation.'; return $FALSE; } if ($IcingaData.Installed -eq $TRUE -and $AllowUpdates -eq $FALSE) { - Write-Host 'The Icinga Agent is already installed on this system. To perform updates or downgrades, please add the "-AllowUpdates" argument'; + Write-IcingaConsoleWarning 'The Icinga Agent is already installed on this system. To perform updates or downgrades, please add the "-AllowUpdates" argument'; return $FALSE; } @@ -24,12 +24,12 @@ function Install-IcingaAgent() if ($Version -eq 'snapshot') { if ($IcingaData.InstallDate -ge $IcingaInstaller.LastUpdate -And [string]::IsNullOrEmpty($InstalledVersion.Snapshot) -eq $FALSE) { - Write-Host 'There is no new snapshot package available which requires to be installed.' + Write-IcingaConsoleNotice 'There is no new snapshot package available which requires to be installed.' return $FALSE; } $IcingaInstaller.Version = 'snapshot'; } elseif ($IcingaInstaller.Version -eq $InstalledVersion.Full) { - Write-Host ([string]::Format( + Write-IcingaConsoleNotice ([string]::Format( 'No installation required. Your installed version [{0}] is matching the online version [{1}]', $InstalledVersion.Full, $IcingaInstaller.Version @@ -63,7 +63,7 @@ function Install-IcingaAgent() } } - Write-Host ([string]::Format('Installing new Icinga Agent version into "{0}"', $InstallFolderMsg)); + Write-IcingaConsoleNotice ([string]::Format('Installing new Icinga Agent version into "{0}"', $InstallFolderMsg)); if ($IcingaData.Installed) { if ((Uninstall-IcingaAgent) -eq $FALSE) { @@ -74,10 +74,10 @@ function Install-IcingaAgent() $InstallProcess = Start-IcingaProcess -Executable 'MsiExec.exe' -Arguments ([string]::Format('/quiet /i "{0}" {1}', $IcingaInstaller.InstallerPath, $InstallTarget)) -FlushNewLines; if ($InstallProcess.ExitCode -ne 0) { - Write-Host ([string]::Format('Failed to install Icinga 2 Agent: {0}{1}', $InstallProcess.Message, $InstallProcess.Error)); + Write-IcingaConsoleError -Message 'Failed to install Icinga 2 Agent: {0}{1}' -Objects $InstallProcess.Message, $InstallProcess.Error; return $FALSE; } - Write-Host 'Icinga Agent was successfully installed'; + Write-IcingaConsoleNotice 'Icinga Agent was successfully installed'; return $TRUE; } diff --git a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 index 5a13f55..a82538d 100644 --- a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 +++ b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 @@ -26,7 +26,7 @@ function Install-IcingaAgentCertificates() } if (-Not (Test-IcingaAgentCertificates -CertDirectory $CertificateDirectory -Hostname $Hostname -Force $Force)) { - Write-Host ([string]::Format('Generating host certificates for host "{0}"', $Hostname)); + Write-IcingaConsoleNotice ([string]::Format('Generating host certificates for host "{0}"', $Hostname)); $arguments = [string]::Format('pki new-cert --cn {0} --key {1}{0}.key --cert {1}{0}.crt', $Hostname, @@ -39,14 +39,14 @@ function Install-IcingaAgentCertificates() } if ([string]::IsNullOrEmpty($Endpoint) -And [string]::IsNullOrEmpty($CACert)) { - Write-Host 'Your host certificates have been generated successfully. Please either specify an endpoint to connect to or provide the path to a valid ca.crt.'; + Write-IcingaConsoleNotice 'Your host certificates have been generated successfully. Please either specify an endpoint to connect to or provide the path to a valid ca.crt.'; return $TRUE; } if (-Not [string]::IsNullOrEmpty($Endpoint)) { if (-Not (Test-IcingaAgentCertificates -CertDirectory $CertificateDirectory -Hostname $Hostname -TestTrustedParent -Force $Force)) { - Write-Host ([string]::Format('Fetching trusted master certificate from "{0}"', $Endpoint)); + Write-IcingaConsoleNotice ([string]::Format('Fetching trusted master certificate from "{0}"', $Endpoint)); # Argument --key for save-cert is deprecated starting with Icinga 2.12.0 if (Compare-IcingaVersions -RequiredVersion '2.12.0') { @@ -65,7 +65,7 @@ function Install-IcingaAgentCertificates() } if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) { - Write-Host 'Unable to connect to your provided Icinga CA. Please verify the entered configuration is correct.' ` + Write-IcingaConsoleError 'Unable to connect to your provided Icinga CA. Please verify the entered configuration is correct.' ` 'If you are not able to connect to your Icinga CA from this machine, you will have to provide the path' ` 'to your Icinga ca.crt and use the CA-Proxy certificate handling.'; return $TRUE; @@ -92,9 +92,9 @@ function Install-IcingaAgentCertificates() } if ([string]::IsNullOrEmpty($Ticket)) { - Write-Host 'Your certificates were generated successfully. Please sign the certificate now on your Icinga CA master. You can lookup open requests with "icinga2 ca list"'; + Write-IcingaConsoleNotice 'Your certificates were generated successfully. Please sign the certificate now on your Icinga CA master. You can lookup open requests with "icinga2 ca list"'; } else { - Write-Host 'Icinga certificates successfully installed'; + Write-IcingaConsoleNotice 'Icinga certificates successfully installed'; } } @@ -103,7 +103,7 @@ function Install-IcingaAgentCertificates() if (-Not (Copy-IcingaAgentCACertificate -CAPath $CACert -Desination $CertificateDirectory)) { return $FALSE; } - Write-Host 'Host-Certificates and ca.crt are present. Please start your Icinga Agent now and manually sign your certificate request on your CA master. You can lookup open requests with "icinga2 ca list"'; + Write-IcingaConsoleNotice 'Host-Certificates and ca.crt are present. Please start your Icinga Agent now and manually sign your certificate request on your CA master. You can lookup open requests with "icinga2 ca list"'; } return $TRUE; @@ -119,11 +119,11 @@ function Start-IcingaAgentCertificateProcess() $Process = Start-IcingaProcess -Executable $Binary -Arguments $Arguments; if ($Process.ExitCode -ne 0) { - Write-Host ([string]::Format('Failed to create certificate.{0}Arguments: {1}{0}Error:{2} {3}', "`r`n", $Arguments, $Process.Message, $Process.Error)); + Write-IcingaConsoleError ([string]::Format('Failed to create certificate.{0}Arguments: {1}{0}Error:{2} {3}', "`r`n", $Arguments, $Process.Message, $Process.Error)); return $FALSE; } - Write-Host $Process.Message; + Write-IcingaConsoleNotice $Process.Message; return $TRUE; } @@ -156,20 +156,20 @@ function Test-IcingaAgentCertificates() if ($TestCACert) { if (Test-Path (Join-Path -Path $CertDirectory -ChildPath 'ca.crt')) { - Write-Host 'Your ca.crt is present. No generation or fetching required'; + Write-IcingaConsoleNotice 'Your ca.crt is present. No generation or fetching required'; return $TRUE; } else { - Write-Host 'Your ca.crt is not present. Manuall copy or fetching from your Icinga CA is required.'; + Write-IcingaConsoleWarning 'Your ca.crt is not present. Manuall copy or fetching from your Icinga CA is required.'; return $FALSE; } } if ($TestTrustedParent) { if (Test-Path (Join-Path -Path $CertDirectory -ChildPath 'trusted-parent.crt')) { - Write-Host 'Your trusted-parent.crt is present. No fetching or generation required'; + Write-IcingaConsoleNotice 'Your trusted-parent.crt is present. No fetching or generation required'; return $TRUE; } else { - Write-Host 'Your trusted master certificate is not present. Fetching from your CA server is required'; + Write-IcingaConsoleWarning 'Your trusted master certificate is not present. Fetching from your CA server is required'; return $FALSE; } } @@ -188,13 +188,13 @@ function Test-IcingaAgentCertificates() if ($cert.Name.toLower() -eq $hostCRT.toLower() -Or $cert.Name.toLower() -eq $hostKEY.toLower()) { $file = $cert.Name.Replace('.key', '').Replace('.crt', ''); if (-Not ($file -clike $Hostname)) { - Write-Host ([string]::Format('Certificate file {0} is not matching the hostname {1}. Certificate generation is required.', $cert.Name, $Hostname)); + Write-IcingaConsoleWarning ([string]::Format('Certificate file {0} is not matching the hostname {1}. Certificate generation is required.', $cert.Name, $Hostname)); return $FALSE; } } } - Write-Host 'Icinga host certificates are present and valid. No generation required.'; + Write-IcingaConsoleNotice 'Icinga host certificates are present and valid. No generation required.'; return $TRUE; } @@ -209,7 +209,7 @@ function Copy-IcingaAgentCACertificate() # Copy ca.crt from local path or network share to certificate path if ((Test-Path $CAPath)) { Copy-Item -Path $CAPath -Destination (Join-Path -Path $Desination -ChildPath 'ca.crt') | Out-Null; - Write-Host ([string]::Format('Copied ca.crt from "{0}" to "{1}', $CAPath, $Desination)); + Write-IcingaConsoleNotice ([string]::Format('Copied ca.crt from "{0}" to "{1}', $CAPath, $Desination)); } else { # It could also be a web ressource try { @@ -221,9 +221,9 @@ function Copy-IcingaAgentCACertificate() $response.RawContent.Length - $Index ); Set-Content -Path (Join-Path $Desination -ChildPath 'ca.crt') -Value $CAContent; - Write-Host ([string]::Format('Downloaded ca.crt from "{0}" to "{1}', $CAPath, $Desination)) + Write-IcingaConsoleNotice ([string]::Format('Downloaded ca.crt from "{0}" to "{1}', $CAPath, $Desination)) } catch { - Write-Host 'Failed to load any provided ca.crt ressource'; + Write-IcingaConsoleError 'Failed to load any provided ca.crt ressource'; return $FALSE; } } diff --git a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 index cb99f8f..4fc8088 100644 --- a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 +++ b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 @@ -3,21 +3,21 @@ function Uninstall-IcingaAgent() $IcingaData = Get-IcingaAgentInstallation; if ($IcingaData.Installed -eq $FALSE) { - Write-Host 'Unable to uninstall the Icinga Agent. The Agent is not installed'; + Write-IcingaConsoleError 'Unable to uninstall the Icinga Agent. The Agent is not installed'; return; } - Write-Host 'Removing current installed Icinga Agent'; + Write-IcingaConsoleNotice 'Removing current installed Icinga Agent'; Stop-IcingaService 'icinga2'; $Uninstaller = Start-IcingaProcess -Executable 'MsiExec.exe' -Arguments ([string]::Format('{0} /q', $IcingaData.Uninstaller)) -FlushNewLine; if ($Uninstaller.ExitCode -ne 0) { - Write-Host ([string]::Format('Failed to remove Icinga 2 Agent: {0}{1}', $Uninstaller.Message, $Uninstaller.Error)); + Write-IcingaConsoleError ([string]::Format('Failed to remove Icinga 2 Agent: {0}{1}', $Uninstaller.Message, $Uninstaller.Error)); return $FALSE; } - Write-Host 'Icinga Agent was successfully removed'; + Write-IcingaConsoleNotice 'Icinga Agent was successfully removed'; return $TRUE; } diff --git a/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 index 983c340..4df1806 100644 --- a/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 +++ b/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 @@ -9,7 +9,7 @@ function Disable-IcingaAgentFeature() } if ((Test-IcingaAgentFeatureEnabled -Feature $Feature) -eq $FALSE) { - Write-Host ([string]::Format('This feature is already disabled [{0}]', $Feature)); + Write-IcingaConsoleWarning ([string]::Format('This feature is already disabled [{0}]', $Feature)); return; } @@ -20,5 +20,5 @@ function Disable-IcingaAgentFeature() throw ([string]::Format('Failed to disable Icinga Feature: {0}', $Process.Message)); } - Write-Host ([string]::Format('Feature "{0}" was successfully disabled', $Feature)); + Write-IcingaConsoleNotice ([string]::Format('Feature "{0}" was successfully disabled', $Feature)); } diff --git a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 index 6721a61..beebc19 100644 --- a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 +++ b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 @@ -9,7 +9,7 @@ function Enable-IcingaAgentFeature() } if ((Test-IcingaAgentFeatureEnabled -Feature $Feature)) { - Write-Host ([string]::Format('This feature is already enabled [{0}]', $Feature)); + Write-IcingaConsoleWarning ([string]::Format('This feature is already enabled [{0}]', $Feature)); return; } @@ -20,5 +20,5 @@ function Enable-IcingaAgentFeature() throw ([string]::Format('Failed to enable Icinga Feature: {0}', $Process.Message)); } - Write-Host ([string]::Format('Feature "{0}" was successfully enabled', $Feature)); + Write-IcingaConsoleNotice ([string]::Format('Feature "{0}" was successfully enabled', $Feature)); } diff --git a/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 b/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 index 076761a..0a5f940 100644 --- a/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 +++ b/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 @@ -4,7 +4,7 @@ function Move-IcingaAgentDefaultConfig() $BackupFile = Join-Path -Path $ConfigDir -ChildPath 'ps_backup\backup_executed.key'; if ((Test-Path $BackupFile)) { - Write-Host 'A backup of your default configuration is not required. A backup was already made.'; + Write-IcingaConsoleNotice 'A backup of your default configuration is not required. A backup was already made.'; return; } @@ -19,5 +19,5 @@ function Move-IcingaAgentDefaultConfig() New-Item (Join-Path -Path $ConfigDir -ChildPath 'zones.conf') -ItemType File | Out-Null; New-Item -Path $BackupFile -ItemType File | Out-Null; - Write-Host 'Successfully backed up Icinga 2 Agent default config'; + Write-IcingaConsoleNotice 'Successfully backed up Icinga 2 Agent default config'; } diff --git a/lib/core/icingaagent/misc/Reset-IcingaAgentConfigFile.psm1 b/lib/core/icingaagent/misc/Reset-IcingaAgentConfigFile.psm1 index a51a005..43a7590 100644 --- a/lib/core/icingaagent/misc/Reset-IcingaAgentConfigFile.psm1 +++ b/lib/core/icingaagent/misc/Reset-IcingaAgentConfigFile.psm1 @@ -22,7 +22,7 @@ function Reset-IcingaAgentConfigFile() $OriginalConfig = Join-Path -Path $ConfigDir -ChildPath 'icinga2.confdirector.bak'; if ((Test-Path $OriginalConfig)) { - Write-Host 'Found icinga2.conf backup file created by old PowerShell module. Restoring original configuration'; + Write-IcingaConsoleWarning 'Found icinga2.conf backup file created by old PowerShell module. Restoring original configuration'; Move-Item -Path $OldConfig -Destination $OldConfigBackup; Move-Item -Path $OriginalConfig -Destination $OldConfig; diff --git a/lib/core/icingaagent/misc/Show-IcingaAgentObjects.psm1 b/lib/core/icingaagent/misc/Show-IcingaAgentObjects.psm1 index 07f4aae..b53bdaf 100644 --- a/lib/core/icingaagent/misc/Show-IcingaAgentObjects.psm1 +++ b/lib/core/icingaagent/misc/Show-IcingaAgentObjects.psm1 @@ -4,7 +4,7 @@ function Show-IcingaAgentObjects() $Output = Start-IcingaProcess -Executable $Binary -Arguments 'object list'; if ($Output.ExitCode -ne 0) { - Write-Host ([string]::Format('Failed to fetch Icinga Agent objects list: {0}{1}', $Output.Message, $Output.Error)); + Write-IcingaConsoleError ([string]::Format('Failed to fetch Icinga Agent objects list: {0}{1}', $Output.Message, $Output.Error)); return $null; } diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 index e7cb29f..d77faf0 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 @@ -57,7 +57,7 @@ function Start-IcingaAgentDirectorWizard() try { $Arguments = Get-IcingaDirectorSelfServiceConfig -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey; } catch { - Write-Host ([string]::Format('Failed to connect to your Icinga Director at "{0}". Please try again', $DirectorUrl)); + Write-IcingaConsoleError ([string]::Format('Failed to connect to your Icinga Director at "{0}". Please try again', $DirectorUrl)); return Start-IcingaAgentDirectorWizard ` -SelfServiceAPIKey ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Please re-enter your SelfService API Key for the Host-Template in case the key is no longer assigned to your host' -Default 'v' -DefaultInput $SelfServiceAPIKey).answer) ` @@ -88,7 +88,7 @@ function Start-IcingaAgentDirectorWizard() # Host is already registered if ($null -eq $SelfServiceAPIKey) { - Write-Host 'The wizard is unable to complete as this host is already registered but the local API key is not stored within the config' + Write-IcingaConsoleError 'The wizard is unable to complete as this host is already registered but the local API key is not stored within the config' return; } @@ -135,8 +135,8 @@ function Start-IcingaDirectorAPIArgumentOverride() ); $NewArguments = @{}; - Write-Host 'Please follow the wizard and manually override all entries you intend to'; - Write-Host '===='; + Write-IcingaConsoleNotice 'Please follow the wizard and manually override all entries you intend to'; + Write-IcingaConsoleNotice '===='; foreach ($entry in $Arguments.Keys) { $value = (Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Please enter the new value for the argument "{0}"', $entry)) -Default 'v' -DefaultInput $Arguments[$entry]).answer; diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 81e3551..ea33ddf 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -171,7 +171,7 @@ function Start-IcingaAgentInstallWizard() } } - Write-Host ([string]::Format('Using hostname "{0}" for the Icinga 2 Agent configuration', $Hostname)); + Write-IcingaConsoleNotice ([string]::Format('Using hostname "{0}" for the Icinga 2 Agent configuration', $Hostname)); $IcingaAgent = Get-IcingaAgentInstallation; if ($IcingaAgent.Installed -eq $FALSE) { @@ -185,7 +185,7 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += "-PackageSource '$PackageSource'"; } - Write-Host ([string]::Format('Using package source "{0}" for the Icinga 2 Agent package', $PackageSource)); + Write-IcingaConsoleNotice ([string]::Format('Using package source "{0}" for the Icinga 2 Agent package', $PackageSource)); $AllowVersionChanges = $TRUE; $InstallerArguments += '-AllowVersionChanges 1'; @@ -193,7 +193,7 @@ function Start-IcingaAgentInstallWizard() $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v' -DefaultInput 'latest').answer; $InstallerArguments += "-AgentVersion '$AgentVersion'"; - Write-Host ([string]::Format('Installing Icinga Version: "{0}"', $AgentVersion)); + Write-IcingaConsoleNotice ([string]::Format('Installing Icinga Version: "{0}"', $AgentVersion)); } } else { $AllowVersionChanges = $FALSE; @@ -221,7 +221,7 @@ function Start-IcingaAgentInstallWizard() $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v').answer; $InstallerArguments += "-AgentVersion '$AgentVersion'"; - Write-Host ([string]::Format('Updating/Downgrading Icinga 2 Agent to version: "{0}"', $AgentVersion)); + Write-IcingaConsoleNotice ([string]::Format('Updating/Downgrading Icinga 2 Agent to version: "{0}"', $AgentVersion)); } if ([string]::IsNullOrEmpty($PackageSource)) { @@ -456,23 +456,23 @@ function Start-IcingaAgentInstallWizard() if ($InstallerArguments.Count -ne 0) { $InstallerArguments += "-RunInstaller"; - Write-Host 'The wizard is complete. These are the configured settings:'; + Write-IcingaConsoleNotice 'The wizard is complete. These are the configured settings:'; - Write-Host '========' - Write-Host ($InstallerArguments | Out-String); - Write-Host '========' + Write-IcingaConsolePlain '========'; + Write-IcingaConsolePlain ($InstallerArguments | Out-String); + Write-IcingaConsolePlain '========'; if (-Not $RunInstaller) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this configuration correct?' -Default 'y').result -eq 1) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to run the installer now? (Otherwise only the configuration command will be printed)' -Default 'y').result -eq 1) { - Write-Host 'To execute your Icinga Agent installation based on your answers again on this or another machine, simply run this command:' + Write-IcingaConsoleNotice 'To execute your Icinga Agent installation based on your answers again on this or another machine, simply run this command:'; $RunInstaller = $TRUE; } else { - Write-Host 'To execute your Icinga Agent installation based on your answers, simply run this command:' + Write-IcingaConsoleNotice 'To execute your Icinga Agent installation based on your answers, simply run this command:'; } } else { - Write-Host 'Please run the wizard again to modify your answers or modify the command below:' + Write-IcingaConsoleNotice 'Please run the wizard again to modify your answers or modify the command below:'; } } Get-IcingaAgentInstallCommand -InstallerArguments $InstallerArguments -PrintConsole; @@ -681,9 +681,9 @@ function Get-IcingaAgentInstallCommand() ); if ($PrintConsole) { - Write-Host '====' - Write-Host $Installer -ForegroundColor ([System.ConsoleColor]::Cyan); - Write-Host '====' + Write-IcingaConsolePlain '====' + Write-IcingaConsolePlain $Installer; + Write-IcingaConsolePlain '====' } else { return $Installer; } diff --git a/lib/core/icingaagent/readers/Read-IcingaAgentDebugLogFile.psm1 b/lib/core/icingaagent/readers/Read-IcingaAgentDebugLogFile.psm1 index 992fb43..139dfe6 100644 --- a/lib/core/icingaagent/readers/Read-IcingaAgentDebugLogFile.psm1 +++ b/lib/core/icingaagent/readers/Read-IcingaAgentDebugLogFile.psm1 @@ -2,7 +2,7 @@ function Read-IcingaAgentDebugLogFile() { $Logfile = Join-Path -Path (Get-IcingaAgentLogDirectory) -ChildPath 'debug.log'; if ((Test-Path $Logfile) -eq $FALSE) { - Write-Host 'Icinga 2 debug logfile not present. Unable to load it'; + Write-IcingaConsoleError 'Icinga 2 debug logfile not present. Unable to load it'; return; } diff --git a/lib/core/icingaagent/readers/Read-IcingaAgentLogFile.psm1 b/lib/core/icingaagent/readers/Read-IcingaAgentLogFile.psm1 index 8ce56bf..a277265 100644 --- a/lib/core/icingaagent/readers/Read-IcingaAgentLogFile.psm1 +++ b/lib/core/icingaagent/readers/Read-IcingaAgentLogFile.psm1 @@ -2,7 +2,7 @@ function Read-IcingaAgentLogFile() { $Logfile = Join-Path -Path (Get-IcingaAgentLogDirectory) -ChildPath 'icinga2.log'; if ((Test-Path $Logfile) -eq $FALSE) { - Write-Host 'Icinga 2 logfile not present. Unable to load it'; + Write-IcingaConsoleError 'Icinga 2 logfile not present. Unable to load it'; return; } diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentNodeName.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentNodeName.psm1 index 4956b41..6262823 100644 --- a/lib/core/icingaagent/setters/Set-IcingaAgentNodeName.psm1 +++ b/lib/core/icingaagent/setters/Set-IcingaAgentNodeName.psm1 @@ -31,5 +31,5 @@ function Set-IcingaAgentNodeName() Set-Content -Path $ConstantsConf -Value $ConfigContent; - Write-Host ([string]::Format('Your hostname was successfully changed to "{0}"', $Hostname)); + Write-IcingaConsoleNotice ([string]::Format('Your hostname was successfully changed to "{0}"', $Hostname)); } diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 index a166b26..ff38c78 100644 --- a/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 +++ b/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 @@ -1,7 +1,7 @@ function Set-IcingaAgentServicePermission() { if (Test-IcingaAgentServicePermission -Silent) { - Write-Host 'The Icinga Service User already has permission to run as service'; + Write-IcingaConsoleNotice 'The Icinga Service User already has permission to run as service'; return; } diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 index 5c1ef0b..c4d79e2 100644 --- a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 +++ b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 @@ -32,10 +32,10 @@ function Set-IcingaAgentServiceUser() Set-IcingaUserPermissions; } - Write-Host 'Service User successfully updated' + Write-IcingaConsoleNotice 'Service User successfully updated' return $TRUE; } else { - Write-Host ([string]::Format('Failed to update the service user: {0}', $Output.Message)); + Write-IcingaConsoleError ([string]::Format('Failed to update the service user: {0}', $Output.Message)); return $FALSE; } } diff --git a/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 b/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 index b69cb3c..249e7a3 100644 --- a/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 +++ b/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 @@ -41,11 +41,11 @@ function Test-IcingaAcl() Write-IcingaTestOutput -Severity 'PASSED' -Message ([string]::Format($messageFormat, $Directory, 'is accessible and writeable', $ServiceUser)); } else { Write-IcingaTestOutput -Severity 'FAILED' -Message ([string]::Format($messageFormat, $Directory, 'is accessible but NOT writeable', $ServiceUser)); - Write-Host "\_ Please run the following command to fix this issue: Set-IcingaAcl -Directory '$Directory'"; + Write-IcingaConsolePlain "\_ Please run the following command to fix this issue: Set-IcingaAcl -Directory '$Directory'"; } } else { Write-IcingaTestOutput -Severity 'FAILED' -Message ([string]::Format($messageFormat, $Directory, 'is not accessible', $ServiceUser)); - Write-Host "\_ Please run the following command to fix this issue: Set-IcingaAcl -Directory '$Directory'"; + Write-IcingaConsolePlain "\_ Please run the following command to fix this issue: Set-IcingaAcl -Directory '$Directory'"; } } diff --git a/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 index 42b78a6..3dc55ab 100644 --- a/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 +++ b/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 @@ -13,7 +13,7 @@ function Test-IcingaAgentConfig() } else { Write-IcingaTestOutput -Severity 'FAILED' -Message 'Icinga Agent configuration is containing errors. Run this command for getting a detailed error report: "Test-IcingaAgentConfig -WriteStackTrace | Out-Null"'; if ($WriteStackTrace) { - Write-Host $ConfigResult.Message; + Write-IcingaConsolePlain $ConfigResult.Message; } return $FALSE; } diff --git a/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 b/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 index 50a235f..0d51505 100644 --- a/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 +++ b/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 @@ -16,5 +16,5 @@ function Write-IcingaAgentApiConfig() $ApiConf = $ApiConf.Substring(0, $ApiConf.Length - 4); Set-Content -Path (Join-Path -Path (Get-IcingaAgentConfigDirectory) -ChildPath 'features-available\api.conf') -Value $ApiConf; - Write-Host 'Api configuration has been written successfully'; + Write-IcingaConsoleNotice 'Api configuration has been written successfully'; } diff --git a/lib/core/icingaagent/writers/Write-IcingaAgentZonesConfig.psm1 b/lib/core/icingaagent/writers/Write-IcingaAgentZonesConfig.psm1 index 4729226..bd0ff6f 100644 --- a/lib/core/icingaagent/writers/Write-IcingaAgentZonesConfig.psm1 +++ b/lib/core/icingaagent/writers/Write-IcingaAgentZonesConfig.psm1 @@ -74,5 +74,5 @@ function Write-IcingaAgentZonesConfig() $ZonesConf = $ZonesConf.Substring(0, $ZonesConf.Length - 4); Set-Content -Path (Join-Path -Path (Get-IcingaAgentConfigDirectory) -ChildPath 'zones.conf') -Value $ZonesConf; - Write-Host 'Icinga Agent zones.conf has been written successfully'; + Write-IcingaConsoleNotice 'Icinga Agent zones.conf has been written successfully'; } diff --git a/lib/core/logging/Write-IcingaConsoleDebug.psm1 b/lib/core/logging/Write-IcingaConsoleDebug.psm1 new file mode 100644 index 0000000..717d950 --- /dev/null +++ b/lib/core/logging/Write-IcingaConsoleDebug.psm1 @@ -0,0 +1,34 @@ +<# +.SYNOPSIS + Default Cmdlet for printing debug messages to console +.DESCRIPTION + Default Cmdlet for printing debug messages to console +.FUNCTIONALITY + Default Cmdlet for printing debug messages to console +.EXAMPLE + PS>Write-IcingaConsoleDebug -Message 'Test message: {0}' -Objects 'Hello World'; +.PARAMETER Message + The message to print with {x} placeholdes replaced by content inside the Objects array. Replace x with the + number of the index from the objects array +.PARAMETER Objects + An array of objects being added to a provided message. The index of the array position has to refer to the + message locations. +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Write-IcingaConsoleDebug() +{ + param ( + [string]$Message, + [array]$Objects + ); + + Write-IcingaConsoleOutput ` + -Message $Message ` + -Objects $Objects ` + -ForeColor 'Blue' ` + -Severity 'Debug'; +} diff --git a/lib/core/logging/Write-IcingaConsoleError.psm1 b/lib/core/logging/Write-IcingaConsoleError.psm1 new file mode 100644 index 0000000..895a6b1 --- /dev/null +++ b/lib/core/logging/Write-IcingaConsoleError.psm1 @@ -0,0 +1,34 @@ +<# +.SYNOPSIS + Default Cmdlet for printing error messages to console +.DESCRIPTION + Default Cmdlet for printing error messages to console +.FUNCTIONALITY + Default Cmdlet for printing error messages to console +.EXAMPLE + PS>Write-IcingaConsoleError -Message 'Test message: {0}' -Objects 'Hello World'; +.PARAMETER Message + The message to print with {x} placeholdes replaced by content inside the Objects array. Replace x with the + number of the index from the objects array +.PARAMETER Objects + An array of objects being added to a provided message. The index of the array position has to refer to the + message locations. +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Write-IcingaConsoleError() +{ + param ( + [string]$Message, + [array]$Objects + ); + + Write-IcingaConsoleOutput ` + -Message $Message ` + -Objects $Objects ` + -ForeColor 'Red' ` + -Severity 'Error'; +} diff --git a/lib/core/logging/Write-IcingaConsoleNotice.psm1 b/lib/core/logging/Write-IcingaConsoleNotice.psm1 new file mode 100644 index 0000000..44939fa --- /dev/null +++ b/lib/core/logging/Write-IcingaConsoleNotice.psm1 @@ -0,0 +1,34 @@ +<# +.SYNOPSIS + Default Cmdlet for printing notice messages to console +.DESCRIPTION + Default Cmdlet for printing notice messages to console +.FUNCTIONALITY + Default Cmdlet for printing notice messages to console +.EXAMPLE + PS>Write-IcingaConsoleNotice -Message 'Test message: {0}' -Objects 'Hello World'; +.PARAMETER Message + The message to print with {x} placeholdes replaced by content inside the Objects array. Replace x with the + number of the index from the objects array +.PARAMETER Objects + An array of objects being added to a provided message. The index of the array position has to refer to the + message locations. +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Write-IcingaConsoleNotice() +{ + param ( + [string]$Message, + [array]$Objects + ); + + Write-IcingaConsoleOutput ` + -Message $Message ` + -Objects $Objects ` + -ForeColor 'Green' ` + -Severity 'Notice'; +} diff --git a/lib/core/logging/Write-IcingaConsoleOutput.psm1 b/lib/core/logging/Write-IcingaConsoleOutput.psm1 new file mode 100644 index 0000000..6a51bdc --- /dev/null +++ b/lib/core/logging/Write-IcingaConsoleOutput.psm1 @@ -0,0 +1,58 @@ +<# +.SYNOPSIS + Standardise console output and make handling of object conversion easier into messages + by using this standard function for displaying severity and log entries +.DESCRIPTION + Standardised function to output console messages controlled by the arguments provided + for coloring, displaying severity and add objects into output messages +.FUNCTIONALITY + Standardise console output and make handling of object conversion easier into messages + by using this standard function for displaying severity and log entries +.EXAMPLE + PS>Write-IcingaConsoleOutput -Message 'Test message: {0}' -Objects 'Hello World' -ForeColor 'Green' -Severity 'Test'; +.PARAMETER Message + The message to print with {x} placeholdes replaced by content inside the Objects array. Replace x with the + number of the index from the objects array +.PARAMETER Objects + An array of objects being added to a provided message. The index of the array position has to refer to the + message locations. +.PARAMETER ForeColor + The color the severity name will be displayed in +.PARAMETER Severity + The severity being displayed before the actual message. Leave empty to skip. +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Write-IcingaConsoleOutput() +{ + param ( + [string]$Message, + [array]$Objects, + [ValidateSet('Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')] + [string]$ForeColor = 'White', + [string]$Severity = 'Notice' + ); + + $OutputMessage = $Message; + [int]$Index = 0; + + foreach ($entry in $Objects) { + + $OutputMessage = $OutputMessage.Replace( + [string]::Format('{0}{1}{2}', '{', $Index, '}'), + $entry + ); + $Index++; + } + + if ([string]::IsNullOrEmpty($Severity) -eq $FALSE) { + Write-Host '[' -NoNewline; + Write-Host $Severity -NoNewline -ForegroundColor $ForeColor; + Write-Host ']: ' -NoNewline; + } + + Write-Host $OutputMessage; +} diff --git a/lib/core/logging/Write-IcingaConsolePlain.psm1 b/lib/core/logging/Write-IcingaConsolePlain.psm1 new file mode 100644 index 0000000..35c1de7 --- /dev/null +++ b/lib/core/logging/Write-IcingaConsolePlain.psm1 @@ -0,0 +1,34 @@ +<# +.SYNOPSIS + Default Cmdlet for printing plain messages to console +.DESCRIPTION + Default Cmdlet for printing plain messages to console +.FUNCTIONALITY + Default Cmdlet for printing plain messages to console +.EXAMPLE + PS>Write-IcingaConsolePlain -Message 'Test message: {0}' -Objects 'Hello World'; +.PARAMETER Message + The message to print with {x} placeholdes replaced by content inside the Objects array. Replace x with the + number of the index from the objects array +.PARAMETER Objects + An array of objects being added to a provided message. The index of the array position has to refer to the + message locations. +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Write-IcingaConsolePlain() +{ + param ( + [string]$Message, + [array]$Objects + ); + + Write-IcingaConsoleOutput ` + -Message $Message ` + -Objects $Objects ` + -ForeColor 'Blue' ` + -Severity $null; +} diff --git a/lib/core/logging/Write-IcingaConsoleWarning.psm1 b/lib/core/logging/Write-IcingaConsoleWarning.psm1 new file mode 100644 index 0000000..b7f7097 --- /dev/null +++ b/lib/core/logging/Write-IcingaConsoleWarning.psm1 @@ -0,0 +1,34 @@ +<# +.SYNOPSIS + Default Cmdlet for printing warning messages to console +.DESCRIPTION + Default Cmdlet for printing warning messages to console +.FUNCTIONALITY + Default Cmdlet for printing warning messages to console +.EXAMPLE + PS>Write-IcingaConsoleWarning -Message 'Test message: {0}' -Objects 'Hello World'; +.PARAMETER Message + The message to print with {x} placeholdes replaced by content inside the Objects array. Replace x with the + number of the index from the objects array +.PARAMETER Objects + An array of objects being added to a provided message. The index of the array position has to refer to the + message locations. +.INPUTS + System.String +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + +function Write-IcingaConsoleWarning() +{ + param ( + [string]$Message, + [array]$Objects + ); + + Write-IcingaConsoleOutput ` + -Message $Message ` + -Objects $Objects ` + -ForeColor 'Yellow' ` + -Severity 'Warning'; +} diff --git a/lib/core/tools/Expand-IcingaIPv6String.psm1 b/lib/core/tools/Expand-IcingaIPv6String.psm1 index 8637b89..423a7ed 100644 --- a/lib/core/tools/Expand-IcingaIPv6String.psm1 +++ b/lib/core/tools/Expand-IcingaIPv6String.psm1 @@ -41,7 +41,7 @@ function Expand-IcingaIPv6String() } if ($RelV -lt 0 -and $Counter -ne 7) { - Write-Host "Invalid IP was provided!"; + Write-IcingaConsoleError "Invalid IP was provided!"; return $null; } diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 8e52e0f..668c4fc 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -320,19 +320,19 @@ function Get-IcingaCheckCommandConfig() Set-Content -Path $OutDirectory -Value $output; # Output-Text - Write-Host "The following commands have been exported:" + Write-IcingaConsoleNotice "The following commands have been exported:" foreach ($check in $CheckName) { - Write-Host "- '$check'"; + Write-IcingaConsoleNotice "- '$check'"; } - Write-Host "JSON export created in '${OutDirectory}'" + Write-IcingaConsoleNotice "JSON export created in '${OutDirectory}'" return; } - Write-Host "Check Command JSON for the following commands:" + Write-IcingaConsoleNotice "Check Command JSON for the following commands:" foreach ($check in $CheckName) { - Write-Host "- '$check'" + Write-IcingaConsoleNotice "- '$check'" } - Write-Host '############################################################'; + Write-IcingaConsoleNotice '############################################################'; return $output; } diff --git a/lib/core/tools/Get-IcingaNetworkInterface.psm1 b/lib/core/tools/Get-IcingaNetworkInterface.psm1 index ad72151..7fa0d7b 100644 --- a/lib/core/tools/Get-IcingaNetworkInterface.psm1 +++ b/lib/core/tools/Get-IcingaNetworkInterface.psm1 @@ -32,14 +32,14 @@ function Get-IcingaNetworkInterface() ); if ([string]::IsNullOrEmpty($IP)) { - Write-Host 'Please specify a valid IP-Address or FQDN'; + Write-IcingaConsoleError 'Please specify a valid IP-Address or FQDN'; return $null; } try { [array]$IP = ([System.Net.Dns]::GetHostAddresses($IP)).IPAddressToString; } catch { - Write-Host 'Invalid IP was provided!'; + Write-IcingaConsoleError 'Invalid IP was provided!'; return $null; } diff --git a/lib/core/tools/New-IcingaCheckCommand.psm1 b/lib/core/tools/New-IcingaCheckCommand.psm1 index ddee00c..042c5b7 100644 --- a/lib/core/tools/New-IcingaCheckCommand.psm1 +++ b/lib/core/tools/New-IcingaCheckCommand.psm1 @@ -96,7 +96,7 @@ function New-IcingaCheckCommand() Add-Content -Path $ScriptFile -Value "}"; - Write-Host ([string]::Format('The Check-Command "{0}" was successfully added.', $CommandName)); + Write-IcingaConsoleNotice ([string]::Format('The Check-Command "{0}" was successfully added.', $CommandName)); # Try to open the default Editor for the new Cmdlet $DefaultEditor = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.psm1\OpenWithList' -Name a).a; @@ -115,7 +115,7 @@ function New-IcingaCheckCommand() Import-Module $ScriptFile -Global; if ([string]::IsNullOrEmpty($DefaultEditor) -eq $FALSE -And ($null -eq (Get-Command $DefaultEditor -ErrorAction SilentlyContinue)) -And ((Test-Path $DefaultEditor) -eq $FALSE)) { - Write-Host 'No default editor for .psm1 files found. Specify a default editor to automaticly open the newly generated check plugin.'; + Write-IcingaConsoleWarning 'No default editor for .psm1 files found. Specify a default editor to automaticly open the newly generated check plugin.'; return; } diff --git a/lib/core/tools/Remove-IcingaDirectorSelfServiceKey.psm1 b/lib/core/tools/Remove-IcingaDirectorSelfServiceKey.psm1 index 6f30b34..3aa608a 100644 --- a/lib/core/tools/Remove-IcingaDirectorSelfServiceKey.psm1 +++ b/lib/core/tools/Remove-IcingaDirectorSelfServiceKey.psm1 @@ -6,9 +6,9 @@ function Remove-IcingaDirectorSelfServiceKey() Remove-IcingaPowerShellConfig 'IcingaDirector.SelfService.ApiKey'; $Value = Get-IcingaPowerShellConfig $Path; if ($null -eq $Value) { - Write-Host 'Icinga Director Self-Service Api key was successfully removed. Please dont forget to drop it within the Icinga Director as well'; + Write-IcingaConsoleNotice 'Icinga Director Self-Service Api key was successfully removed. Please dont forget to drop it within the Icinga Director as well'; } } else { - Write-Host 'There is no Self-Service Api key configured on this system'; + Write-IcingaConsoleWarning 'There is no Self-Service Api key configured on this system'; } } diff --git a/lib/core/tools/Show-IcingaDirectorSelfServiceKey.psm1 b/lib/core/tools/Show-IcingaDirectorSelfServiceKey.psm1 index 806ad98..94103c6 100644 --- a/lib/core/tools/Show-IcingaDirectorSelfServiceKey.psm1 +++ b/lib/core/tools/Show-IcingaDirectorSelfServiceKey.psm1 @@ -4,8 +4,8 @@ function Show-IcingaDirecorSelfServiceKey() $Value = Get-IcingaPowerShellConfig $Path; if ($null -ne $Value) { - Write-Host ([string]::Format('Self-Service Key: "{0}"', $Value)); + Write-IcingaConsoleNotice ([string]::Format('Self-Service Key: "{0}"', $Value)); } else { - Write-Host 'There is no Self-Service Api key configured on this system'; + Write-IcingaConsoleWarning 'There is no Self-Service Api key configured on this system'; } } diff --git a/lib/daemon/Register-IcingaBackgroundDaemon.psm1 b/lib/daemon/Register-IcingaBackgroundDaemon.psm1 index 83aa6b7..3a47438 100644 --- a/lib/daemon/Register-IcingaBackgroundDaemon.psm1 +++ b/lib/daemon/Register-IcingaBackgroundDaemon.psm1 @@ -18,5 +18,5 @@ function Register-IcingaBackgroundDaemon() Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Command', $Path)) -Value $Command; Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Arguments', $Path)) -Value $Arguments; - Write-Host ([string]::Format('Background daemon Cmdlet "{0}" has been configured', $Command)); + Write-IcingaConsoleNotice ([string]::Format('Background daemon Cmdlet "{0}" has been configured', $Command)); } diff --git a/lib/daemon/Unregister-IcingaBackgroundDaemon.psm1 b/lib/daemon/Unregister-IcingaBackgroundDaemon.psm1 index a836b11..19fa89c 100644 --- a/lib/daemon/Unregister-IcingaBackgroundDaemon.psm1 +++ b/lib/daemon/Unregister-IcingaBackgroundDaemon.psm1 @@ -13,5 +13,5 @@ function Unregister-IcingaBackgroundDaemon() Remove-IcingaPowerShellConfig -Path $Path; - Write-Host 'Background daemon has been removed'; + Write-IcingaConsoleNotice 'Background daemon has been removed'; } diff --git a/lib/daemons/ServiceCheckDaemon/Register-IcingaServiceCheck.psm1 b/lib/daemons/ServiceCheckDaemon/Register-IcingaServiceCheck.psm1 index 2492950..9dd1ed3 100644 --- a/lib/daemons/ServiceCheckDaemon/Register-IcingaServiceCheck.psm1 +++ b/lib/daemons/ServiceCheckDaemon/Register-IcingaServiceCheck.psm1 @@ -19,5 +19,5 @@ function Register-IcingaServiceCheck() Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Interval', $Path)) -Value $Interval; Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.TimeIndexes', $Path)) -Value $TimeIndexes; - Write-Host 'Icinga Service Check has been configured'; + Write-IcingaConsoleNotice 'Icinga Service Check has been configured'; } diff --git a/lib/daemons/ServiceCheckDaemon/Set-IcingaRegisteredServiceCheckConfig.psm1 b/lib/daemons/ServiceCheckDaemon/Set-IcingaRegisteredServiceCheckConfig.psm1 index 9edc6b5..7e7e25d 100644 --- a/lib/daemons/ServiceCheckDaemon/Set-IcingaRegisteredServiceCheckConfig.psm1 +++ b/lib/daemons/ServiceCheckDaemon/Set-IcingaRegisteredServiceCheckConfig.psm1 @@ -10,7 +10,7 @@ function Set-IcingaRegisteredServiceCheckConfig() $Services = Get-IcingaRegisteredServiceChecks; if ($Services.ContainsKey($ServiceId) -eq $FALSE) { - Write-Host 'Service Id was not found'; + Write-IcingaConsoleError 'Service Id was not found'; return; } @@ -31,8 +31,8 @@ function Set-IcingaRegisteredServiceCheckConfig() } if ($Modified) { - Write-Host 'Service configuration was successfully updated'; + Write-IcingaConsoleNotice 'Service configuration was successfully updated'; } else { - Write-Host 'No arguments were specified to update the service configuraiton'; + Write-IcingaConsoleWarning 'No arguments were specified to update the service configuration'; } } diff --git a/lib/daemons/ServiceCheckDaemon/Show-IcingaRegisteredServiceChecks.psm1 b/lib/daemons/ServiceCheckDaemon/Show-IcingaRegisteredServiceChecks.psm1 index 69af178..6dc248c 100644 --- a/lib/daemons/ServiceCheckDaemon/Show-IcingaRegisteredServiceChecks.psm1 +++ b/lib/daemons/ServiceCheckDaemon/Show-IcingaRegisteredServiceChecks.psm1 @@ -3,8 +3,8 @@ function Show-IcingaRegisteredServiceChecks() $Services = Get-IcingaRegisteredServiceChecks; foreach ($service in $Services.Keys) { - Write-Host ([string]::Format('Service Id: {0}', $service)); - Write-Host ( + Write-IcingaConsoleNotice ([string]::Format('Service Id: {0}', $service)); + Write-IcingaConsoleNotice ( $Services[$service] | Out-String ); } diff --git a/lib/daemons/ServiceCheckDaemon/Unregister-IcingaServiceCheck.psm1 b/lib/daemons/ServiceCheckDaemon/Unregister-IcingaServiceCheck.psm1 index 9285a11..02f4a96 100644 --- a/lib/daemons/ServiceCheckDaemon/Unregister-IcingaServiceCheck.psm1 +++ b/lib/daemons/ServiceCheckDaemon/Unregister-IcingaServiceCheck.psm1 @@ -12,5 +12,5 @@ function Unregister-IcingaServiceCheck() Remove-IcingaPowerShellConfig -Path $Path; - Write-Host 'Icinga Service Check has been configured'; + Write-IcingaConsolePlain 'Icinga Service Check has been configured'; } diff --git a/lib/help/help/Get-IcingaHelpThresholds.psm1 b/lib/help/help/Get-IcingaHelpThresholds.psm1 index eb79706..388e8b4 100644 --- a/lib/help/help/Get-IcingaHelpThresholds.psm1 +++ b/lib/help/help/Get-IcingaHelpThresholds.psm1 @@ -14,7 +14,7 @@ function Get-IcingaHelpThresholds() return; } - Write-Host + Write-IcingaConsolePlain ' Icinga is providing a basic handling for thresholds to make it easier to check if certain values of metrics should rise an event or not. By default, you are always fine to specify simple numeric values for thresholds throughout the entire Check-Plugins. diff --git a/lib/icinga/enums/Icinga_IcingaEnums.psm1 b/lib/icinga/enums/Icinga_IcingaEnums.psm1 index 0ffac3d..1b11ac1 100644 --- a/lib/icinga/enums/Icinga_IcingaEnums.psm1 +++ b/lib/icinga/enums/Icinga_IcingaEnums.psm1 @@ -18,6 +18,13 @@ 3 = '[UNKNOWN]'; }; +[hashtable]$IcingaExitCodeColor = @{ + 0 = 'Green'; + 1 = 'Yellow'; + 2 = 'Red'; + 3 = 'Magenta'; +}; + [hashtable]$IcingaMeasurementUnits = @{ 's' = 'seconds'; 'ms' = 'milliseconds'; @@ -41,6 +48,7 @@ [hashtable]$IcingaEnums = @{ IcingaExitCode = $IcingaExitCode; IcingaExitCodeText = $IcingaExitCodeText; + IcingaExitCodeColor = $IcingaExitCodeColor; IcingaMeasurementUnits = $IcingaMeasurementUnits; } diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 index b7a1304..95a63df 100644 --- a/lib/icinga/exception/Exit-IcingaThrowException.psm1 +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -71,7 +71,7 @@ function Exit-IcingaThrowException() ); if ($global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { - Write-Host $OutputMessage; + Write-IcingaConsolePlain $OutputMessage; exit $IcingaEnums.IcingaExitCode.Unknown; } } diff --git a/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 b/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 index c9a8746..ab593bc 100644 --- a/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 +++ b/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 @@ -5,7 +5,7 @@ function Write-IcingaPluginOutput() ); if ($global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { - Write-Host $Output; + Write-IcingaConsolePlain $Output; } else { if ($global:IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler')) { $global:IcingaDaemonData.IcingaThreadContent['Scheduler']['PluginCache'] += $Output; diff --git a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 index be86233..ddb4a83 100644 --- a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 +++ b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 @@ -17,7 +17,7 @@ function Write-IcingaPluginPerfData() if ($global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { [string]$PerfDataOutput = (Get-IcingaPluginPerfDataContent -PerfData $PerformanceData -CheckResultCache $CheckResultCache); - Write-Host ([string]::Format('| {0}', $PerfDataOutput)); + Write-IcingaConsolePlain ([string]::Format('| {0}', $PerfDataOutput)); } else { [void](Get-IcingaPluginPerfDataContent -PerfData $PerformanceData -CheckResultCache $CheckResultCache -AsObject $TRUE); } From 7860818be1ee8983454ee74e438212787875353c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 19 May 2020 17:29:42 +0200 Subject: [PATCH 20/34] Adds new exception messages and custom exception handling --- .../exception/Exit-IcingaThrowException.psm1 | 14 +++++++++--- .../Icinga_IcingaExceptionEnums.psm1 | 22 ++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 index 95a63df..b9b8027 100644 --- a/lib/icinga/exception/Exit-IcingaThrowException.psm1 +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -5,7 +5,7 @@ function Exit-IcingaThrowException() [string]$StringPattern, [string]$CustomMessage, [string]$ExceptionThrown, - [ValidateSet('Permission','Input','Unhandled')] + [ValidateSet('Permission','Input','Configuration','Unhandled','Custom')] [string]$ExceptionType = 'Unhandled', [switch]$Force ); @@ -32,9 +32,16 @@ function Exit-IcingaThrowException() $ExceptionTypeString = 'Invalid Input'; $ExceptionMessageLib = $IcingaExceptions.Inputs; }; + 'Configuration' { + $ExceptionTypeString = 'Invalid Configuration'; + $ExceptionMessageLib = $IcingaExceptions.Configuration; + }; 'Unhandled' { $ExceptionTypeString = 'Unhandled'; }; + 'Custom' { + $ExceptionTypeString = 'Custom'; + }; } [string]$ExceptionName = ''; @@ -47,9 +54,10 @@ function Exit-IcingaThrowException() } } } else { - $ExceptionName = 'Unhandled Exception'; + $ExceptionName = [string]::Format('{0} Exception', $ExceptionTypeString); $ExceptionThrown = [string]::Format( - 'Unhandled exception occured:{0}{1}', + '{0} exception occured:{1}{2}', + $ExceptionTypeString, "`r`n", $InputString ); diff --git a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 index 5422093..35158d4 100644 --- a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 +++ b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 @@ -5,17 +5,22 @@ #> [hashtable]$Permission = @{ - PerformanceCounter = 'A Plugin failed to fetch Performance Counter information. This may be caused when the used Service User is not permitted to access these information. To fix this, please add the User the Icinga Agent is running on into the "Performance Log Users" group and restart the service.'; - CacheFolder = "A plugin failed to write new data into the configured cache directory. Please update the permissions of this folder to allow write access for the user the Icinga Service is running with or use another folder as cache directory."; + PerformanceCounter = 'A Plugin failed to fetch Performance Counter information. This may be caused when the used Service User is not permitted to access these information. To fix this, please add the User the Icinga Agent is running on into the "Performance Log Users" group and restart the service.'; + CacheFolder = "A plugin failed to write new data into the configured cache directory. Please update the permissions of this folder to allow write access for the user the Icinga Service is running with or use another folder as cache directory."; }; [hashtable]$Inputs = @{ - PerformanceCounter = 'A plugin failed to fetch Performance Counter information. Please ensure the counter is written properly and available on your system.'; - EventLogLogName = 'Failed to fetch EventLog information. Please specify a valid LogName.'; - EventLog = 'Failed to fetch EventLog information. Please check your inputs for EntryTypes and other categories and try again.'; - ConversionUnitMissing = 'Unable to parse input value. You have to add an unit to your input value. Example: "10GB". Allowed units are: "B, KB, MB, GB, TB, PB, KiB, MiB, GiB, TiB, PiB".'; + PerformanceCounter = 'A plugin failed to fetch Performance Counter information. Please ensure the counter is written properly and available on your system.'; + EventLogLogName = 'Failed to fetch EventLog information. Please specify a valid LogName.'; + EventLog = 'Failed to fetch EventLog information. Please check your inputs for EntryTypes and other categories and try again.'; + ConversionUnitMissing = 'Unable to parse input value. You have to add an unit to your input value. Example: "10GB". Allowed units are: "B, KB, MB, GB, TB, PB, KiB, MiB, GiB, TiB, PiB".'; }; +[hashtable]$Configuration = @{ + PluginArgumentConflict = 'Your plugin argument configuration is causing a conflict. Mostly this error is caused by missmatching configurations by enabling multiple switch arguments which are resulting in a conflicting configuration for the plugin.'; + PluginArgumentmissing = 'Your plugin argument configuration is missing mandatory arguments. This is error is caused when mandatory or required arguments are missing from a plugin call and the operation is unable to process without them.'; +} + <# # Once we defined a new enum hashtable above, simply add it to this list # to make it available within the entire module. @@ -24,8 +29,9 @@ # $IcingaExceptionEnums.IcingaExecptionHandlers.PerformanceCounter #> [hashtable]$IcingaExceptions = @{ - Permission = $Permission; - Inputs = $Inputs; + Permission = $Permission; + Inputs = $Inputs; + Configuration = $Configuration; } Export-ModuleMember -Variable @( 'IcingaExceptions' ); From c4179338a1db1a0b244934e67300ae9d15187189 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 19 May 2020 17:30:50 +0200 Subject: [PATCH 21/34] Adds support to set check state by function call --- lib/icinga/plugin/New-IcingaCheck.psm1 | 52 +++++++++++++++++++++----- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index b7be7a9..78f071b 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -94,6 +94,22 @@ function New-IcingaCheck() return $this.unknownchecks; } + $Check | Add-Member -membertype ScriptMethod -name 'SetUnknown' -value { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Unknown, + $null, + $null + ); + } + + $Check | Add-Member -membertype ScriptMethod -name 'SetWarning' -value { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Warning, + $null, + $null + ); + } + $Check | Add-Member -membertype ScriptMethod -name 'WarnOutOfRange' -value { param($warning); @@ -296,6 +312,14 @@ function New-IcingaCheck() return $this; } + $Check | Add-Member -membertype ScriptMethod -name 'SetCritical' -value { + $this.AddInternalCheckMessage( + $IcingaEnums.IcingaExitCode.Critical, + $null, + $null + ); + } + $Check | Add-Member -membertype ScriptMethod -name 'CritOutOfRange' -value { param($critical); @@ -534,17 +558,25 @@ function New-IcingaCheck() } $this.SetExitCode($state); - $this.AddMessage( - [string]::Format( - '{0}: Value "{1}{4}" is {2} threshold "{3}{4}"', + + if ($null -eq $value -And $null -eq $type) { + $this.AddMessage( $this.name, - $this.TranslateValue($this.value), - $type, - $this.TranslateValue($value), - $this.unit - ), - $state - ); + $state + ); + } else { + $this.AddMessage( + [string]::Format( + '{0}: Value "{1}{4}" is {2} threshold "{3}{4}"', + $this.name, + $this.TranslateValue($this.value), + $type, + $this.TranslateValue($value), + $this.unit + ), + $state + ); + } switch ($state) { $IcingaEnums.IcingaExitCode.Warning { From 84975a475969d8b3b7fd65903363ec93a7deaa2f Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 09:52:48 +0200 Subject: [PATCH 22/34] Adds help for several Cmdlets --- .../Install-IcingaFrameworkPlugins.psm1 | 26 +++++++++++++++++ .../Install-IcingaFrameworkService.psm1 | 26 +++++++++++++++++ .../Install-IcingaFrameworkUpdate.psm1 | 24 +++++++++++++++ lib/core/framework/Remove-ItemSecure.psm1 | 29 +++++++++++++++++++ lib/core/framework/Restart-IcingaService.psm1 | 22 ++++++++++++++ lib/core/framework/Start-IcingaService.psm1 | 23 +++++++++++++++ lib/core/framework/Stop-IcingaService.psm1 | 23 +++++++++++++++ .../Test-IcingaZipBinaryChecksum.psm1 | 23 +++++++++++++++ .../Unblock-IcingaPowerShellFiles.psm1 | 22 ++++++++++++++ .../Uninstall-IcingaFrameworkService.psm1 | 18 ++++++++++++ 10 files changed, 236 insertions(+) diff --git a/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 b/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 index d281c63..a765563 100644 --- a/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 @@ -1,3 +1,29 @@ +<# +.SYNOPSIS + Installs the Icinga Plugins PowerShell module from a remote or local source +.DESCRIPTION + Installs the Icinga PowerShell Plugins from a remote or local source into the + PowerShell module folder and makes them available for usage with Icinga 2 or + other components. +.FUNCTIONALITY + Installs the Icinga Plugins PowerShell module from a remote or local source +.EXAMPLE + PS>Install-IcingaFrameworkPlugins; +.EXAMPLE + PS>Install-IcingaFrameworkPlugins -PluginsUrl 'C:/icinga/icinga-plugins.zip'; +.EXAMPLE + PS>Install-IcingaFrameworkPlugins -PluginsUrl 'https://github.com/Icinga/icinga-powershell-plugins/archive/v1.0.0.zip'; +.PARAMETER PluginsUrl + The URL pointing either to a local or remote ressource to download the plugins from. This requires to be the + full path to the .zip file to download. +.INPUTS + System.String +.OUTPUTS + System.Hashtable +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Install-IcingaFrameworkPlugins() { param( diff --git a/lib/core/framework/Install-IcingaFrameworkService.psm1 b/lib/core/framework/Install-IcingaFrameworkService.psm1 index 1263c0f..5b6c329 100644 --- a/lib/core/framework/Install-IcingaFrameworkService.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkService.psm1 @@ -1,3 +1,29 @@ +<# +.SYNOPSIS + Installs the Icinga PowerShell Services as a Windows service +.DESCRIPTION + Uses the Icinga Service binary which is already installed on the system to register + it as a Windows service and sets the proper user for it +.FUNCTIONALITY + Installs the Icinga PowerShell Services as a Windows service +.EXAMPLE + PS>Install-IcingaFrameworkService -Path C:\Program Files\icinga-service\icinga-service.exe; +.EXAMPLE + PS>Install-IcingaFrameworkService -Path C:\Program Files\icinga-service\icinga-service.exe -User 'NT Authority\NetworkService'; +.PARAMETER Path + The location on where the service binary executable is found +.PARAMETER User + The service user the service is running with +.PARAMETER Password + If the specified service user is requiring a password for registering you can provide it here as secure string +.INPUTS + System.String +.OUTPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Install-IcingaFrameworkService() { param( diff --git a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 index 327efab..6906ce9 100644 --- a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 @@ -1,3 +1,27 @@ +<# +.SYNOPSIS + Update the current version of the PowerShell Framework with a newer or older one +.DESCRIPTION + Allows you to specify a download url or being asked by a wizard on where a update for + the PowerShell framework can be fetched from and applies the up- or downgrade +.FUNCTIONALITY + Update the current version of the PowerShell Framework with a newer or older one +.EXAMPLE + PS>Install-IcingaFrameworkUpdate; +.EXAMPLE + PS>Install-IcingaFrameworkUpdate -FrameworkUrl 'C:/icinga/framework.zip'; +.EXAMPLE + PS>Install-IcingaFrameworkUpdate -FrameworkUrl 'https://github.com/Icinga/icinga-powershell-framework/archive/v1.0.2.zip'; +.PARAMETER FrameworkUrl + The url to a remote or local ressource pointing directly to a .zip file containing the required files for updating +.INPUTS + System.String +.OUTPUTS + Null +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Install-IcingaFrameworkUpdate() { param( diff --git a/lib/core/framework/Remove-ItemSecure.psm1 b/lib/core/framework/Remove-ItemSecure.psm1 index f284c1e..bf88070 100644 --- a/lib/core/framework/Remove-ItemSecure.psm1 +++ b/lib/core/framework/Remove-ItemSecure.psm1 @@ -1,3 +1,32 @@ +<# +.SYNOPSIS + Wrapper for Remove-Item to secuerly remove items allowing better handling for errors +.DESCRIPTION + Removes files and folders from disk and catches possible exceptions with proper return + values to handle errors better +.FUNCTIONALITY + Wrapper for Remove-Item to secuerly remove items allowing better handling for errors +.EXAMPLE + PS>Remove-ItemSecure -Path C:\icinga; +.EXAMPLE + PS>Remove-ItemSecure -Path C:\icinga -Recurse; +.EXAMPLE + PS>Remove-ItemSecure -Path C:\icinga -Recurse -Force; +.PARAMETER Path + The path to a file or folder you wish you delete +.PARAMETER Recurse + Removes sub-folders and sub-files for a given location +.PARAMETER Force + Tries to forefully removes a files and folders if they are either being used or a folder is + still containing items +.INPUTS + System.String +.OUTPUTS + System.Boolean +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Remove-ItemSecure() { param( diff --git a/lib/core/framework/Restart-IcingaService.psm1 b/lib/core/framework/Restart-IcingaService.psm1 index b6166e9..1e18e4e 100644 --- a/lib/core/framework/Restart-IcingaService.psm1 +++ b/lib/core/framework/Restart-IcingaService.psm1 @@ -1,3 +1,23 @@ +<# +.SYNOPSIS + Wrapper for Restart-Service which catches errors and prints proper output messages +.DESCRIPTION + Restarts a service if it is installed and prints console messages if a restart + was triggered or the service is not installed +.FUNCTIONALITY + Wrapper for restart service which catches errors and prints proper output messages +.EXAMPLE + PS>Restart-IcingaService -Service 'icinga2'; +.PARAMETER Service + The name of the service to be restarted +.INPUTS + System.String +.OUTPUTS + Null +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Restart-IcingaService() { param( @@ -7,5 +27,7 @@ function Restart-IcingaService() if (Get-Service $Service -ErrorAction SilentlyContinue) { Write-IcingaConsoleNotice ([string]::Format('Restarting service "{0}"', $Service)); Restart-Service $Service; + } else { + Write-IcingaConsoleWarning -Message 'The service "{0}" is not installed' -Objects $Service; } } diff --git a/lib/core/framework/Start-IcingaService.psm1 b/lib/core/framework/Start-IcingaService.psm1 index ec4b5a7..63487cb 100644 --- a/lib/core/framework/Start-IcingaService.psm1 +++ b/lib/core/framework/Start-IcingaService.psm1 @@ -1,3 +1,23 @@ +<# +.SYNOPSIS + Wrapper for Start-Service which catches errors and prints proper output messages +.DESCRIPTION + Starts a service if it is installed and prints console messages if a start + was triggered or the service is not installed +.FUNCTIONALITY + Wrapper for Start-Service which catches errors and prints proper output messages +.EXAMPLE + PS>Start-IcingaService -Service 'icinga2'; +.PARAMETER Service + The name of the service to be started +.INPUTS + System.String +.OUTPUTS + Null +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Start-IcingaService() { param( @@ -5,6 +25,9 @@ function Start-IcingaService() ); if (Get-Service $Service -ErrorAction SilentlyContinue) { + Write-IcingaConsoleNotice -Message 'Starting service "{0}"' -Objects $Service; Start-Service $Service; + } else { + Write-IcingaConsoleWarning -Message 'The service "{0}" is not installed' -Objects $Service; } } diff --git a/lib/core/framework/Stop-IcingaService.psm1 b/lib/core/framework/Stop-IcingaService.psm1 index ef91fa8..8daaf52 100644 --- a/lib/core/framework/Stop-IcingaService.psm1 +++ b/lib/core/framework/Stop-IcingaService.psm1 @@ -1,3 +1,23 @@ +<# +.SYNOPSIS + Wrapper for Stop-Service which catches errors and prints proper output messages +.DESCRIPTION + Stops a service if it is installed and prints console messages if a stop + was triggered or the service is not installed +.FUNCTIONALITY + Wrapper for Stop-Service which catches errors and prints proper output messages +.EXAMPLE + PS>Stop-IcingaService -Service 'icinga2'; +.PARAMETER Service + The name of the service to be stopped +.INPUTS + System.String +.OUTPUTS + Null +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Stop-IcingaService() { param( @@ -5,6 +25,9 @@ function Stop-IcingaService() ); if (Get-Service $Service -ErrorAction SilentlyContinue) { + Write-IcingaConsoleNotice -Message 'Stopping service "{0}"' -Objects $Service; Stop-Service $Service; + } else { + Write-IcingaConsoleWarning -Message 'The service "{0}" is not installed' -Objects $Service; } } diff --git a/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 b/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 index 94612fa..652a79f 100644 --- a/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 +++ b/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 @@ -1,3 +1,26 @@ +<# +.SYNOPSIS + Compares a binary within a .zip file to a included .md5 to ensure + the checksum is matching +.DESCRIPTION + Compares a possible included .md5 checksum file with the provided binary + to ensure they are identical +.FUNCTIONALITY + Compares a binary within a .zip file to a included .md5 to ensure + the checksum is matching. +.EXAMPLE + PS>Test-IcingaZipBinaryChecksum -Path 'C:\Program Files\icinga-service\icinga-service.exe'; +.PARAMETER Path + Path to the binary to be checked for. A Corresponding .md5 file with the + extension added on the file is required, like icinga-service.exe.md5 +.INPUTS + System.String +.OUTPUTS + Null +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Test-IcingaZipBinaryChecksum() { param( diff --git a/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 b/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 index afa6269..acd2229 100644 --- a/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 +++ b/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 @@ -1,3 +1,25 @@ +<# +.SYNOPSIS + Unblocks a folder with PowerShell module/script files to make them usable + on certain environments +.DESCRIPTION + Wrapper command to unblock recursively a certain folder for PowerShell script + and module files +.FUNCTIONALITY + Unblocks a folder with PowerShell module/script files to make them usable + on certain environments +.EXAMPLE + PS>Unblock-IcingaPowerShellFiles -Path 'C:\Program Files\WindowsPowerShell\Modules\my-module'; +.PARAMETER Path + The path to a PowerShell module folder or script file to unblock it +.INPUTS + System.String +.OUTPUTS + Null +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Unblock-IcingaPowerShellFiles() { param( diff --git a/lib/core/framework/Uninstall-IcingaFrameworkService.psm1 b/lib/core/framework/Uninstall-IcingaFrameworkService.psm1 index 8c2c689..1d13f10 100644 --- a/lib/core/framework/Uninstall-IcingaFrameworkService.psm1 +++ b/lib/core/framework/Uninstall-IcingaFrameworkService.psm1 @@ -1,3 +1,21 @@ +<# +.SYNOPSIS + Uninstalls the Icinga PowerShell Service as a Windows Service +.DESCRIPTION + Uninstalls the Icinga PowerShell Service as a Windows Service. The service binary + will be left on the system. +.FUNCTIONALITY + Uninstalls the Icinga PowerShell Service as a Windows Service +.EXAMPLE + PS>Uninstall-IcingaFrameworkService; +.INPUTS + System.String +.OUTPUTS + System.Object +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> + function Uninstall-IcingaFrameworkService() { Stop-IcingaService 'icingapowershell'; From 6229d3ce3782eb26296ee15575f31293a9d3a18d Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 12:08:42 +0200 Subject: [PATCH 23/34] Fixes FQDN to IP wizard conversion question --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 12 ++++++++---- lib/core/tools/Convert-IcingaEndpointsToIP.psm1 | 15 +++++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index c9777e8..b744c6b 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -285,11 +285,15 @@ function Start-IcingaAgentInstallWizard() if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to convert all possible provided FQDN address for endpoint/network configuration for Icinga 2 to plain IP-Address?', $CAPort)) -Default 'y').result -eq 1) { $InstallerArguments += "-ConvertEndpointIPConfig 1"; $ConvertEndpointIPConfig = $TRUE; - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; - if ($EndpointsConversion.HasErrors) { - Write-Host 'Not all of your endpoints configuration could be converted and was therefor dropped'; + if ($EndpointConnections.Count -eq 0) { + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; + } else { + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; } - $Endpoints = $EndpointsConversion.Network; + if ($EndpointsConversion.HasErrors) { + Write-Host ([string]::Format('Not all of your endpoint configuration could be resolved and is not reachable by this host. These endpoints were dropped: {0}', ([string]::Join(', ', $EndpointsConversion.Unresolved)))); + } + $EndpointConnections = $EndpointsConversion.Network; } else { $InstallerArguments += "-ConvertEndpointIPConfig 0"; $ConvertEndpointIPConfig = $FALSE; diff --git a/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 index 9305b88..0131db4 100644 --- a/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 +++ b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 @@ -25,9 +25,10 @@ function Convert-IcingaEndpointsToIPv4() [array]$NetworkConfig ); - [array]$ResolvedNetwork = @(); - [bool]$HasUnresolved = $FALSE; - [string]$Domain = $ENV:UserDNSDomain; + [array]$ResolvedNetwork = @(); + [array]$UnresolvedNetwork = @(); + [bool]$HasUnresolved = $FALSE; + [string]$Domain = $ENV:UserDNSDomain; foreach ($entry in $NetworkConfig) { $Network = Get-IPConfigFromString -IPConfig $entry; @@ -48,13 +49,15 @@ function Convert-IcingaEndpointsToIPv4() ); $ResolvedNetwork += $entry.Replace($Network.address, $ResolvedIP); } catch { - $HasUnresolved = $TRUE; + $UnresolvedNetwork += $entry; + $HasUnresolved = $TRUE; } } } return @{ - 'Network' = $ResolvedNetwork; - 'HasErrors' = $HasUnresolved; + 'Network' = $ResolvedNetwork; + 'HasErrors' = $HasUnresolved; + 'Unresolved' = $UnresolvedNetwork; }; } From d983f6f76791d341920ffb95e843d8ce42fe0a89 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 12:19:03 +0200 Subject: [PATCH 24/34] Adds support to fully uninstall the Icinga 2 agent including ProgramData Fixes #67 --- .../installer/Uninstall-IcingaAgent.psm1 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 index 4fc8088..740e339 100644 --- a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 +++ b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 @@ -1,5 +1,9 @@ function Uninstall-IcingaAgent() { + param ( + [switch]$RemoveDataFolder = $FALSE + ); + $IcingaData = Get-IcingaAgentInstallation; if ($IcingaData.Installed -eq $FALSE) { @@ -17,7 +21,15 @@ function Uninstall-IcingaAgent() Write-IcingaConsoleError ([string]::Format('Failed to remove Icinga 2 Agent: {0}{1}', $Uninstaller.Message, $Uninstaller.Error)); return $FALSE; } - + + if ($RemoveDataFolder) { + [string]$IcingaProgramData = Join-Path -Path $Env:ProgramData -ChildPath 'icinga2'; + Write-IcingaConsoleNotice -Message 'Removing Icinga 2 directoy from ProgramData: "{0}"' -Objects $IcingaProgramData; + if ((Remove-ItemSecure -Path $IcingaProgramData -Recurse -Force) -eq $FALSE) { + return $FALSE; + } + } + Write-IcingaConsoleNotice 'Icinga Agent was successfully removed'; return $TRUE; } From 2edf351fd472548c8505ef3617dca4074084707a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 12:52:11 +0200 Subject: [PATCH 25/34] Improves connection conversion wizard handling --- .../icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index b744c6b..750a975 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -282,16 +282,16 @@ function Start-IcingaAgentInstallWizard() } if ($null -eq $ConvertEndpointIPConfig) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to convert all possible provided FQDN address for endpoint/network configuration for Icinga 2 to plain IP-Address?', $CAPort)) -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to convert endpoint connection data to IP adresses?' -Default 'y').result -eq 1) { $InstallerArguments += "-ConvertEndpointIPConfig 1"; $ConvertEndpointIPConfig = $TRUE; if ($EndpointConnections.Count -eq 0) { - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; } else { - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; } if ($EndpointsConversion.HasErrors) { - Write-Host ([string]::Format('Not all of your endpoint configuration could be resolved and is not reachable by this host. These endpoints were dropped: {0}', ([string]::Join(', ', $EndpointsConversion.Unresolved)))); + Write-Host ([string]::Format('Not all of your endpoint connection data could be resolved and are not reachable by this host. These endpoints were dropped: {0}', ([string]::Join(', ', $EndpointsConversion.Unresolved)))); } $EndpointConnections = $EndpointsConversion.Network; } else { From 7961a0d0d1eb76607be6343235fedddfa79b468b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 13 May 2020 14:50:11 +0200 Subject: [PATCH 26/34] Adds defaults to certain steps and FQDN to IP conversion --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 35 +++++++++-- .../tools/Convert-IcingaEndpointsToIP.psm1 | 60 +++++++++++++++++++ 2 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 lib/core/tools/Convert-IcingaEndpointsToIP.psm1 diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index ea33ddf..075bafc 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -16,6 +16,7 @@ function Start-IcingaAgentInstallWizard() $AcceptConnections = $null, [array]$Endpoints = @(), [array]$EndpointConnections = @(), + $ConvertEndpointIPConfig = $null, [string]$ParentZone, [array]$GlobalZones = $null, [string]$CAEndpoint, @@ -218,7 +219,7 @@ function Start-IcingaAgentInstallWizard() if ($UpdateAgent -eq 1) { if ([string]::IsNullOrEmpty($AgentVersion)) { - $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v').answer; + $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v' -DefaultInput 'latest').answer; $InstallerArguments += "-AgentVersion '$AgentVersion'"; Write-IcingaConsoleNotice ([string]::Format('Updating/Downgrading Icinga 2 Agent to version: "{0}"', $AgentVersion)); @@ -237,7 +238,7 @@ function Start-IcingaAgentInstallWizard() } if ($Endpoints.Count -eq 0) { - $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify all endpoints this Agent will report to (separated by ",")' -Default 'v').answer; + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify all Icinga endpoints this Agent will report to separated by "," (Example: master-icinga2a, master-icinga2b)' -Default 'v').answer; $Endpoints = ($ArrayString.Replace(' ', '')).Split(','); $InstallerArguments += ("-Endpoints " + ([string]::Join(',', $Endpoints))); } @@ -255,7 +256,7 @@ function Start-IcingaAgentInstallWizard() [bool]$CanConnectToParent = $FALSE; if ($null -eq $AcceptConnections) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this Agent able to connect to its parent node for certificate generation and general communication?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt "Is this Agent able to connect to it's parent node for certificate requests and general communication?" -Default 'y').result -eq 1) { $CanConnectToParent = $TRUE; $AcceptConnections = 1; $InstallerArguments += ("-AcceptConnections 1"); @@ -280,6 +281,21 @@ function Start-IcingaAgentInstallWizard() } } + if ($null -eq $ConvertEndpointIPConfig) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to convert all possible provided FQDN address for endpoint/network configuration for Icinga 2 to plain IP-Address?', $CAPort)) -Default 'y').result -eq 1) { + $InstallerArguments += "-ConvertEndpointIPConfig 1"; + $ConvertEndpointIPConfig = $TRUE; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; + if ($EndpointsConversion.HasErrors) { + Write-Host 'Not all of your endpoints configuration could be converted and was therefor dropped'; + } + $Endpoints = $EndpointsConversion.Network; + } else { + $InstallerArguments += "-ConvertEndpointIPConfig 0"; + $ConvertEndpointIPConfig = $FALSE; + } + } + if ($EndpointConnections.Count -eq 0 -And $AcceptConnections -eq 1) { $NetworkDefault = ''; foreach ($Endpoint in $Endpoints) { @@ -288,8 +304,15 @@ function Start-IcingaAgentInstallWizard() if ([string]::IsNullOrEmpty($NetworkDefault) -eq $FALSE) { $NetworkDefault = $NetworkDefault.Substring(0, $NetworkDefault.Length - 1); } - $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this agent will connect to, separated by ","' -Default 'v' -DefaultInput $NetworkDefault).answer; + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this Agent will connect to separated by "," (Example: 192.168.0.1, [192.168.0.2]:5665, [icinga2.example.com]:5665)' -Default 'v' -DefaultInput $NetworkDefault).answer; $EndpointConnections = ($ArrayString.Replace(' ', '')).Split(','); + + if ($ConvertEndpointIPConfig) { + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; + if ($EndpointsConversion.HasErrors -eq $FALSE) { + $EndpointConnections = $EndpointsConversion.Network; + } + } $InstallerArguments += ("-EndpointConnections " + ([string]::Join(',', $EndpointConnections))); } @@ -342,7 +365,7 @@ function Start-IcingaAgentInstallWizard() if ($CanConnectToParent) { if ([string]::IsNullOrEmpty($CAEndpoint)) { - $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the IP/FQDN for either ONE of your Icinga parent nodes or your Icinga 2 CA master' -Default 'v' -DefaultInput (Get-IPConfigFromString $EndpointConnections[0]).address).answer; + $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the IP/FQDN for either ONE of your Icinga parent nodes or your Icinga 2 CA master for requesting certificates' -Default 'v' -DefaultInput (Get-IPConfigFromString $EndpointConnections[0]).address).answer; $InstallerArguments += "-CAEndpoint $CAEndpoint"; } if ([string]::IsNullOrEmpty($Ticket) -And $null -eq $EmptyTicket) { @@ -400,7 +423,7 @@ function Start-IcingaAgentInstallWizard() if ([string]::IsNullOrEmpty($ServiceUser)) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to change the user the Icinga Agent service is running with (Default: "NT Authority\NetworkService")?' -Default 'n').result -eq 0) { - $ServiceUser = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the user you wish the Icinga Agent service to run with' -Default 'v').answer; + $ServiceUser = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the user you wish the Icinga Agent service to run with' -Default 'v' -DefaultInput 'NT Authority\NetworkService').answer; $InstallerArguments += "-ServiceUser $ServiceUser"; if ($null -eq $ServicePass) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Does your Icinga Service user require a password to login (not required for System users)?' -Default 'y').result -eq 1) { diff --git a/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 new file mode 100644 index 0000000..9305b88 --- /dev/null +++ b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 @@ -0,0 +1,60 @@ +<# +.SYNOPSIS + Converts Icinga Network configuration from FQDN to IP +.DESCRIPTION + This Cmdlet will convert a given Icinga Endpoint configuration based + on a FQDN to a IPv4 based configuration and returns nothing of the + FQDN could not be resolved +.FUNCTIONALITY + Converts Icinga Network configuration from FQDN to IP +.EXAMPLE + PS>Convert-IcingaEndpointsToIPv4 -NetworkConfig @( '[icinga2.example.com]:5665' ); +.PARAMETER NetworkConfig + An array of Icinga endpoint or single network configuration, like '[icinga2.example.com]:5665' + which will be converted to IP based configuration +.INPUTS + System.Array +.OUTPUTS + System.Hashtable +.LINK + https://github.com/Icinga/icinga-powershell-framework +#> +function Convert-IcingaEndpointsToIPv4() +{ + param ( + [array]$NetworkConfig + ); + + [array]$ResolvedNetwork = @(); + [bool]$HasUnresolved = $FALSE; + [string]$Domain = $ENV:UserDNSDomain; + + foreach ($entry in $NetworkConfig) { + $Network = Get-IPConfigFromString -IPConfig $entry; + try { + $ResolvedIP = [System.Net.Dns]::GetHostAddresses($Network.address); + $ResolvedNetwork += $entry.Replace($Network.address, $ResolvedIP); + } catch { + # Once we failed in first place, try to lookup the "FQDN" with our host domain + # we are in. Might resolve some issues if our DNS is not knowing the plain + # hostname and untable to resolve it + try { + $ResolvedIP = [System.Net.Dns]::GetHostAddresses( + [string]::Format( + '{0}.{1}', + $Network.address, + $Domain + ) + ); + $ResolvedNetwork += $entry.Replace($Network.address, $ResolvedIP); + } catch { + $HasUnresolved = $TRUE; + } + } + } + + return @{ + 'Network' = $ResolvedNetwork; + 'HasErrors' = $HasUnresolved; + }; +} From 2ac3de5267ecf6fc3e28db1cb89b19f241f114c9 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 12:08:42 +0200 Subject: [PATCH 27/34] Fixes FQDN to IP wizard conversion question --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 12 ++++++++---- lib/core/tools/Convert-IcingaEndpointsToIP.psm1 | 15 +++++++++------ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 075bafc..a8ebdae 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -285,11 +285,15 @@ function Start-IcingaAgentInstallWizard() if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to convert all possible provided FQDN address for endpoint/network configuration for Icinga 2 to plain IP-Address?', $CAPort)) -Default 'y').result -eq 1) { $InstallerArguments += "-ConvertEndpointIPConfig 1"; $ConvertEndpointIPConfig = $TRUE; - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; - if ($EndpointsConversion.HasErrors) { - Write-Host 'Not all of your endpoints configuration could be converted and was therefor dropped'; + if ($EndpointConnections.Count -eq 0) { + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; + } else { + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; } - $Endpoints = $EndpointsConversion.Network; + if ($EndpointsConversion.HasErrors) { + Write-Host ([string]::Format('Not all of your endpoint configuration could be resolved and is not reachable by this host. These endpoints were dropped: {0}', ([string]::Join(', ', $EndpointsConversion.Unresolved)))); + } + $EndpointConnections = $EndpointsConversion.Network; } else { $InstallerArguments += "-ConvertEndpointIPConfig 0"; $ConvertEndpointIPConfig = $FALSE; diff --git a/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 index 9305b88..0131db4 100644 --- a/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 +++ b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 @@ -25,9 +25,10 @@ function Convert-IcingaEndpointsToIPv4() [array]$NetworkConfig ); - [array]$ResolvedNetwork = @(); - [bool]$HasUnresolved = $FALSE; - [string]$Domain = $ENV:UserDNSDomain; + [array]$ResolvedNetwork = @(); + [array]$UnresolvedNetwork = @(); + [bool]$HasUnresolved = $FALSE; + [string]$Domain = $ENV:UserDNSDomain; foreach ($entry in $NetworkConfig) { $Network = Get-IPConfigFromString -IPConfig $entry; @@ -48,13 +49,15 @@ function Convert-IcingaEndpointsToIPv4() ); $ResolvedNetwork += $entry.Replace($Network.address, $ResolvedIP); } catch { - $HasUnresolved = $TRUE; + $UnresolvedNetwork += $entry; + $HasUnresolved = $TRUE; } } } return @{ - 'Network' = $ResolvedNetwork; - 'HasErrors' = $HasUnresolved; + 'Network' = $ResolvedNetwork; + 'HasErrors' = $HasUnresolved; + 'Unresolved' = $UnresolvedNetwork; }; } From 4a869458cc77c046887a71dd242012ac58d64fd5 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 12:52:11 +0200 Subject: [PATCH 28/34] Improves connection conversion wizard handling --- .../icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index a8ebdae..652faf6 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -282,16 +282,16 @@ function Start-IcingaAgentInstallWizard() } if ($null -eq $ConvertEndpointIPConfig) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to convert all possible provided FQDN address for endpoint/network configuration for Icinga 2 to plain IP-Address?', $CAPort)) -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to convert endpoint connection data to IP adresses?' -Default 'y').result -eq 1) { $InstallerArguments += "-ConvertEndpointIPConfig 1"; $ConvertEndpointIPConfig = $TRUE; if ($EndpointConnections.Count -eq 0) { - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; } else { - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; } if ($EndpointsConversion.HasErrors) { - Write-Host ([string]::Format('Not all of your endpoint configuration could be resolved and is not reachable by this host. These endpoints were dropped: {0}', ([string]::Join(', ', $EndpointsConversion.Unresolved)))); + Write-Host ([string]::Format('Not all of your endpoint connection data could be resolved and are not reachable by this host. These endpoints were dropped: {0}', ([string]::Join(', ', $EndpointsConversion.Unresolved)))); } $EndpointConnections = $EndpointsConversion.Network; } else { From eeb74063824622114731be322e7070b998064101 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 13:20:03 +0200 Subject: [PATCH 29/34] Improves IP conversion by returning unresolved name only --- lib/core/tools/Convert-IcingaEndpointsToIP.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 index 0131db4..f5201c7 100644 --- a/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 +++ b/lib/core/tools/Convert-IcingaEndpointsToIP.psm1 @@ -49,7 +49,7 @@ function Convert-IcingaEndpointsToIPv4() ); $ResolvedNetwork += $entry.Replace($Network.address, $ResolvedIP); } catch { - $UnresolvedNetwork += $entry; + $UnresolvedNetwork += $Network.address; $HasUnresolved = $TRUE; } } From 5aa7e8259d85ad9a57f38aed34851b9ca37b1f70 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 13:20:41 +0200 Subject: [PATCH 30/34] Fixes argument parsing and prompt for IP conversion --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 652faf6..20e51db 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -286,12 +286,12 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += "-ConvertEndpointIPConfig 1"; $ConvertEndpointIPConfig = $TRUE; if ($EndpointConnections.Count -eq 0) { - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $Endpoints.Split(','); } else { - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections.Split(','); } if ($EndpointsConversion.HasErrors) { - Write-Host ([string]::Format('Not all of your endpoint connection data could be resolved and are not reachable by this host. These endpoints were dropped: {0}', ([string]::Join(', ', $EndpointsConversion.Unresolved)))); + Write-IcingaConsoleWarning -Message 'Not all of your endpoint connection data could be resolved. These endpoints were dropped: {0}' -Objects ([string]::Join(', ', $EndpointsConversion.Unresolved)); } $EndpointConnections = $EndpointsConversion.Network; } else { @@ -308,11 +308,11 @@ function Start-IcingaAgentInstallWizard() if ([string]::IsNullOrEmpty($NetworkDefault) -eq $FALSE) { $NetworkDefault = $NetworkDefault.Substring(0, $NetworkDefault.Length - 1); } - $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this Agent will connect to separated by "," (Example: 192.168.0.1, [192.168.0.2]:5665, [icinga2.example.com]:5665)' -Default 'v' -DefaultInput $NetworkDefault).answer; + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this Agent will connect to separated by "," (Examples: 192.168.0.1, [192.168.0.2]:5665, [icinga2.example.com]:5665)' -Default 'v' -DefaultInput $NetworkDefault).answer; $EndpointConnections = ($ArrayString.Replace(' ', '')).Split(','); if ($ConvertEndpointIPConfig) { - $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections; + $EndpointsConversion = Convert-IcingaEndpointsToIPv4 -NetworkConfig $EndpointConnections.Split(','); if ($EndpointsConversion.HasErrors -eq $FALSE) { $EndpointConnections = $EndpointsConversion.Network; } From c6a715468645ff0b81ca8b707fdf6793c42d638c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 13:22:41 +0200 Subject: [PATCH 31/34] Renames Default: to Defaults: on setup wizard --- .../getters/Get-IcingaAgentInstallerAnswerInput.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 index 6f5473b..eaac48d 100644 --- a/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 +++ b/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 @@ -16,7 +16,7 @@ function Get-IcingaAgentInstallerAnswerInput() $DefaultAnswer = ' (y/N)'; } elseif ($Default -eq 'v') { if ([string]::IsNullOrEmpty($DefaultInput) -eq $FALSE) { - $DefaultAnswer = [string]::Format(' (Default: "{0}")', $DefaultInput); + $DefaultAnswer = [string]::Format(' (Defaults: "{0}")', $DefaultInput); } } From 882ce624a00ea62bb1cab1cf253cb893ec190e49 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 13:41:24 +0200 Subject: [PATCH 32/34] Changes error for service installation to warning on missing path --- lib/core/framework/Install-IcingaFrameworkService.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/framework/Install-IcingaFrameworkService.psm1 b/lib/core/framework/Install-IcingaFrameworkService.psm1 index 5b6c329..81607dc 100644 --- a/lib/core/framework/Install-IcingaFrameworkService.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkService.psm1 @@ -33,7 +33,7 @@ function Install-IcingaFrameworkService() ); if ([string]::IsNullOrEmpty($Path)) { - Write-IcingaConsoleError 'No path specified for Framework service. Service will not be installed'; + Write-IcingaConsoleWarning 'No path specified for Framework service. Service will not be installed'; return; } From 987a52c418a767594857d43bf187200db6f92c3c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 13:42:23 +0200 Subject: [PATCH 33/34] Improves console output for certain commands --- .../installer/Install-IcingaAgentCertificates.psm1 | 2 +- lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 | 6 +++--- .../icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 index a82538d..77722cc 100644 --- a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 +++ b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 @@ -194,7 +194,7 @@ function Test-IcingaAgentCertificates() } } - Write-IcingaConsoleNotice 'Icinga host certificates are present and valid. No generation required.'; + Write-IcingaConsoleNotice 'Icinga host certificates are present and valid. No generation required'; return $TRUE; } diff --git a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 index 740e339..ef1d852 100644 --- a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 +++ b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 @@ -11,20 +11,20 @@ function Uninstall-IcingaAgent() return; } - Write-IcingaConsoleNotice 'Removing current installed Icinga Agent'; + Write-IcingaConsoleNotice 'Removing current Icinga Agent'; Stop-IcingaService 'icinga2'; $Uninstaller = Start-IcingaProcess -Executable 'MsiExec.exe' -Arguments ([string]::Format('{0} /q', $IcingaData.Uninstaller)) -FlushNewLine; if ($Uninstaller.ExitCode -ne 0) { - Write-IcingaConsoleError ([string]::Format('Failed to remove Icinga 2 Agent: {0}{1}', $Uninstaller.Message, $Uninstaller.Error)); + Write-IcingaConsoleError ([string]::Format('Failed to remove Icinga Agent: {0}{1}', $Uninstaller.Message, $Uninstaller.Error)); return $FALSE; } if ($RemoveDataFolder) { [string]$IcingaProgramData = Join-Path -Path $Env:ProgramData -ChildPath 'icinga2'; - Write-IcingaConsoleNotice -Message 'Removing Icinga 2 directoy from ProgramData: "{0}"' -Objects $IcingaProgramData; + Write-IcingaConsoleNotice -Message 'Removing Icinga Agent directory: "{0}"' -Objects $IcingaProgramData; if ((Remove-ItemSecure -Path $IcingaProgramData -Recurse -Force) -eq $FALSE) { return $FALSE; } diff --git a/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 b/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 index 0a5f940..901d6cf 100644 --- a/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 +++ b/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 @@ -4,7 +4,7 @@ function Move-IcingaAgentDefaultConfig() $BackupFile = Join-Path -Path $ConfigDir -ChildPath 'ps_backup\backup_executed.key'; if ((Test-Path $BackupFile)) { - Write-IcingaConsoleNotice 'A backup of your default configuration is not required. A backup was already made.'; + Write-IcingaConsoleNotice 'A backup of your default configuration is not required. A backup was already made'; return; } From 971e09dc433c80314b249ed1b8fcd4cac40e2863 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 22 May 2020 16:34:18 +0200 Subject: [PATCH 34/34] Fixes and improves various messages, handlings and severities for wizard --- .../firewall/Disable-IcingaFirewall.psm1 | 4 +- .../Install-IcingaAgentCertificates.psm1 | 2 +- .../misc/Disable-IcingaAgentFeature.psm1 | 2 +- .../misc/Enable-IcingaAgentFeature.psm1 | 2 +- .../misc/Start-IcingaAgentInstallWizard.psm1 | 112 ++++++++++++------ .../Set-IcingaAgentServicePermission.psm1 | 2 +- .../icingaagent/tests/Test-IcingaAcl.psm1 | 6 +- .../icingaagent/tests/Test-IcingaAgent.psm1 | 8 +- .../tests/Test-IcingaAgentConfig.psm1 | 4 +- .../Test-IcingaAgentServicePermission.psm1 | 6 +- .../writers/Write-IcingaTestOutput.psm1 | 8 +- 11 files changed, 95 insertions(+), 61 deletions(-) diff --git a/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 b/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 index d2cafe0..0502a5d 100644 --- a/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 +++ b/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 @@ -11,7 +11,7 @@ function Disable-IcingaFirewall() if ($Firewall.ExitCode -ne 0) { Write-IcingaConsoleError ([string]::Format('Failed to remove legacy firewall: {0}{1}', $Firewall.Message, $Firewall.Error)); } else { - Write-IcingaConsoleNotice 'Successfully removed legacy Firewall rule'; + Write-IcingaConsoleNotice 'Successfully removed legacy firewall rule'; } } @@ -24,7 +24,7 @@ function Disable-IcingaFirewall() if ($Firewall.ExitCode -ne 0) { Write-IcingaConsoleError ([string]::Format('Failed to remove Icinga firewall: {0}{1}', $Firewall.Message, $Firewall.Error)); } else { - Write-IcingaConsoleNotice 'Successfully removed Icinga Firewall rule'; + Write-IcingaConsoleNotice 'Successfully removed Icinga firewall rule'; } } } diff --git a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 index 77722cc..a9ff5fd 100644 --- a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 +++ b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 @@ -39,7 +39,7 @@ function Install-IcingaAgentCertificates() } if ([string]::IsNullOrEmpty($Endpoint) -And [string]::IsNullOrEmpty($CACert)) { - Write-IcingaConsoleNotice 'Your host certificates have been generated successfully. Please either specify an endpoint to connect to or provide the path to a valid ca.crt.'; + Write-IcingaConsoleWarning 'Your host certificates have been generated successfully. Please either specify an endpoint to connect to or provide the path to a valid ca.crt'; return $TRUE; } diff --git a/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 index 4df1806..cef5fc8 100644 --- a/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 +++ b/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 @@ -9,7 +9,7 @@ function Disable-IcingaAgentFeature() } if ((Test-IcingaAgentFeatureEnabled -Feature $Feature) -eq $FALSE) { - Write-IcingaConsoleWarning ([string]::Format('This feature is already disabled [{0}]', $Feature)); + Write-IcingaConsoleNotice ([string]::Format('This feature is already disabled [{0}]', $Feature)); return; } diff --git a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 index beebc19..0a59aa3 100644 --- a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 +++ b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 @@ -9,7 +9,7 @@ function Enable-IcingaAgentFeature() } if ((Test-IcingaAgentFeatureEnabled -Feature $Feature)) { - Write-IcingaConsoleWarning ([string]::Format('This feature is already enabled [{0}]', $Feature)); + Write-IcingaConsoleNotice ([string]::Format('This feature is already enabled [{0}]', $Feature)); return; } diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 20e51db..5fff42d 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -137,8 +137,9 @@ function Start-IcingaAgentInstallWizard() } if ([string]::IsNullOrEmpty($Hostname) -And $null -eq $AutoUseFQDN -And $null -eq $AutoUseHostname) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually specify a hostname?' -Default 'n').result -eq 1) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to automatically fetch the hostname with its FQDN?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to specify the hostname manually?' -Default 'n').result -eq 1) { + $HostFQDN = Get-IcingaHostname -AutoUseFQDN 1 -AutoUseHostname 0 -LowerCase 1 -UpperCase 0; + if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to automatically fetch the hostname as FQDN? (Result: "{0}")', $HostFQDN)) -Default 'y').result -eq 1) { $InstallerArguments += '-AutoUseFQDN 1'; $InstallerArguments += '-AutoUseHostname 0'; $AutoUseFQDN = $TRUE; @@ -149,17 +150,24 @@ function Start-IcingaAgentInstallWizard() $AutoUseFQDN = $FALSE; $AutoUseHostname = $TRUE; } - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to modify the hostname to only include lower case characters?' -Default 'y').result -eq 1) { + $Hostname = Get-IcingaHostname -AutoUseFQDN $AutoUseFQDN -AutoUseHostname $AutoUseHostname -LowerCase 1 -UpperCase 0; + if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to convert the hostname into lower case characters? (Result: "{0}")', $Hostname)) -Default 'y').result -eq 1) { $InstallerArguments += '-LowerCase 1'; $InstallerArguments += '-UpperCase 0'; $LowerCase = $TRUE; $UpperCase = $FALSE; } else { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to modify the hostname to only include upper case characters?' -Default 'n').result -eq 0) { + $Hostname = Get-IcingaHostname -AutoUseFQDN $AutoUseFQDN -AutoUseHostname $AutoUseHostname -LowerCase 0 -UpperCase 1; + if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to convert the hostname into upper case characters? (Result: "{0}")', $Hostname)) -Default 'y').result -eq 1) { $InstallerArguments += '-LowerCase 0'; $InstallerArguments += '-UpperCase 1'; $LowerCase = $FALSE; $UpperCase = $TRUE; + } else { + $InstallerArguments += '-LowerCase 0'; + $InstallerArguments += '-UpperCase 0'; + $LowerCase = $FALSE; + $UpperCase = $FALSE; } } $Hostname = Get-IcingaHostname -AutoUseFQDN $AutoUseFQDN -AutoUseHostname $AutoUseHostname -LowerCase $LowerCase -UpperCase $UpperCase; @@ -172,13 +180,13 @@ function Start-IcingaAgentInstallWizard() } } - Write-IcingaConsoleNotice ([string]::Format('Using hostname "{0}" for the Icinga 2 Agent configuration', $Hostname)); + Write-IcingaConsoleNotice ([string]::Format('Using hostname "{0}" for the Icinga Agent configuration', $Hostname)); $IcingaAgent = Get-IcingaAgentInstallation; if ($IcingaAgent.Installed -eq $FALSE) { if ([string]::IsNullOrEmpty($PackageSource)) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the Icinga Agent now?' -Default 'y').result -eq 1) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to use a different package source then "https://packages.icinga.com/windows/"?' -Default 'n').result -eq 0) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to use a different package source? (Defaults: "https://packages.icinga.com/windows/")' -Default 'n').result -eq 0) { $PackageSource = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify your package source' -Default 'v').answer; $InstallerArguments += "-PackageSource '$PackageSource'"; } else { @@ -186,15 +194,15 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += "-PackageSource '$PackageSource'"; } - Write-IcingaConsoleNotice ([string]::Format('Using package source "{0}" for the Icinga 2 Agent package', $PackageSource)); + Write-IcingaConsoleNotice ([string]::Format('Using package source "{0}" for the Icinga Agent package', $PackageSource)); $AllowVersionChanges = $TRUE; $InstallerArguments += '-AllowVersionChanges 1'; if ([string]::IsNullOrEmpty($AgentVersion)) { - $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v' -DefaultInput 'latest').answer; + $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot" or a version like "2.11.3")' -Default 'v' -DefaultInput 'latest').answer; $InstallerArguments += "-AgentVersion '$AgentVersion'"; - Write-IcingaConsoleNotice ([string]::Format('Installing Icinga Version: "{0}"', $AgentVersion)); + Write-IcingaConsoleNotice ([string]::Format('Installing Icinga version: "{0}"', $AgentVersion)); } } else { $AllowVersionChanges = $FALSE; @@ -205,7 +213,7 @@ function Start-IcingaAgentInstallWizard() } } else { if ($null -eq $UpdateAgent) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'The Icinga 2 Agent is already installed. Would you like to update it?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'The Icinga Agent is already installed. Would you like to update it?' -Default 'y').result -eq 1) { $UpdateAgent = 1; $AllowVersionChanges = $TRUE; $InstallerArguments += '-AllowVersionChanges 1'; @@ -238,14 +246,14 @@ function Start-IcingaAgentInstallWizard() } if ($Endpoints.Count -eq 0) { - $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify all Icinga endpoints this Agent will report to separated by "," (Example: master-icinga2a, master-icinga2b)' -Default 'v').answer; + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the parent node(s) separated by "," (Example: "master-icinga2a, master-icinga2b")' -Default 'v').answer; $Endpoints = ($ArrayString.Replace(' ', '')).Split(','); $InstallerArguments += ("-Endpoints " + ([string]::Join(',', $Endpoints))); } if ($null -eq $CAPort) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Are you using a different port than 5665 for Icinga communications?' -Default 'n').result -eq 0) { - $CAPort = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the port for Icinga 2 communication' -Default 'v').answer; + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Are you using a custom port for Icinga communication?' -Default 'n').result -eq 0) { + $CAPort = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the port for Icinga communication' -Default 'v' -DefaultInput '5665').answer; $InstallerArguments += "-CAPort $CAPort"; } else { $InstallerArguments += "-CAPort 5665"; @@ -256,22 +264,25 @@ function Start-IcingaAgentInstallWizard() [bool]$CanConnectToParent = $FALSE; if ($null -eq $AcceptConnections) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt "Is this Agent able to connect to it's parent node for certificate requests and general communication?" -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt "Is this Agent able to connect to its parent node(s)?" -Default 'y').result -eq 1) { $CanConnectToParent = $TRUE; - $AcceptConnections = 1; - $InstallerArguments += ("-AcceptConnections 1"); - } else { $AcceptConnections = 0; $InstallerArguments += ("-AcceptConnections 0"); + } else { + $AcceptConnections = 1; + $InstallerArguments += ("-AcceptConnections 1"); } - } elseif ($AcceptConnections) { - $CanConnectToParent = $TRUE; + } else { if ((Test-IcingaWizardArgument -Argument 'AcceptConnections') -eq $FALSE) { $InstallerArguments += ([string]::Format('-AcceptConnections {0}', [int]$AcceptConnections)); } + + if ($AcceptConnections -eq $FALSE) { + $CanConnectToParent = $TRUE; + } } - if ($null -eq $AddFirewallRule) { + if ($null -eq $AddFirewallRule -And $CanConnectToParent -eq $FALSE) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to open the Windows Firewall for incoming traffic on Port "{0}"?', $CAPort)) -Default 'y').result -eq 1) { $InstallerArguments += "-AddFirewallRule 1"; $AddFirewallRule = $TRUE; @@ -279,10 +290,15 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += "-AddFirewallRule 0"; $AddFirewallRule = $FALSE; } + } else { + if ($CanConnectToParent -eq $TRUE) { + $InstallerArguments += "-AddFirewallRule 0"; + $AddFirewallRule = $FALSE; + } } - if ($null -eq $ConvertEndpointIPConfig) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to convert endpoint connection data to IP adresses?' -Default 'y').result -eq 1) { + if ($null -eq $ConvertEndpointIPConfig -And $CanConnectToParent -eq $TRUE) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to convert parent node(s) connection data to IP adresses?' -Default 'y').result -eq 1) { $InstallerArguments += "-ConvertEndpointIPConfig 1"; $ConvertEndpointIPConfig = $TRUE; if ($EndpointConnections.Count -eq 0) { @@ -300,7 +316,7 @@ function Start-IcingaAgentInstallWizard() } } - if ($EndpointConnections.Count -eq 0 -And $AcceptConnections -eq 1) { + if ($EndpointConnections.Count -eq 0 -And $AcceptConnections -eq 0) { $NetworkDefault = ''; foreach ($Endpoint in $Endpoints) { $NetworkDefault += [string]::Format('[{0}]:{1},', $Endpoint, $CAPort); @@ -321,7 +337,7 @@ function Start-IcingaAgentInstallWizard() } if ([string]::IsNullOrEmpty($ParentZone)) { - $ParentZone = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the parent zone this agent will connect to' -Default 'v' -DefaultInput 'master').answer; + $ParentZone = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the parent zone this Agent will connect to' -Default 'v' -DefaultInput 'master').answer; $InstallerArguments += "-ParentZone $ParentZone"; } @@ -355,10 +371,15 @@ function Start-IcingaAgentInstallWizard() if ($null -eq $GlobalZones) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to add custom global zones?' -Default 'n').result -eq 0) { - $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify your additional zones seperated by ","' -Default 'v').answer; - $GlobalZones = ($ArrayString.Replace(' ', '')).Split(',') - $GlobalZoneConfig += $GlobalZones; - $InstallerArguments += ("-GlobalZones " + ([string]::Join(',', $GlobalZones))); + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify your additional zones seperated by "," (Example: "global-zone1, global-zone2")' -Default 'v').answer; + if ([string]::IsNullOrEmpty($ArrayString) -eq $FALSE) { + $GlobalZones = ($ArrayString.Replace(' ', '')).Split(',') + $GlobalZoneConfig += $GlobalZones; + $InstallerArguments += ("-GlobalZones " + ([string]::Join(',', $GlobalZones))); + } else { + $GlobalZones = @(); + $InstallerArguments += ("-GlobalZones @()"); + } } else { $GlobalZones = @(); $InstallerArguments += ("-GlobalZones @()"); @@ -369,12 +390,12 @@ function Start-IcingaAgentInstallWizard() if ($CanConnectToParent) { if ([string]::IsNullOrEmpty($CAEndpoint)) { - $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the IP/FQDN for either ONE of your Icinga parent nodes or your Icinga 2 CA master for requesting certificates' -Default 'v' -DefaultInput (Get-IPConfigFromString $EndpointConnections[0]).address).answer; + $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the connection data of the parent node that handles certificate requests' -Default 'v' -DefaultInput (Get-IPConfigFromString $EndpointConnections[0]).address).answer; $InstallerArguments += "-CAEndpoint $CAEndpoint"; } if ([string]::IsNullOrEmpty($Ticket) -And $null -eq $EmptyTicket) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you have a Icinga Ticket available to sign your certificate?' -Default 'y').result -eq 1) { - $Ticket = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your Icinga Ticket' -Default 'v').answer; + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you have a PKI Ticket to sign your certificate request?' -Default 'y').result -eq 1) { + $Ticket = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your PKI Ticket' -Default 'v').answer; if ([string]::IsNullOrEmpty($Ticket)) { $InstallerArguments += "-EmptyTicket 1" } else { @@ -400,7 +421,7 @@ function Start-IcingaAgentInstallWizard() } else { if ([string]::IsNullOrEmpty($CAFile) -And $null -eq $EmptyCA) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is your public Icinga 2 CA (ca.crt) available on a local, network or web share?' -Default 'y').result -eq 1) { - $CAFile = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please provide the full path to your ca.crt file' -Default 'v').answer; + $CAFile = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please provide the full path to your ca.crt file (Examples: "C:\icinga2\ca.crt", "https://icinga.example.com/ca.crt"' -Default 'v').answer; if ([string]::IsNullOrEmpty($CAFile)) { $InstallerArguments += "-EmptyCA 1" } else { @@ -409,7 +430,8 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += "-CAFile '$CAFile'"; } else { $InstallerArguments += "-CAFile ''"; - $InstallerArguments += "-EmptyCA 1" + $InstallerArguments += "-EmptyCA 1"; + $EmptyCA = $TRUE; } } else { if ([string]::IsNullOrEmpty($CAFile)) { @@ -426,11 +448,11 @@ function Start-IcingaAgentInstallWizard() } if ([string]::IsNullOrEmpty($ServiceUser)) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to change the user the Icinga Agent service is running with (Default: "NT Authority\NetworkService")?' -Default 'n').result -eq 0) { - $ServiceUser = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the user you wish the Icinga Agent service to run with' -Default 'v' -DefaultInput 'NT Authority\NetworkService').answer; + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to change the user of the Icinga Agent service? (Defaults: "NT Authority\NetworkService")' -Default 'n').result -eq 0) { + $ServiceUser = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter a custom user for the Icinga Agent service' -Default 'v' -DefaultInput 'NT Authority\NetworkService').answer; $InstallerArguments += "-ServiceUser $ServiceUser"; if ($null -eq $ServicePass) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Does your Icinga Service user require a password to login (not required for System users)?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Does your Icinga Agent service user require a password to login? (Not required for System users)' -Default 'y').result -eq 1) { $ServicePass = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the password for your service user' -Secure -Default 'v').answer; $InstallerArguments += "-ServicePass $ServicePass"; } else { @@ -464,7 +486,7 @@ function Start-IcingaAgentInstallWizard() } if ($null -eq $InstallFrameworkService) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the PowerShell Framework as a Service?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the PowerShell Framework as a service?' -Default 'y').result -eq 1) { $result = Get-IcingaFrameworkServiceBinary; $InstallerArguments += "-InstallFrameworkService 1"; $InstallerArguments += [string]::Format("-FrameworkServiceUrl '{0}'", $result.FrameworkServiceUrl); @@ -511,18 +533,30 @@ function Start-IcingaAgentInstallWizard() Move-IcingaAgentDefaultConfig; Set-IcingaAgentNodeName -Hostname $Hostname; Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass -SetPermission | Out-Null; - Install-IcingaFrameworkService -Path $ServiceBin -User $ServiceUser -Password $ServicePass | Out-Null; + if ($InstallFrameworkService) { + Install-IcingaFrameworkService -Path $ServiceBin -User $ServiceUser -Password $ServicePass | Out-Null; + } Register-IcingaBackgroundDaemon -Command 'Start-IcingaServiceCheckDaemon'; Install-IcingaAgentBaseFeatures; Install-IcingaAgentCertificates -Hostname $Hostname -Endpoint $CAEndpoint -Port $CAPort -CACert $CAFile -Ticket $Ticket | Out-Null; Write-IcingaAgentApiConfig -Port $CAPort; + if ($EmptyCA -eq $TRUE) { + Disable-IcingaAgentFeature 'api'; + Write-IcingaConsoleWarning -Message '{0}{1}{2}{3}{4}' -Objects 'Your Icinga Agent API feature has been disabled. Please provide either your ca.crt ', + 'or connect to a parent node for certificate requests. You can run "Install-IcingaAgentCertificates" ', + 'with your configuration to properly create the host certificate and a valid certificate request. ', + 'After this you can enable the API feature by using "Enable-IcingaAgentFeature api" and restart the ', + 'Icinga Agent service "Restart-IcingaService icinga2"'; + } Write-IcingaAgentZonesConfig -Endpoints $Endpoints -EndpointConnections $EndpointConnections -ParentZone $ParentZone -GlobalZones $GlobalZoneConfig -Hostname $Hostname; if ($AddFirewallRule) { # First cleanup the system by removing all old Firewalls Enable-IcingaFirewall -IcingaPort $CAPort -Force; } Test-IcingaAgent; - Restart-IcingaService 'icingapowershell'; + if ($InstallFrameworkService) { + Restart-IcingaService 'icingapowershell'; + } Restart-IcingaService 'icinga2'; } } diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 index ff38c78..fd63c13 100644 --- a/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 +++ b/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 @@ -12,7 +12,7 @@ function Set-IcingaAgentServicePermission() $NewSystemContent = @(); if ([string]::IsNullOrEmpty($ServiceUser)) { - Write-IcingaTestOutput -Severity 'FAILED' -Message 'There is no user assigned to the Icinga 2 service or the service is not yet installed'; + Write-IcingaTestOutput -Severity 'Failed' -Message 'There is no user assigned to the Icinga 2 service or the service is not yet installed'; return $FALSE; } diff --git a/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 b/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 index 249e7a3..68a950e 100644 --- a/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 +++ b/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 @@ -38,13 +38,13 @@ function Test-IcingaAcl() [string]$messageFormat = 'Directory "{0}" {1} by the Icinga Service User "{2}"'; if ($UserFound) { if ($HasAccess) { - Write-IcingaTestOutput -Severity 'PASSED' -Message ([string]::Format($messageFormat, $Directory, 'is accessible and writeable', $ServiceUser)); + Write-IcingaTestOutput -Severity 'Passed' -Message ([string]::Format($messageFormat, $Directory, 'is accessible and writeable', $ServiceUser)); } else { - Write-IcingaTestOutput -Severity 'FAILED' -Message ([string]::Format($messageFormat, $Directory, 'is accessible but NOT writeable', $ServiceUser)); + Write-IcingaTestOutput -Severity 'Failed' -Message ([string]::Format($messageFormat, $Directory, 'is accessible but NOT writeable', $ServiceUser)); Write-IcingaConsolePlain "\_ Please run the following command to fix this issue: Set-IcingaAcl -Directory '$Directory'"; } } else { - Write-IcingaTestOutput -Severity 'FAILED' -Message ([string]::Format($messageFormat, $Directory, 'is not accessible', $ServiceUser)); + Write-IcingaTestOutput -Severity 'Failed' -Message ([string]::Format($messageFormat, $Directory, 'is not accessible', $ServiceUser)); Write-IcingaConsolePlain "\_ Please run the following command to fix this issue: Set-IcingaAcl -Directory '$Directory'"; } } diff --git a/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 index 32ffdee..1c6cbaf 100644 --- a/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 +++ b/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 @@ -1,18 +1,18 @@ function Test-IcingaAgent() { if (Get-Service 'icinga2' -ErrorAction SilentlyContinue) { - Write-IcingaTestOutput -Severity 'PASSED' -Message 'Icinga Agent Service is installed'; + Write-IcingaTestOutput -Severity 'Passed' -Message 'Icinga Agent service is installed'; Test-IcingaAgentServicePermission | Out-Null; Test-IcingaAcl "$Env:ProgramData\icinga2\etc" -WriteOutput | Out-Null; Test-IcingaAcl "$Env:ProgramData\icinga2\var" -WriteOutput | Out-Null; Test-IcingaAcl (Get-IcingaCacheDir) -WriteOutput | Out-Null; Test-IcingaAgentConfig | Out-Null; if (Test-IcingaAgentFeatureEnabled -Feature 'debuglog') { - Write-IcingaTestOutput -Severity 'WARNING' -Message 'The Debug-Log of the Icinga Agent is enabled. Please keep in mind to disable it once testing is done, as a huge amount of data is generated.' + Write-IcingaTestOutput -Severity 'Warning' -Message 'The debug log of the Icinga Agent is enabled. Please keep in mind to disable it once testing is done, as a huge amount of data is generated' } else { - Write-IcingaTestOutput -Severity 'PASSED' -Message 'Icinga Agent Debug-Log is disabled' + Write-IcingaTestOutput -Severity 'Passed' -Message 'Icinga Agent debug log is disabled' } } else { - Write-IcingaTestOutput -Severity 'FAILED' -Message 'Icinga Agent Service is not installed'; + Write-IcingaTestOutput -Severity 'Failed' -Message 'Icinga Agent service is not installed'; } } diff --git a/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 index 3dc55ab..5fbab5c 100644 --- a/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 +++ b/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 @@ -8,10 +8,10 @@ function Test-IcingaAgentConfig() $ConfigResult = Start-IcingaProcess -Executable $Binary -Arguments 'daemon -C'; if ($ConfigResult.ExitCode -eq 0) { - Write-IcingaTestOutput -Severity 'PASSED' -Message 'Icinga Agent configuration is valid'; + Write-IcingaTestOutput -Severity 'Passed' -Message 'Icinga Agent configuration is valid'; return $TRUE; } else { - Write-IcingaTestOutput -Severity 'FAILED' -Message 'Icinga Agent configuration is containing errors. Run this command for getting a detailed error report: "Test-IcingaAgentConfig -WriteStackTrace | Out-Null"'; + Write-IcingaTestOutput -Severity 'Failed' -Message 'Icinga Agent configuration contains errors. Run this command for getting a detailed error report: "Test-IcingaAgentConfig -WriteStackTrace | Out-Null"'; if ($WriteStackTrace) { Write-IcingaConsolePlain $ConfigResult.Message; } diff --git a/lib/core/icingaagent/tests/Test-IcingaAgentServicePermission.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgentServicePermission.psm1 index 6b53163..b99bebc 100644 --- a/lib/core/icingaagent/tests/Test-IcingaAgentServicePermission.psm1 +++ b/lib/core/icingaagent/tests/Test-IcingaAgentServicePermission.psm1 @@ -15,7 +15,7 @@ function Test-IcingaAgentServicePermission() if ([string]::IsNullOrEmpty($ServiceUser)) { if (-Not $Silent) { - Write-IcingaTestOutput -Severity 'FAILED' -Message 'There is no user assigned to the Icinga 2 service or the service is not yet installed'; + Write-IcingaTestOutput -Severity 'Failed' -Message 'There is no user assigned to the Icinga 2 service or the service is not yet installed'; } return $FALSE; } @@ -40,9 +40,9 @@ function Test-IcingaAgentServicePermission() if (-Not $Silent) { if ($FoundSID) { - Write-IcingaTestOutput -Severity 'PASSED' -Message ([string]::Format('The specified user "{0}" is allowed to run as service.', $ServiceUser)); + Write-IcingaTestOutput -Severity 'Passed' -Message ([string]::Format('The specified user "{0}" is allowed to run as service', $ServiceUser)); } else { - Write-IcingaTestOutput -Severity 'FAILED' -Message ([string]::Format('The specified user "{0}" is not allowed to run as service.', $ServiceUser)); + Write-IcingaTestOutput -Severity 'Failed' -Message ([string]::Format('The specified user "{0}" is not allowed to run as service', $ServiceUser)); } } diff --git a/lib/core/icingaagent/writers/Write-IcingaTestOutput.psm1 b/lib/core/icingaagent/writers/Write-IcingaTestOutput.psm1 index bfb8110..345db68 100644 --- a/lib/core/icingaagent/writers/Write-IcingaTestOutput.psm1 +++ b/lib/core/icingaagent/writers/Write-IcingaTestOutput.psm1 @@ -1,7 +1,7 @@ function Write-IcingaTestOutput() { param( - [ValidateSet('PASSED', 'WARNING', 'FAILED')] + [ValidateSet('Passed', 'Warning', 'Failed')] $Severity, $Message ); @@ -9,15 +9,15 @@ function Write-IcingaTestOutput() $Color = 'Green'; Switch ($Severity) { - 'PASSED' { + 'Passed' { $Color = 'Green'; break; }; - 'WARNING' { + 'Warning' { $Color = 'Yellow'; break; }; - 'FAILED' { + 'Failed' { $Color = 'Red'; break; };