Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable weekly testing of ACR SDK in national clouds #22643

Closed
wants to merge 8 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public async Task CanStartPagingMidCollection(bool anonymous)
}

[RecordedTest, NonParallelizable]
public async Task CanDeleteRepostitory()
public async Task CanDeleteRepository()
{
// Arrange
string registry = TestEnvironment.Registry;
Expand Down Expand Up @@ -144,7 +144,7 @@ public async Task CanDeleteRepostitory()
}

[RecordedTest, NonParallelizable]
public void CanDeleteRepostitory_Anonymous()
public void CanDeleteRepository_Anonymous()
{
// Arrange
string repository = $"library/hello-world";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Core.TestFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using Azure.Core.TestFramework;
using Azure.Identity;
using Microsoft.Azure.Management.ContainerRegistry;
using Microsoft.Azure.Management.ContainerRegistry.Models;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent.Authentication;
using NUnit.Framework;
using System.Linq;
using Task = System.Threading.Tasks.Task;

namespace Azure.Containers.ContainerRegistry.Tests
Expand All @@ -26,22 +27,116 @@ public ContainerRegistryRecordedTestBase(bool isAsync, RecordedTestMode mode) :
Sanitizer = new ContainerRegistryRecordedTestSanitizer();
}

public ContainerRegistryClient CreateClient(bool anonymousAccess = false, string authenticationScope = null)
public ContainerRegistryClient CreateClient(bool anonymousAccess = false)
{
return anonymousAccess ?
return anonymousAccess ? CreateAnonymousClient() : CreateAuthenticatedClient();
}

InstrumentClient(new ContainerRegistryClient(
new Uri(TestEnvironment.AnonymousAccessEndpoint),
InstrumentClientOptions(new ContainerRegistryClientOptions())
)) :
private ContainerRegistryClient CreateAuthenticatedClient()
{
string endpoint = TestEnvironment.Endpoint;
Uri authorityHost = GetAuthorityHost(endpoint);
string authenticationScope = GetAuthenticationScope(authorityHost);

InstrumentClient(new ContainerRegistryClient(
new Uri(TestEnvironment.Endpoint),
return InstrumentClient(new ContainerRegistryClient(
new Uri(endpoint),
TestEnvironment.Credential,
InstrumentClientOptions(new ContainerRegistryClientOptions())
InstrumentClientOptions(new ContainerRegistryClientOptions()
{
AuthenticationScope = authenticationScope
})
));
}

private ContainerRegistryClient CreateAnonymousClient()
{
string endpoint = TestEnvironment.AnonymousAccessEndpoint;
Uri authorityHost = GetAuthorityHost(endpoint);
string authenticationScope = GetAuthenticationScope(authorityHost);

return InstrumentClient(new ContainerRegistryClient(
new Uri(endpoint),
InstrumentClientOptions(new ContainerRegistryClientOptions()
{
AuthenticationScope = authenticationScope
})
));
}

private Uri GetAuthorityHost(string endpoint)
{
if (endpoint.Contains(".azurecr.io"))
{
return AzureAuthorityHosts.AzurePublicCloud;
}

if (endpoint.Contains(".azurecr.cn"))
{
return AzureAuthorityHosts.AzureChina;
}

if (endpoint.Contains(".azurecr.us"))
{
return AzureAuthorityHosts.AzureGovernment;
}

if (endpoint.Contains(".azurecr.de"))
{
return AzureAuthorityHosts.AzureGermany;
}

throw new NotSupportedException($"Cloud for endpoint {endpoint} is not supported.");
}

private string GetAuthenticationScope(Uri authorityHost)
{
if (authorityHost == AzureAuthorityHosts.AzurePublicCloud)
{
return "https://management.core.windows.net/.default";
}

if (authorityHost == AzureAuthorityHosts.AzureChina)
{
return "https://management.chinacloudapi.cn/.default";
}

if (authorityHost == AzureAuthorityHosts.AzureGovernment)
{
// ACR's authentication scope for US Government cloud
return "https://management.usgovcloudapi.net/.default";
}

if (authorityHost == AzureAuthorityHosts.AzureGermany)
{
return "https://management.microsoftazure.de/";
}

throw new NotSupportedException($"Cloud for authority host {authorityHost} is not supported.");
}

[SetUp]
public void ContainerRegistryTestSetup()
{
string endpoint = TestEnvironment.Endpoint;
if (GetAuthorityHost(endpoint) != AzureAuthorityHosts.AzurePublicCloud && UsingAnonymousClient())
{
Assert.Ignore("Anonymous client is not enabled in national clouds.");
}
}

private bool UsingAnonymousClient()
{
var args = TestContext.CurrentContext.Test.Arguments;
if (args != null && args.Length > 0 && args[0].GetType() == typeof(bool))
{
return (bool)args[0];
}

return false;
}

#region Methods using Track 1 Management Plane library

public async Task ImportImageAsync(string registry, string repository, string tag)
{
await ImportImageAsync(registry, repository, new List<string>() { tag });
Expand All @@ -56,7 +151,7 @@ public async Task ImportImageAsync(string registry, string repository, List<stri
ClientSecret = TestEnvironment.ClientSecret,
},
TestEnvironment.TenantId,
AzureEnvironment.AzureGlobalCloud);
GetManagementCloudEnvironment());

var managementClient = new ContainerRegistryManagementClient(credential.WithDefaultSubscription(TestEnvironment.SubscriptionId));
managementClient.SubscriptionId = TestEnvironment.SubscriptionId;
Expand All @@ -80,5 +175,39 @@ await managementClient.Registries.ImportImageAsync(
TargetTags = targetTags.ToList()
});
}

/// <summary>
/// Obtain the track 1 management plane AzureEnvironment value for the
/// cloud correponding to the configured endpoint.
/// </summary>
/// <returns></returns>
private AzureEnvironment GetManagementCloudEnvironment()
{
string endpoint = TestEnvironment.Endpoint;
Uri authorityHost = GetAuthorityHost(endpoint);

if (authorityHost == AzureAuthorityHosts.AzurePublicCloud)
{
return AzureEnvironment.AzureGlobalCloud;
}

if (authorityHost == AzureAuthorityHosts.AzureChina)
{
return AzureEnvironment.AzureChinaCloud;
}

if (authorityHost == AzureAuthorityHosts.AzureGovernment)
{
return AzureEnvironment.AzureUSGovernment;
}

if (authorityHost == AzureAuthorityHosts.AzureGermany)
{
return AzureEnvironment.AzureGermanCloud;
}

throw new NotSupportedException($"Cloud for authority host {authorityHost} is not supported.");
}
#endregion
}
}
8 changes: 6 additions & 2 deletions sdk/containerregistry/test-resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
"metadata": {
"description": "The location of the resource. By default, this is the same as the resource group."
}
},
"containerRegistryEndpointSuffix": {
"defaultValue": ".azurecr.io",
"type": "string"
}
},
"variables": {
"apiVersion": "2020-11-01-preview",
"endpointValue": "[format('https://{0}.azurecr.io', parameters('baseName'))]",
"endpointValue": "[format('https://{0}{1}', parameters('baseName'), parameters('containerRegistryEndpointSuffix'))]",
"anonRegistryName": "[format('{0}anon', parameters('baseName'))]",
"anonEndpointValue": "[format('https://{0}.azurecr.io', variables('anonRegistryName'))]"
"anonEndpointValue": "[format('https://{0}{1}', variables('anonRegistryName'), parameters('containerRegistryEndpointSuffix'))]"
},
"resources": [
{
Expand Down
3 changes: 2 additions & 1 deletion sdk/containerregistry/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ trigger: none
extends:
template: ../../eng/pipelines/templates/stages/archetype-sdk-tests.yml
parameters:
SDKType: client
ServiceDirectory: containerregistry
SDKType: client
SupportedClouds: 'Public,UsGov,China'
6 changes: 5 additions & 1 deletion sdk/core/Azure.Core.TestFramework/src/TestEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,11 @@ public virtual TokenCredential Credential
_credential = new ClientSecretCredential(
GetVariable("TENANT_ID"),
GetVariable("CLIENT_ID"),
GetVariable("CLIENT_SECRET")
GetVariable("CLIENT_SECRET"),
new ClientSecretCredentialOptions()
{
AuthorityHost = new Uri(GetVariable("AZURE_AUTHORITY_HOST"))
}
);
}

Expand Down