Skip to content

Commit 9c6296d

Browse files
azure-sdkbenbp
andauthored
Sync eng/common directory with azure-sdk-tools for PR 2464 (Azure#22305)
* Support AAD graph and Microsoft Graph service principal APIs * Consolidate service principal wrapper creation Co-authored-by: Ben Broderick Phillips <[email protected]>
1 parent 14d537d commit 9c6296d

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

eng/common/TestResources/New-TestResources.ps1

+44-10
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,42 @@ function Retry([scriptblock] $Action, [int] $Attempts = 5)
127127
}
128128
}
129129

130+
# NewServicePrincipalWrapper creates an object from an AAD graph or Microsoft Graph service principal object type.
131+
# This is necessary to work around breaking changes introduced in Az version 7.0.0:
132+
# https://azure.microsoft.com/en-us/updates/update-your-apps-to-use-microsoft-graph-before-30-june-2022/
133+
function NewServicePrincipalWrapper([string]$subscription, [string]$resourceGroup, [string]$displayName)
134+
{
135+
$servicePrincipal = Retry {
136+
New-AzADServicePrincipal -Role "Owner" -Scope "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName" -DisplayName $displayName
137+
}
138+
$spPassword = ""
139+
$appId = ""
140+
if (Get-Member -Name "Secret" -InputObject $servicePrincipal -MemberType property) {
141+
Write-Verbose "Using legacy PSADServicePrincipal object type from AAD graph API"
142+
# Secret property exists on PSADServicePrincipal type from AAD graph in Az # module versions < 7.0.0
143+
$spPassword = $servicePrincipal.Secret
144+
$appId = $servicePrincipal.ApplicationId
145+
} else {
146+
Write-Verbose "Creating password for service principal via MS Graph API"
147+
# Microsoft graph objects (Az version >= 7.0.0) do not provision a secret # on creation so it must be added separately.
148+
# Submitting a password credential object without specifying a password will result in one being generated on the server side.
149+
$password = New-Object -TypeName "Microsoft.Azure.PowerShell.Cmdlets.Resources.MSGraph.Models.ApiV10.MicrosoftGraphPasswordCredential"
150+
$password.DisplayName = "Password for $displayName"
151+
$credential = Retry { New-AzADSpCredential -PasswordCredentials $password -ServicePrincipalObject $servicePrincipal }
152+
$spPassword = ConvertTo-SecureString $credential.SecretText -AsPlainText -Force
153+
$appId = $servicePrincipal.AppId
154+
}
155+
156+
return @{
157+
AppId = $appId
158+
ApplicationId = $appId
159+
# This is the ObjectId/OID but most return objects use .Id so keep it consistent to prevent confusion
160+
Id = $servicePrincipal.Id
161+
DisplayName = $servicePrincipal.DisplayName
162+
Secret = $spPassword
163+
}
164+
}
165+
130166
function LoadCloudConfig([string] $env)
131167
{
132168
$configPath = "$PSScriptRoot/clouds/$env.json"
@@ -522,8 +558,8 @@ try {
522558
# If no test application ID was specified during an interactive session, create a new service principal.
523559
if (!$CI -and !$TestApplicationId) {
524560
# Cache the created service principal in this session for frequent reuse.
525-
$servicePrincipal = if ($AzureTestPrincipal -and (Get-AzADServicePrincipal -ApplicationId $AzureTestPrincipal.ApplicationId) -and $AzureTestSubscription -eq $SubscriptionId) {
526-
Log "TestApplicationId was not specified; loading cached service principal '$($AzureTestPrincipal.ApplicationId)'"
561+
$servicePrincipal = if ($AzureTestPrincipal -and (Get-AzADServicePrincipal -ApplicationId $AzureTestPrincipal.AppId) -and $AzureTestSubscription -eq $SubscriptionId) {
562+
Log "TestApplicationId was not specified; loading cached service principal '$($AzureTestPrincipal.AppId)'"
527563
$AzureTestPrincipal
528564
} else {
529565
Log "TestApplicationId was not specified; creating a new service principal in subscription '$SubscriptionId'"
@@ -537,19 +573,17 @@ try {
537573
$displayName = "$($baseName)$suffix.test-resources.azure.sdk"
538574
}
539575

540-
$servicePrincipal = Retry {
541-
New-AzADServicePrincipal -Role "Owner" -Scope "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName" -DisplayName $displayName
542-
}
576+
$servicePrincipalWrapper = NewServicePrincipalWrapper -subscription $SubscriptionId -resourceGroup $ResourceGroupName -displayName $DisplayName
543577

544-
$global:AzureTestPrincipal = $servicePrincipal
578+
$global:AzureTestPrincipal = $servicePrincipalWrapper
545579
$global:AzureTestSubscription = $SubscriptionId
546580

547-
Log "Created service principal '$($AzureTestPrincipal.ApplicationId)'"
548-
$AzureTestPrincipal
581+
Log "Created service principal. AppId: '$($AzureTestPrincipal.AppId)' ObjectId: '$($AzureTestPrincipal.Id)'"
582+
$servicePrincipalWrapper
549583
$resourceGroupRoleAssigned = $true
550584
}
551585

552-
$TestApplicationId = $servicePrincipal.ApplicationId
586+
$TestApplicationId = $servicePrincipal.AppId
553587
$TestApplicationOid = $servicePrincipal.Id
554588
$TestApplicationSecret = (ConvertFrom-SecureString $servicePrincipal.Secret -AsPlainText)
555589
}
@@ -886,7 +920,7 @@ Bicep templates, test-resources.bicep.env.
886920
887921
.PARAMETER SuppressVsoCommands
888922
By default, the -CI parameter will print out secrets to logs with Azure Pipelines log
889-
commands that cause them to be redacted. For CI environments that don't support this (like
923+
commands that cause them to be redacted. For CI environments that don't support this (like
890924
stress test clusters), this flag can be set to $false to avoid printing out these secrets to the logs.
891925
892926
.EXAMPLE

0 commit comments

Comments
 (0)