maksit-webui/utils/plugins/Helm/HelmSelfDeploy.psm1
Maksym Sadovnychyy b74e9250a7
Some checks are pending
Storybook tests / storybook-tests (push) Waiting to run
(bugfix): HOSTNAMES_ARRAY_POLICY and deepDelta fixes
2026-07-06 21:34:08 +02:00

175 lines
7.1 KiB
PowerShell

#requires -Version 7.0
#requires -PSEdition Core
<#
.SYNOPSIS
Helm self-deploy plugin — upgrade/install the release chart on the target cluster after HelmPush.
.DESCRIPTION
Deployment settings (namespace, postgresWait, charts) are configured on the HelmSelfDeploy plugin
entry in scriptSettings.json. Chart version comes from shared.version (DotNetReleaseVersion).
Existing releases with valuesFile use -f on every upgrade. Without valuesFile, upgrades use --reuse-values. helmSet supports {chartVersion} for --set overrides (e.g. image tags).
#>
if (-not (Get-Command Import-PluginDependency -ErrorAction SilentlyContinue)) {
$srcDir = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
$pluginSupportModulePath = Join-Path $srcDir "modules/Engine/PluginSupport.psm1"
if (Test-Path $pluginSupportModulePath -PathType Leaf) {
Import-Module $pluginSupportModulePath -Force -Global -ErrorAction Stop
}
}
function Invoke-Plugin {
param(
[Parameter(Mandatory = $true)]
$Settings
)
Import-PluginDependency -ModuleName "Logging" -RequiredCommand "Write-Log"
Import-PluginDependency -ModuleName "HelmDeploySupport" -RequiredCommand "Invoke-HelmRemoteChartUpgrade"
$pluginSettings = $Settings
$shared = $Settings.context
$scriptDir = [string]$shared.ScriptDir
$dryRun = Test-PluginSkipsRemoteMutation -Plugin $pluginSettings -SharedSettings $shared
if (-not $pluginSettings.namespace) {
throw "HelmSelfDeploy plugin requires 'namespace'."
}
if (-not $pluginSettings.charts -or @($pluginSettings.charts).Count -eq 0) {
throw "HelmSelfDeploy plugin requires at least one chart in 'charts'."
}
$containerRegistrySecret = Resolve-PluginSecretName -PluginSettings $pluginSettings -PropertyName 'containerRegistrySecret'
if (-not $dryRun -and [string]::IsNullOrWhiteSpace($containerRegistrySecret)) {
throw "HelmSelfDeploy plugin requires 'containerRegistrySecret' (logical secret name, e.g. ContainerRegistry)."
}
$chartVersion = $null
if ($shared.PSObject.Properties.Name -contains 'version' -and -not [string]::IsNullOrWhiteSpace([string]$shared.version)) {
$chartVersion = ([string]$shared.version).Trim() -replace '^[vV]', ''
}
if ([string]::IsNullOrWhiteSpace($chartVersion) -and $shared.PSObject.Properties.Name -contains 'tag') {
$chartVersion = ([string]$shared.tag).Trim() -replace '^[vV]', ''
}
if ([string]::IsNullOrWhiteSpace($chartVersion)) {
throw "HelmSelfDeploy could not derive chart version from shared.version or shared.tag."
}
Confirm-HelmAndKubectlAvailable
if ($dryRun) {
Write-Log -Level "INFO" -Message "HelmSelfDeploy dry run: validating helm upgrade/install for namespace '$($pluginSettings.namespace)'."
}
$namespace = [string]$pluginSettings.namespace
if (-not $dryRun) {
Set-K8sNamespace -Namespace $namespace
}
$deployMode = 'ha'
if ($shared.PSObject.Properties.Name -contains 'deployMode' -and -not [string]::IsNullOrWhiteSpace([string]$shared.deployMode)) {
$deployMode = [string]$shared.deployMode
}
Write-Log -Level 'INFO' -Message "HelmSelfDeploy deploy mode: $deployMode (values.{mode}.yaml when present)."
$skipPostgresWait = $false
if ($pluginSettings.PSObject.Properties.Name -contains 'skipPostgresWait') {
$skipPostgresWait = [bool]$pluginSettings.skipPostgresWait
}
if (-not $dryRun -and -not $skipPostgresWait -and $pluginSettings.PSObject.Properties.Name -contains 'postgresWait') {
Invoke-PostgresClusterWait -PostgresWait $pluginSettings.postgresWait
}
foreach ($chart in @($pluginSettings.charts)) {
if ($chart.source -and [string]$chart.source -ne "remote") {
Write-Log -Level "INFO" -Message "Skipping non-remote chart entry (source=$($chart.source))."
continue
}
$stepMessage = if ($dryRun) {
"Dry run: validating Helm release '$($chart.releaseName)' version $chartVersion ..."
}
else {
"Self-deploying Helm release '$($chart.releaseName)' version $chartVersion ..."
}
Write-Log -Level "STEP" -Message $stepMessage
Invoke-HelmRemoteChartUpgrade `
-Namespace $namespace `
-Chart $chart `
-ChartVersion $chartVersion `
-DeploySettingsDir $scriptDir `
-DefaultHelmCredentialsSecret $containerRegistrySecret `
-SharedSettings $shared `
-DryRun:$dryRun
}
if ($dryRun) {
Write-Log -Level "INFO" -Message "HelmSelfDeploy dry run completed for namespace '$namespace'."
return
}
$waitForPods = $true
if ($pluginSettings.PSObject.Properties.Name -contains 'waitForPodsReady') {
$waitForPods = [bool]$pluginSettings.waitForPodsReady
}
if ($waitForPods) {
$timeout = 600
if ($pluginSettings.PSObject.Properties.Name -contains 'podsReadyTimeoutSeconds' -and $null -ne $pluginSettings.podsReadyTimeoutSeconds) {
$timeout = [int]$pluginSettings.podsReadyTimeoutSeconds
}
if (-not (Wait-NamespacePodsReady -Namespace $namespace -TimeoutSeconds $timeout)) {
throw "Not all pods became ready in namespace '$namespace' within ${timeout}s."
}
}
$bgpServices = @()
if ($pluginSettings.PSObject.Properties.Name -contains 'bgpServices' -and $pluginSettings.bgpServices) {
$bgpServices = @($pluginSettings.bgpServices)
}
if ($bgpServices.Count -gt 0) {
Import-PluginDependency -ModuleName "HelmDeploySupport" -RequiredCommand "Set-BgpServices"
$releaseName = [string]$pluginSettings.charts[0].releaseName
$bgpDefaultPort = 80
if ($pluginSettings.PSObject.Properties.Name -contains 'bgpDefaultPort' -and $null -ne $pluginSettings.bgpDefaultPort) {
$bgpDefaultPort = [int]$pluginSettings.bgpDefaultPort
}
Write-Log -Level "STEP" -Message "Applying $($bgpServices.Count) BGP service(s) for release '$releaseName' ..."
Set-BgpServices -Namespace $namespace -ScriptDir $scriptDir -ReleaseName $releaseName -BgpServices $bgpServices -DefaultPort $bgpDefaultPort
$testBgp = $false
if ($pluginSettings.PSObject.Properties.Name -contains 'testBgpConnectivity') {
$testBgp = [bool]$pluginSettings.testBgpConnectivity
}
if ($testBgp) {
Import-PluginDependency -ModuleName "HelmDeploySupport" -RequiredCommand "Test-BgpConnectivity"
$bgpTimeout = 300
if ($pluginSettings.PSObject.Properties.Name -contains 'bgpConnectivityTimeoutSeconds' -and $null -ne $pluginSettings.bgpConnectivityTimeoutSeconds) {
$bgpTimeout = [int]$pluginSettings.bgpConnectivityTimeoutSeconds
}
Test-BgpConnectivity -BgpServices $bgpServices -TimeoutSeconds $bgpTimeout
}
}
Write-Log -Level "INFO" -Message "HelmSelfDeploy completed for namespace '$namespace'."
}
function Get-PluginMetadata {
[pscustomobject]@{ mutatesRemote = $true }
}
Export-ModuleMember -Function Invoke-Plugin, Get-PluginMetadata