Skip to content

Commit 1793624

Browse files
zesluo1Dongwei WangBethanyZhou
authored
Updated support for synapse role assignment and Added support for role scope (#14172)
* fixing compliationerror * getroleassignment * refine parametersetname * add scope to newroleassignment * add list scope command * refine new-azuresynapseroleassignment * add Itemtype and Item * refine newAzureSynapseRoleAssignment * remove unnecessary feeds * refine deleteroleassignmentid * refine resourceid name * improve remove and getroleassignments * itemtype and item improvement * Fix a few issues * Correct exception types * add principle type * add principaltype * caseinsent * update changelog * add doc for get-azsyanpserolescope * remove powershlles * update help doc * add objectid back * update Az.Synapse.md * update auto generated mdfiles * update changelog * update changelog2 * update changelog3 * update changelog4 * update changelog5 * update changelog6 * update changelog7 * Update src/Synapse/Synapse/ChangeLog.md Co-authored-by: Beisi Zhou <[email protected]> Co-authored-by: Dongwei Wang <[email protected]> Co-authored-by: Beisi Zhou <[email protected]>
1 parent 301e81f commit 1793624

20 files changed

+737
-90
lines changed

src/Synapse/Synapse/Az.Synapse.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ CmdletsToExport = 'Get-AzSynapseSparkJob', 'Stop-AzSynapseSparkJob',
123123
'Remove-AzSynapseFirewallRule', 'Get-AzSynapseFirewallRule',
124124
'Update-AzSynapseFirewallRule', 'Get-AzSynapseRoleAssignment',
125125
'New-AzSynapseRoleAssignment', 'Remove-AzSynapseRoleAssignment',
126-
'Get-AzSynapseRoleDefinition', 'Get-AzSynapseSqlDatabase',
126+
'Get-AzSynapseRoleDefinition', 'Get-AzSynapseRoleScope', 'Get-AzSynapseSqlDatabase',
127127
'New-AzSynapseSqlDatabase', 'Remove-AzSynapseSqlDatabase',
128128
'Update-AzSynapseSqlDatabase', 'Test-AzSynapseSqlDatabase',
129129
'Disable-AzSynapseSqlPoolSensitivityRecommendation',

src/Synapse/Synapse/ChangeLog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
- Additional information about change #1
1919
-->
2020
## Upcoming Release
21+
* Add support for Synapse Role-based access control
22+
- Upgraded Azure.Analytics.Synapse.AccessControl to 1.0.0-preview.3
23+
- Updated `New-AzSynapseRoleAssignment` cmdlet
24+
- Updated `Get-AzSynapseRoleAssignment` cmdlet
25+
- Updated `Remove-AzSynapseRoleAssignment` cmdlet
26+
- Added `Get-AzSynapseRoleScope` cmdlet
2127
* Renamed -AllowAllAzureIP to -AllowAllAzureIp and changed IP range to 0.0.0.0-0.0.0.0
2228
* Added -AllowAllIp and set IP range to 0.0.0.0-255.255.255.255
2329
* Fixed the issue of retrieving Apache Spark pool information through management API

src/Synapse/Synapse/Commands/DataPlaneCommands/AccessControl/GetAzureSynapseRoleAssignment.cs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
using Azure.Analytics.Synapse.AccessControl;
2-
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
1+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
32
using Microsoft.Azure.Commands.Synapse.Common;
43
using Microsoft.Azure.Commands.Synapse.Models;
54
using Microsoft.WindowsAzure.Commands.Utilities.Common;
6-
using System;
7-
using System.Collections.Generic;
85
using System.Linq;
96
using System.Management.Automation;
10-
using System.Text;
7+
using System.Text.RegularExpressions;
8+
using static Microsoft.Azure.Commands.Synapse.Models.SynapseConstants;
119

1210
namespace Microsoft.Azure.Commands.Synapse
1311
{
@@ -110,6 +108,44 @@ public class GetAzureSynapseRoleAssignment : SynapseRoleCmdletBase
110108
[ValidateNotNullOrEmpty]
111109
public string ObjectId { get; set; }
112110

111+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameAndNameParameterSet,
112+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
113+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameAndIdParameterSet,
114+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
115+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameAndRoleDefinitionIdAndObjectIdParameterSet,
116+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
117+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameAndServicePrincipalNameParameterSet,
118+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
119+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectAndNameParameterSet,
120+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
121+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectAndIdParameterSet,
122+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
123+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectAndRoleDefinitionIdAndObjectIdParameterSet,
124+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
125+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectAndServicePrincipalNameParameterSet,
126+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
127+
[ValidateNotNullOrEmpty]
128+
public WorkspaceItemType ItemType { get; set; }
129+
130+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameAndNameParameterSet,
131+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
132+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameAndIdParameterSet,
133+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
134+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameAndRoleDefinitionIdAndObjectIdParameterSet,
135+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
136+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameAndServicePrincipalNameParameterSet,
137+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
138+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectAndNameParameterSet,
139+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
140+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectAndIdParameterSet,
141+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
142+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectAndRoleDefinitionIdAndObjectIdParameterSet,
143+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
144+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectAndServicePrincipalNameParameterSet,
145+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
146+
[ValidateNotNullOrEmpty]
147+
public string Item { get; set; }
148+
113149
public override void ExecuteCmdlet()
114150
{
115151
if (this.IsParameterBound(c => c.WorkspaceObject))
@@ -132,22 +168,39 @@ public override void ExecuteCmdlet()
132168
this.ObjectId = SynapseAnalyticsClient.GetObjectIdFromServicePrincipalName(this.ServicePrincipalName);
133169
}
134170

171+
string itemType = null;
172+
if (this.IsParameterBound(c => c.ItemType))
173+
{
174+
itemType = this.ItemType.GetItemTypeString();
175+
}
176+
135177
if (this.IsParameterBound(c => c.RoleAssignmentId))
136178
{
137179
WriteObject(new PSRoleAssignmentDetails(SynapseAnalyticsClient.GetRoleAssignmentById(this.RoleAssignmentId)));
138180
}
139181
else
140182
{
141-
var roleAssignment = SynapseAnalyticsClient.ListRoleAssignments(this.RoleDefinitionId, this.ObjectId)
142-
.Select(element => new PSRoleAssignmentDetails(element));
183+
var roleAssignments = SynapseAnalyticsClient.ListRoleAssignments(this.RoleDefinitionId, this.ObjectId).Select(element => new PSRoleAssignmentDetails(element));
184+
string allowedScopePattern = null;
185+
if (this.IsParameterBound(c => c.ItemType) && this.IsParameterBound(c => c.Item))
186+
{
187+
allowedScopePattern = $"(^workspaces/{this.WorkspaceName}$)|(^workspaces/{this.WorkspaceName}/{itemType}/{this.Item}$)";
188+
}
189+
else if (this.IsParameterBound(c => c.ItemType) && !this.IsParameterBound(c => c.Item))
190+
{
191+
allowedScopePattern = $"(^workspaces/{this.WorkspaceName}$)|(^workspaces/{this.WorkspaceName}/{itemType}/[^/]+$)";
192+
}
193+
else if (!this.IsParameterBound(c => c.ItemType) && this.IsParameterBound(c => c.Item))
194+
{
195+
allowedScopePattern = $"(^workspaces/{this.WorkspaceName}$)|(^workspaces/{this.WorkspaceName}/[^/]+/{this.Item}$)";
196+
}
143197

144-
// TODO: Currently, when only `ObjectId` is specified, the cmdlet returns incorrect result. Filter from client side as a workaround
145-
if (!string.IsNullOrEmpty(this.ObjectId))
198+
if (!string.IsNullOrEmpty(allowedScopePattern))
146199
{
147-
roleAssignment = roleAssignment.Where(element => element.ObjectId == this.ObjectId);
200+
roleAssignments = roleAssignments.Where(ra => ra.Scope == null || Regex.IsMatch(ra.Scope, allowedScopePattern, RegexOptions.IgnoreCase));
148201
}
149202

150-
WriteObject(roleAssignment, true);
203+
WriteObject(roleAssignments, true);
151204
}
152205
}
153206
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using Microsoft.Azure.Commands.Common.Exceptions;
2+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
3+
using Microsoft.Azure.Commands.Synapse.Common;
4+
using Microsoft.Azure.Commands.Synapse.Models;
5+
using Microsoft.Azure.Commands.Synapse.Properties;
6+
using Microsoft.Azure.Management.Internal.Resources.Utilities.Models;
7+
using Microsoft.WindowsAzure.Commands.Utilities.Common;
8+
using System;
9+
using System.Linq;
10+
using System.Management.Automation;
11+
12+
namespace Microsoft.Azure.Commands.Synapse
13+
{
14+
[Cmdlet(VerbsCommon.Get, ResourceManager.Common.AzureRMConstants.AzureRMPrefix + SynapseConstants.SynapsePrefix + SynapseConstants.RoleScope,
15+
DefaultParameterSetName = GetByWorkspaceNameParameterSet)]
16+
[OutputType(typeof(PSSynapseRole))]
17+
public class GetAzureSynapseRoleScope : SynapseRoleCmdletBase
18+
{
19+
private const string GetByWorkspaceNameParameterSet = "GetByWorkspaceNameParameterSet";
20+
private const string GetByWorkspaceObjectParameterSet = "GetByWorkspaceObjectParameterSet";
21+
22+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameParameterSet,
23+
Mandatory = true, HelpMessage = HelpMessages.WorkspaceName)]
24+
[ResourceNameCompleter(ResourceTypes.Workspace, "ResourceGroupName")]
25+
[ValidateNotNullOrEmpty]
26+
public override string WorkspaceName { get; set; }
27+
28+
[Parameter(ValueFromPipeline = true, ParameterSetName = GetByWorkspaceObjectParameterSet,
29+
Mandatory = true, HelpMessage = HelpMessages.WorkspaceObject)]
30+
[ValidateNotNull]
31+
public PSSynapseWorkspace WorkspaceObject { get; set; }
32+
33+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceNameParameterSet,
34+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceResourceId)]
35+
[Parameter(ValueFromPipelineByPropertyName = false, ParameterSetName = GetByWorkspaceObjectParameterSet,
36+
Mandatory = false, HelpMessage = HelpMessages.WorkspaceResourceId)]
37+
[ValidateNotNullOrEmpty]
38+
public string ResourceId { get; set; }
39+
40+
public override void ExecuteCmdlet()
41+
{
42+
if (this.IsParameterBound(c => c.ResourceId))
43+
{
44+
var resourceIdentifier = new ResourceIdentifier(this.ResourceId);
45+
this.WorkspaceName = resourceIdentifier.ResourceName;
46+
}
47+
48+
if (this.IsParameterBound(c => c.WorkspaceObject))
49+
{
50+
this.WorkspaceName = this.WorkspaceObject.Name;
51+
}
52+
53+
var roleScopes = SynapseAnalyticsClient.ListRoleScopes();
54+
WriteObject(roleScopes, true);
55+
}
56+
}
57+
}

src/Synapse/Synapse/Commands/DataPlaneCommands/AccessControl/NewAzureSynapseRoleAssignment.cs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
using Azure.Analytics.Synapse.AccessControl.Models;
1+
using Microsoft.Azure.Commands.Common.Exceptions;
22
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
33
using Microsoft.Azure.Commands.Synapse.Common;
44
using Microsoft.Azure.Commands.Synapse.Models;
55
using Microsoft.Azure.Commands.Synapse.Properties;
66
using Microsoft.WindowsAzure.Commands.Utilities.Common;
77
using System;
8-
using System.Collections.Generic;
98
using System.Management.Automation;
10-
using System.Text;
9+
using static Microsoft.Azure.Commands.Synapse.Models.SynapseConstants;
1110

1211
namespace Microsoft.Azure.Commands.Synapse
1312
{
@@ -97,6 +96,20 @@ public class NewAzureSynapseRoleAssignment : SynapseRoleCmdletBase
9796
[ValidateNotNullOrEmpty]
9897
public string ObjectId { get; set; }
9998

99+
// Compared with Remove-AzSynapseRoleAssignment and Get-AzSynapseRoleAssignment, no need to specify roleAssignment, it is created as
100+
// random uuid. Hence unnecessary to specify the ParameterSetName
101+
[Parameter(ValueFromPipelineByPropertyName = false, Mandatory = false, HelpMessage = HelpMessages.WorkspaceItemType)]
102+
[ValidateNotNullOrEmpty]
103+
public WorkspaceItemType ItemType { get; set; }
104+
105+
[Parameter(ValueFromPipelineByPropertyName = false, Mandatory = false, HelpMessage = HelpMessages.WorkspaceItem)]
106+
[ValidateNotNullOrEmpty]
107+
public string Item { get; set; }
108+
109+
[Parameter(ValueFromPipelineByPropertyName = false, Mandatory = false, HelpMessage = HelpMessages.WorkspacePrincipalType)]
110+
[ValidateNotNullOrEmpty]
111+
public PrincipalType PrincipalType { get; set; }
112+
100113
[Parameter(Mandatory = false, HelpMessage = HelpMessages.AsJob)]
101114
public SwitchParameter AsJob { get; set; }
102115

@@ -122,9 +135,30 @@ public override void ExecuteCmdlet()
122135
this.ObjectId = SynapseAnalyticsClient.GetObjectIdFromServicePrincipalName(this.ServicePrincipalName);
123136
}
124137

138+
string itemType = null;
139+
if (this.IsParameterBound(c => c.ItemType))
140+
{
141+
itemType = this.ItemType.GetItemTypeString();
142+
}
143+
144+
string principalType = null;
145+
if (this.IsParameterBound(c => c.PrincipalType))
146+
{
147+
principalType = this.PrincipalType.GetPrincipalTypeString();
148+
}
149+
125150
if (this.ShouldProcess(this.WorkspaceName, String.Format(Resources.CreatingSynapseRoleAssignment, this.WorkspaceName, this.RoleDefinitionId, this.ObjectId)))
126151
{
127-
PSRoleAssignmentDetails roleAssignmentDetails = new PSRoleAssignmentDetails(SynapseAnalyticsClient.CreateRoleAssignment(this.RoleDefinitionId, this.ObjectId));
152+
// Item type and item should appear Report error if either item type or item is specified.
153+
if ((!this.IsParameterBound(c => c.ItemType) && this.IsParameterBound(c => c.Item)) ||
154+
(this.IsParameterBound(c => c.ItemType) && !this.IsParameterBound(c => c.Item)))
155+
{
156+
throw new AzPSInvalidOperationException(String.Format(Resources.WorkspaceItemTypeAndItemNotAppearTogether));
157+
}
158+
159+
string roleAssignmentId = Guid.NewGuid().ToString();
160+
string scope = SynapseAnalyticsClient.GetRoleAssignmentScope(this.WorkspaceName, itemType, this.Item);
161+
PSRoleAssignmentDetails roleAssignmentDetails = new PSRoleAssignmentDetails(SynapseAnalyticsClient.CreateRoleAssignment(roleAssignmentId, this.RoleDefinitionId, this.ObjectId, scope, principalType));
128162
WriteObject(roleAssignmentDetails);
129163
}
130164
}

0 commit comments

Comments
 (0)