Skip to content

Commit 2185ac9

Browse files
LucasYao93dingmeng-xueBethanyZhou
authored
[Network]Add Microsoft.Network/privateLinkServices configuration to support the private endpoint connection (#18000)
* Add Microsoft.Network/privateLinkServices configuration to support PEC and add hasSupportResourceURI parameter. * [Network] modified privatelinkresourcetype dynamic parameter. * [Network]throw message when RP not support private endpoint connection or private link resource. * update example * update code * [Network] adjust private endpoint connection and link resource logic. * [Network] modified help message. * [Network] delete unnecessary. * [Network]adjust prinvate link resource logic. * [Network] add changelog. * [Network] update changelog. * Update src/Network/Network/ChangeLog.md * Update src/Network/Network/ChangeLog.md * [Network] adjust private link feature logic. * [Network] add VaildateParentResourceAttribute for resource id field." * [Network] changed public to internal. Co-authored-by: dingmeng-xue <[email protected]> Co-authored-by: Beisi Zhou <[email protected]>
1 parent 4597dd4 commit 2185ac9

File tree

9 files changed

+148
-45
lines changed

9 files changed

+148
-45
lines changed

documentation/development-docs/examples/private-link-resource-example.md

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,68 @@
11
## Applicability
2-
Az.Network supports the retrieval of private link resource in `Get-AzPrivateLinkResource` as well as the management of private endpoint connection in `Approve-AzPrivateEndpointConnect`, `Deny-AzPrivateEndpointConnect`, `Remove-AzPrivateEndpointConnect` and `Set-AzPrivateEndpointConnect`.
2+
Az.Network supports the retrieval of private link resource in `Get-AzPrivateLinkResource` as well as the management of private endpoint connection by `Get-AzPrivateEndpointConnection`, `Approve-AzPrivateEndpointConnection`, `Deny-AzPrivateEndpointConnection`, `Remove-AzPrivateEndpointConnection` and `Set-AzPrivateEndpointConnection`.
33

4-
For providers who
5-
- supports the features of private linke resource and private endpoint connection already
6-
- and want to onboard these features in Azure PowerShell,
4+
For provider who
5+
- supports the features of private link resource or private endpoint connection already
6+
- and wants to onboard these features in Azure PowerShell,
7+
You need to register provider configuration in [ProviderConfiguration.cs](https://github.com/Azure/azure-powershell/blob/main/src/Network/Network/PrivateLinkService/PrivateLinkServiceProvider/ProviderConfiguration.cs#L12).
78

8-
they need register provider configuration in [ProviderConfiguration.cs](https://github.com/Azure/azure-powershell/blob/main/src/Network/Network/PrivateLinkService/PrivateLinkServiceProvider/ProviderConfiguration.cs#L12).
9-
10-
Notes: No additional commands for the features of private linke resource and private endpoint connection need to be added.
9+
Notes: No additional commands for the features of PrivateLinkResource and PrivateEndpointConnection need to be added.
1110

1211
## Prerequisite
1312
We assume the API for `List` private link resource and `Get` private endpoint connection is available in the provider that claims to support private endpoint connection features. That means it supports following APIs:
1413

1514
```
1615
# List Private Link Resource API
17-
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{Top-Level-Resource}/{Top-Level-Resource-Name}/privateLinkResources"
16+
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{topResourceType}/{topResourceName}/privateLinkResources"
1817
```
1918
```
2019
# Get Private Endpoint Connection API
21-
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{Top-Level-Resource}/{Top-Level-Resource-Name}/privateEndpointConnections/{PrivateEndpointConnection-Name}"
20+
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{topResourceType}/{topResourceName}/privateEndpointConnections/{privateEndpointConnectionName}"
2221
```
2322

24-
if "List Private Endpoint Connection API" is not available, `privateEndpointConnections` must be included in the properties of top resource returned by
25-
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{Top-Level-Resource}/{Top-Level-Resource-Name}". So that `Private Endpoint Connections` will be retrieved from the top resource.
23+
if "List Private Endpoint Connection API" below is not available, `privateEndpointConnections` must be included in the properties of top resource returned by
24+
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{topResourceType}/{topResourceName}". So that `Get-AzPrivateEndpointConnect` will retrieve connections from the top resource.
2625

2726
```
2827
# List Private Endpoint Connection API
29-
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{Top-Level-Resource}/{Top-Level-Resource-Name}/privateEndpointConnections"
28+
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{topResourceType}/{topResourceName}/privateEndpointConnections"
3029
```
3130

3231
## Code Changes Needed
33-
To add corresponding {Provider}, {Top-Level-Resource} and {API-Version} into [ProviderConfiguration.cs](https://github.com/Azure/azure-powershell/blob/main/src/Network/Network/PrivateLinkService/PrivateLinkServiceProvider/ProviderConfiguration.cs#L12), we need to follow
34-
in following pattern:
32+
To add corresponding {Provider}, {topResourceType} and {API-Version} into [ProviderConfiguration.cs](https://github.com/Azure/azure-powershell/blob/main/src/Network/Network/PrivateLinkService/PrivateLinkServiceProvider/ProviderConfiguration.cs#L12), we need to follow in following pattern:
3533
```
36-
RegisterConfiguration("{Provider}/{Top-Level-Resource}", "{API-Version}", bool hasPrivateEndppointConnectionsURI, bool hasPrivateLinkResourceURI)
34+
RegisterConfiguration(string type, string apiVersion, bool hasConnectionsURI = false, bool supportGetPrivateLinkResource = false, bool supportPrivateLinkResource = true)
3735
```
38-
- "{Provider}/{Top-Level-Resource}" describes the type of provider. For example, "Microsoft.Sql/servers".
39-
- "{API-Version}" specifies the API version to be used. For example, "2018-06-01-preview".
40-
- `hasPrivateEndppointConnectionsURI` marks the provider whether provides "List Private Endpoint Connection API".
36+
- `type` includes resource provider and resource type which supports PrivateLink feature. For example, "Microsoft.Sql/servers".
37+
- `apiVersion` specifies the API version to be used. For example, "2018-06-01-preview".
38+
- `hasConnectionsURI` marks whether the provider exposes "List Private Endpoint Connection API". Default value is false.
4139
```
4240
# Get Private Link Resource API
43-
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{Top-Level-Resource}/{Top-Level-Resource-Name}/privateLinkResources/{PrivateLinkResource-Name}"
41+
"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{provider}/{topResourceType}/{topResourceName}/privateLinkResources/{privateLinkResourceName}"
4442
```
45-
- `hasPrivateLinkResourceURI` marks the provider whether providers "Get Private Endpoint Connection API".
43+
- `supportGetPrivateLinkResource` marks whether the provider supports Get API of PrivateLinkResource. Default value is false.
4644

47-
For instance, for provider "Microsoft.Sql/servers" with API version "2018-06-01-preview", it supports "List Private Endpoint Connection API" and "Get Private Endpoint Connection API". So it's registration configuration should be
45+
For instance, for provider "Microsoft.Sql/servers" with API version "2018-06-01-preview", it supports "List Private Endpoint Connection API" and "Get Private Link Resource API". So its registration configuration should be:
4846
```
4947
RegisterConfiguration("Microsoft.Sql/servers", "2018-06-01-preview", true, true);
5048
```
5149

50+
- `supportListPrivateLinkResource` marks whether the provider supports List API of PrivateLinkResource. Default value is true.
51+
52+
For instance, `Microsoft.Network/privateLinkServices` supports PrivateEndpointConnections but doesn't support resource type PrivateLinkResource (We assume List API is mandatory to resource support). Its configuration should be:
53+
```
54+
RegisterConfiguration("Microsoft.Network/privateLinkServices", "2020-05-01", true, false, false);
55+
```
56+
5257
## End-To-End Test
5358

5459
### Item Needed
5560

5661
+ Top level resource
5762
```
58-
New-Az{Top-Level-Resource} -ResourceGroupName {rg_name} -Name {top_level_resource_name}
63+
New-Az{topResourceType} -ResourceGroupName {rgName} -Name {topResourceName}
5964
60-
$TopLevelResource = Get-Az{Top-Level-Resource} -ResourceGroupName {rg_name} -Name {top_level_resource_name}
65+
$TopLevelResource = Get-Az{topResourceType} -ResourceGroupName {rgName} -Name {topResourceName}
6166
```
6267

6368
+ private link resource
@@ -67,24 +72,24 @@ $PrivateLinkResource = Get-AzPrivateLinkResource -PrivateLinkResourceId $TopLeve
6772

6873
+ subnet config (object in memory)
6974
```
70-
$SubnetConfig = New-AzVirtualNetworkSubnetConfig -Name {config_name} -AddressPrefix "11.0.1.0/24" -PrivateEndpointNetworkPolicies "Disabled"
75+
$SubnetConfig = New-AzVirtualNetworkSubnetConfig -Name {configName} -AddressPrefix "11.0.1.0/24" -PrivateEndpointNetworkPolicies "Disabled"
7176
```
7277

7378
+ virtual network
7479
```
75-
New-AzVirtualNetwork -ResourceGroupName {rg_name} -Name {vnet_name} -Location {location} -AddressPrefix "11.0.0.0/16" -Subnet $SubnetConfig
80+
New-AzVirtualNetwork -ResourceGroupName {rgName} -Name {vnetName} -Location {location} -AddressPrefix "11.0.0.0/16" -Subnet $SubnetConfig
7681
77-
$VNet=Get-AzVirtualNetwork -ResourceGroupName {rg_name} -Name {vnet_name}
82+
$VNet=Get-AzVirtualNetwork -ResourceGroupName {rgName} -Name {vnetName}
7883
```
7984

8085
+ private link service connection (object in memory)
8186
```
82-
$PLSConnection = New-AzPrivateLinkServiceConnection -Name {pls_connection_name} -PrivateLinkServiceId $TopLevelResource.Id -GroupId $TopLevelResource.GroupId
87+
$PLSConnection = New-AzPrivateLinkServiceConnection -Name {plsConnectionName} -PrivateLinkServiceId $TopLevelResource.Id -GroupId $TopLevelResource.GroupId
8388
```
8489

8590
+ endpoint
8691
```
87-
New-AzPrivateEndpoint -ResourceGroupName {rg_name} -Name {endpoint_name} -Location {location} -Subnet $VNet.subnets[0] -PrivateLinkServiceConnection $PLSConnection -ByManualRequest
92+
New-AzPrivateEndpoint -ResourceGroupName {rgName} -Name {endpointName} -Location {location} -Subnet $VNet.subnets[0] -PrivateLinkServiceConnection $PLSConnection -ByManualRequest
8893
```
8994

9095
### step-by-step
@@ -99,7 +104,7 @@ $connection = Get-AzPrivateEndpointConnection -PrivateLinkResourceId $TopLevelRe
99104

100105
* To get the connection, if `list` for private endpoint connection was not supported,
101106
```
102-
$TopLevelResource = Get-Az{Top-Level-Resource} -ResourceGroupName {rg_name} -Name {top_level_resource_name}
107+
$TopLevelResource = Get-Az{topResourceType} -ResourceGroupName {rgName} -Name {topResourceName}
103108
104109
$ConnectionId = $TopLevelResource.PrivateEndpointConnection[0].Id
105110

src/Network/Network/ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
--->
2020

2121
## Upcoming Release
22+
* Supported `Microsoft.Network/privateLinkServices` in `Get-AzPrivateEndpointConnection` [#16984].
23+
* Provided friendly message if resource type is not supported for private endpoint connection features [#17091].
2224
* Added `DisableIPsecProtection` to `Virtual Network Gateway`.
2325
* Added new cmdlets to create/manage authorization objects for ExpressRoutePort:
2426
- `Add-AzExpressRoutePortAuthorization`

src/Network/Network/PrivateLinkService/PrivateEndpointConnection/PrivateEndpointConnectionBaseCmdlet.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15+
using Microsoft.Azure.Commands.Common.Exceptions;
1516
using Microsoft.Azure.Commands.Network.PrivateLinkService.PrivateLinkServiceProvider;
1617
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
1718
using System.Management.Automation;
19+
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
20+
using System;
1821

1922
namespace Microsoft.Azure.Commands.Network
2023
{
@@ -25,6 +28,7 @@ public abstract class PrivateEndpointConnectionBaseCmdlet : NetworkBaseCmdlet, I
2528
ParameterSetName = "ByResourceId",
2629
ValueFromPipelineByPropertyName = true)]
2730
[ValidateNotNullOrEmpty]
31+
[ValidateParentResourceNotNullOrEmpty]
2832
public string ResourceId { get; set; }
2933

3034
[Alias("ResourceName")]
@@ -62,7 +66,7 @@ public abstract class PrivateEndpointConnectionBaseCmdlet : NetworkBaseCmdlet, I
6266
{
6367
var parameters = new RuntimeDefinedParameterDictionary();
6468
RuntimeDefinedParameter namedParameter;
65-
if (ProviderConfiguration.TryGetProvideServiceParameter(privateEndpointTypeName, NamedContextParameterSet, out namedParameter))
69+
if (ProviderConfiguration.TryGetEndpointConnectionServiceParameter(privateEndpointTypeName, NamedContextParameterSet, out namedParameter))
6670
{
6771
parameters.Add(privateEndpointTypeName, namedParameter);
6872
}
@@ -76,7 +80,26 @@ public abstract class PrivateEndpointConnectionBaseCmdlet : NetworkBaseCmdlet, I
7680

7781
protected IPrivateLinkProvider BuildProvider(string subscription, string privateLinkResourceType)
7882
{
83+
if (!GenericProvider.SupportsPrivateLinkFeature(privateLinkResourceType))
84+
throw new AzPSApplicationException(string.Format(Properties.Resources.UnsupportPrivateEndpointConnectionType, privateLinkResourceType));
7985
return PrivateLinkProviderFactory.CreatePrivateLinkProvder(this, subscription, privateLinkResourceType);
8086
}
87+
88+
/// <summary>
89+
/// Validate parent resource of the resource id not null or empty.
90+
/// </summary>
91+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
92+
internal sealed class ValidateParentResourceNotNullOrEmptyAttribute : ValidateArgumentsAttribute
93+
{
94+
protected override void Validate(object arguments, EngineIntrinsics engineIntrinsics)
95+
{
96+
string resourceId = (string)arguments;
97+
var resourceIdentifier = new ResourceIdentifier(resourceId);
98+
if (string.IsNullOrEmpty(resourceIdentifier.ParentResource))
99+
{
100+
throw new AzPSApplicationException(string.Format(Properties.Resources.InvalidResourceId, resourceId));
101+
}
102+
}
103+
}
81104
}
82105
}

src/Network/Network/PrivateLinkService/PrivateLinkResource/GetAzurePrivateLinkResourceCommand.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15+
using Microsoft.Azure.Commands.Common.Exceptions;
1516
using Microsoft.Azure.Commands.Network.Models;
1617
using Microsoft.Azure.Commands.Network.PrivateLinkService.PrivateLinkServiceProvider;
1718
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
@@ -63,9 +64,10 @@ public class GetAzurePrivateLinkResourceCommand : NetworkBaseCmdlet, IDynamicPar
6364

6465
public new object GetDynamicParameters()
6566
{
67+
InvocationInfo invocationInfo = MyInvocation;
6668
var parameters = new RuntimeDefinedParameterDictionary();
6769
RuntimeDefinedParameter namedParameter;
68-
if (ProviderConfiguration.TryGetProvideServiceParameter(privateEndpointTypeName, NamedContextParameterSet, out namedParameter))
70+
if (ProviderConfiguration.TryGetLinkResourceServiceParameter(privateEndpointTypeName, NamedContextParameterSet, out namedParameter))
6971
{
7072
parameters.Add(privateEndpointTypeName, namedParameter);
7173
}
@@ -89,6 +91,12 @@ public override void Execute()
8991
this.Subscription = DefaultProfile.DefaultContext.Subscription.Id;
9092
this.PrivateLinkResourceType = DynamicParameters[privateEndpointTypeName].Value as string;
9193
}
94+
// First check resource type whether support private link feature, if support then check whether support private link resource feature.
95+
if (!GenericProvider.SupportsPrivateLinkFeature(this.PrivateLinkResourceType) || !ProviderConfiguration.GetProviderConfiguration(this.PrivateLinkResourceType).SupportListPrivateLinkResource)
96+
{
97+
throw new AzPSApplicationException(string.Format(Properties.Resources.UnsupportPrivateLinkResourceType, this.PrivateLinkResourceType));
98+
}
99+
92100
IPrivateLinkProvider provider = PrivateLinkProviderFactory.CreatePrivateLinkProvder(this, Subscription, PrivateLinkResourceType);
93101
if (provider == null)
94102
{

src/Network/Network/PrivateLinkService/PrivateLinkServiceProvider/GenericProvider.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using Microsoft.Azure.Internal.Common;
2121
using System.Collections.Generic;
2222
using System.Linq;
23+
using Microsoft.Azure.Commands.Common.Exceptions;
2324

2425
namespace Microsoft.Azure.Commands.Network.PrivateLinkService.PrivateLinkServiceProvider
2526
{
@@ -36,7 +37,7 @@ public GenericProvider(NetworkBaseCmdlet baseCmdlet, string subscription, string
3637

3738
#region Interface Implementation
3839

39-
public static bool SupportsPrivateLinkResourceType(string privateLinkResourceType)
40+
public static bool SupportsPrivateLinkFeature(string privateLinkResourceType)
4041
{
4142
ProviderConfiguration configuration = ProviderConfiguration.GetProviderConfiguration(privateLinkResourceType);
4243
return (configuration != null);
@@ -133,16 +134,14 @@ public void DeletePrivateEndpointConnection(string resourceGroupName, string ser
133134

134135
public PSPrivateLinkResource GetPrivateLinkResource(string resourceGroupName, string serviceName, string name)
135136
{
136-
if (_configuration.HasResourceURI)
137+
if (_configuration.SupportGetPrivateLinkResource)
137138
{
138139
string url = BuildPrivateLinkResourceURL(resourceGroupName, serviceName, name);
139140
PrivateLinkResource resource = ServiceClient.Operations.GetResource<PrivateLinkResource>(url, _configuration.ApiVersion);
140141
return ToPsPrivateLinkResource(resource);
141142
}
142-
else
143-
{
144-
return ListPrivateLinkResource(resourceGroupName, serviceName).Single(plr => plr.Name.Equals(name));
145-
}
143+
144+
return ListPrivateLinkResource(resourceGroupName, serviceName).Single(plr => plr.Name.Equals(name));
146145
}
147146

148147
public List<PSPrivateLinkResource> ListPrivateLinkResource(string resourceGroupName, string serviceName)

src/Network/Network/PrivateLinkService/PrivateLinkServiceProvider/PrivateLinkProviderFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static IPrivateLinkProvider CreatePrivateLinkProvder(NetworkBaseCmdlet cm
2727
return new NetworkingProvider(cmdlet);
2828
}
2929

30-
if(GenericProvider.SupportsPrivateLinkResourceType(privateLinkResourceType))
30+
if(GenericProvider.SupportsPrivateLinkFeature(privateLinkResourceType))
3131
{
3232
return new GenericProvider(cmdlet, subscription, privateLinkResourceType);
3333
}

0 commit comments

Comments
 (0)