From ddef1bd087ef538af1073e742c528097fcc32f20 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 13:43:20 +0100 Subject: [PATCH] Add support to download and install PowerShell service --- icinga-module-windows.psd1 | 2 +- icinga-module-windows.psm1 | 5 +++ .../framework/Expand-IcingaZipArchive.psm1 | 23 ++++++++++ .../Get-IcingaFrameworkServiceBinary.psm1 | 43 +++++++++++++++++++ .../Install-IcingaPowerShellService.psm1 | 26 +++++++++++ .../Test-IcingaZipBinaryChecksum.psm1 | 23 ++++++++++ 6 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 lib/core/framework/Expand-IcingaZipArchive.psm1 create mode 100644 lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 create mode 100644 lib/core/framework/Install-IcingaPowerShellService.psm1 create mode 100644 lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 diff --git a/icinga-module-windows.psd1 b/icinga-module-windows.psd1 index fdb32d1..e8e36fe 100644 --- a/icinga-module-windows.psd1 +++ b/icinga-module-windows.psd1 @@ -25,7 +25,7 @@ Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor t PowerShellVersion = '3.0' # Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind. -FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir' ) +FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Get-IcingaPowerShellModuleFile' ) # Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Plat'zhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind. CmdletsToExport = @() diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index c50c163..77f45d8 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -165,3 +165,8 @@ function Get-IcingaPowerShellConfigDir() { return (Join-Path -Path $PSScriptRoot -ChildPath 'config'); } + +function Get-IcingaPowerShellModuleFile() +{ + return (Join-Path -Path $PSScriptRoot -ChildPath 'icinga-module-windows.psm1'); +} diff --git a/lib/core/framework/Expand-IcingaZipArchive.psm1 b/lib/core/framework/Expand-IcingaZipArchive.psm1 new file mode 100644 index 0000000..658e63a --- /dev/null +++ b/lib/core/framework/Expand-IcingaZipArchive.psm1 @@ -0,0 +1,23 @@ +function Expand-IcingaZipArchive() +{ + param( + $Path, + $Destination + ); + + 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'; + return $FALSE; + } + + Add-Type -AssemblyName System.IO.Compression.FileSystem; + + try { + [System.IO.Compression.ZipFile]::ExtractToDirectory($Path, $Destination); + return $TRUE; + } catch { + throw $_.Exception; + } + + return $FALSE; +} diff --git a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 new file mode 100644 index 0000000..a80cc72 --- /dev/null +++ b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 @@ -0,0 +1,43 @@ +function Get-IcingaFrameworkServiceBinary() +{ + param( + [string]$DownloadUrl, + [string]$InstallDir + ); + + $ProgressPreference = "SilentlyContinue"; + + if ([string]::IsNullOrEmpty($DownloadUrl)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you provide a custom source of the service binary?' -Default 'n').result -eq 1) { + $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/LordHepipud/icinga-windows-service/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; + $DownloadUrl = $LatestRelease.Replace('/tag/', '/download/'); + $Tag = $DownloadUrl.Split('/')[-1]; + $DownloadUrl = [string]::Format('{0}/icinga-service-{1}.zip', $DownloadUrl, $Tag); + } else { + $DownloadUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the full path to your service binary repository' -Default 'v').answer; + } + } + + if ([string]::IsNullOrEmpty($InstallDir)) { + $InstallDir = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the path you wish to install the service to' -Default 'v' -DefaultInput 'C:\Program Files\icinga-framework-service\').answer; + } + + if ((Test-Path $InstallDir) -eq $FALSE) { + New-Item -Path $InstallDir -Force -ItemType Directory | Out-Null; + } + + $ZipArchive = Join-Path -Path $InstallDir -ChildPath ($DownloadUrl.Split('/')[-1]); + $ServiceBin = Join-Path -Path $InstallDir -ChildPath 'icinga-service.exe'; + + Invoke-WebRequest -Uri $DownloadUrl -UseBasicParsing -OutFile $ZipArchive; + + if ((Expand-IcingaZipArchive -Path $ZipArchive -Destination $InstallDir) -eq $FALSE) { + throw 'Failed to expand the downloaded ZIP archive'; + } + + if ((Test-IcingaZipBinaryChecksum -Path $ServiceBin) -eq $FALSE) { + throw 'The checksum of the downloaded file and the required MD5 hash are not matching'; + } + + return $ServiceBin; +} diff --git a/lib/core/framework/Install-IcingaPowerShellService.psm1 b/lib/core/framework/Install-IcingaPowerShellService.psm1 new file mode 100644 index 0000000..cd1e2da --- /dev/null +++ b/lib/core/framework/Install-IcingaPowerShellService.psm1 @@ -0,0 +1,26 @@ +function Install-IcingaPowerShellService() +{ + param( + $Path, + $Username, + [SecureString]$Password + ); + + if ((Test-Path $Path) -eq $FALSE) { + throw 'Please specify the path directly to the service binary'; + } + + $Path = [string]::Format( + '{0} \"{1}\"', + $Path, + (Get-IcingaPowerShellModuleFile) + ); + + $ServiceCreation = Start-IcingaProcess -Executable 'sc.exe' -Arguments ([string]::Format('create icingapowershell binPath= "{0}" DisplayName= "Icinga PowerShell Service" start= auto', $Path)); + + if ($ServiceCreation.ExitCode -ne 0) { + throw ([string]::Format('Failed to install Icinga PowerShell Service: {0}{1}', $ServiceCreation.Message, $ServiceCreation.Error)); + } + + return (Set-IcingaAgentServiceUser -User $Username -Password $Password -Service 'icingapowershell'); +} diff --git a/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 b/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 new file mode 100644 index 0000000..94612fa --- /dev/null +++ b/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 @@ -0,0 +1,23 @@ +function Test-IcingaZipBinaryChecksum() +{ + param( + $Path + ); + + $MD5Path = [string]::Format('{0}.md5', $Path); + + if ((Test-Path $MD5Path) -eq $FALSE) { + return $TRUE; + } + + [string]$MD5Checksum = Get-Content $MD5Path; + $MD5Checksum = ($MD5Checksum.Split(' ')[0]).ToLower(); + + $FileHash = ((Get-FileHash $Path -Algorithm MD5).Hash).ToLower(); + + if ($MD5Checksum -ne $FileHash) { + return $FALSE; + } + + return $TRUE; +}