Skip to content

Commit d0b105f

Browse files
author
Hovsep Mkrtchyan
committed
Added Role Definition tests for bash.
1 parent b691ce0 commit d0b105f

File tree

8 files changed

+243
-49
lines changed

8 files changed

+243
-49
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Param(
2+
[string]$groupName,
3+
[string]$location
4+
)
5+
6+
Write-Host "=== Managing Role Definitions in Azure ==="
7+
8+
Write-Host "1. Create a new resource group"
9+
New-AzureRmResourceGroup -Name $groupName -Location $location
10+
11+
Write-Host "2. Creating a new Role Definition."
12+
$rd = New-AzureRmRoleDefinition -InputFile roleDefinition.json
13+
14+
Write-Host "3. Get information about Role Definitions."
15+
Get-AzureRmRoleDefinition -Name $rd.Name
16+
17+
Write-Host "4. Update Role Definition."
18+
$rd.Actions.Add('Microsoft.Authorization/*/write')
19+
$updatedRd = Set-AzureRmRoleDefinition -Role $rd
20+
Assert-NotNull $updatedRd
21+
22+
Write-Host "5. Delete Role Definition."
23+
Remove-AzureRmRoleDefinition -Id $rd.Id -Force -PassThru
24+
$readRd = Get-AzureRmRoleDefinition -Name $rd.Name
25+
Assert-Null $readRd
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
set -e
3+
printf "\n=== Managing Role Definitions in Azure ===\n"
4+
5+
printf "\n1. Creating a new resource group: %s and location: %s.\n" "$groupName" "$location"
6+
azure group create --name "$groupName" --location "$location"
7+
8+
printf "\n2. Creating a new Role Definition.\n"
9+
roleDefinition=$(azure role definition create --inputfile $BASEDIR/resource-management/roleDefinition.json)
10+
11+
printf "\n3. Get information about Role Definitions.\n"
12+
roleDefinitionName=$(echo $roleDefinition | jq '.Name' --raw-output)
13+
azure role definition get -n $roleDefinitionName
14+
15+
printf "\n4. Update Role Definition.\n"
16+
updatedRoleDefinition=$(echo $roleDefinition | jq '.Actions |= .+ ["Microsoft.Authorization/*/write"]')
17+
azure role definition set --Role "$updatedRoleDefinition"
18+
19+
printf "\n5. Delete Role Definition.\n"
20+
roleDefinitionId=$(echo $roleDefinition | jq '.Id' --raw-output)
21+
azure role definition remove --Id $roleDefinitionId --PassThru -f
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Name": "CluRoleDefinition",
3+
"Description": "Super awesome Clu Role Definition",
4+
"Actions": [
5+
"Microsoft.Authorization/*/read",
6+
"Microsoft.Support/*"
7+
],
8+
"NotActions": [],
9+
"AssignableScopes": [ "/subscriptions/3ca49042-782a-4cc9-89b5-ee1b487fe115" ]
10+
}

src/CLU/Microsoft.Azure.Commands.Resources/Models.Authorization/AuthorizationClient.cs

Lines changed: 78 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ public PSRoleDefinition GetRoleDefinition(string roleId)
7373
return AuthorizationManagementClient.RoleDefinitions.GetById(roleId).ToPSRoleDefinition();
7474
}
7575

76+
/// <summary>
77+
/// Gets a single role definition by the role Id guid.
78+
/// </summary>
79+
/// <param name="roleId">RoleId guid</param>
80+
public PSRoleDefinition GetRoleDefinition(string roleId, string scope)
81+
{
82+
return AuthorizationManagementClient.RoleDefinitions.Get(scope, roleId).ToPSRoleDefinition();
83+
}
84+
7685
/// <summary>
7786
/// Gets a single role definition by the role Id guid.
7887
/// </summary>
@@ -90,22 +99,51 @@ public PSRoleDefinition GetRoleDefinition(Guid roleId)
9099
/// </summary>
91100
/// <param name="name">The role name</param>
92101
/// <returns>The matched role Definitions</returns>
93-
public List<PSRoleDefinition> FilterRoleDefinitions(string name)
102+
public List<PSRoleDefinition> FilterRoleDefinitions(string name, string scope, bool scopeAndBelow = false)
94103
{
95104
List<PSRoleDefinition> result = new List<PSRoleDefinition>();
105+
106+
ODataQuery<RoleDefinitionFilter> odataFilter = null;
107+
108+
if (scopeAndBelow)
109+
{
110+
odataFilter = new ODataQuery<RoleDefinitionFilter>(item => item.AtScopeAndBelow() && item.RoleName == name);
111+
}
112+
else
113+
{
114+
odataFilter = new ODataQuery<RoleDefinitionFilter>(item => item.RoleName == name);
115+
}
116+
96117
result.AddRange(AuthorizationManagementClient.RoleDefinitions.List(
97-
"subscriptions/" + AuthorizationManagementClient.SubscriptionId,
98-
new ODataQuery<RoleDefinition>( item => item.Name == name))
118+
scope,
119+
odataFilter)
99120
.Select(r => r.ToPSRoleDefinition()));
100121

101122
return result;
102123
}
124+
public List<PSRoleDefinition> FilterRoleDefinitions(FilterRoleDefinitionOptions options)
125+
{
126+
if (options.RoleDefinitionId != Guid.Empty)
127+
{
128+
return new List<PSRoleDefinition> { GetRoleDefinition(options.RoleDefinitionId.ToString(), options.Scope) };
129+
}
130+
else if (options.CustomOnly)
131+
{
132+
// Special case - if custom only flag is specified then you don't need to lookup on a specific id or name since it will be a bit redundant
133+
return FilterRoleDefinitionsByCustom(options.Scope, options.ScopeAndBelow);
134+
}
135+
else
136+
{
137+
// If RoleDefinition name is not specified (null/empty), service will handle it and return all roles
138+
return FilterRoleDefinitions(options.RoleDefinitionName, options.Scope, options.ScopeAndBelow);
139+
}
140+
}
103141

104142
/// <summary>
105143
/// Fetches all existing role Definitions.
106144
/// </summary>
107145
/// <returns>role Definitions</returns>
108-
public List<PSRoleDefinition> GetRoleDefinitions()
146+
public List<PSRoleDefinition> GetRoleDefinitionsAtScopeAndBelow()
109147
{
110148
List<PSRoleDefinition> result = new List<PSRoleDefinition>();
111149
result.AddRange(AuthorizationManagementClient.RoleDefinitions.List(
@@ -118,11 +156,13 @@ public List<PSRoleDefinition> GetRoleDefinitions()
118156
/// Filters the existing role Definitions by CustomRole.
119157
/// </summary>
120158
/// <returns>The custom role Definitions</returns>
121-
public List<PSRoleDefinition> FilterRoleDefinitionsByCustom()
159+
public List<PSRoleDefinition> FilterRoleDefinitionsByCustom(string scope, bool scopeAndBelow)
122160
{
123161
List<PSRoleDefinition> result = new List<PSRoleDefinition>();
162+
124163
result.AddRange(AuthorizationManagementClient.RoleDefinitions.List(
125-
"subscriptions/" + AuthorizationManagementClient.SubscriptionId)
164+
scope,
165+
scopeAndBelow ? new ODataQuery<RoleDefinitionFilter>(filter => filter.AtScopeAndBelow()) : null)
126166
.Where(r => r.Properties.Type == AuthorizationClientExtensions.CustomRole)
127167
.Select(r => r.ToPSRoleDefinition()));
128168
return result;
@@ -138,7 +178,7 @@ public PSRoleAssignment CreateRoleAssignment(FilterRoleAssignmentsOptions parame
138178
Guid principalId = ActiveDirectoryClient.GetObjectId(parameters.ADObjectFilter);
139179
Guid roleAssignmentId = RoleAssignmentNames.Count == 0 ? Guid.NewGuid() : RoleAssignmentNames.Dequeue();
140180
string roleDefinitionId = !string.IsNullOrEmpty(parameters.RoleDefinitionName)
141-
? AuthorizationHelper.GetRoleDefinitionFullyQualifiedId(subscriptionId, GetRoleRoleDefinition(parameters.RoleDefinitionName).Id)
181+
? AuthorizationHelper.GetRoleDefinitionFullyQualifiedId(subscriptionId, GetSingleRoleDefinitionByName(parameters.RoleDefinitionName, parameters.Scope).Id)
142182
: AuthorizationHelper.GetRoleDefinitionFullyQualifiedId(subscriptionId, parameters.RoleDefinitionId);
143183

144184
var createParameters = new RoleAssignmentProperties
@@ -318,9 +358,9 @@ public IEnumerable<PSRoleAssignment> RemoveRoleAssignment(FilterRoleAssignmentsO
318358
return roleAssignments;
319359
}
320360

321-
public PSRoleDefinition GetRoleRoleDefinition(string name)
361+
public PSRoleDefinition GetSingleRoleDefinitionByName(string name, string scope)
322362
{
323-
List<PSRoleDefinition> roles = FilterRoleDefinitions(name);
363+
List<PSRoleDefinition> roles = FilterRoleDefinitions(name, scope);
324364

325365
if (roles == null || !roles.Any())
326366
{
@@ -334,38 +374,52 @@ public PSRoleDefinition GetRoleRoleDefinition(string name)
334374
return roles.First();
335375
}
336376

377+
public PSRoleDefinition RemoveRoleDefinition(FilterRoleDefinitionOptions options)
378+
{
379+
if (options.RoleDefinitionId != Guid.Empty)
380+
{
381+
return this.RemoveRoleDefinition(options.RoleDefinitionId, options.Scope);
382+
}
383+
else if (!string.IsNullOrEmpty(options.RoleDefinitionName))
384+
{
385+
return this.RemoveRoleDefinition(options.RoleDefinitionName, options.Scope);
386+
}
387+
else
388+
{
389+
throw new InvalidOperationException("RoleDefinition Name or Id should be specified.");
390+
}
391+
}
337392
/// <summary>
338393
/// Deletes a role definition based on the id.
339394
/// </summary>
340395
/// <param name="roleDefinitionId">The role definition id to delete</param>
341396
/// <param name="subscriptionId">Current subscription id</param>
342397
/// <returns>The deleted role definition.</returns>
343-
public PSRoleDefinition RemoveRoleDefinition(Guid roleDefinitionId, string subscriptionId)
398+
public PSRoleDefinition RemoveRoleDefinition(Guid roleDefinitionId, string scope)
344399
{
345400
string id = roleDefinitionId.ToString();
346401

347-
PSRoleDefinition roleDefinition = this.GetRoleDefinition(roleDefinitionId);
402+
PSRoleDefinition roleDefinition = this.GetRoleDefinition(id, scope);
348403
if (roleDefinition != null)
349404
{
350-
return AuthorizationManagementClient.RoleDefinitions
351-
.Delete(roleDefinition.AssignableScopes.First(), roleDefinitionId.ToString()).ToPSRoleDefinition();
405+
return AuthorizationManagementClient.RoleDefinitions.Delete(scope, id).ToPSRoleDefinition();
352406
}
353407
else
354408
{
355-
throw new KeyNotFoundException(string.Format(ProjectResources.RoleDefinitionWithIdNotFound, id));
409+
throw new KeyNotFoundException(string.Format(ProjectResources.RoleDefinitionWithIdNotFound, roleDefinitionId));
356410
}
357411
}
358-
412+
359413
/// <summary>
360414
/// Deletes a role definition based on the name.
361415
/// </summary>
362416
/// <param name="roleDefinitionName">The role definition name.</param>
363417
/// <returns>The deleted role definition.</returns>
364-
public PSRoleDefinition RemoveRoleDefinition(string roleDefinitionName, string subscriptionId)
418+
public PSRoleDefinition RemoveRoleDefinition(string roleDefinitionName, string scope)
365419
{
366-
PSRoleDefinition roleDefinition = this.GetRoleRoleDefinition(roleDefinitionName);
420+
PSRoleDefinition roleDefinition = this.GetSingleRoleDefinitionByName(roleDefinitionName, scope);
367421
return AuthorizationManagementClient.RoleDefinitions
368-
.Delete(roleDefinition.AssignableScopes.First(), roleDefinition.Id).ToPSRoleDefinition();
422+
.Delete(scope, roleDefinition.Id).ToPSRoleDefinition();
369423
}
370424

371425
/// <summary>
@@ -381,34 +435,26 @@ public PSRoleDefinition UpdateRoleDefinition(PSRoleDefinition role, string subsc
381435
throw new InvalidOperationException(ProjectResources.RoleDefinitionIdShouldBeAGuid);
382436
}
383437

384-
PSRoleDefinition roleDefinition = this.GetRoleDefinition(roleDefinitionId);
438+
PSRoleDefinition roleDefinition = this.GetRoleDefinition(roleDefinitionId.ToString(), role.AssignableScopes.First());
385439
if (roleDefinition == null)
386440
{
387441
throw new KeyNotFoundException(string.Format(ProjectResources.RoleDefinitionWithIdNotFound, role.Id));
388442
}
389-
390-
string roleDefinitionFullyQualifiedId = AuthorizationHelper.GetRoleDefinitionFullyQualifiedId(subscriptionId, role.Id);
391-
392-
roleDefinition.Name = role.Name ?? roleDefinition.Name;
393-
roleDefinition.Actions = role.Actions ?? roleDefinition.Actions;
394-
roleDefinition.NotActions = role.NotActions ?? roleDefinition.NotActions;
395-
roleDefinition.AssignableScopes = role.AssignableScopes ?? roleDefinition.AssignableScopes;
396-
roleDefinition.Description = role.Description ?? roleDefinition.Description;
397-
443+
398444
ValidateRoleDefinition(roleDefinition);
399445

400446
return
401447
AuthorizationManagementClient.RoleDefinitions.CreateOrUpdate(
402-
roleDefinitionId.ToString(),
403448
roleDefinition.AssignableScopes.First(),
449+
roleDefinitionId.ToString(),
404450
new RoleDefinition()
405451
{
406-
Id = roleDefinitionFullyQualifiedId,
407452
Name = roleDefinitionId.ToString(),
408453
Properties =
409454
new RoleDefinitionProperties()
410455
{
411-
RoleName = roleDefinition.Name,
456+
AssignableScopes = roleDefinition.AssignableScopes,
457+
Description = roleDefinition.Description,
412458
Permissions =
413459
new List<Permission>()
414460
{
@@ -418,8 +464,7 @@ public PSRoleDefinition UpdateRoleDefinition(PSRoleDefinition role, string subsc
418464
NotActions = roleDefinition.NotActions
419465
}
420466
},
421-
AssignableScopes = roleDefinition.AssignableScopes,
422-
Description = roleDefinition.Description
467+
RoleName = roleDefinition.Name
423468
}
424469
}
425470
).ToPSRoleDefinition();

src/CLU/Microsoft.Azure.Commands.Resources/Models.Authorization/AuthorizationClientExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public static IEnumerable<PSRoleAssignment> ToPSRoleAssignments(this IEnumerable
7474
}
7575
else
7676
{
77-
roleDefinitions = policyClient.GetRoleDefinitions();
77+
roleDefinitions = policyClient.GetRoleDefinitionsAtScopeAndBelow();
7878
}
7979

8080
foreach (RoleAssignment assignment in assignments)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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;
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using System.Text;
19+
using System.Threading.Tasks;
20+
21+
namespace Microsoft.Azure.Commands.Resources.Models.Authorization
22+
{
23+
public class FilterRoleDefinitionOptions
24+
{
25+
public bool CustomOnly { get; set; }
26+
27+
public bool ScopeAndBelow { get; set; }
28+
29+
public string RoleDefinitionName { get; set; }
30+
31+
// Guid Id
32+
public Guid RoleDefinitionId { get; set; }
33+
34+
private string scope;
35+
36+
public string Scope
37+
{
38+
get
39+
{
40+
string result;
41+
string resourceIdentifier = ResourceIdentifier.ToString();
42+
43+
if (!string.IsNullOrEmpty(this.scope))
44+
{
45+
result = this.scope;
46+
}
47+
else if (!string.IsNullOrEmpty(resourceIdentifier))
48+
{
49+
result = resourceIdentifier;
50+
}
51+
else
52+
{
53+
result = null;
54+
}
55+
56+
return result;
57+
}
58+
set
59+
{
60+
this.scope = value;
61+
}
62+
}
63+
64+
public ResourceIdentifier ResourceIdentifier { get; set; }
65+
}
66+
}

0 commit comments

Comments
 (0)