Icinga2Agent.psm1: push latest version

This commit is contained in:
Christian Stein 2017-07-20 18:33:24 +02:00 committed by Thomas Gelf
parent d4324bfeeb
commit 8ffdb96d65
1 changed files with 323 additions and 74 deletions

View File

@ -20,11 +20,12 @@ function Icinga2AgentModule {
[bool]$AgentAddFirewallRule = $FALSE,
[array]$ParentEndpoints,
[array]$EndpointsConfig,
[array]$GlobalZones,
[array]$GlobalZones = @( 'director-global' ),
# Agent installation / update
[string]$IcingaServiceUser,
[string]$DownloadUrl = 'https://packages.icinga.com/windows/',
[string]$AgentInstallDirectory,
[bool]$AllowUpdates = $FALSE,
[array]$InstallerHashes,
[bool]$FlushApiDirectory = $FALSE,
@ -41,7 +42,7 @@ function Icinga2AgentModule {
[string]$DirectorPassword,
[string]$DirectorDomain,
[string]$DirectorAuthToken,
[string]$DirectorHostObject,
[System.Object]$DirectorHostObject,
[bool]$DirectorDeployConfig = $FALSE,
# NSClient Installer
@ -54,9 +55,13 @@ function Icinga2AgentModule {
# Uninstaller arguments
[bool]$FullUninstallation = $FALSE,
[bool]$RemoveNSClient = $FALSE,
#Internal handling
[bool]$DebugMode = $FALSE
[switch]$RunInstaller = $FALSE,
[switch]$RunUninstaller = $FALSE,
[bool]$DebugMode = $FALSE,
[string]$ModuleLogFile
);
#
@ -78,10 +83,11 @@ function Icinga2AgentModule {
icinga_enable_debug_log = $IcingaEnableDebugLog;
agent_add_firewall_rule = $AgentAddFirewallRule;
parent_endpoints = $ParentEndpoints;
endpoints_config = $EndpointsConfig;
endpoints_config = $EndpointsConfig;
global_zones = $GlobalZones;
icinga_service_user = $IcingaServiceUser;
download_url = $DownloadUrl;
agent_install_directory = $AgentInstallDirectory;
allow_updates = $AllowUpdates;
installer_hashes = $InstallerHashes;
flush_api_directory = $FlushApiDirectory;
@ -103,7 +109,9 @@ function Icinga2AgentModule {
nsclient_directory = $NSClientDirectory;
nsclient_installer_path = $NSClientInstallerPath;
full_uninstallation = $FullUninstallation;
remove_nsclient = $RemoveNSClient;
debug_mode = $DebugMode;
module_log_file = $ModuleLogFile;
}
#
@ -173,7 +181,7 @@ function Icinga2AgentModule {
# $this.setProperty('agent_version', '2.4.10')
#
$installer | Add-Member -membertype ScriptMethod -name 'setProperty' -value {
param([string] $key, [string]$value);
param([string]$key, $value);
# Initialse some variables first
# will only be called once
@ -195,20 +203,81 @@ function Icinga2AgentModule {
}
#
# Print an exception message and wait 5 seconds
# before continuing the execution. After each
# exception call we should ensure the script
# ends with exit.
# Todo: Adding exit 1 here results in an script
# error we should take care off before adding it
# again
# Deprecated: Do no longer use!
# Write all output from consoles to a logfile
#
$installer | Add-Member -membertype ScriptMethod -name 'writeLogFile' -value {
param([string]$severity, [string]$content);
# If no logfile is specified, do nothing
if (-Not $this.config('module_log_file')) {
return;
}
# Store our logfile into a variable
$logFile = $this.config('module_log_file');
# Have we specified a directory to write into or a file already?
try {
# Check if we are a directory or a file
# Will return false for files or non-existing files
$directory = (Get-Item $logFile) -is [System.IO.DirectoryInfo];
} catch {
# Nothing to catch. Simply get rid of error messages from aboves function in case of error
# Will return false anyways on error
}
# If we are a directory, add a file we can write to
if ($directory) {
$logFile = Join-Path -Path $logFile -ChildPath 'icinga2agent_psmodule.log';
}
# Format a timestamp to get to know the exact date and time. Example: 2017-13-07 22:09:13.263.263
$timestamp = Get-Date -Format "yyyy-dd-MM HH:mm:ss.fff";
$content = [string]::Format('{0} [{1}]: {2}', $timestamp, $severity, $content);
# Write the content to our logfile
Add-Content -Path $logFile -Value $content;
}
#
# This function will print messages as errors, but add them internally to
# an exception list. These will re-printed at the end to summarize possible
# issues during the run
#
$installer | Add-Member -membertype ScriptMethod -name 'exception' -value {
param([string]$message, [string[]]$args);
$Error.clear();
$this.warn('Calling deprecated function exception. Use throw instead.');
throw 'Exception: ' + $message;
[array]$exceptions = $this.getProperty('exception_messages');
if ($exceptions -eq $null) {
$exceptions = @();
}
$exceptions += $message;
$this.setProperty('exception_messages', $exceptions);
write-host 'Fatal:' $message -ForegroundColor red;
$this.writeLogFile('fatal', $message);
}
#
# Get the current exit code of the script. Return 0 for no errors and 1 for
# possible errors, including a summary of what went wrong
#
$installer | Add-Member -membertype ScriptMethod -name 'getScriptExitCode' -value {
[array]$exceptions = $this.getProperty('exception_messages');
if ($exceptions -eq $null) {
return 0;
}
$this.writeLogFile('fatal', '##################################################################');
$message = '######## The script encountered several errors during run ########';
$this.writeLogFile('fatal', $message);
$this.writeLogFile('fatal', '##################################################################');
write-host $message -ForegroundColor red;
foreach ($err in $exceptions) {
write-host 'Fatal:' $err -ForegroundColor red;
$this.writeLogFile('fatal', $err);
}
return 1;
}
#
@ -247,6 +316,7 @@ function Icinga2AgentModule {
$installer | Add-Member -membertype ScriptMethod -name 'error' -value {
param([string] $message, [array] $args);
Write-Host 'Error:' $message -ForegroundColor red;
$this.writeLogFile('error', $message);
}
#
@ -255,6 +325,7 @@ function Icinga2AgentModule {
$installer | Add-Member -membertype ScriptMethod -name 'warn' -value {
param([string] $message, [array] $args);
Write-Host 'Warning:' $message -ForegroundColor yellow;
$this.writeLogFile('warning', $message);
}
#
@ -263,6 +334,7 @@ function Icinga2AgentModule {
$installer | Add-Member -membertype ScriptMethod -name 'info' -value {
param([string] $message, [array] $args);
Write-Host 'Notice:' $message -ForegroundColor green;
$this.writeLogFile('info', $message);
}
#
@ -273,6 +345,7 @@ function Icinga2AgentModule {
param([string] $message, [array] $args);
if ($this.config('debug_mode')) {
Write-Host 'Debug:' $message -ForegroundColor blue;
$this.writeLogFile('debug', $message);
}
}
@ -283,8 +356,8 @@ function Icinga2AgentModule {
$installer | Add-Member -membertype ScriptMethod -name 'init' -value {
$this.setProperty('initialized', $TRUE);
# Set the default config dir
$this.setProperty('config_dir', $Env:ProgramData + '\icinga2\etc\icinga2\');
$this.setProperty('api_dir', $Env:ProgramData + '\icinga2\var\lib\icinga2\api');
$this.setProperty('config_dir', (Join-Path -Path $Env:ProgramData -ChildPath 'icinga2\etc\icinga2\'));
$this.setProperty('api_dir', (Join-Path -Path $Env:ProgramData -ChildPath 'icinga2\var\lib\icinga2\api'));
$this.setProperty('icinga_ticket', $this.config('ticket'));
$this.setProperty('local_hostname', $this.config('agent_name'));
# Ensure we generate the required configuration content
@ -383,8 +456,7 @@ function Icinga2AgentModule {
# Load all configured global zones
[array]$global_zones = $this.config('global_zones');
# Add director-global zone as default - always
[string]$zones = 'object Zone "director-global" {' + "`n" + ' global = true' + "`n" + '}' + "`n";
[string]$zones = '';
# In case no zones are given, simply add director-global
if ($global_zones -eq $NULL) {
@ -394,8 +466,7 @@ function Icinga2AgentModule {
# Loop through all given zones and add them to our configuration
foreach ($zone in $global_zones) {
# Ignore possible configured director-global zone, as already present
if ($zone -ne 'director-global') {
if ($zone -ne '') {
$zones = $zones + 'object Zone "' + $zone + '" {' + "`n" + ' global = true' + "`n" + '}' + "`n";
}
}
@ -538,7 +609,7 @@ function Icinga2AgentModule {
# We could try to install the Agent from a local directory
#
$installer | Add-Member -membertype ScriptMethod -name 'isDownloadPathLocal' -value {
if (Test-Path ($this.config('download_url'))) {
if ($this.config('download_url') -And (Test-Path ($this.config('download_url')))) {
return $TRUE;
}
return $FALSE;
@ -563,10 +634,10 @@ function Icinga2AgentModule {
$client.DownloadFile($url, $this.getInstallerPath());
if (-Not $this.installerExists()) {
throw 'Unable to locate downloaded Icinga 2 Agent installer file from ' + $url + '. Download destination: ' + $this.getInstallerPath();
$this.exception('Unable to locate downloaded Icinga 2 Agent installer file from ' + $url + '. Download destination: ' + $this.getInstallerPath());
}
} catch {
throw 'Unable to download Icinga 2 Agent from ' + $url + '. Please ensure the link does exist and access is possible. Error: ' + $_.Exception.Message;
$this.exception('Unable to download Icinga 2 Agent from ' + $url + '. Please ensure the link does exist and access is possible. Error: ' + $_.Exception.Message);
}
}
}
@ -616,14 +687,19 @@ function Icinga2AgentModule {
# Returns the full path to our installer package
#
$installer | Add-Member -membertype ScriptMethod -name 'getInstallerPath' -value {
if (-Not $this.config('download_url') -Or -Not $this.getProperty('install_msi_package')) {
return '';
}
$installerPath = Join-Path -Path $this.config('download_url') -ChildPath $this.getProperty('install_msi_package')
if ($this.isDownloadPathLocal()) {
if (Test-Path ($this.config('download_url') + $this.getProperty('install_msi_package'))) {
return $this.config('download_url') + $this.getProperty('install_msi_package');
if (Test-Path $installerPath) {
return $installerPath;
} else {
throw 'Failed to locate local Icinga 2 Agent installer at ' + $this.config('download_url') + $this.getProperty('install_msi_package');
$this.exception('Failed to locate local Icinga 2 Agent installer at ' + $installerPath);
return '';
}
} else {
return $Env:temp + '\' + $this.getProperty('install_msi_package');
return (Join-Path -Path $Env:temp -ChildPath $this.getProperty('install_msi_package'));
}
}
@ -632,30 +708,57 @@ function Icinga2AgentModule {
# does exist in first place
#
$installer | Add-Member -membertype ScriptMethod -name 'installerExists' -value {
if (Test-Path $this.getInstallerPath()) {
if ($this.getInstallerPath() -And (Test-Path $this.getInstallerPath())) {
return $TRUE;
}
return $FALSE;
}
#
# Get all arguments for the Icinga 2 Agent installer package
#
$installer | Add-Member -membertype ScriptMethod -name 'getIcingaAgentInstallerArguments' -value {
# Initialise some basic variables
[string]$arguments = '';
[string]$installerLocation = '';
# By default, install the Icinga 2 Agent again in the pre-installed directory
# before the update. Will only apply during updates / downgrades of the Agent
if ($this.getProperty('cur_install_dir')) {
$installerLocation = [string]::Format(' INSTALL_ROOT="{0}"', $this.getProperty('cur_install_dir'));
}
# However, if we specified a custom directory over the argument, always use that
# one as installer target directory
if ($this.config('agent_install_directory')) {
$installerLocation = [string]::Format(' INSTALL_ROOT="{0}"', $this.config('agent_install_directory'));
$this.setProperty('cur_install_dir', $this.config('agent_install_directory'));
}
$arguments += $installerLocation;
return $arguments;
}
#
# Install the Icinga 2 agent from the provided installation package
#
$installer | Add-Member -membertype ScriptMethod -name 'installAgent' -value {
$this.downloadInstaller();
if (-Not $this.installerExists()) {
throw 'Failed to setup Icinga 2 Agent. Installer package not found.';
$this.exception('Failed to setup Icinga 2 Agent. Installer package not found.');
return;
}
$this.verifyInstallerChecksumAndThrowException();
$this.info('Installing Icinga 2 Agent');
$this.info('Installing Icinga 2 Agent...');
# Start the installer process
$result = $this.startProcess('MsiExec.exe', $TRUE, '/quiet /i "' + $this.getInstallerPath() + '"');
$result = $this.startProcess('MsiExec.exe', $TRUE, [string]::Format('/quiet /i "{0}" {1}', $this.getInstallerPath(), $this.getIcingaAgentInstallerArguments()));
# Exit Code 0 means the Agent was installed successfully
# Otherwise we require to throw an error
if ($result.Get_Item('exitcode') -ne 0) {
$this.error('Failed to install Icinga 2 Agent. ' + $result.Get_Item('message'));
$this.exception('Failed to install Icinga 2 Agent. ' + $result.Get_Item('message'));
} else {
$this.info('Icinga 2 Agent installed.');
}
@ -670,11 +773,13 @@ function Icinga2AgentModule {
$installer | Add-Member -membertype ScriptMethod -name 'updateAgent' -value {
$this.downloadInstaller();
if (-Not $this.installerExists()) {
throw 'Failed to update Icinga 2 Agent. Installer package not found.';
$this.exception('Failed to update Icinga 2 Agent. Installer package not found.');
return;
}
$this.verifyInstallerChecksumAndThrowException()
if (-Not $this.getProperty('uninstall_id')) {
throw 'Failed to update Icinga 2 Agent. Uninstaller is not specified.';
$this.exception('Failed to update Icinga 2 Agent. Uninstaller is not specified.');
return;
}
$this.info('Removing previous Icinga 2 Agent version...');
@ -684,24 +789,23 @@ function Icinga2AgentModule {
# Exit Code 0 means the Agent was removed successfully
# Otherwise we require to throw an error
if ($result.Get_Item('exitcode') -ne 0) {
$this.error('Failed to remove Icinga 2 Agent. ' + $result.Get_Item('message'));
$this.exception('Failed to remove Icinga 2 Agent. ' + $result.Get_Item('message'));
} else {
$this.info('Icinga 2 Agent successfully removed.');
}
$this.info('Installing new Icinga 2 Agent version...');
# Start the installer process
$result = $this.startProcess('MsiExec.exe', $TRUE, '/quiet /i "' + $this.getInstallerPath() + '"');
$result = $this.startProcess('MsiExec.exe', $TRUE, [string]::Format('/quiet /i "{0}" {1}', $this.getInstallerPath(), $this.getIcingaAgentInstallerArguments()));
# Exit Code 0 means the Agent was removed successfully
# Otherwise we require to throw an error
if ($result.Get_Item('exitcode') -ne 0) {
$this.error('Failed to install new Icinga 2 Agent. ' + $result.Get_Item('message'));
$this.exception('Failed to install new Icinga 2 Agent. ' + $result.Get_Item('message'));
} else {
$this.info('Icinga 2 Agent successfully updated.');
}
$this.setProperty('cur_install_dir', $this.getProperty('def_install_dir'));
$this.setProperty('require_restart', 'true');
}
@ -712,7 +816,6 @@ function Icinga2AgentModule {
#
$installer | Add-Member -membertype ScriptMethod -name 'isAgentInstalled' -value {
[string]$architecture = '';
[string]$defaultInstallDir = ${Env:ProgramFiles} + "\ICINGA2";
if ([IntPtr]::Size -eq 4) {
$architecture = "x86";
$regPath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*';
@ -738,7 +841,6 @@ function Icinga2AgentModule {
if ($localData.UninstallString) {
$this.setProperty('uninstall_id', $localData.UninstallString.Replace("MsiExec.exe ", ""));
}
$this.setProperty('def_install_dir', $defaultInstallDir);
$this.setProperty('cur_install_dir', $localData.InstallLocation);
$this.setProperty('agent_version', $localData.DisplayVersion);
$this.setProperty('install_msi_package', 'Icinga2-v' + $this.config('agent_version') + '-' + $architecture + '.msi');
@ -748,6 +850,8 @@ function Icinga2AgentModule {
return $TRUE;
} else {
$this.warn('Icinga 2 Agent does not seem to be installed on the system');
# Set Default value for install dir
$this.setProperty('cur_install_dir', (Join-Path $Env:ProgramFiles -ChildPath 'ICINGA2'));
}
return $FALSE;
}
@ -805,7 +909,7 @@ function Icinga2AgentModule {
$installer | Add-Member -membertype ScriptMethod -name 'getNSClientDefaultExecutablePath' -value {
if ($this.config('nsclient_directory')) {
return $this.config('nsclient_directory') + '\nscp.exe';
return (Join-Path -Path $this.config('nsclient_directory') -ChildPath 'nscp.exe');
}
if (Test-Path ('C:\Program Files\NSClient++\nscp.exe')) {
@ -826,7 +930,7 @@ function Icinga2AgentModule {
# the correct, valid installation path
#
$installer | Add-Member -membertype ScriptMethod -name 'getInstallPath' -value {
[string]$agentPath = $this.getProperty('def_install_dir');
[string]$agentPath = '';
if ($this.getProperty('cur_install_dir')) {
$agentPath = $this.getProperty('cur_install_dir');
}
@ -842,7 +946,7 @@ function Icinga2AgentModule {
# use them later again
#
$installer | Add-Member -membertype ScriptMethod -name 'backupDefaultConfig' -value {
[string]$configFile = $this.getProperty('config_dir') + 'icinga2.conf';
[string]$configFile = Join-Path -Path $this.getProperty('config_dir') -ChildPath 'icinga2.conf';
[string]$configBackupFile = $configFile + 'director.bak';
# Check if a config and backup file already exists
@ -862,7 +966,7 @@ function Icinga2AgentModule {
#
$installer | Add-Member -membertype ScriptMethod -name 'cleanupAgentInstaller' -value {
if (-Not ($this.isDownloadPathLocal())) {
if (Test-Path $this.getInstallerPath()) {
if ($this.getInstallerPath() -And (Test-Path $this.getInstallerPath())) {
$this.info('Removing downloaded Icinga 2 Agent installer');
Remove-Item $this.getInstallerPath() | out-null;
}
@ -1106,15 +1210,27 @@ function Icinga2AgentModule {
}
[string]$icingaNewConfig =
'/** Icinga 2 Config - proposed by Icinga 2 PowerShell Module */
'/**
* Icinga 2 Config - Proposed by Icinga 2 PowerShell Module
*/
/* Define our includes to run the agent properly. */
include "constants.conf"
include <itl>
include <plugins>
include <nscp>
include <windows-plugins>
/* Define our block required to enable or disable Icinga 2 debug log
* Enable or disable it by using the PowerShell Module with
* argument -IcingaEnableDebugLog or by switching
* PowerShellIcinga2EnableDebug to true or false manually.
* true: Debug log is active
* false: Debug log is deactivated
* IMPORTANT: ";" after true or false has to remain to allow the
* PowerShell Module to switch this feature on or off.
*/
const PowerShellIcinga2EnableDebug = false;
if (PowerShellIcinga2EnableDebug) {
object FileLogger "debug-file" {
severity = "debug"
@ -1122,26 +1238,49 @@ if (PowerShellIcinga2EnableDebug) {
}
}
/* Try to define a constant for our NSClient++ installation
* IMPORTANT: If the NSClient++ is installed newly to the system, the
* Icinga Service has to be restarted in order to set this variable
* correctly. If the NSClient++ is installed over the PowerShell Module,
* the Icinga 2 Service is restarted automaticly.
*/
if (!globals.contains("NscpPath")) {
NscpPath = dirname(msi_get_component_path("{5C45463A-4AE9-4325-96DB-6E239C034F93}"))
}
/* Enable our default main logger feature to write log output. */
object FileLogger "main-log" {
severity = "information"
path = LocalStateDir + "/log/icinga2/icinga2.log"
}
/* All informations required to correctly connect to our parent Icinga 2 nodes. */
object Endpoint "' + $this.getProperty('local_hostname') + '" {}
' + $this.getProperty('endpoint_objects') + '
/* Define the zone and its containing endpoints we should communicate with. */
object Zone "' + $this.config('parent_zone') + '" {
endpoints = [ ' + $this.getProperty('endpoint_nodes') +' ]
}
/* All of our global zones, check commands and other configuration are synced into.
* Director global zone must be defined in case the Icinga Director is beeing used.
* Default value for this is "director-global".
* All additional zones can be configured with -GlobalZones argument.
* IMPORTANT: If -GlobalZones argument is used, the Icinga Director global zones has
* to be defined as well within the argument array.
*/
' + $this.getProperty('global_zones') + '
/* Define a zone for our current agent and set our parent zone for proper communication. */
object Zone "' + $this.getProperty('local_hostname') + '" {
parent = "' + $this.config('parent_zone') + '"
endpoints = [ "' + $this.getProperty('local_hostname') + '" ]
}
/* Configure all settings we require for our API listener to properly work.
* This will include the certificates, if we accept configurations which
* can be changed with argument -AcceptConfig and the bind informations.
* The bind_port can be modified with argument -AgentListenPort.
*/
object ApiListener "api" {
cert_path = SysconfDir + "/icinga2/pki/' + $this.getProperty('local_hostname') + '.crt"
key_path = SysconfDir + "/icinga2/pki/' + $this.getProperty('local_hostname') + '.key"
@ -1201,7 +1340,7 @@ object ApiListener "api" {
# Return the path to the Icinga 2 config file
#
$installer | Add-Member -membertype ScriptMethod -name 'getIcingaConfigFile' -value {
return ($this.getProperty('config_dir') + 'icinga2.conf');
return (Join-Path -Path $this.getProperty('config_dir') -ChildPath 'icinga2.conf');
}
#
@ -1260,8 +1399,8 @@ object ApiListener "api" {
$installer | Add-Member -membertype ScriptMethod -name 'generateCertificates' -value {
if ($this.getProperty('local_hostname') -And $this.config('ca_server') -And $this.getProperty('icinga_ticket')) {
[string]$icingaPkiDir = $this.getProperty('config_dir') + 'pki\';
[string]$icingaBinary = $this.getInstallPath() + '\sbin\icinga2.exe';
[string]$icingaPkiDir = Join-Path -Path $this.getProperty('config_dir') -ChildPath 'pki\';
[string]$icingaBinary = Join-Path -Path $this.getInstallPath() -ChildPath 'sbin\icinga2.exe';
[string]$agentName = $this.getProperty('local_hostname');
if (-Not (Test-Path $icingaBinary)) {
@ -1335,12 +1474,12 @@ object ApiListener "api" {
# Agent. If not, return FALSE
#
$installer | Add-Member -membertype ScriptMethod -name 'hasCertificates' -value {
[string]$icingaPkiDir = $this.getProperty('config_dir') + 'pki\';
[string]$icingaPkiDir = Join-Path -Path $this.getProperty('config_dir') -ChildPath 'pki';
[string]$agentName = $this.getProperty('local_hostname');
if (
((Test-Path ($icingaPkiDir + $agentName + '.key')) `
-And (Test-Path ($icingaPkiDir + $agentName + '.crt')) `
-And (Test-Path ($icingaPkiDir + 'ca.crt')))
((Test-Path ((Join-Path -Path $icingaPkiDir -ChildPath $agentName) + '.key'))) `
-And (Test-Path ((Join-Path -Path $icingaPkiDir -ChildPath $agentName) + '.crt')) `
-And (Test-Path (Join-Path -Path $icingaPkiDir -ChildPath 'ca.crt'))
) {
return $TRUE;
}
@ -1386,11 +1525,26 @@ object ApiListener "api" {
# Have we specified a version to install the Agent?
#
$installer | Add-Member -membertype ScriptMethod -name 'canInstallAgent' -value {
if (-Not $this.config('agent_version')) {
if ($this.config('download_url') -And $this.config('agent_version')) {
return $TRUE;
}
if (-Not $this.config('download_url') -And -Not $this.config('agent_version')) {
$this.warn('Icinga 2 Agent will not be installed. Arguments -DownloadUrl and -InstallAgentVersion both not defined.');
return $FALSE;
}
return $TRUE;
if (-Not $this.config('agent_version')) {
$this.warn('Icinga 2 Agent will not be installed. Argument -InstallAgentVersion is not defined.');
return $FALSE;
}
if (-Not $this.config('download_url')) {
$this.warn('Icinga 2 Agent will not be installed. Argument -DownloadUrl is not defined.');
return $FALSE;
}
return $FALSE;
}
#
@ -1418,7 +1572,7 @@ object ApiListener "api" {
if (-Not $this.config('parent_zone') -And $checkInternal) {
throw 'Parent Zone not defined. Please specify it with -ParentZone <name>';
}
$icingaBinary = $this.getInstallPath() + '\sbin\icinga2.exe';
$icingaBinary = Join-Path -Path $this.getInstallPath() -ChildPath 'sbin\icinga2.exe';
if (Test-Path $icingaBinary) {
$result = $this.startProcess($icingaBinary, $FALSE, 'daemon -C');
@ -1782,7 +1936,7 @@ object ApiListener "api" {
#
$installer | Add-Member -membertype ScriptMethod -name 'writeHostAPIKeyToDisk' -value {
if (Test-Path ($this.getProperty('config_dir'))) {
[string]$apiFile = $this.getProperty('config_dir') + 'icingadirector.token';
[string]$apiFile = Join-Path -Path $this.getProperty('config_dir') -ChildPath 'icingadirector.token';
$this.info('Writing host API-Key "' + $this.getProperty('director_host_token') + '" to "' + $apiFile + '"');
[System.IO.File]::WriteAllText($apiFile, $this.getProperty('director_host_token'));
}
@ -1792,7 +1946,7 @@ object ApiListener "api" {
# Read Host API-Key from disk for usage
#
$installer | Add-Member -membertype ScriptMethod -name 'readHostAPIKeyFromDisk' -value {
[string]$apiFile = $this.getProperty('config_dir') + 'icingadirector.token';
[string]$apiFile = Join-Path -Path $this.getProperty('config_dir') -ChildPath 'icingadirector.token';
if (Test-Path ($apiFile)) {
[string]$hostToken = [System.IO.File]::ReadAllText($apiFile);
$this.setProperty('director_host_token', $hostToken);
@ -1870,6 +2024,46 @@ object ApiListener "api" {
return $TRUE;
}
#
# This function will convert a [hashtable] or [array] object to string
# with function ConvertTo-Json for argument -DirectorHostObject.
# It will however only process those if the PowerShell Version is 3
# and above, because Version 2 is not providing the required
# functionality. In that case the module will throw an exception
#
$installer | Add-Member -membertype ScriptMethod -name 'convertDirectorHostObjectArgument' -value {
# First add the value to an object we can work with
[System.Object]$json = $this.config('director_host_object');
# Prevent processing of empty data
if ($json -eq $null -Or $json -eq '') {
return;
}
# In case the argument is already a string -> nothing to do
if ($json.GetType() -eq [string]) {
# Do nothing
return;
} elseif ($json.GetType() -eq [hashtable] -Or $json.GetType() -eq [array]) {
# Check which PowerShell Version we are using and throw an error in case our Version does not support the argument
if ($PSVersionTable.PSVersion.Major -lt 3) {
[string]$errorMessage = 'You are trying to pass an object of type [hashtable] or [array] for argument "-DirectorHostObject", but are using ' +
'PowerShell Version 2 or lower. Passing hashtables through this argument is possible, but it requires to be ' +
'converted with function ConvertTo-Json, which is available on PowerShell Version 3 and above only. ' +
'You can still process JSON-Values with this module, even on PowerShell Version 2, but you will have to pass the ' +
'JSON as string instead of an object. This module will now exit with an error code. For further details, please ' +
'read the documentation for the "-DirectorHostObject" argument. ' +
'Documentation: https://github.com/Icinga/icinga2-powershell-module/blob/master/doc/10-Basic-Arguments.md';
$this.exception($errorMessage);
throw 'PowerShell Version exception.';
}
# If our PowerShell Version is supporting the function, convert it to a valid string
$this.overrideConfig('director_host_object', (ConvertTo-Json -Compress $json));
}
}
#
# This function will fetch all arguments configured inside the Icinga Director
# to allow an entire auto configuration of the Icinga 2 Agent
@ -1995,7 +2189,7 @@ object ApiListener "api" {
# Exit Code 0 means the NSClient was installed successfully
# Otherwise we require to throw an error
if ($result.Get_Item('exitcode') -ne 0) {
$this.error('Failed to install NSClient++. ' + $result.Get_Item('message'));
$this.exception('Failed to install NSClient++. ' + $result.Get_Item('message'));
} else {
$this.info('NSClient++ successfully installed.');
}
@ -2034,13 +2228,13 @@ object ApiListener "api" {
$this.info('Trying to download NSClient++ from ' + $this.config('nsclient_installer_path'));
[System.Object]$client = New-Object System.Net.WebClient;
$client.DownloadFile($this.config('nsclient_installer_path'), $Env:temp + '\NSCP.msi');
$client.DownloadFile($this.config('nsclient_installer_path'), (Join-Path -Path $Env:temp -ChildPath 'NSCP.msi'));
return $Env:temp + '\NSCP.msi';
return (Join-Path -Path $Env:temp -ChildPath 'NSCP.msi');
} else {
# Icinga is shipping a NSClient Version after installation
# Install this version if defined
return $this.getInstallPath() + '\sbin\NSCP.msi';
return (Join-Path -Path $this.getInstallPath() -ChildPath 'sbin\NSCP.msi');
}
return '';
@ -2141,8 +2335,12 @@ object ApiListener "api" {
# Deprecated function
#
$installer | Add-Member -membertype ScriptMethod -name 'installIcinga2Agent' -value {
$this.warn('The function "installIcinga2Agent" is deprecated and will be removed soon. Please use "installMonitoringComponents" instead.')
return $this.installMonitoringComponents();
$this.warn('The function "installIcinga2Agent" is deprecated and will be removed soon. Please use "install" instead.')
return $this.install();
}
$installer | Add-Member -membertype ScriptMethod -name 'installMonitoringComponents' -value {
$this.warn('The function "installMonitoringComponents" is deprecated and will be removed soon. Please use "install" instead.')
return $this.install();
}
#
@ -2152,14 +2350,18 @@ object ApiListener "api" {
# including download and update if
# specified. Returnd 0 or 1 as exit code
#
$installer | Add-Member -membertype ScriptMethod -name 'installMonitoringComponents' -value {
$installer | Add-Member -membertype ScriptMethod -name 'install' -value {
try {
if (-Not $this.isAdmin()) {
return 1;
}
# Write an output to the logfile only, ensuring we always get a proper 'start entry' for the user
$this.info('Started script run...');
# Get the current API-Version from the Icinga Director
$this.getIcingaDirectorVersion();
# Convert our DirectorHostObject argument from Object to String if required
$this.convertDirectorHostObjectArgument();
# Read arguments for auto config from the Icinga Director
# At first only with our public key for global config attributes
$this.fetchArgumentsFromIcingaDirector($TRUE);
@ -2227,17 +2429,30 @@ object ApiListener "api" {
# We modify the service user at the very last to ensure
# the user we defined for logging in is valid
$this.modifyIcingaServiceUser();
return 0;
return $this.getScriptExitCode();
} catch {
$this.printLastException();
[void]$this.getScriptExitCode();
return 1;
}
}
#
# Removes the Icinga 2 Agent from the system
# Deprecated function
#
$installer | Add-Member -membertype ScriptMethod -name 'uninstallIcinga2Agent' -value {
$this.warn('The function "uninstallIcinga2Agent" is deprecated and will be removed soon. Please use "uninstall" instead.')
return $this.uninstall();
}
$installer | Add-Member -membertype ScriptMethod -name 'uninstallMonitoringComponents' -value {
$this.warn('The function "uninstallMonitoringComponents" is deprecated and will be removed soon. Please use "uninstall" instead.')
return $this.uninstall();
}
#
# Removes the Icinga 2 Agent from the system
#
$installer | Add-Member -membertype ScriptMethod -name 'uninstall' -value {
$this.info('Trying to locate Icinga 2 Agent...');
if ($this.isAgentInstalled()) {
@ -2254,22 +2469,56 @@ object ApiListener "api" {
if ($this.config('full_uninstallation')) {
$this.info('Flushing Icinga 2 program data directory...');
if (Test-Path ($Env:ProgramData + '\icinga2\')) {
if (Test-Path ((Join-Path -Path $Env:ProgramData -ChildPath 'icinga2'))) {
try {
[System.Object]$folder = New-Object -ComObject Scripting.FileSystemObject;
$folder.DeleteFolder($Env:ProgramData + '\icinga2');
[void]$folder.DeleteFolder((Join-Path -Path $Env:ProgramData -ChildPath 'icinga2'));
$this.info('Remaining Icinga 2 configuration successfully removed.');
} catch {
$this.error('Failed to delete Icinga 2 Program Data Directory: ' + $_.Exception.Message);
return 1;
$this.exception('Failed to delete Icinga 2 Program Data Directory: ' + $_.Exception.Message);
}
} else {
$this.warn('Icinga 2 Agent program directory not present.');
}
}
return 0;
if ($this.config('remove_nsclient')) {
$this.info('Trying to remove installed NSClient++...');
$nsclient = Get-WmiObject -Class Win32_Product |
Where-Object {
$_.Name -match 'NSClient*';
}
if ($nsclient -ne $null) {
$this.info('Removing installed NSClient++...');
[void]$nsclient.Uninstall();
$this.info('NSClient++ has been successfully removed.');
} else {
$this.warn('NSClient++ could not be located on the system. Nothing to remove.');
}
}
return $this.getScriptExitCode();
}
# Make the installation / uninstallation of the script easier and shorter
[int]$installerExitCode = 0;
[int]$uninstallerExitCode = 0;
# If flag RunUninstaller is set, do the uninstallation of the components
if ($RunUninstaller) {
$uninstallerExitCode = $installer.uninstall();
}
# If flag RunInstaller is set, do the installation of the components
if ($RunInstaller) {
$installerExitCode = $installer.install();
}
if ($RunInstaller -Or $RunUninstaller) {
if ($installerExitCode -ne 0 -Or $uninstallerExitCode -ne 0) {
return 1;
}
}
# Otherwise handle everything as before
return $installer;
}