764 lines
24 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

param(
[string]$ConfigPath = (Join-Path $PSScriptRoot 'config.txt'),
[switch]$Help
)
# PAM 部署主脚本PowerShell 实现)。
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Show-DeployUsage {
@'
Usage:
powershell -File .\deploy.ps1 [-ConfigPath .\config.txt]
Notes:
- deploy.bat is only a wrapper for this script.
- The wrapper avoids cmd.exe delayed-expansion issues with CLIENT_SECRET values
containing exclamation marks.
'@ | Write-Host
}
function Write-Info([string]$Message) { Write-Host "[INFO] $Message" }
function Write-WarnLog([string]$Message) { Write-Host "[WARN] $Message" }
function Write-ErrLog([string]$Message) { Write-Host "[ERROR] $Message" }
function Convert-ResponseContent {
param([AllowNull()][string]$Content)
if ([string]::IsNullOrWhiteSpace($Content)) {
return $null
}
try {
if ($PSVersionTable.PSVersion.Major -ge 6) {
return $Content | ConvertFrom-Json -Depth 100
}
return $Content | ConvertFrom-Json
} catch {
return $Content
}
}
function Get-ErrorBody {
param([System.Management.Automation.ErrorRecord]$ErrorRecord)
try {
$response = $ErrorRecord.Exception.Response
if ($null -eq $response) {
return $ErrorRecord.Exception.Message
}
$stream = $response.GetResponseStream()
if ($null -eq $stream) {
return $ErrorRecord.Exception.Message
}
$reader = New-Object System.IO.StreamReader($stream)
try {
return $reader.ReadToEnd()
} finally {
$reader.Dispose()
}
} catch {
return $ErrorRecord.Exception.Message
}
}
function Get-ResponseValue {
param(
$Response,
[string[]]$Candidates
)
foreach ($candidate in $Candidates) {
$current = $Response
foreach ($segment in ($candidate -split '\.')) {
if ($null -eq $current) {
break
}
if ($current -is [string]) {
$current = $null
break
}
if ($current -is [System.Collections.IDictionary]) {
if ($current.Contains($segment)) {
$current = $current[$segment]
} else {
$current = $null
break
}
} elseif ($current.PSObject.Properties.Name -contains $segment) {
$current = $current.$segment
} else {
$current = $null
break
}
}
if ($null -ne $current -and -not [string]::IsNullOrWhiteSpace([string]$current)) {
return [string]$current
}
}
return $null
}
function Get-PamConfig {
param([string]$Path)
$config = [ordered]@{}
if (Test-Path -LiteralPath $Path) {
foreach ($rawLine in Get-Content -LiteralPath $Path -Encoding UTF8) {
$line = $rawLine.TrimEnd("`r")
if ($line -match '^\s*$' -or $line -match '^\s*[#;]') {
continue
}
$index = $line.IndexOf('=')
if ($index -lt 1) {
continue
}
$key = $line.Substring(0, $index).Trim()
$value = $line.Substring($index + 1).Trim()
if ($value -match '^(.*?\S)\s+[;#].*$') {
$value = $Matches[1]
}
switch ($key) {
'HOME_BASE_URL' { $config[$key] = $value }
'CLIENT_ID' { $config[$key] = $value }
'CLIENT_SECRET' { $config[$key] = $value }
'AIRPORT_CODE' { $config[$key] = $value }
'APP_NAME' { $config[$key] = $value }
'MODULE_NAME' { $config[$key] = $value }
'VERSION_NUMBER' { $config[$key] = $value }
'ZIP_FILE_PATH' { $config[$key] = $value }
'ACTION_TYPE' { $config[$key] = $value }
'TIMEOUT' { $config[$key] = $value }
'LOG_NAME' { $config[$key] = $value }
}
}
} else {
Write-WarnLog "Config file not found: $Path. Defaults will be used."
}
$defaults = [ordered]@{
HOME_BASE_URL = 'https://pam.home.com'
CLIENT_ID = 'your_client_id'
CLIENT_SECRET = 'your_client_secret'
AIRPORT_CODE = 'HET'
APP_NAME = 'PAM'
MODULE_NAME = 'Node'
VERSION_NUMBER = '2.0.5'
ZIP_FILE_PATH = 'C:\path\to\pam-2.0.5.zip'
ACTION_TYPE = 'FULL'
TIMEOUT = '120'
LOG_NAME = 'app.log'
}
foreach ($name in $defaults.Keys) {
if (-not $config.Contains($name) -or [string]::IsNullOrWhiteSpace([string]$config[$name])) {
$config[$name] = $defaults[$name]
}
}
return [pscustomobject]$config
}
function Join-RequestPairs {
param([System.Collections.IDictionary]$Values)
$pairs = foreach ($key in $Values.Keys) {
$encodedValue = [System.Uri]::EscapeDataString([string]$Values[$key])
'{0}={1}' -f $key, $encodedValue
}
return ($pairs -join '&')
}
function Test-ZipFile {
param($Config)
if (-not (Test-Path -LiteralPath $Config.ZIP_FILE_PATH)) {
throw "Package file not found: $($Config.ZIP_FILE_PATH)"
}
}
function Invoke-PamWebRequest {
param(
[ValidateSet('GET', 'POST', 'PUT')]
[string]$Method,
[string]$Url,
[string]$Token,
[hashtable]$Headers = @{},
[AllowNull()]$Body = $null,
[string]$ContentType = '',
[string]$OutFile = ''
)
$allHeaders = @{}
if ($Token) {
$allHeaders['Authorization'] = "Basic $Token"
}
foreach ($key in $Headers.Keys) {
$allHeaders[$key] = $Headers[$key]
}
$params = @{
Uri = $Url
Method = $Method
Headers = $allHeaders
ErrorAction = 'Stop'
}
if ($PSVersionTable.PSVersion.Major -lt 6) {
$params['UseBasicParsing'] = $true
}
if ($PSBoundParameters.ContainsKey('Body') -and $null -ne $Body -and "$Body" -ne '') {
$params['Body'] = $Body
}
if ($ContentType) {
$params['ContentType'] = $ContentType
}
if ($OutFile) {
$params['OutFile'] = $OutFile
}
try {
$response = Invoke-WebRequest @params
if ($OutFile) {
return $OutFile
}
return Convert-ResponseContent $response.Content
} catch {
$body = Get-ErrorBody $_
throw "Request failed [$Method] $Url`n$body"
}
}
function Invoke-PamMultipartUpload {
param(
[string]$Url,
[string]$Token,
[string]$FilePath,
[hashtable]$Fields
)
Add-Type -AssemblyName System.Net.Http
$client = [System.Net.Http.HttpClient]::new()
try {
$client.DefaultRequestHeaders.Authorization =
[System.Net.Http.Headers.AuthenticationHeaderValue]::new('Basic', $Token)
$content = [System.Net.Http.MultipartFormDataContent]::new()
foreach ($entry in $Fields.GetEnumerator()) {
$stringContent = [System.Net.Http.StringContent]::new([string]$entry.Value, [System.Text.Encoding]::UTF8)
$content.Add($stringContent, $entry.Key)
}
$stream = [System.IO.File]::OpenRead($FilePath)
try {
$fileContent = [System.Net.Http.StreamContent]::new($stream)
$fileContent.Headers.ContentType =
[System.Net.Http.Headers.MediaTypeHeaderValue]::Parse('application/octet-stream')
$content.Add($fileContent, 'file', [System.IO.Path]::GetFileName($FilePath))
$response = $client.PostAsync($Url, $content).GetAwaiter().GetResult()
$body = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
if (-not $response.IsSuccessStatusCode) {
throw "Upload failed [HTTP $([int]$response.StatusCode)]`n$body"
}
return Convert-ResponseContent $body
} finally {
$stream.Dispose()
}
} finally {
$client.Dispose()
}
}
function Get-Token {
param($Config)
Write-Info 'Getting token...'
$body = Join-RequestPairs ([ordered]@{
grant_type = 'client_credentials'
client_id = $Config.CLIENT_ID
client_secret = $Config.CLIENT_SECRET
})
$response = Invoke-PamWebRequest -Method POST -Url "$($Config.HOME_BASE_URL)/oauth/token" -Token '' -Body $body -ContentType 'application/x-www-form-urlencoded'
$token = Get-ResponseValue -Response $response -Candidates @('access_token')
if (-not $token) {
throw "Invalid token response: $response"
}
return $token
}
function New-VersionRecord {
param($Config, [string]$Token)
Write-Info 'Step 2.1: create version record'
$body = Join-RequestPairs ([ordered]@{
versionNumber = $Config.VERSION_NUMBER
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
description = 'Auto Deploy'
})
[void](Invoke-PamWebRequest -Method POST -Url "$($Config.HOME_BASE_URL)/api/version/upgrade" -Token $Token -Body $body -ContentType 'application/x-www-form-urlencoded')
}
function Upload-Package {
param($Config, [string]$Token)
Write-Info 'Step 2.2: upload package'
$response = Invoke-PamMultipartUpload -Url "$($Config.HOME_BASE_URL)/api/version/upgrade/upload" -Token $Token -FilePath $Config.ZIP_FILE_PATH -Fields @{
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
versionNumber = $Config.VERSION_NUMBER
}
$hashCode = Get-ResponseValue -Response $response -Candidates @('hashCode', 'data.hashCode')
if (-not $hashCode -and $response -is [string]) {
$hashCode = $response.Trim()
}
if (-not $hashCode) {
throw "Unable to parse hashCode from upload response: $response"
}
return $hashCode
}
function Publish-Version {
param($Config, [string]$Token, [string]$HashCode)
Write-Info 'Step 2.3: publish version'
$payload = @{
airportCodesWhite = @($Config.AIRPORT_CODE)
hashCode = $HashCode
state = 'RELEASE'
} | ConvertTo-Json -Depth 5
$query = Join-RequestPairs ([ordered]@{
versionNumber = $Config.VERSION_NUMBER
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
})
[void](Invoke-PamWebRequest -Method PUT -Url "$($Config.HOME_BASE_URL)/api/version/upgrade/profile?$query" -Token $Token -Body $payload -ContentType 'application/json')
}
function Get-NodeUrl {
param($Config, [string]$Token)
Write-Info 'Step 3.1: resolve node url'
$response = Invoke-PamWebRequest -Method GET -Url "$($Config.HOME_BASE_URL)/api/mcp/airport/target-node?airportCode=$($Config.AIRPORT_CODE)" -Token $Token
if ($response -is [System.Collections.IDictionary]) {
return [string]($response.Keys | Select-Object -First 1)
}
$propertyNames = @($response.PSObject.Properties.Name)
if ($propertyNames.Count -gt 0) {
return [string]$propertyNames[0]
}
throw "Unable to resolve node url: $response"
}
function Get-OnlineIps {
param($Config, [string]$Token, [string]$NodeUrl)
Write-Info 'Step 3.2: query online IP list'
$query = Join-RequestPairs ([ordered]@{
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
airportCode = $Config.AIRPORT_CODE
})
$response = Invoke-PamWebRequest -Method GET -Url "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/ips?$query" -Token $Token -Headers @{
'Target-Node' = $NodeUrl
}
$ips = @()
if ($response -is [System.Array]) {
$ips = @($response | ForEach-Object { [string]$_ } | Where-Object { $_ })
} elseif ($response -is [System.Collections.IEnumerable] -and -not ($response -is [string])) {
$ips = @($response | ForEach-Object { [string]$_ } | Where-Object { $_ })
}
if ($ips.Count -eq 0) {
throw "No online workstation matched the module. Raw response: $response"
}
return $ips
}
function Wait-DownloadProgress {
param($Config, [string]$Token, [string]$NodeUrl)
$query = Join-RequestPairs ([ordered]@{
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
airportCode = $Config.AIRPORT_CODE
})
$progressUrl = "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/download-cloud/progress?$query"
for ($attempt = 0; $attempt -lt 60; $attempt++) {
$response = Invoke-PamWebRequest -Method GET -Url $progressUrl -Token $Token -Headers @{
'Target-Node' = $NodeUrl
}
$status = Get-ResponseValue -Response $response -Candidates @('status')
$successFlag = Get-ResponseValue -Response $response -Candidates @('success')
if ($status -eq 'completed' -or $successFlag -eq 'true') {
return
}
$message = Get-ResponseValue -Response $response -Candidates @('message')
if ($message -and $message -match '(?i)fail|error') {
throw "Node download failed: $message"
}
Start-Sleep -Seconds 2
}
throw 'Node download timed out.'
}
function Download-CloudToNode {
param($Config, [string]$Token, [string]$NodeUrl)
Write-Info 'Step 3.3: download package to node'
$query = Join-RequestPairs ([ordered]@{
versionNumber = $Config.VERSION_NUMBER
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
timeOut = $Config.TIMEOUT
})
[void](Invoke-PamWebRequest -Method GET -Url "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/download-cloud?$query" -Token $Token -Headers @{
'Target-Node' = $NodeUrl
'airport-code' = $Config.AIRPORT_CODE
})
Wait-DownloadProgress -Config $Config -Token $Token -NodeUrl $NodeUrl
}
function Invoke-UpgradeRequest {
param($Config, [string]$Token, [string]$NodeUrl, [string]$Ip)
$body = Join-RequestPairs ([ordered]@{
airportCode = $Config.AIRPORT_CODE
targetIp = $Ip
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
versionNumber = $Config.VERSION_NUMBER
action = $Config.ACTION_TYPE
autoStart = 'false'
timeOut = $Config.TIMEOUT
})
Invoke-PamWebRequest -Method POST -Url "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade" -Token $Token -Headers @{
'Target-Node' = $NodeUrl
} -Body $body -ContentType 'application/x-www-form-urlencoded'
}
function Start-Application {
param($Config, [string]$Token, [string]$NodeUrl, [string]$Ip)
$body = Join-RequestPairs ([ordered]@{
airportCode = $Config.AIRPORT_CODE
targetIp = $Ip
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
runstart = 'true'
})
[void](Invoke-PamWebRequest -Method POST -Url "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/start-stop" -Token $Token -Headers @{
'Target-Node' = $NodeUrl
} -Body $body -ContentType 'application/x-www-form-urlencoded')
}
function Stop-Application {
param($Config, [string]$Token, [string]$NodeUrl, [string]$Ip)
$body = Join-RequestPairs ([ordered]@{
airportCode = $Config.AIRPORT_CODE
targetIp = $Ip
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
runstart = 'false'
})
[void](Invoke-PamWebRequest -Method POST -Url "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/start-stop" -Token $Token -Headers @{
'Target-Node' = $NodeUrl
} -Body $body -ContentType 'application/x-www-form-urlencoded')
}
function Verify-Ip {
param($Config, [string]$Token, [string]$NodeUrl, [string]$Ip)
$query = Join-RequestPairs ([ordered]@{
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
airportCode = $Config.AIRPORT_CODE
targetIp = $Ip
})
Invoke-PamWebRequest -Method GET -Url "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/verify?$query" -Token $Token -Headers @{
'Target-Node' = $NodeUrl
}
}
function Download-DeployLog {
param($Config, [string]$Token, [string]$NodeUrl, [string]$Ip)
$logsDir = Join-Path $PSScriptRoot 'logs'
if (-not (Test-Path -LiteralPath $logsDir)) {
$null = New-Item -ItemType Directory -Path $logsDir
}
$logFile = Join-Path $logsDir ("deploy_{0}.log" -f $Ip)
$errorFile = Join-Path $logsDir ("error_{0}.log" -f $Ip)
$query = Join-RequestPairs ([ordered]@{
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
airportCode = $Config.AIRPORT_CODE
targetIp = $Ip
logName = $Config.LOG_NAME
})
try {
[void](Invoke-PamWebRequest -Method GET -Url "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/log-download?$query" -Token $Token -Headers @{
'Target-Node' = $NodeUrl
} -OutFile $logFile)
if ((Get-Item -LiteralPath $logFile).Length -gt 0) {
Get-Content -LiteralPath $logFile -Tail 5 | Set-Content -LiteralPath "$logFile.summary"
} else {
'Log content empty or no data' | Set-Content -LiteralPath "$logFile.summary"
}
} catch {
Get-ErrorBody $_ | Set-Content -LiteralPath $errorFile
"Log download failed. See $errorFile" | Set-Content -LiteralPath $logFile
'Log download failed' | Set-Content -LiteralPath "$logFile.summary"
}
return $logFile
}
function Invoke-Rollback {
param($Config, [string]$Token, [string]$NodeUrl, [string]$Ip, [bool]$StopFirst)
if ($StopFirst) {
try {
Stop-Application -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
} catch {
}
}
try {
$body = Join-RequestPairs ([ordered]@{
airportCode = $Config.AIRPORT_CODE
targetIp = $Ip
applicationName = $Config.APP_NAME
moduleName = $Config.MODULE_NAME
timeOut = $Config.TIMEOUT
})
$response = Invoke-PamWebRequest -Method POST -Url "$($Config.HOME_BASE_URL)/node_proxy/$($Config.AIRPORT_CODE)/api/mcp/version/upgrade/rollback" -Token $Token -Headers @{
'Target-Node' = $NodeUrl
} -Body $body -ContentType 'application/x-www-form-urlencoded'
$rollbackSuccess = Get-ResponseValue -Response $response -Candidates @('success')
if ($rollbackSuccess -and $rollbackSuccess -ne 'true') {
return 'ROLLBACK_FAILED'
}
} catch {
return 'ROLLBACK_REQUEST_FAILED'
}
try {
$verify = Verify-Ip -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
if ((Get-ResponseValue -Response $verify -Candidates @('success')) -eq 'true') {
return 'ROLLBACK_SUCCESS'
}
return 'ROLLBACK_VERIFY_FAILED'
} catch {
return 'ROLLBACK_VERIFY_FAILED'
}
}
function Invoke-IpDeploy {
param(
$Config,
[string]$Token,
[string]$NodeUrl,
[string]$Ip
)
Write-Info "Processing IP: $Ip"
try {
$upgrade = Invoke-UpgradeRequest -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
} catch {
$logFile = Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
return [pscustomobject]@{
Ip = $Ip
Status = 'FAILED'
Stage = 'UPGRADE'
Message = 'Upgrade request failed'
Rollback = 'ROLLBACK_NOT_RUN'
LogFile = $logFile
}
}
if ((Get-ResponseValue -Response $upgrade -Candidates @('success')) -ne 'true') {
$rollback = Invoke-Rollback -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip -StopFirst:$false
$logFile = Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
$message = Get-ResponseValue -Response $upgrade -Candidates @('message')
if (-not $message) { $message = 'Upgrade failed' }
return [pscustomobject]@{
Ip = $Ip
Status = 'FAILED'
Stage = 'UPGRADE'
Message = $message
Rollback = $rollback
LogFile = $logFile
}
}
try {
Start-Application -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
} catch {
$rollback = Invoke-Rollback -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip -StopFirst:$true
$logFile = Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
return [pscustomobject]@{
Ip = $Ip
Status = 'FAILED'
Stage = 'START'
Message = 'Application start failed'
Rollback = $rollback
LogFile = $logFile
}
}
try {
$verify = Verify-Ip -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
} catch {
$rollback = Invoke-Rollback -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip -StopFirst:$true
$logFile = Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
return [pscustomobject]@{
Ip = $Ip
Status = 'FAILED'
Stage = 'VERIFY'
Message = 'Health check request failed'
Rollback = $rollback
LogFile = $logFile
}
}
if ((Get-ResponseValue -Response $verify -Candidates @('success')) -eq 'true') {
$logFile = Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
return [pscustomobject]@{
Ip = $Ip
Status = 'SUCCESS'
Stage = '-'
Message = '-'
Rollback = '-'
LogFile = $logFile
}
}
$rollback = Invoke-Rollback -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip -StopFirst:$true
$logFile = Download-DeployLog -Config $Config -Token $Token -NodeUrl $NodeUrl -Ip $Ip
$message = Get-ResponseValue -Response $verify -Candidates @('message')
if (-not $message) { $message = 'Health check failed' }
return [pscustomobject]@{
Ip = $Ip
Status = 'FAILED'
Stage = 'VERIFY'
Message = $message
Rollback = $rollback
LogFile = $logFile
}
}
function Write-DeployReport {
param(
$Config,
[System.Collections.Generic.List[object]]$Results,
[int]$TotalCount
)
$successCount = @($Results | Where-Object { $_.Status -eq 'SUCCESS' }).Count
$failCount = @($Results | Where-Object { $_.Status -ne 'SUCCESS' }).Count
Write-Host ''
Write-Host '====================== DEPLOY REPORT ======================'
Write-Host 'Mode: Batch/PowerShell'
Write-Host "Airport: $($Config.AIRPORT_CODE)"
Write-Host "Application: $($Config.APP_NAME)"
Write-Host "Module: $($Config.MODULE_NAME)"
Write-Host "Version: $($Config.VERSION_NUMBER)"
Write-Host "Total: $TotalCount"
Write-Host "Success: $successCount"
Write-Host "Failed: $failCount"
Write-Host ''
Write-Host ('{0,-18} {1,-8} {2,-12} {3,-22} {4}' -f 'IP', 'STATUS', 'STAGE', 'ROLLBACK', 'LOG')
foreach ($item in $Results) {
Write-Host ('{0,-18} {1,-8} {2,-12} {3,-22} {4}' -f $item.Ip, $item.Status, $item.Stage, $item.Rollback, $item.LogFile)
if ($item.Status -ne 'SUCCESS') {
Write-Host (" Reason: {0}" -f $item.Message)
}
}
}
function Invoke-PamDeploy {
param([string]$ConfigPath)
$config = Get-PamConfig -Path $ConfigPath
Test-ZipFile -Config $config
Write-Info "Deploy start: airport=$($config.AIRPORT_CODE), version=$($config.VERSION_NUMBER), module=$($config.APP_NAME)/$($config.MODULE_NAME)"
$token = Get-Token -Config $config
New-VersionRecord -Config $config -Token $token
$hashCode = Upload-Package -Config $config -Token $token
Publish-Version -Config $config -Token $token -HashCode $hashCode
$nodeUrl = Get-NodeUrl -Config $config -Token $token
$ips = Get-OnlineIps -Config $config -Token $token -NodeUrl $nodeUrl
Download-CloudToNode -Config $config -Token $token -NodeUrl $nodeUrl
$results = [System.Collections.Generic.List[object]]::new()
foreach ($ip in $ips) {
$results.Add((Invoke-IpDeploy -Config $config -Token $token -NodeUrl $nodeUrl -Ip $ip))
}
Write-DeployReport -Config $config -Results $results -TotalCount $ips.Count
}
if ($Help) {
Show-DeployUsage
exit 0
}
if ($MyInvocation.InvocationName -ne '.') {
try {
Invoke-PamDeploy -ConfigPath $ConfigPath
} catch {
Write-ErrLog $_
exit 1
}
}