Skip to content

Commit

Permalink
Sync eng/common directory with azure-sdk-tools repository (#8109)
Browse files Browse the repository at this point in the history
  • Loading branch information
azure-sdk authored Jun 29, 2020
1 parent 0103ea6 commit b77a607
Show file tree
Hide file tree
Showing 31 changed files with 2,580 additions and 742 deletions.
150 changes: 100 additions & 50 deletions eng/common/TestResources/New-TestResources.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ param (
[ValidateNotNullOrEmpty()]
[string] $TenantId,

[Parameter(ParameterSetName = 'Provisioner')]
[ValidatePattern('^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$')]
[string] $SubscriptionId,

[Parameter(ParameterSetName = 'Provisioner', Mandatory = $true)]
[ValidatePattern('^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$')]
[string] $ProvisionerApplicationId,
Expand All @@ -48,18 +52,20 @@ param (
[string] $Location = '',

[Parameter()]
[ValidateNotNullOrEmpty()]
[ValidateSet('AzureCloud', 'AzureUSGovernment', 'AzureChinaCloud')]
[string] $Environment = 'AzureCloud',

[Parameter()]
[ValidateNotNullOrEmpty()]
[hashtable] $AdditionalParameters,

[Parameter()]
[switch] $CI = ($null -ne $env:SYSTEM_TEAMPROJECTID),

[Parameter()]
[switch] $Force
[switch] $Force,

[Parameter()]
[switch] $OutFile
)

# By default stop for any error.
Expand Down Expand Up @@ -105,7 +111,8 @@ trap {
}

# Enumerate test resources to deploy. Fail if none found.
$root = [System.IO.Path]::Combine("$PSScriptRoot/../sdk", $ServiceDirectory) | Resolve-Path
$repositoryRoot = "$PSScriptRoot/../../.." | Resolve-Path
$root = [System.IO.Path]::Combine($repositoryRoot, "sdk", $ServiceDirectory) | Resolve-Path
$templateFileName = 'test-resources.json'
$templateFiles = @()

Expand All @@ -126,17 +133,11 @@ if (!$templateFiles) {
# environment. If no matching environment is found $Location remains an empty
# string.
if (!$Location) {
$defaultLocations = @{
$Location = @{
'AzureCloud' = 'westus2';
'AzureUSGovernment' = 'usgovvirginia';
'AzureChinaCloud' = 'chinaeast2';
}

if ($defaultLocations.ContainsKey($Environment)) {
$Location = $defaultLocations[$Environment]
} else {
Write-Error "Location cannot be empty and there is no default location for Environment: '$Environment'"
}
}[$Environment]

Write-Verbose "Location was not set. Using default location for environment: '$Location'"
}
Expand All @@ -149,8 +150,13 @@ if ($ProvisionerApplicationId) {
$provisionerSecret = ConvertTo-SecureString -String $ProvisionerApplicationSecret -AsPlainText -Force
$provisionerCredential = [System.Management.Automation.PSCredential]::new($ProvisionerApplicationId, $provisionerSecret)

# Use the given subscription ID if provided.
$subscriptionArgs = if ($SubscriptionId) {
@{SubscriptionId = $SubscriptionId}
}

$provisionerAccount = Retry {
Connect-AzAccount -Tenant $TenantId -Credential $provisionerCredential -ServicePrincipal -Environment $Environment
Connect-AzAccount -Force:$Force -Tenant $TenantId -Credential $provisionerCredential -ServicePrincipal -Environment $Environment @subscriptionArgs
}

$exitActions += {
Expand All @@ -170,19 +176,20 @@ if ($TestApplicationId -and !$TestApplicationOid) {
}
}


# If the ServiceDirectory is an absolute path use the last directory name
# (e.g. D:\foo\bar\ -> bar)
$serviceName = if (Split-Path -IsAbsolute $ServiceDirectory) {
Split-Path -Leaf $ServiceDirectory
} else {
$ServiceDirectory
}

# Format the resource group name based on resource group naming recommendations and limitations.
$resourceGroupName = if ($CI) {
$BaseName = 't' + (New-Guid).ToString('n').Substring(0, 16)
Write-Verbose "Generated base name '$BaseName' for CI build"

# If the ServiceDirectory is an absolute path use the last directory name
# (e.g. D:\foo\bar\ -> bar)
$serviceName = if (Split-Path -IsAbsolute $ServiceDirectory) {
Split-Path -Leaf $ServiceDirectory
} else {
$ServiceDirectory
}

"rg-{0}-$BaseName" -f ($serviceName -replace '[\\\/:]', '-').Substring(0, [Math]::Min($serviceName.Length, 90 - $BaseName.Length - 4)).Trim('-')
} else {
"rg-$BaseName"
Expand Down Expand Up @@ -279,12 +286,21 @@ foreach ($templateFile in $templateFiles) {
Write-Verbose "Successfully deployed template '$templateFile' to resource group '$($resourceGroup.ResourceGroupName)'"
}

if ($deployment.Outputs.Count -and !$CI) {
# Write an extra new line to isolate the environment variables for easy reading.
Log "Persist the following environment variables based on your detected shell ($shell):`n"
$serviceDirectoryPrefix = $serviceName.ToUpperInvariant() + "_"

$context = Get-AzContext;

# Add default values
$deploymentOutputs = @{
"$($serviceDirectoryPrefix)CLIENT_ID" = $TestApplicationId;
"$($serviceDirectoryPrefix)CLIENT_SECRET" = $TestApplicationSecret;
"$($serviceDirectoryPrefix)TENANT_ID" = $context.Tenant.Id;
"$($serviceDirectoryPrefix)SUBSCRIPTION_ID" = $context.Subscription.Id;
"$($serviceDirectoryPrefix)RESOURCE_GROUP" = $resourceGroup.ResourceGroupName;
"$($serviceDirectoryPrefix)LOCATION" = $resourceGroup.Location;
"$($serviceDirectoryPrefix)ENVIRONMENT" = $context.Environment.Name;
}

$deploymentOutputs = @{}
foreach ($key in $deployment.Outputs.Keys) {
$variable = $deployment.Outputs[$key]

Expand All @@ -293,23 +309,54 @@ foreach ($templateFile in $templateFiles) {

if ($variable.Type -eq 'String' -or $variable.Type -eq 'SecureString') {
$deploymentOutputs[$key] = $variable.Value
}
}

if ($OutFile)
{
if (!$IsWindows)
{
Write-Host "File option is supported only on Windows"
}

$outputFile = "$templateFile.env"

$environmentText = $deploymentOutputs | ConvertTo-Json;
$bytes = ([System.Text.Encoding]::UTF8).GetBytes($environmentText)
$protectedBytes = [Security.Cryptography.ProtectedData]::Protect($bytes, $null, [Security.Cryptography.DataProtectionScope]::CurrentUser)

Set-Content $outputFile -Value $protectedBytes -AsByteStream -Force

Write-Host "Test environment settings`n $environmentText`nstored into encrypted $outputFile"
}
else
{

if (!$CI) {
# Write an extra new line to isolate the environment variables for easy reading.
Log "Persist the following environment variables based on your detected shell ($shell):`n"
}

foreach ($key in $deploymentOutputs.Keys)
{
$value = $deploymentOutputs[$key]

if ($CI) {
# Treat all ARM template output variables as secrets since "SecureString" variables do not set values.
# In order to mask secrets but set environment variables for any given ARM template, we set variables twice as shown below.
Write-Host "Setting variable '$key': ***"
Write-Host "##vso[task.setvariable variable=_$key;issecret=true;]$($variable.Value)"
Write-Host "##vso[task.setvariable variable=$key;]$($variable.Value)"
Write-Host "##vso[task.setvariable variable=_$key;issecret=true;]$($value)"
Write-Host "##vso[task.setvariable variable=$key;]$($value)"
} else {
Write-Host ($shellExportFormat -f $key, $variable.Value)
Write-Host ($shellExportFormat -f $key, $value)
}
}
}

if ($key) {
# Isolate the environment variables for easy reading.
Write-Host "`n"
$key = $null
if ($key) {
# Isolate the environment variables for easy reading.
Write-Host "`n"
$key = $null
}
}

$postDeploymentScript = $templateFile | Split-Path | Join-Path -ChildPath 'test-resources-post.ps1'
Expand Down Expand Up @@ -385,6 +432,10 @@ The tenant ID of a service principal when a provisioner is specified. The same
Tenant ID is used for Test Application and Provisioner Application. This value
is passed to the ARM template as 'tenantId'.
.PARAMETER SubscriptionId
Optional subscription ID to use for new resources when logging in as a
provisioner. You can also use Set-AzContext if not provisioning.
.PARAMETER ProvisionerApplicationId
The AAD Application ID used to provision test resources when a provisioner is
specified.
Expand Down Expand Up @@ -415,29 +466,36 @@ timestamp is less than the current time.
This isused for CI automation.
.PARAMETER Location
Optional location where resources should be created. By default this is
'westus2'.
Optional location where resources should be created. If left empty, the default
is based on the cloud to which the template is being deployed:
.PARAMETER AdditionalParameters
Optional key-value pairs of parameters to pass to the ARM template(s).
* AzureCloud -> 'westus2'
* AzureUSGovernment -> 'usgovvirginia'
* AzureChinaCloud -> 'chinaeast2'
.PARAMETER Environment
Name of the cloud environment. The default is the Azure Public Cloud
('PublicCloud')
.PARAMETER AdditionalParameters
Optional key-value pairs of parameters to pass to the ARM template(s).
.PARAMETER CI
Indicates the script is run as part of a Continuous Integration / Continuous
Deployment (CI/CD) build (only Azure Pipelines is currently supported).
.PARAMETER Force
Force creation of resources instead of being prompted.
.PARAMETER OutFile
Save test environment settings into a test-resources.json.env file next to test-resources.json. File is protected via DPAPI. Supported only on windows.
The environment file would be scoped to the current repository directory.
.EXAMPLE
$subscriptionId = "REPLACE_WITH_SUBSCRIPTION_ID"
Connect-AzAccount -Subscription $subscriptionId
Connect-AzAccount -Subscription "REPLACE_WITH_SUBSCRIPTION_ID"
$testAadApp = New-AzADServicePrincipal -Role Owner -DisplayName 'azure-sdk-live-test-app'
.\eng\common\LiveTestResources\New-TestResources.ps1 `
-BaseName 'myalias' `
New-TestResources.ps1 `
-BaseName 'uuid123' `
-ServiceDirectory 'keyvault' `
-TestApplicationId $testAadApp.ApplicationId.ToString() `
-TestApplicationSecret (ConvertFrom-SecureString $testAadApp.Secret -AsPlainText)
Expand All @@ -449,7 +507,7 @@ Requires PowerShell 7 to use ConvertFrom-SecureString -AsPlainText or convert
the SecureString to plaintext by another means.
.EXAMPLE
eng/New-TestResources.ps1 `
New-TestResources.ps1 `
-BaseName 'Generated' `
-ServiceDirectory '$(ServiceDirectory)' `
-TenantId '$(TenantId)' `
Expand All @@ -466,14 +524,6 @@ Run this in an Azure DevOps CI (with approrpiate variables configured) before
executing live tests. The script will output variables as secrets (to enable
log redaction).
.OUTPUTS
Entries from the ARM templates' "output" section in environment variable syntax
(e.g. $env:RESOURCE_NAME='<< resource name >>') that can be used for running
live tests.
If run in -CI mode the environment variables will be output in syntax that Azure
DevOps can consume.
.LINK
Remove-TestResources.ps1
#>
65 changes: 49 additions & 16 deletions eng/common/TestResources/New-TestResources.ps1.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ New-TestResources.ps1 [-BaseName] <String> -ServiceDirectory <String> -TestAppli
### Provisioner
```
New-TestResources.ps1 [-BaseName] <String> -ServiceDirectory <String> -TestApplicationId <String>
[-TestApplicationSecret <String>] [-TestApplicationOid <String>] -TenantId <String>
[-TestApplicationSecret <String>] [-TestApplicationOid <String>] -TenantId <String> [-SubscriptionId <String>]
-ProvisionerApplicationId <String> -ProvisionerApplicationSecret <String> [-DeleteAfterHours <Int32>]
[-Location <String>] [-Environment <String>] [-AdditionalParameters <Hashtable>] [-CI] [-Force] [-WhatIf]
[-Confirm] [<CommonParameters>]
Expand Down Expand Up @@ -53,11 +53,10 @@ specified in $ProvisionerApplicationId and $ProvisionerApplicationSecret.

### EXAMPLE 1
```
$subscriptionId = "REPLACE_WITH_SUBSCRIPTION_ID"
Connect-AzAccount -Subscription $subscriptionId
Connect-AzAccount -Subscription "REPLACE_WITH_SUBSCRIPTION_ID"
$testAadApp = New-AzADServicePrincipal -Role Owner -DisplayName 'azure-sdk-live-test-app'
.\eng\common\LiveTestResources\New-TestResources.ps1 `
-BaseName 'myalias' `
New-TestResources.ps1 `
-BaseName 'uuid123' `
-ServiceDirectory 'keyvault' `
-TestApplicationId $testAadApp.ApplicationId.ToString() `
-TestApplicationSecret (ConvertFrom-SecureString $testAadApp.Secret -AsPlainText)
Expand All @@ -71,7 +70,7 @@ the SecureString to plaintext by another means.

### EXAMPLE 2
```
eng/New-TestResources.ps1 `
New-TestResources.ps1 `
-BaseName 'Generated' `
-ServiceDirectory '$(ServiceDirectory)' `
-TenantId '$(TenantId)' `
Expand Down Expand Up @@ -214,6 +213,23 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -SubscriptionId
Optional subscription ID to use for new resources when logging in as a
provisioner.
You can also use Set-AzContext if not provisioning.
```yaml
Type: String
Parameter Sets: Provisioner
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -ProvisionerApplicationId
The AAD Application ID used to provision test resources when a provisioner is
specified.
Expand Down Expand Up @@ -283,8 +299,12 @@ Accept wildcard characters: False
### -Location
Optional location where resources should be created.
By default this is
'westus2'.
If left empty, the default
is based on the cloud to which the template is being deployed:
* AzureCloud -\> 'westus2'
* AzureUSGovernment -\> 'usgovvirginia'
* AzureChinaCloud -\> 'chinaeast2'
```yaml
Type: String
Expand All @@ -293,7 +313,7 @@ Aliases:

Required: False
Position: Named
Default value: Westus2
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
Expand Down Expand Up @@ -392,19 +412,32 @@ Accept pipeline input: False
Accept wildcard characters: False
```
### -OutFile
save test environment settings into a test-resources.json.env file next to test-resources.json.
The file is protected via DPAPI. The environment file would be scoped to the current repository directory.
Note: Supported only on Windows.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### CommonParameters
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
## INPUTS
## OUTPUTS
### Entries from the ARM templates' "output" section in environment variable syntax
### (e.g. $env:RESOURCE_NAME='<< resource name >>') that can be used for running
### live tests.
### If run in -CI mode the environment variables will be output in syntax that Azure
### DevOps can consume.
## NOTES
## RELATED LINKS
[Remove-TestResources.ps1](./New-TestResources.ps1.md)
[Remove-TestResources.ps1](./Remove-TestResources.ps1.md)
Loading

0 comments on commit b77a607

Please sign in to comment.