From a7cd25e112554e8c67a081402c13f7c8561df526 Mon Sep 17 00:00:00 2001 From: Vishnu Priya Ananthu Sundaram Date: Thu, 27 Oct 2016 15:57:54 -0700 Subject: [PATCH 1/3] ProfileMap Endpoint Discovery (i) Updating Get-AzProfile function to serve $ProfileMap json from Cache, Embedded source or Azure Endpoint (ii) Updating functions that call Get-AzProfile to consume the PSCustomObject returned (iii) ListAvailable option with "Get-AzureRmProfile" will list all the modules and versions. --- .../AzureRM.Bootstrapper.psm1 | 140 +++++++++++++----- 1 file changed, 104 insertions(+), 36 deletions(-) diff --git a/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 b/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 index 0bced343618a..08b6344c1ce0 100644 --- a/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 +++ b/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 @@ -1,5 +1,5 @@ -$RollUpModule = "AzureRM" - +$RollUpModule = "AzureRM" +$PSProfileMapEndpoint = "https://profile.azureedge.net/powershell/ProfileMap.json" $PSModule = $ExecutionContext.SessionState.Module $script:BootStrapRepo = "BootStrap" $RepoLocation = "\\aaptfile01\adxsdk\PowerShell\bootstrapper" @@ -14,33 +14,90 @@ else } -function Get-AzProfile +function Get-ProfileCachePath { - @{ - '2015-05' = - @{ - 'AzureRM' = @('1.2.4'); - 'AzureRM.Storage' = @('1.2.4'); - 'Azure.Storage' = @('1.2.4'); - 'AzureRM.Profile' = @('1.2.4'); - }; - '2016-09' = - @{ - 'AzureRM' = @('2.0.1'); - 'AzureRM.Storage' = @('2.0.1') - 'Azure.Storage' = @('2.0.1'); - 'AzureRM.Profile' = @('2.0.1'); - } - } + $ProfileCache = Join-Path -path $env:LOCALAPPDATA -childpath "Microsoft\AzurePowerShell\ProfileCache" + return $ProfileCache } +# Get-ProfileMap from Azure Endpoint +function Get-AzureProfileMap +{ + $ProfileCache = Get-ProfileCachePath + if(-Not (Test-Path $ProfileCache)) + { + New-Item -ItemType Directory -Force -Path $ProfileCache + } + + $response = Invoke-RestMethod -Uri $PSProfileMapEndpoint -ErrorVariable RestError -OutFile "$ProfileCache\ProfileMap.Json" + + if ($RestError) + { + $HttpStatusCode = $RestError.ErrorRecord.Exception.Response.StatusCode.value__ + $HttpStatusDescription = $RestError.ErrorRecord.Exception.Response.StatusDescription + + Throw "Http Status Code: $($HttpStatusCode) `nHttp Status Description: $($HttpStatusDescription)" + } + + $ProfileMap = Get-Content -Raw -Path "$ProfileCache\ProfileMap.json" -ErrorAction SilentlyContinue | ConvertFrom-Json + + return $ProfileMap +} + + +function Get-AzProfile +{ + [CmdletBinding()] + param() + DynamicParam + { + $params = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary + Add-ForceParam $params + Add-SwitchParam $params "ListAvailable" "ListAvailableParameterSet" + return $params + } + + PROCESS + { + $Force = $PSBoundParameters.Force + # If force is present, download ProfileMap from Storage blob endpoint + if ($Force.IsPresent) + { + return (Get-AzureProfileMap) + } + + # Check the cache + $ProfileCache = Get-ProfileCachePath + if(Test-Path $ProfileCache) + { + $ProfileMap = Get-Content -Raw -Path "$ProfileCache\ProfileMap.json" -ErrorAction SilentlyContinue | ConvertFrom-Json + + if ($ProfileMap -ne $null) + { + return $ProfileMap + } + } + + # If cache doesn't exist, Check embedded source + $defaults = [System.IO.Path]::GetDirectoryName($PSCommandPath) + $ProfileMap = Get-Content -Raw -Path "$defaults\ProfileMap.json" -ErrorAction SilentlyContinue | ConvertFrom-Json + if($profileMap -eq $null) + { + # Cache & Embedded source empty; Return error and stop + throw [System.IO.FileNotFoundException] "$ProfileMap not found." + } + + return $ProfileMap + } +} + function Add-ProfileParam { param([System.Management.Automation.RuntimeDefinedParameterDictionary]$params, [string]$set = "__AllParameterSets") $ProfileMap = (Get-AzProfile) - $AllProfiles = $ProfileMap.Keys + $AllProfiles = ($ProfileMap | Get-Member -MemberType NoteProperty).Name $profileAttribute = New-Object -Type System.Management.Automation.ParameterAttribute $profileAttribute.ParameterSetName = $set $profileAttribute.Mandatory = $true @@ -57,7 +114,6 @@ function Add-ForceParam { param([System.Management.Automation.RuntimeDefinedParameterDictionary]$params, [string]$set = "__AllParameterSets") Add-SwitchParam $params "Force" $set - } function Add-SwitchParam @@ -83,9 +139,12 @@ function Get-AzureRmModule { $params = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary Add-ProfileParam $params - $enum = $ProfileMap.Values.GetEnumerator() + $Profiles = ($ProfileMap | Get-Member -MemberType NoteProperty).Name + $enum = $Profiles.GetEnumerator() $toss = $enum.MoveNext() - $moduleValid = New-Object -Type System.Management.Automation.ValidateSetAttribute($enum.Current.Keys) + $Current = $enum.Current + $Keys = ($($ProfileMap.$Current) | Get-Member -MemberType NoteProperty).Name + $moduleValid = New-Object -Type System.Management.Automation.ValidateSetAttribute($Keys) $moduleAttribute = New-Object -Type System.Management.Automation.ParameterAttribute $moduleAttribute.ParameterSetName = $moduleAttribute.Mandatory = $true @@ -101,10 +160,10 @@ function Get-AzureRmModule PROCESS { $ProfileMap = (Get-AzProfile) - $AllProfiles = $ProfileMap.Keys + $AllProfiles = ($ProfileMap | Get-Member -MemberType NoteProperty).Name $Profile = $PSBoundParameters.Profile $Module = $PSBoundParameters.Module - $versionList = $ProfileMap[$Profile][$Module] + $versionList = $ProfileMap.$Profile.$Module $moduleList = Get-Module -Name $Module -ListAvailable | where {$_.RepositorySourceLocation -ne $null} foreach ($version in $versionList) { @@ -132,16 +191,25 @@ function Get-AzureRmProfile { $params = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary Add-SwitchParam $params "ListAvailable" "ListAvailableParameterSet" + Add-ForceParam $params return $params } PROCESS { [switch]$ListAvailable = $PSBoundParameters.ListAvailable - $ProfileMap = (Get-AzProfile) - $AllProfiles = $ProfileMap.Keys + $ProfileMap = (Get-AzProfile @PSBoundParameters) + $AllProfiles = ($ProfileMap | Get-Member -MemberType NoteProperty).Name if ($ListAvailable.IsPresent) { - $AllProfiles + foreach ($Profile in $ProfileMap) + { + foreach ($Module in ($Profile | get-member -MemberType NoteProperty).Name) + { + Write-Output "Profile: $Module" + Write-Output "----------------" + $Profile.$Module | fl + } + } } else { @@ -177,14 +245,14 @@ function Use-AzureRmProfile { $Force = $PSBoundParameters.Force $ProfileMap = (Get-AzProfile) - $AllProfiles = $ProfileMap.Keys + $AllProfiles = ($ProfileMap | Get-Member -MemberType NoteProperty).Name $Profile = $PSBoundParameters.Profile if ($PSCmdlet.ShouldProcess($Profile, "Loading modules for profile in the current scope")) { $version = Get-AzureRmModule -Profile $Profile -Module $RollUpModule if (($version -eq $null) -and ($Force.IsPresent -or $PSCmdlet.ShouldContinue("Install Modules for Profile $Profile from the gallery?", "Installing Modules for Profile $Profile"))) { - $versions = $ProfileMap[$Profile][$RollUpModule] + $versions = $ProfileMap.$Profile.$RollUpModule $versionEnum = $versions.GetEnumerator() $toss = $versionEnum.MoveNext() $version = $versionEnum.Current @@ -213,9 +281,9 @@ function Install-AzureRmProfile PROCESS { $ProfileMap = (Get-AzProfile) - $AllProfiles = $ProfileMap.Keys + $AllProfiles = ($ProfileMap | Get-Member -MemberType NoteProperty).Name $Profile = $PSBoundParameters.Profile - $versions = $ProfileMap[$Profile][$RollUpModule] + $versions = $ProfileMap.$Profile.$RollUpModule $versionEnum = $versions.GetEnumerator() $toss = $versionEnum.MoveNext() $version = $versionEnum.Current @@ -242,10 +310,10 @@ function Uninstall-AzureRmProfile PROCESS { $Force = $PSBoundParameters.Force $ProfileMap = (Get-AzProfile) - $AllProfiles = $ProfileMap.Keys + $AllProfiles = ($ProfileMap | Get-Member -MemberType NoteProperty).Name $Profile = $PSBoundParameters.Profile - $versions = $ProfileMap[$Profile] - foreach ($module in $versions.Keys) + $versions = ($ProfileMap.$profile | Get-Member -MemberType NoteProperty).Name + foreach ($module in $versions) { $canceled = $false Do @@ -285,4 +353,4 @@ function Set-BootstrapRepo [CmdletBinding()] param([string]$Repo) $script:BootStrapRepo = $Repo -} \ No newline at end of file +} From e84bafec6c264f98e9d630b8739553f33482207f Mon Sep 17 00:00:00 2001 From: Vishnu Priya Ananthu Sundaram Date: Thu, 10 Nov 2016 15:19:49 -0800 Subject: [PATCH 2/3] Update AzureRM.Bootstrapper.psm1 Fixing minor bugs --- tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 b/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 index 08b6344c1ce0..ea9b70982d21 100644 --- a/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 +++ b/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 @@ -27,10 +27,10 @@ function Get-AzureProfileMap $ProfileCache = Get-ProfileCachePath if(-Not (Test-Path $ProfileCache)) { - New-Item -ItemType Directory -Force -Path $ProfileCache + New-Item -ItemType Directory -Force -Path $ProfileCache | Out-Null } - $response = Invoke-RestMethod -Uri $PSProfileMapEndpoint -ErrorVariable RestError -OutFile "$ProfileCache\ProfileMap.Json" + $response = Invoke-RestMethod -ea SilentlyContinue -Uri $PSProfileMapEndpoint -ErrorVariable RestError -OutFile "$ProfileCache\ProfileMap.Json" if ($RestError) { @@ -82,7 +82,7 @@ function Get-AzProfile # If cache doesn't exist, Check embedded source $defaults = [System.IO.Path]::GetDirectoryName($PSCommandPath) $ProfileMap = Get-Content -Raw -Path "$defaults\ProfileMap.json" -ErrorAction SilentlyContinue | ConvertFrom-Json - if($profileMap -eq $null) + if($ProfileMap -eq $null) { # Cache & Embedded source empty; Return error and stop throw [System.IO.FileNotFoundException] "$ProfileMap not found." @@ -139,6 +139,7 @@ function Get-AzureRmModule { $params = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary Add-ProfileParam $params + $ProfileMap = (Get-AzProfile) $Profiles = ($ProfileMap | Get-Member -MemberType NoteProperty).Name $enum = $Profiles.GetEnumerator() $toss = $enum.MoveNext() From 17c899658512bc3c1b2135560a498762f74795ff Mon Sep 17 00:00:00 2001 From: Vishnu Priya Ananthu Sundaram Date: Sun, 13 Nov 2016 14:11:24 -0800 Subject: [PATCH 3/3] Update Bootstrapper with CR comments Change -Force parameter to -Update; Update $RepoLocation to PS Gallery --- tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 b/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 index ea9b70982d21..69d6f85fc695 100644 --- a/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 +++ b/tools/AzureRM.BootStrapper/AzureRM.Bootstrapper.psm1 @@ -2,7 +2,7 @@ $RollUpModule = "AzureRM" $PSProfileMapEndpoint = "https://profile.azureedge.net/powershell/ProfileMap.json" $PSModule = $ExecutionContext.SessionState.Module $script:BootStrapRepo = "BootStrap" -$RepoLocation = "\\aaptfile01\adxsdk\PowerShell\bootstrapper" +$RepoLocation = "https://www.powershellgallery.com/api/v2/" $existingRepos = Get-PSRepository | Where {$_.SourceLocation -eq $RepoLocation} if ($existingRepos -eq $null) { @@ -53,16 +53,16 @@ function Get-AzProfile DynamicParam { $params = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary - Add-ForceParam $params + Add-SwitchParam $params "Update" Add-SwitchParam $params "ListAvailable" "ListAvailableParameterSet" return $params } PROCESS { - $Force = $PSBoundParameters.Force - # If force is present, download ProfileMap from Storage blob endpoint - if ($Force.IsPresent) + $Update = $PSBoundParameters.Update + # If Update is present, download ProfileMap from Storage blob endpoint + if ($Update.IsPresent) { return (Get-AzureProfileMap) } @@ -192,7 +192,7 @@ function Get-AzureRmProfile { $params = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary Add-SwitchParam $params "ListAvailable" "ListAvailableParameterSet" - Add-ForceParam $params + Add-SwitchParam $params "Update" return $params } PROCESS