icinga-powershell-framework/lib/core/dev/Publish-IcingaForWindowsComponent.psm1
2022-04-27 11:20:35 +02:00

175 lines
7.8 KiB
PowerShell

<#
.SYNOPSIS
Updates an Icinga for Windows component by updating the NestedModules entry
of the manifest including documentation and provides an optional .zip file
for usage within the Icinga for Windows repositories
.DESCRIPTION
Updates an Icinga for Windows component by updating the NestedModules entry
of the manifest including documentation and provides an optional .zip file
for usage within the Icinga for Windows repositories
.PARAMETER Name
The name of the Icinga for Windows component and module
.PARAMETER ReleasePackagePath
The path on where the .zip file for release will be created at.
Defaults to the current users home folder
.PARAMETER NoOutput
Use this flag to disable console outputs for the progress, required by other
functions using this function
.PARAMETER CreateReleasePackage
If set, the function will create a .zip file for this specific module which
can be used within the Icinga for Windows repository manager.
Use -ReleasePackagePath to override the default location on where the
package will be created in. Default location is the current users
home folder
#>
function Publish-IcingaForWindowsComponent()
{
param (
[string]$Name,
[string]$ReleasePackagePath = '',
[switch]$NoOutput = $FALSE,
[switch]$CreateReleasePackage = $FALSE
);
if ([string]::IsNullOrEmpty($Name)) {
Write-IcingaConsoleError 'Please specify the name of the component you want to publish';
return;
}
[string]$ModuleName = [string]::Format('icinga-powershell-{0}', $Name.ToLower());
[string]$ModuleRoot = Get-IcingaForWindowsRootPath;
[string]$ModuleDir = Join-Path -Path $ModuleRoot -ChildPath $ModuleName;
[string]$ModuleManifest = (Join-Path -Path $ModuleDir -ChildPath ([string]::Format('{0}.psd1', $ModuleName)))
if ((Test-Path $ModuleDir) -eq $FALSE) {
Write-IcingaConsoleError 'A component with the name "{0}" does not exist. Use "New-IcingaForWindowsComponent" to create a new one or verify that the provided name is correct.' -Objects $Name;
return;
}
$ComponentType = '';
$ManifestScript = '';
$ManifestContent = Get-Content -Path $ModuleManifest;
foreach ($entry in $ManifestContent) {
[string]$LineContent = [string]$entry;
if ($LineContent.Contains('#')) {
$LineContent = $LineContent.Substring(0, $LineContent.IndexOf('#'));
}
if ([string]::IsNullOrEmpty($LineContent) -Or $LineContent -eq "`r`n" -Or $LineContent -eq "`n" -Or [string]::IsNullOrEmpty($LineContent.Replace(' ', ''))) {
continue;
}
$ManifestScript += $LineContent;
$ManifestScript += "`r`n";
}
[ScriptBlock]$ManifestScriptBlock = [ScriptBlock]::Create('return ' + $ManifestScript);
$ModuleManifestData = (& $ManifestScriptBlock);
$ModuleFiles = Get-ChildItem -Path $ModuleDir -Recurse -Filter '*.psm1';
[array]$FunctionList = @();
[array]$CmdletList = @();
[array]$VariableList = @();
[array]$AliasList = @();
[string]$CompiledFolder = (Join-Path -Path $ModuleDir -ChildPath 'compiled');
[string]$CompiledFile = [string]::Format('{0}.ifw_compilation.psm1', $ModuleName.ToLower());
[string]$CompiledFileInclude = [string]::Format('.\compiled\{0}', $CompiledFile);
[string]$CompiledFilePath = (Join-Path -Path $CompiledFolder -ChildPath $CompiledFile);
foreach ($entry in $ModuleFiles) {
# Ensure the compilation file never includes itself
if ($entry.FullName -eq $CompiledFilePath) {
continue;
}
$FunctionList += Get-IcingaForWindowsComponentPublicFunctions -FileObject $entry -ModuleName $ModuleName;
$FileConfig = (Read-IcingaPowerShellModuleFile -File $entry.FullName);
$VariableList += $FileConfig.VariableList;
$AliasList += $FileConfig.AliasList;
$CmdletList += $FileConfig.ExportCmdlet;
}
if ((Test-Path -Path $CompiledFolder) -eq $FALSE) {
New-Item -Path $CompiledFolder -ItemType Directory -Force | Out-Null;
}
Copy-ItemSecure -Path (Join-Path -Path (Get-IcingaFrameworkRootPath) -ChildPath 'templates\compilation.psm1.template') -Destination $CompiledFilePath -Force | Out-Null;
if ($NoOutput) {
Disable-IcingaFrameworkConsoleOutput;
}
Write-IcingaForWindowsComponentManifest -Name $Name -ModuleList @( $CompiledFileInclude ) -FunctionList $FunctionList -VariableList $VariableList -AliasList $AliasList -CmdletList $CmdletList;
if ($ModuleManifestData.PrivateData.Type -eq 'plugins') {
Publish-IcingaPluginConfiguration -ComponentName $Name;
Publish-IcingaPluginDocumentation -ModulePath $ModuleDir;
}
Copy-ItemSecure -Path (Join-Path -Path (Get-IcingaFrameworkRootPath) -ChildPath 'templates\compilation.psm1.template') -Destination $CompiledFilePath -Force | Out-Null;
if ($CreateReleasePackage) {
if ([string]::IsNullOrEmpty($ReleasePackagePath)) {
$ReleasePackagePath = Join-Path -Path $ENV:HOMEDRIVE -ChildPath $ENV:HOMEPATH;
$ReleasePackagePath = Join-Path -Path $ReleasePackagePath -ChildPath ([string]::Format('ifw_releases\{0}', $ModuleName))
}
if ((Test-Path $ReleasePackagePath) -eq $FALSE) {
New-Item -ItemType Directory -Path $ReleasePackagePath | Out-Null;
}
if ((Test-Path $ReleasePackagePath) -eq $FALSE) {
Write-IcingaConsoleError 'Failed to create path "{0}" for providing .zip archive for module "{1}"' -Objects $ReleasePackagePath, $ModuleName;
return;
}
if ((Test-IcingaAddTypeExist 'System.IO.Compression.FileSystem') -eq $FALSE) {
Add-Type -Assembly 'System.IO.Compression.FileSystem';
}
[string]$ZipName = [string]::Format(
'{0}-{1}.zip', $ModuleName, $ModuleManifestData.PrivateData.Version
);
$ZipFile = Join-Path -Path $ReleasePackagePath -ChildPath $ZipName;
if (Test-Path $ZipFile) {
Remove-ItemSecure -Path $ZipFile -Force | Out-Null;
}
$ReleaseTmpDir = New-IcingaTemporaryDirectory;
Copy-ItemSecure -Path $ModuleDir -Destination $ReleaseTmpDir -Recurse -Force | Out-Null;
$ReleaseTmpContent = Get-ChildItem -Path (Join-Path -Path $ReleaseTmpDir -ChildPath $ModuleName) -Recurse;
foreach ($entry in $ReleaseTmpContent) {
if ((Test-Path $entry.FullName) -eq $FALSE) {
continue;
}
if ($entry.Name[0] -eq '.') {
Remove-ItemSecure -Path $entry.FullName -Recurse -Force | Out-Null;
}
}
[System.IO.Compression.ZipFile]::CreateFromDirectory(
$ReleaseTmpDir,
$ZipFile,
[System.IO.Compression.CompressionLevel]::Optimal,
$FALSE
);
Remove-ItemSecure -Path $ReleaseTmpDir -Force -Recurse | Out-Null;
if (Test-Path $ZipFile) {
Write-IcingaConsoleNotice 'Published module with version "{0}" at "{1}"' -Objects $ModuleManifestData.PrivateData.Version, $ZipFile;
} else {
Write-IcingaConsoleError 'Failed to publish module "{0}" at "{1}". Please verify you have enough permissions to access this location and try again' -Objects $ModuleName, $ZipFile;
}
}
Write-IcingaConsoleNotice 'Component "{0}" has been updated as module "icinga-powershell-{1}" at location "{2}" successfully' -Objects $Name, $Name.ToLower(), $ModuleDir;
Enable-IcingaFrameworkConsoleOutput;
}