From 499b4d3bdba126d537fb5150c56b999bc0657b5f Mon Sep 17 00:00:00 2001 From: Akshay Gupta Date: Thu, 26 Mar 2020 13:35:26 -0700 Subject: [PATCH] mocks and tests --- .../Models/KeyVaultDataServiceClient.cs | 7 +- src/Network/Network.Test/Network.Test.csproj | 2 + .../ScenarioTests/ApplicationGatewayTests.cs | 26 ++++ .../ScenarioTests/ApplicationGatewayTests.ps1 | 134 ++++++++++++++++++ .../ScenarioTests/NetworkTestRunner.cs | 77 +++++++++- src/Network/Network.sln | 6 + src/Network/Network/ChangeLog.md | 1 + .../EnvironmentSetupHelper.cs | 2 + tools/TestFx/ITestRunnerFactory.cs | 2 + tools/TestFx/TestManager.cs | 19 +++ 10 files changed, 272 insertions(+), 4 deletions(-) diff --git a/src/KeyVault/KeyVault/Models/KeyVaultDataServiceClient.cs b/src/KeyVault/KeyVault/Models/KeyVaultDataServiceClient.cs index 8cc3d7af384d..62e1bef74369 100644 --- a/src/KeyVault/KeyVault/Models/KeyVaultDataServiceClient.cs +++ b/src/KeyVault/KeyVault/Models/KeyVaultDataServiceClient.cs @@ -21,10 +21,12 @@ using System.Security; using System.Security.Cryptography.X509Certificates; using System.Xml; +using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.KeyVault; using Microsoft.Azure.KeyVault.Models; using Microsoft.Azure.KeyVault.WebKey; +using Microsoft.Rest; using Microsoft.Rest.Azure; using KeyVaultProperties = Microsoft.Azure.Commands.KeyVault.Properties; @@ -41,9 +43,8 @@ public KeyVaultDataServiceClient(IAuthenticationFactory authFactory, IAzureConte if (context.Environment == null) throw new ArgumentException(KeyVaultProperties.Resources.InvalidAzureEnvironment); - var credential = new DataServiceCredential(authFactory, context, AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId); - this.keyVaultClient = new KeyVaultClient(credential.OnAuthentication); - + ServiceClientCredentials clientCredentials = authFactory.GetServiceClientCredentials(context, AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId); + this.keyVaultClient = AzureSession.Instance.ClientFactory.CreateCustomArmClient(clientCredentials); this.vaultUriHelper = new VaultUriHelper( context.Environment.GetEndpoint(AzureEnvironment.Endpoint.AzureKeyVaultDnsSuffix)); diff --git a/src/Network/Network.Test/Network.Test.csproj b/src/Network/Network.Test/Network.Test.csproj index a644f8d8c850..f63b4781b885 100644 --- a/src/Network/Network.Test/Network.Test.csproj +++ b/src/Network/Network.Test/Network.Test.csproj @@ -14,6 +14,8 @@ + + diff --git a/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs b/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs index fdbd99928804..44a03f8920b4 100644 --- a/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs +++ b/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs @@ -14,6 +14,8 @@ using System; using Microsoft.Azure.Commands.Network.Test.ScenarioTests; +using Microsoft.Azure.Test.HttpRecorder; +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; @@ -66,6 +68,30 @@ public void TestApplicationGatewayCRUD3() TestRunner.RunTestScript(string.Format("Test-ApplicationGatewayCRUD3 -baseDir '{0}'", AppDomain.CurrentDomain.BaseDirectory)); } + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + [Trait(Category.Owner, NrpTeamAlias.nvadev)] + public void TestKeyVaultIntegrationTest() + { + string environmentConnectionString = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"); + string servicePrincipal = "fakefakefake"; + if (!string.IsNullOrEmpty(environmentConnectionString)) + { + var connectionInfo = new ConnectionString(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION")); + var mode = connectionInfo.GetValue(ConnectionStringKeys.HttpRecorderModeKey); + if (mode == HttpRecorderMode.Playback) + { + servicePrincipal = HttpMockServer.GetVariable("spn", "fake"); + } + else + { + servicePrincipal = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalKey); + HttpMockServer.Variables["spn"] = servicePrincipal; + } + } + TestRunner.RunTestScript(string.Format("Test-KeyVaultIntegrationTest -baseDir '{0}' -spn '{1}'", AppDomain.CurrentDomain.BaseDirectory, servicePrincipal)); + } + [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] [Trait(Category.Owner, NrpTeamAlias.nvadev)] diff --git a/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.ps1 b/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.ps1 index ccbf985b2851..fb06f3397078 100644 --- a/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.ps1 +++ b/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.ps1 @@ -1390,6 +1390,140 @@ function Test-ApplicationGatewayCRUD3 } } +<# +.SYNOPSIS +Application gateway v2 tests for key vault +#> +function Test-KeyVaultIntegrationTest +{ + param + ( + [string]$basedir = "./", + [string]$spn + ) + + # Setup + $location = Get-ProviderLocation "Microsoft.Network/applicationGateways" "West US 2" + + $rgname = Get-ResourceGroupName + $appgwName = Get-ResourceName + $identityName = Get-ResourceName + $vnetName = Get-ResourceName + $gwSubnetName = Get-ResourceName + $publicIpName = Get-ResourceName + $gipconfigname = Get-ResourceName + + $frontendPort01Name = Get-ResourceName + $fipconfigName = Get-ResourceName + $listener01Name = Get-ResourceName + + $poolName = Get-ResourceName + $poolSetting01Name = Get-ResourceName + + $rule01Name = Get-ResourceName + + $keyVaultName = Get-ResourceName + $sslCert01Name = Get-ResourceName + $sslCert02Name = Get-ResourceName + + try + { + # resource group + New-AzResourceGroup -Name $rgname -Location $location -Tags @{ testtag = "APPGw tag"} + + # managed identity + $identity = New-AzUserAssignedIdentity -Name $identityName -Location $location -ResourceGroup $rgname + + # keyvault + if ((Get-NetworkTestMode) -ne 'Playback') + { + New-AzKeyVault -Name $keyVaultName -ResourceGroupName $rgname -Location $location -EnableSoftDelete + Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ServicePrincipalName $spn -PermissionsToSecrets get -PermissionsToCertificates get,list,delete,create,import,update,managecontacts,getissuers,listissuers,setissuers,deleteissuers,manageissuers,recover,purge,backup,restore + Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $identity.PrincipalId -PermissionsToSecrets get -BypassObjectIdValidation + + $policy = New-AzKeyVaultCertificatePolicy -ValidityInMonths 12 ` + -SubjectName "CN=www.app.com" -IssuerName self ` + -RenewAtNumberOfDaysBeforeExpiry 30 + + $certificate01 = Add-AzKeyVaultCertificate -VaultName $keyVaultName -Name $sslCert01Name -CertificatePolicy $policy + $certificate02 = Add-AzKeyVaultCertificate -VaultName $keyVaultName -Name $sslCert02Name -CertificatePolicy $policy + + Start-Sleep 30 + + $certificate01 = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $sslCert01Name + $secretId01 = $certificate01.SecretId.Replace($certificate01.Version, "") + + $certificate02 = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $sslCert02Name + $secretId02 = $certificate02.SecretId.Replace($certificate02.Version, "") + } + else + { + $secretId01 = "https://$keyVaultName.vault.azure.net/secrets/$sslCert01Name" + $secretId02 = "https://$keyVaultName.vault.azure.net/secrets/$sslCert02Name" + } + + # virtual network + $gwSubnet = New-AzVirtualNetworkSubnetConfig -Name $gwSubnetName -AddressPrefix 10.0.0.0/24 + $vnet = New-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname -Location $location -AddressPrefix 10.0.0.0/16 -Subnet $gwSubnet + $vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname + $gwSubnet = Get-AzVirtualNetworkSubnetConfig -Name $gwSubnetName -VirtualNetwork $vnet + + # public ip + $publicip = New-AzPublicIpAddress -ResourceGroupName $rgname -name $publicIpName -location $location -AllocationMethod Static -sku Standard + + # ip configuration + $gipconfig = New-AzApplicationGatewayIPConfiguration -Name $gipconfigname -Subnet $gwSubnet + + $fipconfig = New-AzApplicationGatewayFrontendIPConfig -Name $fipconfigName -PublicIPAddress $publicip + $fp01 = New-AzApplicationGatewayFrontendPort -Name $frontendPort01Name  -Port 80 + $listener01 = New-AzApplicationGatewayHttpListener -Name $listener01Name -Protocol Http -FrontendIPConfiguration $fipconfig -FrontendPort $fp01 + + # backend part + $pool = New-AzApplicationGatewayBackendAddressPool -Name $poolName -BackendIPAddresses 10.0.0.1 + $poolSetting01 = New-AzApplicationGatewayBackendHttpSettings -Name $poolSetting01Name -Port 80 -Protocol Http -CookieBasedAffinity Enabled -PickHostNameFromBackendAddress + + # rule + $rule01 = New-AzApplicationGatewayRequestRoutingRule -Name $rule01Name -RuleType basic -BackendHttpSettings $poolSetting01 -HttpListener $listener01 -BackendAddressPool $pool + + # sku + $sku = New-AzApplicationGatewaySku -Name Standard_v2 -Tier Standard_v2 -Capacity 2 + + # appgw identity + $appgwIdentity = New-AzApplicationGatewayIdentity -UserAssignedIdentity $identity.Id + + # ssl cert + $sslCert01 = New-AzApplicationGatewaySslCertificate -Name $sslCert01Name -KeyVaultSecretId $secretId01 + + # create + $appgw = New-AzApplicationGateway -Sku $sku -Identity $appgwIdentity -Name $appgwName -ResourceGroupName $rgname -Zone 1,2 -Location $location ` + -BackendAddressPools $pool -BackendHttpSettingsCollection $poolSetting01 ` + -FrontendIpConfigurations $fipconfig -GatewayIpConfigurations $gipconfig -FrontendPorts $fp01 -HttpListeners $listener01 ` + -SslCertificates $sslCert01 ` + -RequestRoutingRules $rule01 + + Assert-AreEqual $appgw.SslCertificates.Count 1 + Assert-AreEqual $appgw.SslCertificates[0].KeyVaultSecretId $secretId01 + + # modify the certificate + $appgw = Set-AzApplicationGatewaySslCertificate -Name $sslCert01Name -KeyVaultSecretId $secretId02 -ApplicationGateway $appgw + $result = Set-AzApplicationGateway -ApplicationGateway $appgw + + Assert-AreEqual $result.SslCertificates[0].KeyVaultSecretId $secretId02 + + $result = Remove-AzApplicationGatewaySslCertificate -Name $sslCert01Name -ApplicationGateway $result + + Assert-AreEqual $result.SslCertificates.Count 0 + + # delete + Remove-AzApplicationGateway -Name $appgwName -ResourceGroupName $rgname -Force + } + finally + { + # Cleanup + Clean-ResourceGroup $rgname + } +} + <# .SYNOPSIS Compare connectionDraining of backendhttpsettings diff --git a/src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs b/src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs index a629cfceba0e..fddd5200cefa 100644 --- a/src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs +++ b/src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs @@ -1,5 +1,17 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Microsoft.Azure.Commands.TestFx; +using Microsoft.Azure.Internal.Common; +using Microsoft.Azure.KeyVault; +using Microsoft.Azure.Management.Compute; +using Microsoft.Azure.Management.Internal.Resources; +using Microsoft.Azure.Management.KeyVault; +using Microsoft.Azure.Management.ManagedServiceIdentity; +using Microsoft.Azure.Management.Network; +using Microsoft.Azure.Test.HttpRecorder; +using Microsoft.IdentityModel.Clients.ActiveDirectory; +using Microsoft.Rest; +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using Xunit.Abstractions; namespace Microsoft.Azure.Commands.Network.Test.ScenarioTests @@ -27,6 +39,7 @@ protected NetworkTestRunner(ITestOutputHelper output) helper.GetRMModulePath("AzureRM.Storage.psd1"), helper.GetRMModulePath("AzureRM.ContainerInstance.psd1"), helper.GetRMModulePath("AzureRM.OperationalInsights.psd1"), + helper.GetRMModulePath("AzureRM.KeyVault.psd1"), helper.GetRMModulePath("AzureRM.ManagedServiceIdentity.psd1"), }) .WithNewRecordMatcherArguments ( @@ -41,10 +54,72 @@ protected NetworkTestRunner(ITestOutputHelper output) {"Microsoft.Features", null}, {"Microsoft.Authorization", null}, {"Microsoft.Storage", null}, + {"Microsoft.KeyVault", null}, {"Microsoft.ManagedServiceIdentity", null}, } + ).WithManagementClients( + GetResourceManagementClient, + GetManagedServiceIdentityClient, + GetKeyVaultManagementClient, + GetNetworkManagementClient, + GetComputeManagementClient, + GetKeyVaultClient, + GetAzureRestClient ) .Build(); } + + private static ResourceManagementClient GetResourceManagementClient(MockContext context) + { + return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + } + + private static ManagedServiceIdentityClient GetManagedServiceIdentityClient(MockContext context) + { + return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + } + + private static KeyVaultManagementClient GetKeyVaultManagementClient(MockContext context) + { + return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + } + + private static NetworkManagementClient GetNetworkManagementClient(MockContext context) + { + return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + } + + private static ComputeManagementClient GetComputeManagementClient(MockContext context) + { + return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + } + + private static AzureRestClient GetAzureRestClient(MockContext context) + { + return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + } + + private static KeyVaultClient GetKeyVaultClient(MockContext context) + { + string environmentConnectionString = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"); + string accessToken = "fakefakefake"; + + // When recording, we should have a connection string passed into the code from the environment + if (!string.IsNullOrEmpty(environmentConnectionString)) + { + // Gather test client credential information from the environment + var connectionInfo = new ConnectionString(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION")); + string servicePrincipal = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalKey); + string servicePrincipalSecret = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalSecretKey); + string aadTenant = connectionInfo.GetValue(ConnectionStringKeys.AADTenantKey); + + // Create credentials + var clientCredentials = new ClientCredential(servicePrincipal, servicePrincipalSecret); + var authContext = new AuthenticationContext($"https://login.windows.net/{aadTenant}", TokenCache.DefaultShared); + accessToken = authContext.AcquireTokenAsync("https://vault.azure.net", clientCredentials).Result.AccessToken; + } + + return new KeyVaultClient(new TokenCredentials(accessToken), HttpMockServer.CreateInstance()); + } } } diff --git a/src/Network/Network.sln b/src/Network/Network.sln index 6df692440e18..5c3d1141f6d5 100644 --- a/src/Network/Network.sln +++ b/src/Network/Network.sln @@ -32,6 +32,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScenarioTest.ResourceManage EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestFx", "..\..\tools\TestFx\TestFx.csproj", "{BC80A1D0-FFA4-43D9-AA74-799F5CB54B58}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sql.LegacySdk", "..\Sql\Sql.LegacySdk\Sql.LegacySdk.csproj", "{AD8D31C1-3C84-4213-A13A-A21C7440E591}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -94,6 +96,10 @@ Global {BC80A1D0-FFA4-43D9-AA74-799F5CB54B58}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC80A1D0-FFA4-43D9-AA74-799F5CB54B58}.Release|Any CPU.ActiveCfg = Release|Any CPU {BC80A1D0-FFA4-43D9-AA74-799F5CB54B58}.Release|Any CPU.Build.0 = Release|Any CPU + {AD8D31C1-3C84-4213-A13A-A21C7440E591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD8D31C1-3C84-4213-A13A-A21C7440E591}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD8D31C1-3C84-4213-A13A-A21C7440E591}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD8D31C1-3C84-4213-A13A-A21C7440E591}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Network/Network/ChangeLog.md b/src/Network/Network/ChangeLog.md index ccf6e60e99a4..4dfeb52a8fe0 100644 --- a/src/Network/Network/ChangeLog.md +++ b/src/Network/Network/ChangeLog.md @@ -25,6 +25,7 @@ - `New-AzVirtualHub` - `Update-AzVirtualHub` * Removed Sql Management SDK dependency +* Bug fix for Set-AzApplicationGatewaySslCertificate (https://github.com/Azure/azure-powershell/issues/9488) ## Version 2.3.2 * Updated Sql Management SDK. diff --git a/tools/ScenarioTest.ResourceManager/EnvironmentSetupHelper.cs b/tools/ScenarioTest.ResourceManager/EnvironmentSetupHelper.cs index befacea71c5a..efdd5aaf4b3f 100644 --- a/tools/ScenarioTest.ResourceManager/EnvironmentSetupHelper.cs +++ b/tools/ScenarioTest.ResourceManager/EnvironmentSetupHelper.cs @@ -427,6 +427,8 @@ public void SetupAzureEnvironmentFromEnvironmentVariables(AzureModule mode) environment.AzureDataLakeAnalyticsCatalogAndJobEndpointSuffix = currentEnvironment.Endpoints.DataLakeAnalyticsJobAndCatalogServiceUri.OriginalString.Replace("https://", ""); // because it is just a sufix environment.AzureDataLakeStoreFileSystemEndpointSuffix = currentEnvironment.Endpoints.DataLakeStoreServiceUri.OriginalString.Replace("https://", ""); // because it is just a sufix environment.StorageEndpointSuffix = AzureEnvironmentConstants.AzureStorageEndpointSuffix; + environment.AzureKeyVaultDnsSuffix = AzureEnvironmentConstants.AzureKeyVaultDnsSuffix; + environment.AzureKeyVaultServiceEndpointResourceId = AzureEnvironmentConstants.AzureKeyVaultServiceEndpointResourceId; if (!AzureRmProfileProvider.Instance.GetProfile().EnvironmentTable.ContainsKey(testEnvironmentName)) { AzureRmProfileProvider.Instance.GetProfile().EnvironmentTable[testEnvironmentName] = environment; diff --git a/tools/TestFx/ITestRunnerFactory.cs b/tools/TestFx/ITestRunnerFactory.cs index bf76c3d0d4e2..ec4c27517ea0 100644 --- a/tools/TestFx/ITestRunnerFactory.cs +++ b/tools/TestFx/ITestRunnerFactory.cs @@ -14,6 +14,7 @@ using System; using System.Collections.Generic; +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using Microsoft.WindowsAzure.Commands.ScenarioTest; namespace Microsoft.Azure.Commands.TestFx @@ -30,5 +31,6 @@ public interface ITestRunnerFactory ITestRunnerFactory WithExtraUserAgentsToIgnore(Dictionary userAgentsToIgnore); ITestRunnerFactory WithRecordMatcher(RecordMatcherDelegate recordMatcher); ITestRunnerFactory WithNewRecordMatcherArguments(Dictionary userAgentsToIgnore, Dictionary resourceProviders); + ITestRunnerFactory WithManagementClients(params Func []initializedManagementClients); } } diff --git a/tools/TestFx/TestManager.cs b/tools/TestFx/TestManager.cs index 4e77eedafedd..5528180655c1 100644 --- a/tools/TestFx/TestManager.cs +++ b/tools/TestFx/TestManager.cs @@ -41,6 +41,7 @@ public class TestManager : ITestRunnerFactory, ITestRunner private Dictionary _matcherNewUserAgentsToIgnore; private Dictionary _matcherResourceProviders; private Action _mockContextAction; + private Func[] _initializedManagementClients; protected EnvironmentSetupHelper Helper; protected readonly List RmModules; protected readonly List CommonPsScripts = new List(); @@ -195,6 +196,12 @@ public ITestRunnerFactory WithTestOutputHelper(ITestOutputHelper output) return this; } + public ITestRunnerFactory WithManagementClients(params Func[] initializedManagementClients) + { + _initializedManagementClients = initializedManagementClients; + return this; + } + public ITestRunner Build() { SetupSessionAndProfile(); @@ -214,6 +221,7 @@ public void RunTestScript(params string[] scripts) { _mockContextAction?.Invoke(); AzureSession.Instance.ClientFactory = new TestClientFactory(mockContext); + SetupManagementClients(mockContext); Helper.SetupEnvironment(AzureModule.AzureResourceManager); SetupAzureContext(); Helper.RunPowerShellTest(scripts); @@ -331,6 +339,17 @@ protected void SetupMockServerMatcher() HttpMockServer.Matcher = RecordMatcher(true, resourceProviders, userAgentsToIgnore); } + protected void SetupManagementClients(MockContext context) + { + if (this._initializedManagementClients != null) { + var clients = new List(); + foreach (var client in this._initializedManagementClients) + { + clients.Add(client(context)); + } + Helper.SetupManagementClients(clients.ToArray()); + } + } #endregion } }