280 lines
12 KiB
PowerShell
280 lines
12 KiB
PowerShell
function Get-NewRelicApmUpgradeData {
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Compares the current version of NewRelic APM to the expected version, and returns an object describing if an upgrade or downgrade is required.
|
|
|
|
.DESCRIPTION
|
|
Compares the current version of NewRelic APM to the expected version, and returns an object describing if an upgrade or downgrade is required. Uses either
|
|
the supplied desired version value OR the calculated value based on the deployed ORB version, if applicable.
|
|
|
|
.PARAMETER DesiredAPMVersion
|
|
Optional parameter indicating the desired APM version. When not supplied, will calculate the desired version based on deployed ORB version
|
|
|
|
.PARAMETER SourceFeed
|
|
Optional parameter. If supplied, should be the full soruce URL for the desired Chocolatey feed to pull the newrelic-dotnet package froms
|
|
|
|
.PARAMETER NewRelicPackageName
|
|
Optional parameter, defaults to "newrelic-dotnet". Should be set to the NewRelic APM MSI-based chocolatey package you want to install
|
|
|
|
.OUTPUTS
|
|
An object which contains the below properties
|
|
- ActionRequired [Boolean] : Indicates if an upgrade or downgrade is required
|
|
- ActionType [String] : Value should be one of Upgrade or Downgrade
|
|
- TargetVersion [System.Version] : The dervied version for install
|
|
- SourceFeed [String] : The feed URL which should be used for install
|
|
.Example
|
|
e
|
|
|
|
#>
|
|
[CmdletBinding()]
|
|
[OutputType([System.Object])]
|
|
param(
|
|
[Parameter(Mandatory = $false)]
|
|
[System.Version]$DesiredAPMVersion = $null,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$SourceFeed = $null,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$NewRelicPackageName = "newrelic-dotnet"
|
|
)
|
|
|
|
|
|
#TODO: Add -ComputerName to allow remote-running this?
|
|
|
|
|
|
$alkamiFeedMatch = "http?://packagerepo.orb.alkamitech.com/nuget/choco.*"
|
|
$alkamiFeedBlockExpression = "choco.sre|choco.internal"
|
|
|
|
$logLead = Get-LogLeadName
|
|
|
|
$hostname = Get-FullyQualifiedServerName
|
|
|
|
$newrelicApmUpgradelData = @{
|
|
ComputerName = $hostname
|
|
ActionRequired = $false
|
|
ActionType = $null
|
|
TargetVersion = $null
|
|
FeedUrl = $null
|
|
FoundPackage = $null
|
|
}
|
|
$takeAction = $null
|
|
|
|
if (Test-StringIsNullOrEmpty -Value $DesiredAPMVersion) {
|
|
# No target version was supplied, lets see if we can figure it out from what's deployed
|
|
Write-Verbose "$logLEad : No DesiredAPMVersion supplied. Will attempt to determine target version based on deployed platform version"
|
|
$deployedPlatformVersion = Get-OrbVersion
|
|
|
|
if (-NOT (Test-StringIsNullOrEmpty -Value $deployedPlatformVersion)) {
|
|
$targetAPMVersion = Get-SupportedPlatformAPMVersion -PlatformVersion $deployedPlatformVersion
|
|
}
|
|
|
|
} else {
|
|
# Lets assume the person calling the function knows what they want
|
|
$targetAPMVersion = $DesiredAPMVersion
|
|
}
|
|
|
|
if ($null -eq $targetAPMVersion) {
|
|
# Since no version was supplied, we will use the latest on the feed. This may be the case for non-ORB servers where they just want whatever
|
|
# is appropriate, and not a specific version
|
|
Write-Host "$logLead : Could not determine the appropriate target APM version. The latest version in the configured feeds will be used"
|
|
}
|
|
|
|
# Print what we're going to compare against
|
|
$targetVersionString = Test-IsNull $targetAPMVersion "LATEST AVAILABLE" -Strict
|
|
|
|
Write-Host "$logLead : Evaluating current state vs. desired APM version [$targetVersionString]"
|
|
|
|
# Get the local NewRelic APM version
|
|
$localChoco = Get-ChocoState -LocalOnly -Exact -PackageName $NewRelicPackageName
|
|
|
|
if ($null -eq $localChoco) {
|
|
Write-Host "$logLead : No local NewRelic APM choco package detected."
|
|
} else {
|
|
$localChocoVersion = $localChoco.Version
|
|
Write-Host "$logLead : Detected local NewRelic APM choco package version: [$localChocoVersion]"
|
|
}
|
|
|
|
# Figure out where we're installing NewRelic APM from, if not supplied by the caller
|
|
#region FindPackage
|
|
[hashtable]$foundPackage = @{
|
|
PackageId = $null
|
|
PackageVersion = $null
|
|
Source = $null
|
|
FeedUrl = $null
|
|
}
|
|
|
|
if (Test-StringIsNullOrEmpty -Value $SourceFeed) {
|
|
# Pull the local feeds matching $alkamiFeedMatch
|
|
#[array]$sources = Get-ChocolateySources | Where-Object {
|
|
# $_.Source -like $alkamiFeedMatch -and
|
|
# [bool]$_.IsSDK -eq $false -and
|
|
# [bool]$_.Disabled -eq $false
|
|
#}
|
|
[array]$sources = (Get-ChocolateySources).Where({
|
|
$_.Source -like $alkamiFeedMatch -and
|
|
[bool]$_.IsSDK -eq $false -and
|
|
[bool]$_.Disabled -eq $false -and
|
|
$_.Source -notmatch $alkamiFeedBlockExpression
|
|
})
|
|
|
|
if (Test-IsCollectionNullOrEmpty -Collection $sources) {
|
|
# (/) TESTCASE - Get-ChocolateySources - return hashtable with 1 item that has a .Source member
|
|
# https://packagerepo.orb.alkamitech.com/nuget/choco.sre
|
|
# should write this warning and eventually return a ActionRequired=$false object
|
|
|
|
# No matching choco sources found. We have to exit early
|
|
Write-Warning "$logLead : Could not find a configured feed which matches the requirements for NewRelic APM. Evaluation cannot continue"
|
|
$takeAction = $false
|
|
|
|
} else {
|
|
#TESTCASE - Get-ChocolateySources - return hashtable with 1 item that has a .Source member
|
|
# https://packagerepo.orb.alkamitech.com/nuget/choco.good
|
|
# should write this verbose and call Get-ChocoState and more
|
|
|
|
|
|
# Find the feed with NewRelic APM
|
|
foreach ($feedSource in $sources) {
|
|
|
|
Write-Verbose "$logLead : Checking source with name [$($feedSource.Name)] and Feed URL [$($feedSource.Source)]"
|
|
|
|
# In order to not overwrite this value, we CONTINUE once found
|
|
# Get-ChocoState returns an array, even though we often only get 1 result
|
|
# sometimes powershell unboxes for us, sometimes it doesn't
|
|
# Take no changes, force the Select-Object -First 1 anyway
|
|
$availableChocoPackageList = Get-ChocoState -Exact -PackageName $NewRelicPackageName -PackageVersion $targetAPMVersion -Source $feedSource.Source -ErrorAction Continue
|
|
|
|
$availableChocoPackage = Select-Object -InputObject $availableChocoPackageList -First 1
|
|
|
|
|
|
if ($null -eq $availableChocoPackage -or (Test-IsCollectionNullOrEmpty -Collection $availableChocoPackage)) {
|
|
|
|
Write-Host "$logLead : Package $NewRelicPackageName not found at feed [$($feedSource.Source)]."
|
|
|
|
} else {
|
|
Write-Host "$logLead : Package $NewRelicPackageName found at $($feedSource.Source). Adding this package with this source to the list"
|
|
# The first found package is enough, even if there are other versions on other feeds
|
|
# I know Source and FeedUrl are redundant. It is convenient.
|
|
$packageSource = $feedSource.Source
|
|
$foundPackage.PackageId = $availableChocoPackage.Name
|
|
$foundPackage.PackageVersion = [Version]($availableChocoPackage.Version)
|
|
$foundPackage.Source = $feedSource
|
|
$foundPackage.FeedUrl = $feedSource.Source
|
|
continue
|
|
|
|
}
|
|
}
|
|
|
|
if ($null -eq $packageSource) {
|
|
|
|
Write-Host "$logLead : No configured feed has package $NewRelicPackageName available. Evaluation cannot continue."
|
|
$takeAction = $false
|
|
}
|
|
}
|
|
}
|
|
#endregion FindPackage
|
|
|
|
# Now the Version Comparison
|
|
#region CompareVersions
|
|
# Compare-Semver shorthand
|
|
# -1 -> first value TRAILS/IS LESS THAN second value
|
|
# 0 -> values are equal
|
|
# +1 -> first value LEADS/IS MORE THAN second value
|
|
# SO
|
|
# -1 = should upgrade
|
|
# 0 = do nothing
|
|
# 1 = should downgrade
|
|
$actions = @{
|
|
-1 = "Upgrade"
|
|
0 = "Nothing"
|
|
1 = "Downgrade"
|
|
}
|
|
|
|
if ($takeAction -eq $false) {
|
|
Write-Warning "$loglead : Skipping version comparison due to previous condition preventing action"
|
|
$actionValue = 0
|
|
} else {
|
|
Write-Host "$loglead : Comparing versions to determine what action to take"
|
|
# OK so we have a local NewRelic version already.
|
|
if ($null -ne $localChocoVersion) {
|
|
#region Have Local Installation
|
|
|
|
|
|
# we don't really *need* this if-else....
|
|
# both of them use the $foundPackage anyway because we added -Version
|
|
# to Get-ChocoState and we need whatever we found to be installed....
|
|
# so figure out how to not have this `if ($null -eq $targetAPMVersion)` - go off of $foundPackage
|
|
# instead
|
|
# The insides are basically teh same anyway, right?
|
|
# The Write-Hosts are subtly different, but... uh... do we really need them?
|
|
if ($null -eq $targetAPMVersion) {
|
|
# But we don't have a specific target version. So we need to upgrade/downgrade to the latest, if it's different
|
|
|
|
$actionValue = Compare-SemVer -Version1 $localChocoVersion -Version2 $foundPackage.PackageVersion
|
|
|
|
if ($actionValue -ne 0) {
|
|
|
|
Write-Host "$logLead : A(n) $($actions[$actionValue]) is required because local choco version [$localChocoVersion] is not equivalent to the highest available version on the feeds [$($foundPackage.PackageVersion)]."
|
|
$takeAction = $true
|
|
$targetAPMVersion = $foundPackage.PackageVersion
|
|
} else {
|
|
|
|
Write-Host "$logLead : A(n) $($actions[$actionValue]) is not required because local choco version [$localChocoVersion] is equivalent to the highest available version on the feeds [$($foundPackage.PackageVersion)]."
|
|
$takeAction = $false
|
|
}
|
|
} else {
|
|
# We DO have a target
|
|
$actionValue = Compare-SemVer -Version1 $localChocoVersion -Version2 $targetAPMVersion
|
|
|
|
# We do have a specific target version. So let's compare against that
|
|
if ($actionValue -ne 0) {
|
|
|
|
Write-Host "$logLead : A(n) $($actions[$actionValue]) is required because local choco version [$localChocoVersion] is not equivalent to the target APM version [$targetAPMVersion]."
|
|
$takeAction = $true
|
|
} else {
|
|
|
|
Write-Host "$logLead : A(n) $($actions[$actionValue]) is not required because local choco version [$localChocoVersion] is equivalent to the target APM version [$targetAPMVersion]."
|
|
$takeAction = $false
|
|
}
|
|
}
|
|
#endregion Have Local Installation
|
|
} else {
|
|
#region No Local Installation
|
|
|
|
# There is no local choco version.
|
|
# The only reason we would return false here is if the calculated target version is not on the feed
|
|
if ($null -eq $targetAPMVersion -and $null -eq $foundPackage.PackageVersion) {
|
|
|
|
# No version specified, but it wouldn't matter either way.
|
|
Write-Host "$logLead : No local NewRelic APM choco package is installed, and no configured feeds host any version of the package [$NewRelicPackageName]. Upgrade/downgrade cannot be performed"
|
|
$takeAction = $false
|
|
|
|
}
|
|
|
|
#if ($null -ne $targetAPMVersion) {
|
|
# We have a specific target version. Lets check to see if there
|
|
# $foundPackage below handles this.
|
|
#}
|
|
|
|
if ($null -ne $foundPackage.PackageVersion) {
|
|
$actionValue = -1
|
|
Write-Host "$loglead : A(n) $($actions[$actionValue]) is required because no local NewRelic APM choco package is installed and version [$($foundPackage.PackageVersion)] was found on the feed named [$($foundPackage.Source.Name)]"
|
|
$takeAction = $true
|
|
}
|
|
#endregion No Local Installation
|
|
}
|
|
#endregion CompareVersions
|
|
|
|
}
|
|
|
|
|
|
|
|
$newrelicApmUpgradelData.ActionRequired = $takeAction
|
|
$newrelicApmUpgradelData.ActionType = $actions[$actionValue]
|
|
$newrelicApmUpgradelData.TargetVersion = $foundPackage.PackageVersion
|
|
$newrelicApmUpgradelData.FeedUrl = $foundPackage.FeedUrl
|
|
$newrelicApmUpgradelData.FoundPackage = $foundPackage
|
|
# And the result!
|
|
return $newrelicApmUpgradelData
|
|
} |