Skip to content

Commit 712fd6d

Browse files
appgw: validate cert only if certificateFile is specified in set ssl cert command (#12794)
* code changes * added tests * change log * add client for private dns
1 parent 4e60cdb commit 712fd6d

File tree

12 files changed

+4527
-6
lines changed

12 files changed

+4527
-6
lines changed

src/KeyVault/KeyVault/Models/KeyVaultDataServiceClient.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121
using System.Security;
2222
using System.Security.Cryptography.X509Certificates;
2323
using System.Xml;
24+
using Microsoft.Azure.Commands.Common.Authentication;
2425
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
2526
using Microsoft.Azure.KeyVault;
2627
using Microsoft.Azure.KeyVault.Models;
2728
using Microsoft.Azure.KeyVault.WebKey;
29+
using Microsoft.Rest;
2830
using Microsoft.Rest.Azure;
2931
using KeyVaultProperties = Microsoft.Azure.Commands.KeyVault.Properties;
3032

@@ -41,9 +43,8 @@ public KeyVaultDataServiceClient(IAuthenticationFactory authFactory, IAzureConte
4143
if (context.Environment == null)
4244
throw new ArgumentException(KeyVaultProperties.Resources.InvalidAzureEnvironment);
4345

44-
var credential = new DataServiceCredential(authFactory, context, AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId);
45-
this.keyVaultClient = new KeyVaultClient(credential.OnAuthentication);
46-
46+
ServiceClientCredentials clientCredentials = authFactory.GetServiceClientCredentials(context, AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId);
47+
this.keyVaultClient = AzureSession.Instance.ClientFactory.CreateCustomArmClient<KeyVaultClient>(clientCredentials);
4748

4849
this.vaultUriHelper = new VaultUriHelper(
4950
context.Environment.GetEndpoint(AzureEnvironment.Endpoint.AzureKeyVaultDnsSuffix));

src/Network/Network.Test/Network.Test.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<PsModuleName>Network</PsModuleName>
@@ -15,12 +15,16 @@
1515
<ItemGroup>
1616
<PackageReference Include="Microsoft.Azure.Graph.RBAC" Version="3.4.0-preview" />
1717
<PackageReference Include="Microsoft.Azure.Management.Network" Version="20.0.2-preview" />
18+
<PackageReference Include="Microsoft.Azure.KeyVault" Version="3.0.5" />
19+
<PackageReference Include="Microsoft.Azure.Management.KeyVault" Version="3.0.1" />
1820
<PackageReference Include="Microsoft.Azure.Insights" Version="0.16.0-preview" />
1921
<PackageReference Include="Microsoft.Azure.Management.Compute" Version="38.1.0" />
2022
<PackageReference Include="Microsoft.Azure.Management.ContainerInstance" Version="2.0.0" />
23+
<PackageReference Include="Microsoft.Azure.Management.PrivateDns" Version="1.0.0" />
2124
<PackageReference Include="Microsoft.Azure.Management.Redis" Version="4.4.1" />
2225
<PackageReference Include="Microsoft.Azure.Management.OperationalInsights" Version="0.21.0-preview" />
2326
<PackageReference Include="Microsoft.Azure.Management.ManagedServiceIdentity" Version="0.10.0-preview" />
27+
<PackageReference Include="Microsoft.Azure.Management.Storage" Version="17.2.0" />
2428
</ItemGroup>
2529

2630
<ItemGroup>

src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
using System;
1616
using Microsoft.Azure.Commands.Network.Test.ScenarioTests;
17+
using Microsoft.Azure.Test.HttpRecorder;
18+
using Microsoft.Rest.ClientRuntime.Azure.TestFramework;
1719
using Microsoft.WindowsAzure.Commands.ScenarioTest;
1820
using Xunit;
1921

@@ -66,6 +68,30 @@ public void TestApplicationGatewayCRUD3()
6668
TestRunner.RunTestScript(string.Format("Test-ApplicationGatewayCRUD3 -baseDir '{0}'", AppDomain.CurrentDomain.BaseDirectory));
6769
}
6870

71+
[Fact]
72+
[Trait(Category.AcceptanceType, Category.CheckIn)]
73+
[Trait(Category.Owner, NrpTeamAlias.nvadev)]
74+
public void TestKeyVaultIntegrationTest()
75+
{
76+
string environmentConnectionString = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION");
77+
string servicePrincipal = "fakefakefake";
78+
if (!string.IsNullOrEmpty(environmentConnectionString))
79+
{
80+
var connectionInfo = new ConnectionString(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"));
81+
var mode = connectionInfo.GetValue<string>(ConnectionStringKeys.HttpRecorderModeKey);
82+
if (mode == HttpRecorderMode.Playback.ToString())
83+
{
84+
servicePrincipal = HttpMockServer.GetVariable("spn", "fake");
85+
}
86+
else
87+
{
88+
servicePrincipal = connectionInfo.GetValue<string>(ConnectionStringKeys.ServicePrincipalKey);
89+
HttpMockServer.Variables["spn"] = servicePrincipal;
90+
}
91+
}
92+
TestRunner.RunTestScript(string.Format("Test-KeyVaultIntegrationTest -baseDir '{0}' -spn '{1}'", AppDomain.CurrentDomain.BaseDirectory, servicePrincipal));
93+
}
94+
6995
[Fact]
7096
[Trait(Category.AcceptanceType, Category.CheckIn)]
7197
[Trait(Category.Owner, NrpTeamAlias.nvadev)]

src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.ps1

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,140 @@ function Test-ApplicationGatewayCRUD3
13901390
}
13911391
}
13921392

1393+
<#
1394+
.SYNOPSIS
1395+
Application gateway v2 tests for key vault
1396+
#>
1397+
function Test-KeyVaultIntegrationTest
1398+
{
1399+
param
1400+
(
1401+
[string]$basedir = "./",
1402+
[string]$spn
1403+
)
1404+
1405+
# Setup
1406+
$location = Get-ProviderLocation "Microsoft.Network/applicationGateways" "West US 2"
1407+
1408+
$rgname = Get-ResourceGroupName
1409+
$appgwName = Get-ResourceName
1410+
$identityName = Get-ResourceName
1411+
$vnetName = Get-ResourceName
1412+
$gwSubnetName = Get-ResourceName
1413+
$publicIpName = Get-ResourceName
1414+
$gipconfigname = Get-ResourceName
1415+
1416+
$frontendPort01Name = Get-ResourceName
1417+
$fipconfigName = Get-ResourceName
1418+
$listener01Name = Get-ResourceName
1419+
1420+
$poolName = Get-ResourceName
1421+
$poolSetting01Name = Get-ResourceName
1422+
1423+
$rule01Name = Get-ResourceName
1424+
1425+
$keyVaultName = Get-ResourceName
1426+
$sslCert01Name = Get-ResourceName
1427+
$sslCert02Name = Get-ResourceName
1428+
1429+
try
1430+
{
1431+
# resource group
1432+
New-AzResourceGroup -Name $rgname -Location $location -Tags @{ testtag = "APPGw tag"}
1433+
1434+
# managed identity
1435+
$identity = New-AzUserAssignedIdentity -Name $identityName -Location $location -ResourceGroup $rgname
1436+
1437+
# keyvault
1438+
if ((Get-NetworkTestMode) -ne 'Playback')
1439+
{
1440+
New-AzKeyVault -Name $keyVaultName -ResourceGroupName $rgname -Location $location -EnableSoftDelete
1441+
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
1442+
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $identity.PrincipalId -PermissionsToSecrets get -BypassObjectIdValidation
1443+
1444+
$policy = New-AzKeyVaultCertificatePolicy -ValidityInMonths 12 `
1445+
-SubjectName "CN=www.app.com" -IssuerName self `
1446+
-RenewAtNumberOfDaysBeforeExpiry 30
1447+
1448+
$certificate01 = Add-AzKeyVaultCertificate -VaultName $keyVaultName -Name $sslCert01Name -CertificatePolicy $policy
1449+
$certificate02 = Add-AzKeyVaultCertificate -VaultName $keyVaultName -Name $sslCert02Name -CertificatePolicy $policy
1450+
1451+
Start-Sleep 30
1452+
1453+
$certificate01 = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $sslCert01Name
1454+
$secretId01 = $certificate01.SecretId.Replace($certificate01.Version, "")
1455+
1456+
$certificate02 = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $sslCert02Name
1457+
$secretId02 = $certificate02.SecretId.Replace($certificate02.Version, "")
1458+
}
1459+
else
1460+
{
1461+
$secretId01 = "https://$keyVaultName.vault.azure.net:443/secrets/$sslCert01Name/"
1462+
$secretId02 = "https://$keyVaultName.vault.azure.net:443/secrets/$sslCert02Name/"
1463+
}
1464+
1465+
# virtual network
1466+
$gwSubnet = New-AzVirtualNetworkSubnetConfig -Name $gwSubnetName -AddressPrefix 10.0.0.0/24
1467+
$vnet = New-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname -Location $location -AddressPrefix 10.0.0.0/16 -Subnet $gwSubnet
1468+
$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname
1469+
$gwSubnet = Get-AzVirtualNetworkSubnetConfig -Name $gwSubnetName -VirtualNetwork $vnet
1470+
1471+
# public ip
1472+
$publicip = New-AzPublicIpAddress -ResourceGroupName $rgname -name $publicIpName -location $location -AllocationMethod Static -sku Standard
1473+
1474+
# ip configuration
1475+
$gipconfig = New-AzApplicationGatewayIPConfiguration -Name $gipconfigname -Subnet $gwSubnet
1476+
1477+
$fipconfig = New-AzApplicationGatewayFrontendIPConfig -Name $fipconfigName -PublicIPAddress $publicip
1478+
$fp01 = New-AzApplicationGatewayFrontendPort -Name $frontendPort01Name  -Port 80
1479+
$listener01 = New-AzApplicationGatewayHttpListener -Name $listener01Name -Protocol Http -FrontendIPConfiguration $fipconfig -FrontendPort $fp01
1480+
1481+
# backend part
1482+
$pool = New-AzApplicationGatewayBackendAddressPool -Name $poolName -BackendIPAddresses 10.0.0.1
1483+
$poolSetting01 = New-AzApplicationGatewayBackendHttpSettings -Name $poolSetting01Name -Port 80 -Protocol Http -CookieBasedAffinity Enabled -PickHostNameFromBackendAddress
1484+
1485+
# rule
1486+
$rule01 = New-AzApplicationGatewayRequestRoutingRule -Name $rule01Name -RuleType basic -BackendHttpSettings $poolSetting01 -HttpListener $listener01 -BackendAddressPool $pool
1487+
1488+
# sku
1489+
$sku = New-AzApplicationGatewaySku -Name Standard_v2 -Tier Standard_v2 -Capacity 2
1490+
1491+
# appgw identity
1492+
$appgwIdentity = New-AzApplicationGatewayIdentity -UserAssignedIdentity $identity.Id
1493+
1494+
# ssl cert
1495+
$sslCert01 = New-AzApplicationGatewaySslCertificate -Name $sslCert01Name -KeyVaultSecretId $secretId01
1496+
1497+
# create
1498+
$appgw = New-AzApplicationGateway -Sku $sku -Identity $appgwIdentity -Name $appgwName -ResourceGroupName $rgname -Zone 1,2 -Location $location `
1499+
-BackendAddressPools $pool -BackendHttpSettingsCollection $poolSetting01 `
1500+
-FrontendIpConfigurations $fipconfig -GatewayIpConfigurations $gipconfig -FrontendPorts $fp01 -HttpListeners $listener01 `
1501+
-SslCertificates $sslCert01 `
1502+
-RequestRoutingRules $rule01
1503+
1504+
Assert-AreEqual $appgw.SslCertificates.Count 1
1505+
Assert-AreEqual $appgw.SslCertificates[0].KeyVaultSecretId $secretId01
1506+
1507+
# modify the certificate
1508+
$appgw = Set-AzApplicationGatewaySslCertificate -Name $sslCert01Name -KeyVaultSecretId $secretId02 -ApplicationGateway $appgw
1509+
$result = Set-AzApplicationGateway -ApplicationGateway $appgw
1510+
1511+
Assert-AreEqual $result.SslCertificates[0].KeyVaultSecretId $secretId02
1512+
1513+
$result = Remove-AzApplicationGatewaySslCertificate -Name $sslCert01Name -ApplicationGateway $result
1514+
1515+
Assert-AreEqual $result.SslCertificates.Count 0
1516+
1517+
# delete
1518+
Remove-AzApplicationGateway -Name $appgwName -ResourceGroupName $rgname -Force
1519+
}
1520+
finally
1521+
{
1522+
# Cleanup
1523+
Clean-ResourceGroup $rgname
1524+
}
1525+
}
1526+
13931527
<#
13941528
.SYNOPSIS
13951529
Compare connectionDraining of backendhttpsettings

src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using Microsoft.Azure.Commands.TestFx;
4+
using Microsoft.Azure.Internal.Common;
5+
using Microsoft.Azure.KeyVault;
6+
using Microsoft.Azure.Management.Compute;
7+
using Microsoft.Azure.Management.Internal.Resources;
8+
using Microsoft.Azure.Management.KeyVault;
9+
using Microsoft.Azure.Management.ManagedServiceIdentity;
10+
using Microsoft.Azure.Management.Network;
11+
using Microsoft.Azure.Management.PrivateDns;
12+
using Microsoft.Azure.Management.Storage;
13+
using Microsoft.Azure.Test.HttpRecorder;
14+
using Microsoft.IdentityModel.Clients.ActiveDirectory;
15+
using Microsoft.Rest;
16+
using Microsoft.Rest.ClientRuntime.Azure.TestFramework;
317
using Xunit.Abstractions;
418

519
namespace Microsoft.Azure.Commands.Network.Test.ScenarioTests
@@ -28,6 +42,7 @@ protected NetworkTestRunner(ITestOutputHelper output)
2842
helper.GetRMModulePath("AzureRM.Sql.psd1"),
2943
helper.GetRMModulePath("AzureRM.ContainerInstance.psd1"),
3044
helper.GetRMModulePath("AzureRM.OperationalInsights.psd1"),
45+
helper.GetRMModulePath("AzureRM.KeyVault.psd1"),
3146
helper.GetRMModulePath("AzureRM.ManagedServiceIdentity.psd1"),
3247
helper.GetRMModulePath("AzureRM.PrivateDns.psd1"),
3348
})
@@ -44,11 +59,89 @@ protected NetworkTestRunner(ITestOutputHelper output)
4459
{"Microsoft.Authorization", null},
4560
{"Microsoft.Storage", null},
4661
{"Microsoft.Sql", null},
62+
{"Microsoft.KeyVault", null},
4763
{"Microsoft.ManagedServiceIdentity", null},
4864
{"Microsoft.PrivateDns", null},
4965
}
66+
).WithManagementClients(
67+
GetResourceManagementClient,
68+
GetManagedServiceIdentityClient,
69+
GetKeyVaultManagementClient,
70+
GetNetworkManagementClient,
71+
GetComputeManagementClient,
72+
GetStorageManagementClient,
73+
GetKeyVaultClient,
74+
GetAzureRestClient,
75+
GetPrivateDnsManagementClient
5076
)
5177
.Build();
5278
}
79+
80+
private static ResourceManagementClient GetResourceManagementClient(MockContext context)
81+
{
82+
return context.GetServiceClient<ResourceManagementClient>(TestEnvironmentFactory.GetTestEnvironment());
83+
}
84+
85+
private static ManagedServiceIdentityClient GetManagedServiceIdentityClient(MockContext context)
86+
{
87+
return context.GetServiceClient<ManagedServiceIdentityClient>(TestEnvironmentFactory.GetTestEnvironment());
88+
}
89+
90+
private static KeyVaultManagementClient GetKeyVaultManagementClient(MockContext context)
91+
{
92+
return context.GetServiceClient<KeyVaultManagementClient>(TestEnvironmentFactory.GetTestEnvironment());
93+
}
94+
95+
private static NetworkManagementClient GetNetworkManagementClient(MockContext context)
96+
{
97+
return context.GetServiceClient<NetworkManagementClient>(TestEnvironmentFactory.GetTestEnvironment());
98+
}
99+
100+
private static ComputeManagementClient GetComputeManagementClient(MockContext context)
101+
{
102+
return context.GetServiceClient<ComputeManagementClient>(TestEnvironmentFactory.GetTestEnvironment());
103+
}
104+
105+
private static StorageManagementClient GetStorageManagementClient(MockContext context)
106+
{
107+
return context.GetServiceClient<StorageManagementClient>(TestEnvironmentFactory.GetTestEnvironment());
108+
}
109+
110+
private static AzureRestClient GetAzureRestClient(MockContext context)
111+
{
112+
return context.GetServiceClient<AzureRestClient>(TestEnvironmentFactory.GetTestEnvironment());
113+
}
114+
115+
private static PrivateDnsManagementClient GetPrivateDnsManagementClient(MockContext context)
116+
{
117+
return context.GetServiceClient<PrivateDnsManagementClient>(TestEnvironmentFactory.GetTestEnvironment());
118+
}
119+
120+
private static KeyVaultClient GetKeyVaultClient(MockContext context)
121+
{
122+
string environmentConnectionString = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION");
123+
string accessToken = "fakefakefake";
124+
125+
// When recording, we should have a connection string passed into the code from the environment
126+
if (!string.IsNullOrEmpty(environmentConnectionString))
127+
{
128+
// Gather test client credential information from the environment
129+
var connectionInfo = new ConnectionString(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"));
130+
var mode = connectionInfo.GetValue<string>(ConnectionStringKeys.HttpRecorderModeKey);
131+
if (mode == HttpRecorderMode.Record.ToString())
132+
{
133+
string servicePrincipal = connectionInfo.GetValue<string>(ConnectionStringKeys.ServicePrincipalKey);
134+
string servicePrincipalSecret = connectionInfo.GetValue<string>(ConnectionStringKeys.ServicePrincipalSecretKey);
135+
string aadTenant = connectionInfo.GetValue<string>(ConnectionStringKeys.AADTenantKey);
136+
137+
// Create credentials
138+
var clientCredentials = new ClientCredential(servicePrincipal, servicePrincipalSecret);
139+
var authContext = new AuthenticationContext($"https://login.windows.net/{aadTenant}", TokenCache.DefaultShared);
140+
accessToken = authContext.AcquireTokenAsync("https://vault.azure.net", clientCredentials).Result.AccessToken;
141+
}
142+
}
143+
144+
return new KeyVaultClient(new TokenCredentials(accessToken), HttpMockServer.CreateInstance());
145+
}
53146
}
54147
}

0 commit comments

Comments
 (0)