Skip to content

Commit da20abe

Browse files
authored
Merge pull request Azure#9313 from Nilambari/network-april2019
Brooklyn Feature:- Set AAD authentication configuration for VpnClient on Gateway resource.
2 parents 56eb66a + 5a7e570 commit da20abe

File tree

10 files changed

+13944
-11
lines changed

10 files changed

+13944
-11
lines changed

src/Network/Network.Test/ScenarioTests/VirtualNetworkGatewayTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ public void VirtualNetworkGatewayOpenVPNTest()
100100
TestRunner.RunTestScript("Test-VirtualNetworkGatewayOpenVPN");
101101
}
102102

103+
[Fact]
104+
[Trait(Category.AcceptanceType, Category.CheckIn)]
105+
[Trait(Category.Owner, NrpTeamAlias.brooklynft_subset3)]
106+
public void VirtualNetworkGatewayOpenVPNAADAuthTest()
107+
{
108+
TestRunner.RunTestScript("Test-VirtualNetworkGatewayOpenVPNAADAuth");
109+
}
110+
103111
[Fact]
104112
[Trait(Category.AcceptanceType, Category.CheckIn)]
105113
[Trait(Category.Owner, NrpTeamAlias.brooklynft_subset3)]

src/Network/Network.Test/ScenarioTests/VirtualNetworkGatewayTests.ps1

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,94 @@ function Test-VirtualNetworkGatewayOpenVPN
688688
}
689689
}
690690

691+
<#
692+
.SYNOPSIS
693+
Virtual network gateway P2S OpenVPN AAD authentication API test
694+
#>
695+
function Test-VirtualNetworkGatewayOpenVPNAADAuth
696+
{
697+
# Setup
698+
$rgname = Get-ResourceGroupName
699+
$rname = Get-ResourceName
700+
$domainNameLabel = Get-ResourceName
701+
$vnetName = Get-ResourceName
702+
$publicIpName = Get-ResourceName
703+
$vnetGatewayConfigName = Get-ResourceName
704+
$rglocation = Get-ProviderLocation ResourceManagement
705+
$resourceTypeParent = "Microsoft.Network/virtualNetworkGateways"
706+
$location = Get-ProviderLocation $resourceTypeParent
707+
708+
try
709+
{
710+
# Create the resource group
711+
$resourceGroup = New-AzResourceGroup -Name $rgname -Location $rglocation -Tags @{ testtag = "testval" }
712+
713+
# AAD authentication configurations
714+
$aadTenant = "https://login.microsoftonline.com/0ab2c4f4-81e6-44cc-a0b2-b3a47a1443f4"
715+
$aadIssuer = "https://sts.windows.net/0ab2c4f4-81e6-44cc-a0b2-b3a47a1443f4/"
716+
$aadAudience = "a21fce82-76af-45e6-8583-a08cb3b956f9"
717+
$aadAudienceNew = "a21fce82-76af-45e6-8583-a08cb3b956g9"
718+
719+
# Create the Virtual Network
720+
$subnet = New-AzVirtualNetworkSubnetConfig -Name "GatewaySubnet" -AddressPrefix 10.0.0.0/24
721+
$vnet = New-AzvirtualNetwork -Name $vnetName -ResourceGroupName $rgname -Location $location -AddressPrefix 10.0.0.0/16 -Subnet $subnet
722+
$vnet = Get-AzvirtualNetwork -Name $vnetName -ResourceGroupName $rgname
723+
$subnet = Get-AzVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet
724+
725+
# Create the IP config
726+
$publicip = New-AzPublicIpAddress -ResourceGroupName $rgname -name $publicIpName -location $location -AllocationMethod Dynamic -DomainNameLabel $domainNameLabel
727+
$vnetIpConfig = New-AzVirtualNetworkGatewayIpConfig -Name $vnetGatewayConfigName -PublicIpAddress $publicip -Subnet $subnet
728+
729+
# Create & Get P2S OpenVPN AAD authentication on virtualnetworkgateway
730+
New-AzVirtualNetworkGateway -ResourceGroupName $rgname -name $rname -location $location -IpConfigurations $vnetIpConfig -GatewayType Vpn -VpnType RouteBased -VpnClientProtocol OpenVPN -EnableBgp $false -GatewaySku VpnGw1 -VpnClientAddressPool 201.169.0.0/16 #-AadTenantUri $aadTenant -AadIssuerUri $aadIssuer -AadAudienceId $aadAudience
731+
$actual = Get-AzVirtualNetworkGateway -ResourceGroupName $rgname -name $rname
732+
$protocols = $actual.VpnClientConfiguration.VpnClientProtocols
733+
Assert-AreEqual 1 @($protocols).Count
734+
Assert-AreEqual "OpenVPN" $protocols[0]
735+
Assert-AreEqual "201.169.0.0/16" $actual.VpnClientConfiguration.VpnClientAddressPool.AddressPrefixes
736+
#Assert-AreEqual $aadTenant $actual.VpnClientConfiguration.AadTenant
737+
#Assert-AreEqual $aadIssuer $actual.VpnClientConfiguration.AadIssuer
738+
#Assert-AreEqual $aadAudience $actual.VpnClientConfiguration.AadAudience
739+
740+
# Set an existing virtualnetworkgateway with updated AAD authentication configuration.
741+
Set-AzVirtualNetworkGateway -VirtualNetworkGateway $actual -AadTenantUri $aadTenant -AadIssuerUri $aadIssuer -AadAudienceId $aadAudienceNew
742+
$actual = Get-AzVirtualNetworkGateway -ResourceGroupName $rgname -name $rname
743+
744+
Assert-AreEqual "VpnGw1" $actual.Sku.Tier
745+
$protocols = $actual.VpnClientConfiguration.VpnClientProtocols
746+
Assert-AreEqual 1 @($protocols).Count
747+
Assert-AreEqual "OpenVPN" $protocols[0]
748+
Assert-AreEqual "201.169.0.0/16" $actual.VpnClientConfiguration.VpnClientAddressPool.AddressPrefixes
749+
Assert-AreEqual $aadTenant $actual.VpnClientConfiguration.AadTenant
750+
Assert-AreEqual $aadIssuer $actual.VpnClientConfiguration.AadIssuer
751+
Assert-AreEqual $aadAudienceNew $actual.VpnClientConfiguration.AadAudience
752+
753+
# create the client root cert
754+
$clientRootCertName = "BrkLiteTestMSFTRootCA.cer"
755+
#[SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine")]
756+
$samplePublicCertData = "MIIDUzCCAj+gAwIBAgIQRggGmrpGj4pCblTanQRNUjAJBgUrDgMCHQUAMDQxEjAQBgNVBAoTCU1pY3Jvc29mdDEeMBwGA1UEAxMVQnJrIExpdGUgVGVzdCBSb290IENBMB4XDTEzMDExOTAwMjQxOFoXDTIxMDExOTAwMjQxN1owNDESMBAGA1UEChMJTWljcm9zb2Z0MR4wHAYDVQQDExVCcmsgTGl0ZSBUZXN0IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7SmE+iPULK0Rs7mQBO/6a6B6/G9BaMxHgDGzAmSG0Qsyt5e08aqgFnPdkMl3zRJw3lPKGha/JCvHRNrO8UpeAfc4IXWaqxx2iBipHjwmHPHh7+VB8lU0EJcUe7WBAI2n/sgfCwc+xKtuyRVlOhT6qw/nAi8e5don/iHPU6q7GCcnqoqtceQ/pJ8m66cvAnxwJlBFOTninhb2VjtvOfMQ07zPP+ZuYDPxvX5v3nd6yDa98yW4dZPuiGO2s6zJAfOPT2BrtyvLekItnSgAw3U5C0bOb+8XVKaDZQXbGEtOw6NZvD4L2yLd47nGkN2QXloiPLGyetrj3Z2pZYcrZBo8hAgMBAAGjaTBnMGUGA1UdAQReMFyAEOncRAPNcvJDoe4WP/gH2U+hNjA0MRIwEAYDVQQKEwlNaWNyb3NvZnQxHjAcBgNVBAMTFUJyayBMaXRlIFRlc3QgUm9vdCBDQYIQRggGmrpGj4pCblTanQRNUjAJBgUrDgMCHQUAA4IBAQCGyHhMdygS0g2tEUtRT4KFM+qqUY5HBpbIXNAav1a1dmXpHQCziuuxxzu3iq4XwnWUF1OabdDE2cpxNDOWxSsIxfEBf9ifaoz/O1ToJ0K757q2Rm2NWqQ7bNN8ArhvkNWa95S9gk9ZHZLUcjqanf0F8taJCYgzcbUSp+VBe9DcN89sJpYvfiBiAsMVqGPc/fHJgTScK+8QYrTRMubtFmXHbzBSO/KTAP5rBTxse88EGjK5F8wcedvge2Ksk6XjL3sZ19+Oj8KTQ72wihN900p1WQldHrrnbixSpmHBXbHr9U0NQigrJp5NphfuU5j81C8ixvfUdwyLmTv7rNA7GTAD";
757+
$rootCert = New-AzVpnClientRootCertificate -Name $clientRootCertName -PublicCertData $samplePublicCertData
758+
759+
# remove AAD authentication configuration.
760+
#Set-AzVirtualNetworkGateway -VirtualNetworkGateway $actual -VpnClientRootCertificates $rootCert -RemoveAadAuthentication
761+
$actual = Get-AzVirtualNetworkGateway -ResourceGroupName $rgname -name $rname
762+
763+
Assert-AreEqual "VpnGw1" $actual.Sku.Tier
764+
$protocols = $actual.VpnClientConfiguration.VpnClientProtocols
765+
Assert-AreEqual 1 @($protocols).Count
766+
Assert-AreEqual "OpenVPN" $protocols[0]
767+
Assert-AreEqual "201.169.0.0/16" $actual.VpnClientConfiguration.VpnClientAddressPool.AddressPrefixes
768+
#Assert-Null $actual.VpnClientConfiguration.AadTenant
769+
#Assert-Null $actual.VpnClientConfiguration.AadIssuer
770+
#Assert-Null $actual.VpnClientConfiguration.AadAudience
771+
}
772+
finally
773+
{
774+
# Cleanup
775+
Clean-ResourceGroup $rgname
776+
}
777+
}
778+
691779
<#
692780
.SYNOPSIS
693781
Virtual network gateway tests

src/Network/Network.Test/SessionRecords/Commands.Network.Test.ScenarioTests.VirtualNetworkGatewayTests/VirtualNetworkGatewayOpenVPNAADAuthTest.json

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

src/Network/Network/ChangeLog.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,16 @@
5252
* Fixed VirtualHub reference creation for ExpressRouteGateways, VpnGateway
5353
* Added support for Availability Zones in AzureFirewall and NatGateway
5454
* Added cmdlet Get-AzNetworkServiceTag
55-
5655
* Add support for multiple public IP addresses for Azure Firewall
5756
- Updated New-AzFirewall cmdlet:
5857
- Added parameter -PublicIpAddress which accepts one or more Public IP Address objects
5958
- Added parameter -VirtualNetwork which accepts a Virtual Network object
6059
- Added methods AddPublicIpAddress and RemovePublicIpAddress on firewall object - these accept a Public IP Address object as input
6160
- Deprecated parameters -PublicIpName and -VirtualNetworkName
61+
* Updated below commands for feature: Set VpnClient AAD authentication options to Virtual network gateway resource.
62+
- Updated New-AzVirtualNetworkGateway: Added optional parameters AadTenantUri,AadAudienceId,AadIssuerUri to set VpnClient AAD authentication options on Gateway.
63+
- Updated Set-AzVirtualNetworkGateway: Added optional parameter AadTenantUri,AadAudienceId,AadIssuerUri to set VpnClient AAD authentication options on Gateway.
64+
- Updated Set-AzVirtualNetworkGateway: Added optional switch parameter RemoveAadAuthentication to remove VpnClient AAD authentication options from Gateway.
6265

6366
## Version 1.8.1
6467
* Add DisableBgpRoutePropagation flag to Effective Route Table output

src/Network/Network/Generated/Models/PSVpnClientConfiguration.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ public partial class PSVpnClientConfiguration
3838
public string RadiusServerAddress { get; set; }
3939
[Ps1Xml(Target = ViewControl.Table)]
4040
public string RadiusServerSecret { get; set; }
41+
[Ps1Xml(Target = ViewControl.Table)]
42+
public string AadTenant { get; set; }
43+
[Ps1Xml(Target = ViewControl.Table)]
44+
public string AadIssuer { get; set; }
45+
[Ps1Xml(Target = ViewControl.Table)]
46+
public string AadAudience { get; set; }
4147
public PSAddressSpace VpnClientAddressPool { get; set; }
4248
public List<PSVpnClientRootCertificate> VpnClientRootCertificates { get; set; }
4349
public List<PSVpnClientRevokedCertificate> VpnClientRevokedCertificates { get; set; }

src/Network/Network/VirtualNetworkGateway/NewAzureVirtualNetworkGatewayCommand.cs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ public class NewAzureVirtualNetworkGatewayCommand : VirtualNetworkGatewayBaseCmd
3838
ValueFromPipelineByPropertyName = true,
3939
ParameterSetName = VirtualNetworkGatewayParameterSets.RadiusServerConfiguration,
4040
HelpMessage = "The resource name.")]
41+
[Parameter(
42+
Mandatory = true,
43+
ValueFromPipelineByPropertyName = true,
44+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
45+
HelpMessage = "The resource name.")]
4146
[Parameter(
4247
Mandatory = true,
4348
ValueFromPipelineByPropertyName = true,
@@ -51,6 +56,11 @@ public class NewAzureVirtualNetworkGatewayCommand : VirtualNetworkGatewayBaseCmd
5156
ValueFromPipelineByPropertyName = true,
5257
ParameterSetName = VirtualNetworkGatewayParameterSets.RadiusServerConfiguration,
5358
HelpMessage = "The resource group name.")]
59+
[Parameter(
60+
Mandatory = true,
61+
ValueFromPipelineByPropertyName = true,
62+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
63+
HelpMessage = "The resource group name.")]
5464
[Parameter(
5565
Mandatory = true,
5666
ValueFromPipelineByPropertyName = true,
@@ -65,6 +75,11 @@ public class NewAzureVirtualNetworkGatewayCommand : VirtualNetworkGatewayBaseCmd
6575
ValueFromPipelineByPropertyName = true,
6676
ParameterSetName = VirtualNetworkGatewayParameterSets.RadiusServerConfiguration,
6777
HelpMessage = "location.")]
78+
[Parameter(
79+
Mandatory = true,
80+
ValueFromPipelineByPropertyName = true,
81+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
82+
HelpMessage = "location.")]
6883
[Parameter(
6984
Mandatory = true,
7085
ValueFromPipelineByPropertyName = true,
@@ -214,6 +229,30 @@ public class NewAzureVirtualNetworkGatewayCommand : VirtualNetworkGatewayBaseCmd
214229
[ValidateNotNullOrEmpty]
215230
public SecureString RadiusServerSecret { get; set; }
216231

232+
[Parameter(
233+
Mandatory = true,
234+
ValueFromPipelineByPropertyName = true,
235+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
236+
HelpMessage = "P2S AAD authentication option:AadTenantUri.")]
237+
[ValidateNotNullOrEmpty]
238+
public string AadTenantUri { get; set; }
239+
240+
[Parameter(
241+
Mandatory = true,
242+
ValueFromPipelineByPropertyName = true,
243+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
244+
HelpMessage = "P2S AAD authentication option:AadAudienceId.")]
245+
[ValidateNotNullOrEmpty]
246+
public string AadAudienceId { get; set; }
247+
248+
[Parameter(
249+
Mandatory = true,
250+
ValueFromPipelineByPropertyName = true,
251+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
252+
HelpMessage = "P2S AAD authentication option:AadIssuerUri.")]
253+
[ValidateNotNullOrEmpty]
254+
public string AadIssuerUri { get; set; }
255+
217256
[Parameter(
218257
Mandatory = false,
219258
ValueFromPipelineByPropertyName = true,
@@ -319,7 +358,8 @@ private PSVirtualNetworkGateway CreateVirtualNetworkGateway()
319358
this.VpnClientRootCertificates != null ||
320359
this.VpnClientRevokedCertificates != null ||
321360
this.RadiusServerAddress != null ||
322-
(this.VpnClientIpsecPolicy != null && this.VpnClientIpsecPolicy.Length != 0))
361+
(this.VpnClientIpsecPolicy != null && this.VpnClientIpsecPolicy.Length != 0) ||
362+
this.AadTenantUri != null)
323363
{
324364
vnetGateway.VpnClientConfiguration = new PSVpnClientConfiguration();
325365

@@ -366,6 +406,26 @@ private PSVirtualNetworkGateway CreateVirtualNetworkGateway()
366406
vnetGateway.VpnClientConfiguration.RadiusServerAddress = this.RadiusServerAddress;
367407
vnetGateway.VpnClientConfiguration.RadiusServerSecret = SecureStringExtensions.ConvertToString(this.RadiusServerSecret);
368408
}
409+
410+
if (this.AadTenantUri != null)
411+
{
412+
if (this.AadIssuerUri == null || this.AadAudienceId == null)
413+
{
414+
throw new ArgumentException("AadTenantUri, AadIssuerUri and AadAudienceId must be specified if AAD authentication is being configured for P2S.");
415+
}
416+
417+
if (vnetGateway.VpnClientConfiguration.VpnClientProtocols.Count() == 1 &&
418+
vnetGateway.VpnClientConfiguration.VpnClientProtocols.First().Equals(MNM.VpnClientProtocol.OpenVPN))
419+
{
420+
vnetGateway.VpnClientConfiguration.AadTenant = this.AadTenantUri;
421+
vnetGateway.VpnClientConfiguration.AadIssuer = this.AadIssuerUri;
422+
vnetGateway.VpnClientConfiguration.AadAudience = this.AadAudienceId;
423+
}
424+
else
425+
{
426+
throw new ArgumentException("Virtual Network Gateway VpnClientProtocol should be :" + MNM.VpnClientProtocol.OpenVPN + " when P2S AAD authentication is being configured.");
427+
}
428+
}
369429
}
370430
else
371431
{

src/Network/Network/VirtualNetworkGateway/UpdateAzureVirtualNetworkGatewayCommand.cs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,35 @@ public class SetAzureVirtualNetworkGatewayCommand : VirtualNetworkGatewayBaseCmd
148148
[ValidateNotNullOrEmpty]
149149
public SecureString RadiusServerSecret { get; set; }
150150

151+
[Parameter(
152+
Mandatory = true,
153+
ValueFromPipelineByPropertyName = true,
154+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
155+
HelpMessage = "P2S AAD authentication option:AadTenantUri.")]
156+
[ValidateNotNullOrEmpty]
157+
public string AadTenantUri { get; set; }
158+
159+
[Parameter(
160+
Mandatory = true,
161+
ValueFromPipelineByPropertyName = true,
162+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
163+
HelpMessage = "P2S AAD authentication option:AadAudienceId.")]
164+
[ValidateNotNullOrEmpty]
165+
public string AadAudienceId { get; set; }
166+
167+
[Parameter(
168+
Mandatory = true,
169+
ValueFromPipelineByPropertyName = true,
170+
ParameterSetName = VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration,
171+
HelpMessage = "P2S AAD authentication option:AadIssuerUri.")]
172+
[ValidateNotNullOrEmpty]
173+
public string AadIssuerUri { get; set; }
174+
175+
[Parameter(
176+
Mandatory = false,
177+
HelpMessage = "Flag to remove AAD authentication for P2S client from virtual network gateway.")]
178+
public SwitchParameter RemoveAadAuthentication { get; set; }
179+
151180
[Parameter(
152181
Mandatory = false,
153182
ValueFromPipelineByPropertyName = true,
@@ -216,7 +245,8 @@ public override void Execute()
216245
this.VpnClientRevokedCertificates != null ||
217246
this.RadiusServerAddress != null ||
218247
this.RadiusServerSecret != null ||
219-
(this.VpnClientIpsecPolicy != null && this.VpnClientIpsecPolicy.Length != 0)) &&
248+
(this.VpnClientIpsecPolicy != null && this.VpnClientIpsecPolicy.Length != 0) ||
249+
this.AadTenantUri != null) &&
220250
this.VirtualNetworkGateway.VpnClientConfiguration == null)
221251
{
222252
this.VirtualNetworkGateway.VpnClientConfiguration = new PSVpnClientConfiguration();
@@ -259,6 +289,33 @@ public override void Execute()
259289
this.VirtualNetworkGateway.VpnClientConfiguration.RadiusServerSecret = SecureStringExtensions.ConvertToString(this.RadiusServerSecret);
260290
}
261291

292+
if (ParameterSetName.Contains(VirtualNetworkGatewayParameterSets.AadAuthenticationConfiguration))
293+
{
294+
if (this.AadTenantUri == null || this.AadIssuerUri == null || this.AadAudienceId == null)
295+
{
296+
throw new ArgumentException("AadTenantUri, AadIssuerUri and AadAudienceId must be specified if AAD authentication is being configured for P2S.");
297+
}
298+
299+
if (this.VirtualNetworkGateway.VpnClientConfiguration.VpnClientProtocols.Count() == 1 &&
300+
this.VirtualNetworkGateway.VpnClientConfiguration.VpnClientProtocols.First().Equals(MNM.VpnClientProtocol.OpenVPN))
301+
{
302+
this.VirtualNetworkGateway.VpnClientConfiguration.AadTenant = this.AadTenantUri;
303+
this.VirtualNetworkGateway.VpnClientConfiguration.AadIssuer = this.AadIssuerUri;
304+
this.VirtualNetworkGateway.VpnClientConfiguration.AadAudience = this.AadAudienceId;
305+
}
306+
else
307+
{
308+
throw new ArgumentException("Virtual Network Gateway VpnClientProtocol should be :" + MNM.VpnClientProtocol.OpenVPN + " when P2S AAD authentication is being configured.");
309+
}
310+
}
311+
312+
if (this.RemoveAadAuthentication.IsPresent)
313+
{
314+
this.VirtualNetworkGateway.VpnClientConfiguration.AadTenant = null;
315+
this.VirtualNetworkGateway.VpnClientConfiguration.AadIssuer = null;
316+
this.VirtualNetworkGateway.VpnClientConfiguration.AadAudience = null;
317+
}
318+
262319
if ((this.Asn > 0 || this.PeerWeight > 0) && this.VirtualNetworkGateway.BgpSettings == null)
263320
{
264321
this.VirtualNetworkGateway.BgpSettings = new PSBgpSettings();

src/Network/Network/VirtualNetworkGateway/VirtualNetworkGatewayParameterSets.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class VirtualNetworkGatewayParameterSets
1212

1313
public const string RadiusServerConfiguration = @"RadiusServerConfiguration";
1414

15+
public const string AadAuthenticationConfiguration = @"AadAuthenticationConfiguration";
16+
1517
public const string UpdateResourceWithTags = @"UpdateResourceWithTags";
1618
}
1719
}

0 commit comments

Comments
 (0)