Skip to content

Commit

Permalink
[Functions] Update the logic to populate the function app creation st…
Browse files Browse the repository at this point in the history
…acks cache and tab completers. (Azure#24656)

* Update Stacks API parser logic

* Update Functions Stack definitions

* Update the logic to populate tab completers only when the Az.Functions cmdlets are invoked

* Update test
  • Loading branch information
Francisco-Gamino authored and qinzhouxu committed Jun 5, 2024
1 parent 1458a4e commit a1b978b
Show file tree
Hide file tree
Showing 18 changed files with 627 additions and 437 deletions.

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Functions/Functions.Autorest/custom/Get-AzFunctionApp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ function Get-AzFunctionApp {

process {

RegisterFunctionsTabCompleters

$apps = $null
$locationToUse = $null
$parameterSetName = $PsCmdlet.ParameterSetName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ function Get-AzFunctionAppAvailableLocation {

process {

RegisterFunctionsTabCompleters

# Remove bound parameters from the dictionary that cannot be process by the intenal cmdlets
$paramsToRemove = @(
"OSType",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ function Get-AzFunctionAppPlan {

process {

RegisterFunctionsTabCompleters

$plans = $null
$locationToUse = $null
$parameterSetName = $PsCmdlet.ParameterSetName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ function Get-AzFunctionAppSetting {
)

process {

RegisterFunctionsTabCompleters

if ($PsCmdlet.ParameterSetName -eq "ByObjectInput")
{
Expand Down
165 changes: 94 additions & 71 deletions src/Functions/Functions.Autorest/custom/HelperFunctions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1843,11 +1843,7 @@ function ParseMinorVersion
(
[Parameter(Mandatory=$false)]
[System.String]
$RuntimeName,

[Parameter(Mandatory=$false)]
[System.String]
$RuntimeVersion,
$StackMinorVersion,

[Parameter(Mandatory=$false)]
[System.String]
Expand All @@ -1862,45 +1858,54 @@ function ParseMinorVersion
$RuntimeFullName,

[Parameter(Mandatory=$false)]
[Switch]
[Bool]
$StackIsLinux
)

# If this FunctionsVersion is not supported, skip it
if ($RuntimeSettings.supportedFunctionsExtensionVersions -notcontains "~$DefaultFunctionsVersion")
{
$supportedFunctionsExtensionVersions = $RuntimeSettings.supportedFunctionsExtensionVersions -join ", "
Write-Debug "$DEBUG_PREFIX Minimium required Functions version '$DefaultFunctionsVersion' is not supported. Current supported Functions versions: $supportedFunctionsExtensionVersions. Skipping..."
Write-Debug "$DEBUG_PREFIX Minimium required Functions version '$DefaultFunctionsVersion' is not supported. Runtime supported Functions versions: $supportedFunctionsExtensionVersions. Skipping..."
return
}
else
{
Write-Debug "$DEBUG_PREFIX Minimium required Functions version '$DefaultFunctionsVersion' is supported."
}

if (-not $RuntimeName)
{
$RuntimeName = GetRuntimeName -AppSettingsDictionary $RuntimeSettings.AppSettingsDictionary
}
$runtimeName = GetRuntimeName -AppSettingsDictionary $RuntimeSettings.AppSettingsDictionary

if ($runtimeName -like "dotnet*" -or $runtimeName -like "node*")
$version = $null
if ($RuntimeName -eq "Java" -and $RuntimeSettings.RuntimeVersion -eq "1.8")
{
$RuntimeVersion = GetRuntimeVersion -Version $RuntimeVersion
# Java 8 is only supported in Windows. The display value is 8; however, the actual SiteConfig.JavaVersion is 1.8
$version = $StackMinorVersion
}

# Some runtimes do not have a version like custom handler
if (-not $runtimeVersion -and $RuntimeSettings.RuntimeVersion)
else
{
$version = GetRuntimeVersion -Version $RuntimeSettings.RuntimeVersion -StackIsLinux $StackIsLinux.IsPresent
$RuntimeVersion = $version
$version = $RuntimeSettings.RuntimeVersion
}

$runtimeVersion = GetRuntimeVersion -Version $version -StackIsLinux $StackIsLinux

# For Java function app, the version from the Stacks API is 8.0, 11.0, and 17.0. However, this is a breaking change which cannot be supported in the current release.
# We will convert the version to 8, 11, and 17. This change will be reverted for the November 2023 breaking release.
# We will convert the version to 8, 11, and 17. This change will be reverted for the May 2024 breaking release.
if ($RuntimeName -eq "Java")
{
$RuntimeVersion = [int]$RuntimeVersion
Write-Debug "$DEBUG_PREFIX Runtime version for Java is modified to be compatible with the current release. Current version '$RuntimeVersion'"
$runtimeVersion = [int]$runtimeVersion
Write-Debug "$DEBUG_PREFIX Runtime version for Java is modified to be compatible with the current release. Current version '$runtimeVersion'"
}

# For DotNet function app, the version from the Stacks API is 6.0. 7.0, and 8.0. However, this is a breaking change which cannot be supported in the current release.
# We will convert the version to 6, 7, and 8. This change will be reverted for the May 2024 breaking release.
if ($RuntimeName -like "DotNet*")
{
if ($runtimeVersion.EndsWith(".0"))
{
$runtimeVersion = [int]$runtimeVersion
}
Write-Debug "$DEBUG_PREFIX Runtime version for $runtimeName is modified to be compatible with the current release. Current version '$runtimeVersion'"
}

$runtime = [Runtime]::new()
Expand All @@ -1926,10 +1931,10 @@ function ParseMinorVersion
return
}

if ($RuntimeVersion -and ($runtimeName -ne "custom"))
if ($runtimeVersion -and ($runtimeName -ne "custom"))
{
Write-Debug "$DEBUG_PREFIX Runtime version: $RuntimeVersion"
$runtime.Version = $RuntimeVersion
Write-Debug "$DEBUG_PREFIX Runtime version: $runtimeVersion"
$runtime.Version = $runtimeVersion
}
else
{
Expand All @@ -1947,7 +1952,7 @@ function ParseMinorVersion
$runtime.PreferredOs = $PreferredOs
}

$targetOs = if ($StackIsLinux.IsPresent) { 'Linux' } else { 'Windows' }
$targetOs = if ($StackIsLinux) { 'Linux' } else { 'Windows' }
Write-Debug "$DEBUG_PREFIX Runtime '$runtimeName' for '$targetOs' parsed successfully."

return $runtime
Expand All @@ -1959,23 +1964,28 @@ function GetRuntimeVersion
[Microsoft.Azure.PowerShell.Cmdlets.Functions.DoNotExportAttribute()]
param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[Parameter(Mandatory=$false)]
[System.String]
$Version,

[Parameter(Mandatory=$false)]
[Switch]
[Bool]
$StackIsLinux
)

if ($StackIsLinux.IsPresent)
if (-not $Version)
{
# Some runtimes do not have a version like custom handler
return
}

if ($StackIsLinux)
{
$Version = $Version.Split('|')[1]
}
else
{
$valuesToReplace = @('STS', 'non-', 'LTS', 'Isolated', '(', ')', '~', 'custom')
$valuesToReplace = @('v', '~')
foreach ($value in $valuesToReplace)
{
if ($Version.Contains($value))
Expand All @@ -1986,8 +1996,7 @@ function GetRuntimeVersion
}

$Version = $Version.Trim()

return $Version
return $Version
}

function GetDictionary
Expand Down Expand Up @@ -2123,27 +2132,26 @@ function SetLinuxandWindowsSupportedRuntimes
{
$preferredOs = $stackDefinition.properties.preferredOs

# runtime name is the $stackDefinition.Name
$runtimeName = $stackDefinition.properties.value
Write-Debug "$DEBUG_PREFIX Parsing runtime name: $runtimeName"
$stackName = $stackDefinition.properties.value
Write-Debug "$DEBUG_PREFIX Parsing stack name: $stackName"

foreach ($majorVersion in $stackDefinition.properties.majorVersions)
{
foreach ($minorVersion in $majorVersion.minorVersions)
{
$runtimeFullName = $minorVersion.DisplayText
$runtimeVersion = $minorVersion.value
Write-Debug "$DEBUG_PREFIX runtime full name: $runtimeFullName"
Write-Debug "$DEBUG_PREFIX runtime version: $runtimeVersion"

$stackMinorVersion = $minorVersion.value
Write-Debug "$DEBUG_PREFIX stack minor version: $stackMinorVersion"
$runtime = $null

if (ContainsProperty -Object $minorVersion.stackSettings -PropertyName "windowsRuntimeSettings")
{
$runtime = ParseMinorVersion -RuntimeVersion $runtimeVersion `
-RuntimeSettings $minorVersion.stackSettings.windowsRuntimeSettings `
$runtime = ParseMinorVersion -RuntimeSettings $minorVersion.stackSettings.windowsRuntimeSettings `
-RuntimeFullName $runtimeFullName `
-PreferredOs $preferredOs
-PreferredOs $preferredOs `
-StackMinorVersion $stackMinorVersion

if ($runtime)
{
Expand All @@ -2153,11 +2161,10 @@ function SetLinuxandWindowsSupportedRuntimes

if (ContainsProperty -Object $minorVersion.stackSettings -PropertyName "linuxRuntimeSettings")
{
$runtime = ParseMinorVersion -RuntimeVersion $runtimeVersion `
-RuntimeSettings $minorVersion.stackSettings.linuxRuntimeSettings `
$runtime = ParseMinorVersion -RuntimeSettings $minorVersion.stackSettings.linuxRuntimeSettings `
-RuntimeFullName $runtimeFullName `
-PreferredOs $preferredOs `
-StackIsLinux
-StackIsLinux $true

if ($runtime)
{
Expand All @@ -2168,44 +2175,60 @@ function SetLinuxandWindowsSupportedRuntimes
}
}
}
SetLinuxandWindowsSupportedRuntimes

# New-AzFunction app ArgumentCompleter for the RuntimeVersion parameter
# The values of RuntimeVersion depend on the selection of the Runtime parameter
$GetRuntimeVersionCompleter = {

param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
# This method pulls down the Functions stack definitions from the ARM API and builds a list of supported runtimes and runtime versions.
# This is used to build the tab completers for the New-AzFunctionApp cmdlet.
function RegisterFunctionsTabCompleters
{
[Microsoft.Azure.PowerShell.Cmdlets.Functions.DoNotExportAttribute()]
param ()

if ($fakeBoundParameters.ContainsKey('Runtime'))
if ($env:FunctionsTabCompletersRegistered)
{
# RuntimeVersions is defined in SetLinuxandWindowsSupportedRuntimes
$AllRuntimeVersions[$fakeBoundParameters.Runtime] | Where-Object {
$_ -like "$wordToComplete*"
} | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
return
}
}

# New-AzFunction app ArgumentCompleter for the Runtime parameter
$GetAllRuntimesCompleter = {
SetLinuxandWindowsSupportedRuntimes

param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
# New-AzFunction app ArgumentCompleter for the RuntimeVersion parameter
# The values of RuntimeVersion depend on the selection of the Runtime parameter
$GetRuntimeVersionCompleter = {

$runtimeValues = $AllRuntimeVersions.Keys | Sort-Object | ForEach-Object { $_ }
param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

$runtimeValues | Where-Object { $_ -like "$wordToComplete*" }
}
if ($fakeBoundParameters.ContainsKey('Runtime'))
{
# RuntimeVersions is defined in SetLinuxandWindowsSupportedRuntimes
$AllRuntimeVersions[$fakeBoundParameters.Runtime] | Where-Object {
$_ -like "$wordToComplete*"
} | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
}
}

# New-AzFunction app ArgumentCompleter for the Runtime parameter
$GetAllFunctionsVersionsCompleter = {
# New-AzFunction app ArgumentCompleter for the Runtime parameter
$GetAllRuntimesCompleter = {

param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

$functionsVersions = $AllFunctionsExtensionVersions | Sort-Object | ForEach-Object { $_ }
$runtimeValues = $AllRuntimeVersions.Keys | Sort-Object | ForEach-Object { $_ }

$functionsVersions | Where-Object { $_ -like "$wordToComplete*" }
}
$runtimeValues | Where-Object { $_ -like "$wordToComplete*" }
}

# New-AzFunction app ArgumentCompleter for the Runtime parameter
$GetAllFunctionsVersionsCompleter = {

param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

# Register tab completers
Register-ArgumentCompleter -CommandName New-AzFunctionApp -ParameterName FunctionsVersion -ScriptBlock $GetAllFunctionsVersionsCompleter
Register-ArgumentCompleter -CommandName New-AzFunctionApp -ParameterName Runtime -ScriptBlock $GetAllRuntimesCompleter
Register-ArgumentCompleter -CommandName New-AzFunctionApp -ParameterName RuntimeVersion -ScriptBlock $GetRuntimeVersionCompleter
$functionsVersions = $AllFunctionsExtensionVersions | Sort-Object | ForEach-Object { $_ }

$functionsVersions | Where-Object { $_ -like "$wordToComplete*" }
}

# Register tab completers
Register-ArgumentCompleter -CommandName New-AzFunctionApp -ParameterName FunctionsVersion -ScriptBlock $GetAllFunctionsVersionsCompleter
Register-ArgumentCompleter -CommandName New-AzFunctionApp -ParameterName Runtime -ScriptBlock $GetAllRuntimesCompleter
Register-ArgumentCompleter -CommandName New-AzFunctionApp -ParameterName RuntimeVersion -ScriptBlock $GetRuntimeVersionCompleter

$env:FunctionsTabCompletersRegistered = $true
}
3 changes: 3 additions & 0 deletions src/Functions/Functions.Autorest/custom/New-AzFunctionApp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ function New-AzFunctionApp {
)

process {

RegisterFunctionsTabCompleters

# Remove bound parameters from the dictionary that cannot be process by the intenal cmdlets.
$paramsToRemove = @(
"StorageAccountName",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ function New-AzFunctionAppPlan {
${ProxyUseDefaultCredentials}
)
process {

RegisterFunctionsTabCompleters

# Remove bound parameters from the dictionary that cannot be process by the intenal cmdlets.
foreach ($paramName in @("Sku", "WorkerType", "MaximumWorkerCount", "MinimumWorkerCount", "Location", "Tag"))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ function Remove-AzFunctionApp {
${ProxyUseDefaultCredentials}
)
process {

RegisterFunctionsTabCompleters

# The input object is an ISite. This needs to be transformed into a FunctionsIdentity
if ($PsCmdlet.ParameterSetName -eq "ByObjectInput")
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ function Remove-AzFunctionAppPlan {
)

process {

RegisterFunctionsTabCompleters

if ($PsCmdlet.ParameterSetName -eq "ByObjectInput")
{
if ($PSBoundParameters.ContainsKey("InputObject"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ function Remove-AzFunctionAppSetting {
)
process {

RegisterFunctionsTabCompleters

# Remove bound parameters from the dictionary that cannot be process by the intenal cmdlets
$paramsToRemove = @(
"AppSettingName"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ function Restart-AzFunctionApp {

process {

RegisterFunctionsTabCompleters

# The input object is an ISite. This needs to be transformed into a FunctionsIdentity
if ($PsCmdlet.ParameterSetName -eq "ByObjectInput")
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ function Start-AzFunctionApp {

process {

RegisterFunctionsTabCompleters

# The input object is an ISite. This needs to be transformed into a FunctionsIdentity.
if ($PsCmdlet.ParameterSetName -eq "ByObjectInput")
{
Expand Down
Loading

0 comments on commit a1b978b

Please sign in to comment.