Skip to content

Commit 27661df

Browse files
authored
Application Gateway Private Link Cmdlets (#12133)
* Application Gateway Private Link Cmdlets * add change log
1 parent f6b8af1 commit 27661df

File tree

36 files changed

+13091
-111
lines changed

36 files changed

+13091
-111
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,13 @@ public void TestApplicationGatewayWithListenerHostNames()
137137
{
138138
TestRunner.RunTestScript(string.Format("Test-ApplicationGatewayWithListenerHostNames -baseDir '{0}'", AppDomain.CurrentDomain.BaseDirectory));
139139
}
140+
141+
[Fact]
142+
[Trait(Category.AcceptanceType, Category.CheckIn)]
143+
[Trait(Category.Owner, NrpTeamAlias.nvadev_subset1)]
144+
public void TestApplicationGatewayWithPrivateLinkConfiguration()
145+
{
146+
TestRunner.RunTestScript(string.Format("Test-ApplicationGatewayWithPrivateLinkConfiguration -baseDir '{0}'", AppDomain.CurrentDomain.BaseDirectory));
147+
}
140148
}
141149
}

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

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,3 +2800,149 @@ function Test-ApplicationGatewayWithListenerHostNames
28002800
Clean-ResourceGroup $rgname
28012801
}
28022802
}
2803+
2804+
function Test-ApplicationGatewayWithPrivateLinkConfiguration
2805+
{
2806+
param
2807+
(
2808+
$basedir = "./"
2809+
)
2810+
2811+
# Setup
2812+
$location = Get-ProviderLocation "Microsoft.Network/applicationGateways" "westus2"
2813+
2814+
$rgname = Get-ResourceGroupName
2815+
$appgwName = Get-ResourceName
2816+
$vnetName = Get-ResourceName
2817+
$gwSubnetName = Get-ResourceName
2818+
$plsSubnetName = Get-ResourceName
2819+
$publicIpName = Get-ResourceName
2820+
$gipconfigname = Get-ResourceName
2821+
2822+
$frontendPort01Name = Get-ResourceName
2823+
$fipconfigName = Get-ResourceName
2824+
$listener01Name = Get-ResourceName
2825+
2826+
$poolName = Get-ResourceName
2827+
$trustedRootCertName = Get-ResourceName
2828+
$poolSetting01Name = Get-ResourceName
2829+
2830+
$rule01Name = Get-ResourceName
2831+
2832+
$probeHttpName = Get-ResourceName
2833+
2834+
$privateLinkIpConfigName1 = Get-ResourceName
2835+
$privateLinkIpConfigName2 = Get-ResourceName
2836+
$privateLinkIpConfigName3 = Get-ResourceName
2837+
2838+
$privateLinkConfigName = Get-ResourceName
2839+
$privateLinkConfigName2 = Get-ResourceName
2840+
2841+
try
2842+
{
2843+
# Create the resource group
2844+
$resourceGroup = New-AzResourceGroup -Name $rgname -Location $location -Tags @{ testtag = "APPGw tag"}
2845+
# Create the Virtual Network
2846+
$gwSubnet = New-AzVirtualNetworkSubnetConfig -Name $gwSubnetName -AddressPrefix 10.0.0.0/24 -PrivateLinkServiceNetworkPoliciesFlag "Disabled"
2847+
$plsSubnet = New-AzVirtualNetworkSubnetConfig -Name $plsSubnetName -AddressPrefix 10.0.1.0/24 -PrivateLinkServiceNetworkPoliciesFlag "Disabled"
2848+
$vnet = New-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname -Location $location -AddressPrefix 10.0.0.0/16 -Subnet $gwSubnet, $plsSubnet
2849+
$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname
2850+
$gwSubnet = Get-AzVirtualNetworkSubnetConfig -Name $gwSubnetName -VirtualNetwork $vnet
2851+
$plsSubnet = Get-AzVirtualNetworkSubnetConfig -Name $plsSubnetName -VirtualNetwork $vnet
2852+
2853+
# Create public ip
2854+
$publicip = New-AzPublicIpAddress -ResourceGroupName $rgname -name $publicIpName -location $location -AllocationMethod Static -sku Standard
2855+
2856+
# Create ip configuration
2857+
$gipconfig = New-AzApplicationGatewayIPConfiguration -Name $gipconfigname -Subnet $gwSubnet
2858+
2859+
# private link configuration
2860+
$privateLinkIpConfiguration1 = New-AzApplicationGatewayPrivateLinkIpConfiguration -Name $privateLinkIpConfigName1 -Subnet $plsSubnet -Primary
2861+
$privateLinkIpConfiguration2 = New-AzApplicationGatewayPrivateLinkIpConfiguration -Name $privateLinkIpConfigName2 -Subnet $plsSubnet
2862+
$privateLinkConfiguration = New-AzApplicationGatewayPrivateLinkConfiguration -Name $privateLinkConfigName -IpConfiguration $privateLinkIpConfiguration1, $privateLinkIpConfiguration2
2863+
2864+
$fipconfig = New-AzApplicationGatewayFrontendIPConfig -Name $fipconfigName -PublicIPAddress $publicip -PrivateLinkConfiguration $privateLinkConfiguration
2865+
$fp01 = New-AzApplicationGatewayFrontendPort -Name $frontendPort01Name  -Port 80
2866+
$listener01 = New-AzApplicationGatewayHttpListener -Name $listener01Name -Protocol Http -FrontendIPConfiguration $fipconfig -FrontendPort $fp01
2867+
2868+
# backend part
2869+
# trusted root cert part
2870+
$certFilePath = $basedir + "/ScenarioTests/Data/ApplicationGatewayAuthCert.cer"
2871+
$trustedRoot01 = New-AzApplicationGatewayTrustedRootCertificate -Name $trustedRootCertName -CertificateFile $certFilePath
2872+
$pool = New-AzApplicationGatewayBackendAddressPool -Name $poolName -BackendIPAddresses www.microsoft.com, www.bing.com
2873+
$probeHttp = New-AzApplicationGatewayProbeConfig -Name $probeHttpName -Protocol Https -HostName "probe.com" -Path "/path/path.htm" -Interval 89 -Timeout 88 -UnhealthyThreshold 8 -port 1234
2874+
$poolSetting01 = New-AzApplicationGatewayBackendHttpSetting -Name $poolSetting01Name -Port 443 -Protocol Https -Probe $probeHttp -CookieBasedAffinity Enabled -PickHostNameFromBackendAddress -TrustedRootCertificate $trustedRoot01
2875+
2876+
#rule
2877+
$rule01 = New-AzApplicationGatewayRequestRoutingRule -Name $rule01Name -RuleType basic -BackendHttpSettings $poolSetting01 -HttpListener $listener01 -BackendAddressPool $pool
2878+
2879+
# sku
2880+
$sku = New-AzApplicationGatewaySku -Name Standard_v2 -Tier Standard_v2
2881+
2882+
# autoscale configuration
2883+
$autoscaleConfig = New-AzApplicationGatewayAutoscaleConfiguration -MinCapacity 3
2884+
2885+
# Create Application Gateway
2886+
$appgw = New-AzApplicationGateway -Name $appgwName -ResourceGroupName $rgname -Zone 1,2 -Location $location -Probes $probeHttp -BackendAddressPools $pool -BackendHttpSettingsCollection $poolSetting01 -FrontendIpConfigurations $fipconfig -GatewayIpConfigurations $gipconfig -FrontendPorts $fp01 -HttpListeners $listener01 -RequestRoutingRules $rule01 -Sku $sku -TrustedRootCertificate $trustedRoot01 -AutoscaleConfiguration $autoscaleConfig -PrivateLinkConfiguration $privateLinkConfiguration
2887+
2888+
# Get Application Gateway
2889+
$getgw = Get-AzApplicationGateway -Name $appgwName -ResourceGroupName $rgname
2890+
2891+
# Operational State
2892+
Assert-AreEqual "Running" $getgw.OperationalState
2893+
2894+
# Verify PrivateLink Configuration
2895+
Assert-NotNull $getgw.PrivateLinkConfigurations
2896+
Assert-AreEqual 1 $getgw.PrivateLinkConfigurations.Count
2897+
$getPrivateLinkConfig = Get-AzApplicationGatewayPrivateLinkConfiguration -Name $privateLinkConfigName -ApplicationGateway $getgw
2898+
Assert-NotNull $getPrivateLinkConfig
2899+
Assert-AreEqual $getPrivateLinkConfig.IpConfigurations.Count 2
2900+
2901+
# Verify Frontend Ip has PrivateLink Configuration
2902+
$getFipConfig = Get-AzApplicationGatewayFrontendIPConfig -ApplicationGateway $getgw -Name $fipconfigName
2903+
Assert-NotNull $getFipconfig
2904+
Assert-NotNull $getFipconfig.PrivateLinkConfiguration
2905+
Assert-AreEqual $getPrivateLinkConfig.Id $getFipconfig.PrivateLinkConfiguration.Id
2906+
2907+
# check autoscale configuration
2908+
$autoscaleConfig01 = Get-AzApplicationGatewayAutoscaleConfiguration -ApplicationGateway $getgw
2909+
Assert-NotNull $autoscaleConfig01
2910+
Assert-AreEqual $autoscaleConfig01.MinCapacity 3
2911+
2912+
# Set AppGw
2913+
$getgw01 = Set-AzApplicationGateway -ApplicationGateway $getgw
2914+
2915+
# Cannot add same PrivateLinkConfiguration
2916+
Assert-ThrowsLike { Add-AzApplicationGatewayPrivateLinkConfiguration -ApplicationGateway $getgw01 -Name $privateLinkConfigName -IpConfiguration $privateLinkIpConfiguration1 } "*already exists*"
2917+
2918+
# add another private link configuration and change the ip configuration
2919+
$getgw01 = Add-AzApplicationGatewayPrivateLinkConfiguration -ApplicationGateway $getgw01 -Name $privateLinkConfigName2 -IpConfiguration $privateLinkIpConfiguration1
2920+
$privateLinkIpConfiguration3 = New-AzApplicationGatewayPrivateLinkIpConfiguration -Name $privateLinkIpConfigName3 -Subnet $plsSubnet -Primary
2921+
$getgw01 = Set-AzApplicationGatewayPrivateLinkConfiguration -ApplicationGateway $getgw01 -Name $privateLinkConfigName2 -IpConfiguration $privateLinkIpConfiguration3
2922+
$getPrivateLinkConfig = Get-AzApplicationGatewayPrivateLinkConfiguration -Name $privateLinkConfigName2 -ApplicationGateway $getgw01
2923+
Assert-NotNull $getPrivateLinkConfig
2924+
Assert-AreEqual $getPrivateLinkConfig.IpConfigurations.Count 1
2925+
Assert-AreEqual $getPrivateLinkConfig.IpConfigurations.Name $privateLinkIpConfigName3
2926+
2927+
# add / remove privateLinkConfiguration
2928+
$getgw = Set-AzApplicationGateway -ApplicationGateway $getgw01
2929+
$privateLinkConfigurations = Get-AzApplicationGatewayPrivateLinkConfiguration -ApplicationGateway $getgw
2930+
Assert-NotNull $privateLinkConfigurations
2931+
Assert-AreEqual $privateLinkConfigurations.Count 2
2932+
2933+
$getgw01 = Remove-AzApplicationGatewayPrivateLinkConfiguration -ApplicationGateway $getgw01 -Name $privateLinkConfigName2
2934+
$getgw = Set-AzApplicationGateway -ApplicationGateway $getgw01
2935+
2936+
$privateLinkConfigurations = Get-AzApplicationGatewayPrivateLinkConfiguration -ApplicationGateway $getgw
2937+
Assert-NotNull $privateLinkConfigurations
2938+
Assert-AreEqual $privateLinkConfigurations.Count 1
2939+
2940+
# Delete Application Gateway
2941+
Remove-AzApplicationGateway -Name $appgwName -ResourceGroupName $rgname -Force
2942+
}
2943+
finally
2944+
{
2945+
# Cleanup
2946+
Clean-ResourceGroup $rgname
2947+
}
2948+
}

src/Network/Network.Test/SessionRecords/Commands.Network.Test.ScenarioTests.ApplicationGatewayTests/TestApplicationGatewayWithPrivateLinkConfiguration.json

Lines changed: 11316 additions & 0 deletions
Large diffs are not rendered by default.

src/Network/Network/ApplicationGateway/FrontendIPConfiguration/AzureApplicationGatewayFrontendIPConfigBase.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ public class AzureApplicationGatewayFrontendIPConfigBase : NetworkBaseCmdlet
5454
HelpMessage = "PublicIPAddress")]
5555
public PSPublicIpAddress PublicIPAddress { get; set; }
5656

57+
[Parameter(
58+
Mandatory = false,
59+
ParameterSetName = "SetByResource",
60+
HelpMessage = "PrivateLinkConfiguration")]
61+
public PSApplicationGatewayPrivateLinkConfiguration PrivateLinkConfiguration { get; set; }
62+
63+
[Parameter(
64+
Mandatory = false,
65+
ParameterSetName = "SetByResourceId",
66+
HelpMessage = "PrivateLinkConfigurationId")]
67+
public string PrivateLinkConfigurationId { get; set; }
68+
5769
public override void ExecuteCmdlet()
5870
{
5971
base.ExecuteCmdlet();
@@ -69,6 +81,11 @@ public override void ExecuteCmdlet()
6981
{
7082
this.PublicIPAddressId = this.PublicIPAddress.Id;
7183
}
84+
85+
if (this.PrivateLinkConfiguration != null)
86+
{
87+
this.PrivateLinkConfigurationId = this.PrivateLinkConfiguration.Id;
88+
}
7289
}
7390
}
7491

@@ -99,6 +116,12 @@ public PSApplicationGatewayFrontendIPConfiguration NewObject()
99116
frontendIPConfig.PublicIPAddress.Id = this.PublicIPAddressId;
100117
}
101118

119+
if (!string.IsNullOrEmpty(this.PrivateLinkConfigurationId))
120+
{
121+
frontendIPConfig.PrivateLinkConfiguration = new PSResourceId();
122+
frontendIPConfig.PrivateLinkConfiguration.Id = this.PrivateLinkConfigurationId;
123+
}
124+
102125
frontendIPConfig.Id = ApplicationGatewayChildResourceHelper.GetResourceNotSetId(
103126
this.NetworkClient.NetworkManagementClient.SubscriptionId,
104127
Microsoft.Azure.Commands.Network.Properties.Resources.ApplicationGatewayFrontendIPConfigName,

src/Network/Network/ApplicationGateway/NewAzureApplicationGatewayCommand.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ public class NewAzureApplicationGatewayCommand : ApplicationGatewayBaseCmdlet
229229
[ValidateNotNullOrEmpty]
230230
public PSApplicationGatewayCustomError[] CustomErrorConfiguration { get; set; }
231231

232+
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The list of privateLink Configuration")]
233+
public PSApplicationGatewayPrivateLinkConfiguration[] PrivateLinkConfiguration { get; set; }
234+
232235
public override void ExecuteCmdlet()
233236
{
234237
base.ExecuteCmdlet();
@@ -355,6 +358,11 @@ private PSApplicationGateway CreateApplicationGateway()
355358
applicationGateway.AutoscaleConfiguration = this.AutoscaleConfiguration;
356359
}
357360

361+
if (this.PrivateLinkConfiguration != null)
362+
{
363+
applicationGateway.PrivateLinkConfigurations = this.PrivateLinkConfiguration?.ToList();
364+
}
365+
358366
if (this.EnableHttp2.IsPresent)
359367
{
360368
applicationGateway.EnableHttp2 = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System.Collections.Generic;
16+
using Microsoft.Azure.Commands.Network.Models;
17+
using System.Management.Automation;
18+
using System.Linq;
19+
using System;
20+
21+
namespace Microsoft.Azure.Commands.Network
22+
{
23+
[Cmdlet(VerbsCommon.Add, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ApplicationGatewayPrivateLinkConfiguration"), OutputType(typeof(PSApplicationGateway))]
24+
public class AddAzureApplicationGatewayPrivateLinkConfigurationCommand : AzureApplicationGatewayPrivateLinkConfigurationBase
25+
{
26+
[Parameter(
27+
Mandatory = true,
28+
ValueFromPipeline = true,
29+
HelpMessage = "The applicationGateway")]
30+
public PSApplicationGateway ApplicationGateway { get; set; }
31+
32+
public override void ExecuteCmdlet()
33+
{
34+
base.ExecuteCmdlet();
35+
36+
var privateLinkConfiguration = this.ApplicationGateway.PrivateLinkConfigurations.SingleOrDefault
37+
(resource => string.Equals(resource.Name, this.Name, System.StringComparison.CurrentCultureIgnoreCase));
38+
39+
if (privateLinkConfiguration != null)
40+
{
41+
throw new ArgumentException("PrivateLinkConfiguration with the specified name already exists");
42+
}
43+
44+
privateLinkConfiguration = base.NewObject();
45+
this.ApplicationGateway.PrivateLinkConfigurations.Add(privateLinkConfiguration);
46+
47+
WriteObject(this.ApplicationGateway);
48+
}
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System.Linq;
16+
using System.Management.Automation;
17+
using Microsoft.Azure.Commands.Network.Models;
18+
19+
namespace Microsoft.Azure.Commands.Network
20+
{
21+
public class AzureApplicationGatewayPrivateLinkConfigurationBase : NetworkBaseCmdlet
22+
{
23+
[Parameter(
24+
Mandatory = true,
25+
HelpMessage = "The name of the privateLink configuration")]
26+
[ValidateNotNullOrEmpty]
27+
public string Name { get; set; }
28+
29+
[Parameter(
30+
Mandatory = true,
31+
ValueFromPipelineByPropertyName = true,
32+
HelpMessage = "The list of ipConfiguration")]
33+
[ValidateNotNullOrEmpty]
34+
public PSApplicationGatewayPrivateLinkIpConfiguration[] IpConfiguration { get; set; }
35+
36+
public override void ExecuteCmdlet()
37+
{
38+
base.ExecuteCmdlet();
39+
}
40+
41+
public PSApplicationGatewayPrivateLinkConfiguration NewObject()
42+
{
43+
var privateLinkConfiguration = new PSApplicationGatewayPrivateLinkConfiguration();
44+
45+
privateLinkConfiguration.Name = this.Name;
46+
privateLinkConfiguration.IpConfigurations = this.IpConfiguration?.ToList();
47+
48+
privateLinkConfiguration.Id = ApplicationGatewayChildResourceHelper.GetResourceNotSetId(
49+
this.NetworkClient.NetworkManagementClient.SubscriptionId,
50+
Microsoft.Azure.Commands.Network.Properties.Resources.ApplicationGatewayPrivateLinkConfigurationName,
51+
this.Name);
52+
53+
return privateLinkConfiguration;
54+
}
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.Azure.Commands.Network.Models;
16+
using System.Linq;
17+
using System.Management.Automation;
18+
19+
namespace Microsoft.Azure.Commands.Network
20+
{
21+
[Cmdlet("Get", ResourceManager.Common.AzureRMConstants.AzureRMPrefix + "ApplicationGatewayPrivateLinkConfiguration"), OutputType(typeof(PSApplicationGatewayPrivateLinkConfiguration))]
22+
public class GetAzureApplicationGatewayPrivateLinkConfigurationCommand : NetworkBaseCmdlet
23+
{
24+
[Parameter(
25+
Mandatory = true,
26+
ValueFromPipeline = true,
27+
HelpMessage = "The applicationGateway")]
28+
public PSApplicationGateway ApplicationGateway { get; set; }
29+
30+
[Parameter(
31+
Mandatory = false,
32+
HelpMessage = "The name of the application gateway privateLink configuration")]
33+
[ValidateNotNullOrEmpty]
34+
public string Name { get; set; }
35+
36+
public override void ExecuteCmdlet()
37+
{
38+
if (!string.IsNullOrEmpty(this.Name))
39+
{
40+
var privateLinkConfiguration =
41+
this.ApplicationGateway.PrivateLinkConfigurations.First(resource => string.Equals(resource.Name, this.Name, System.StringComparison.CurrentCultureIgnoreCase));
42+
WriteObject(privateLinkConfiguration);
43+
}
44+
else
45+
{
46+
var privateLinkConfigurations = this.ApplicationGateway.PrivateLinkConfigurations;
47+
WriteObject(privateLinkConfigurations, true);
48+
}
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)