Skip to content

Commit 2572887

Browse files
committed
Managed Identity for policyAssignments
1 parent 0f781b0 commit 2572887

File tree

39 files changed

+3864
-2055
lines changed

39 files changed

+3864
-2055
lines changed

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Commands.Resources.Rest.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@
100100
<Compile Include="Entities\ResourceGroup\ExportTemplateParameters.cs" />
101101
<Compile Include="Entities\ResourceGroup\ResourceBatchMoveParameters.cs" />
102102
<Compile Include="Entities\Resources\Resource.cs" />
103+
<Compile Include="Entities\Resources\ResourceIdentityType.cs" />
103104
<Compile Include="Entities\Resources\ResourcePlan.cs" />
105+
<Compile Include="Entities\Resources\ResourceIdentity.cs" />
104106
<Compile Include="Entities\Resources\ResourceSku.cs" />
105107
<Compile Include="Entities\Resources\TerminalProvisioningStates.cs" />
106108
<Compile Include="Extensions\AsyncExtensions.cs" />

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Components/Constants.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,17 @@ public static class Constants
7777
/// <summary>
7878
/// The default policy definition API version.
7979
/// </summary>
80-
public static readonly string PolicyDefinitionApiVersion = "2018-03-01";
80+
public static readonly string PolicyDefinitionApiVersion = "2018-05-01";
8181

8282
/// <summary>
8383
/// The default policy set definition API version.
8484
/// </summary>
85-
public static readonly string PolicySetDefintionApiVersion = "2018-03-01";
85+
public static readonly string PolicySetDefintionApiVersion = "2018-05-01";
8686

8787
/// <summary>
8888
/// The default policy assignment API version.
8989
/// </summary>
90-
public static readonly string PolicyAssignmentApiVersion = "2018-03-01";
90+
public static readonly string PolicyAssignmentApiVersion = "2018-05-01";
9191

9292
/// <summary>
9393
/// The default providers API version.

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Entities/Policy/PolicyAssignment.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.Policy
1616
{
17+
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.Resources;
1718
using Newtonsoft.Json;
1819

1920
/// <summary>
@@ -38,5 +39,17 @@ public class PolicyAssignment
3839
/// </summary>
3940
[JsonProperty(Required = Required.Always)]
4041
public PolicySku Sku { get; set; }
42+
43+
/// <summary>
44+
/// The resource identity assigned to the policy assignment.
45+
/// </summary>
46+
[JsonProperty(Required = Required.Default)]
47+
public ResourceIdentity Identity { get; set; }
48+
49+
/// <summary>
50+
/// The policy assignment's location.
51+
/// </summary>
52+
[JsonProperty(Required = Required.Default)]
53+
public string Location { get; set; }
4154
}
4255
}

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Entities/Resources/Resource.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ public class Resource<TProperties>
5353
[JsonProperty(Required = Required.Default)]
5454
public ResourceSku Sku { get; set; }
5555

56-
5756
/// <summary>
5857
/// Gets or sets the kind of the resource definition.
5958
/// </summary>
@@ -95,5 +94,11 @@ public class Resource<TProperties>
9594
/// </summary>
9695
[JsonProperty(Required = Required.Default)]
9796
public InsensitiveDictionary<string> Tags { get; set; }
97+
98+
/// <summary>
99+
/// The identity assigned to the resource.
100+
/// </summary>
101+
[JsonProperty(Required = Required.Default)]
102+
public ResourceIdentity Identity { get; set; }
98103
}
99104
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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 Newtonsoft.Json;
16+
17+
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.Resources
18+
{
19+
/// <summary>
20+
/// The resource identity object that represents the resource's Managed Service Identity.
21+
/// </summary>
22+
public class ResourceIdentity
23+
{
24+
/// <summary>
25+
/// Gets or sets the type of identity assigned to the resource.
26+
/// </summary>
27+
[JsonProperty(Required = Required.Default)]
28+
public string Type { get; set; }
29+
30+
/// <summary>
31+
/// Gets or sets the principal ID of the assigned identity.
32+
/// </summary>
33+
[JsonProperty(Required = Required.Default)]
34+
public string PrincipalId { get; set; }
35+
36+
/// <summary>
37+
/// Gets or sets the Azure Active Directory tenant ID that contains the assigned identity.
38+
/// </summary>
39+
[JsonProperty(Required = Required.Default)]
40+
public string TenantId { get; set; }
41+
}
42+
}
43+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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+
namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.Resources
16+
{
17+
/// <summary>
18+
/// The type of resource identity that is assigned to a resource.
19+
/// </summary>
20+
public class ResourceIdentityType
21+
{
22+
/// <summary>
23+
/// The name of the resource identity type that will automatically create an identity for the resource.
24+
/// </summary>
25+
public const string SystemAssigned = "SystemAssigned";
26+
27+
/// <summary>
28+
/// The name of the resource identity type that indicates the resource should have no identity assigned.
29+
/// </summary>
30+
public const string None = "None";
31+
}
32+
}
33+

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Extensions/ResourceExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ internal static PSObject ToPsObject(this Resource<JToken> resource)
5959
{ "CreatedTime", resource.CreatedTime },
6060
{ "ChangedTime", resource.ChangedTime },
6161
{ "ETag", resource.ETag },
62-
{ "Sku", resource.Sku.ToJToken().ToPsObject() }
62+
{ "Sku", resource.Sku.ToJToken().ToPsObject() },
63+
{ "Identity", resource.Identity?.ToJToken().ToPsObject() }
6364
};
6465

6566
var resourceTypeName = resourceType == null && extensionResourceType == null

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Implementation/Policy/GetAzurePolicyAssignment.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ private async Task<ResponseWithContinuation<JObject[]>> GetResources()
118118
cancellationToken: this.CancellationToken.Value,
119119
odataQuery: null)
120120
.ConfigureAwait(continueOnCapturedContext: false);
121+
121122
ResponseWithContinuation<JObject[]> retVal;
122123
return resource.TryConvertTo(out retVal) && retVal.Value != null
123124
? retVal

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Implementation/Policy/NewAzurePolicyAssignment.cs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation
2727
using System.Collections;
2828
using System.Linq;
2929
using System.Management.Automation;
30+
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.Resources;
31+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
3032

3133
/// <summary>
3234
/// Creates a policy assignment.
@@ -120,6 +122,19 @@ public class NewAzurePolicyAssignmentCmdlet : PolicyCmdletBase, IDynamicParamete
120122
[CmdletParameterBreakingChange("Sku", ChangeDescription = "The -Sku parameter is deprecated and ignored")]
121123
public Hashtable Sku { get; set; }
122124

125+
/// <summary>
126+
/// Gets or sets a flag indicating whether a system assigned identity should be added to the policy assignment.
127+
/// </summary>
128+
[Parameter(Mandatory = false, HelpMessage = PolicyHelpStrings.PolicyAssignmentAssignIdentityHelp)]
129+
public SwitchParameter AssignIdentity { get; set; }
130+
131+
/// <summary>
132+
/// Gets or sets the location of the policy assignment. Only required when assigning a resource identity to the assignment.
133+
/// </summary>
134+
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = PolicyHelpStrings.PolicyAssignmentLocationHelp)]
135+
[LocationCompleter("Microsoft.ManagedIdentity/userAssignedIdentities")]
136+
public string Location { get; set; }
137+
123138
/// <summary>
124139
/// Executes the cmdlet.
125140
/// </summary>
@@ -184,6 +199,8 @@ private JToken GetResource()
184199
{
185200
Name = this.Name,
186201
Sku = Sku?.ToDictionary(addValueLayer: false).ToJson().FromJson<PolicySku>(), // only store Sku if it was provided by user
202+
Identity = this.AssignIdentity.IsPresent ? new ResourceIdentity { Type = ResourceIdentityType.SystemAssigned } : null,
203+
Location = this.Location,
187204
Properties = new PolicyAssignmentProperties
188205
{
189206
DisplayName = this.DisplayName ?? null,
@@ -223,28 +240,33 @@ object IDynamicParameters.GetDynamicParameters()
223240
{
224241
foreach (var param in parameters.Properties)
225242
{
226-
var type = (param.Value as PSObject).Properties["type"];
227-
var typeString = type != null ? type.Value.ToString() : string.Empty;
228-
var description = (param.Value as PSObject).GetPSObjectProperty("metadata.description");
229-
var helpString = description != null ? description.ToString() : string.Format("The {0} policy parameter.", param.Name);
230-
var dp = new RuntimeDefinedParameter
243+
if (param.Value is PSObject paramValue)
231244
{
232-
Name = param.Name,
233-
ParameterType = typeString.Equals("array", StringComparison.OrdinalIgnoreCase) ? typeof(string[]) : typeof(string)
234-
};
235-
dp.Attributes.Add(new ParameterAttribute
236-
{
237-
ParameterSetName = PolicyCmdletBase.DefaultParameterSet,
238-
Mandatory = true,
239-
ValueFromPipelineByPropertyName = false,
240-
HelpMessage = helpString
241-
});
242-
this.dynamicParameters.Add(param.Name, dp);
245+
var type = paramValue.Properties["type"];
246+
var typeString = type != null ? type.Value.ToString() : string.Empty;
247+
var description = paramValue.GetPSObjectProperty("metadata.description");
248+
var helpString = description != null ? description.ToString() : string.Format("The {0} policy parameter.", param.Name);
249+
var dp = new RuntimeDefinedParameter
250+
{
251+
Name = param.Name,
252+
ParameterType = typeString.Equals("array", StringComparison.OrdinalIgnoreCase) ? typeof(string[]) : typeof(string)
253+
};
254+
255+
// Dynamic parameter should not be mandatory if it has a default value
256+
dp.Attributes.Add(new ParameterAttribute
257+
{
258+
ParameterSetName = PolicyCmdletBase.DefaultParameterSet,
259+
Mandatory = paramValue.Properties["defaultValue"] == null,
260+
ValueFromPipelineByPropertyName = false,
261+
HelpMessage = helpString
262+
});
263+
264+
this.dynamicParameters.Add(param.Name, dp);
265+
}
243266
}
244267
}
245268

246-
RegisterDynamicParameters(dynamicParameters);
247-
269+
this.RegisterDynamicParameters(this.dynamicParameters);
248270
return this.dynamicParameters;
249271
}
250272

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Implementation/Policy/PolicyHelpStrings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public static class PolicyHelpStrings
4747
public const string SetPolicyAssignmentDescriptionHelp = "The description of the updated policy assignment";
4848
public const string SetPolicyAssignmentMetadataHelp = "The updated metadata for the policy assignment. This can either be a path to a file name containing the metadata, or the metadata as a string.";
4949
public const string SetPolicyAssignmentSkuHelp = "A hash table which specifies sku properties. This parameter is deprecated and ignored.";
50+
public const string PolicyAssignmentAssignIdentityHelp = "Generate and assign an Azure Active Directory Identity for this policy assignment. The identity will be used when executing deployments for 'deployIfNotExists' policies.";
51+
public const string PolicyAssignmentLocationHelp = "The location of the policy assignment. This is only required when the policy assignment has a resource identity.";
5052

5153
/// <summary>
5254
/// Policy definition cmdlet parameter help strings

src/ResourceManager/Resources/Commands.ResourceManager/Cmdlets/Implementation/Policy/SetAzurePolicyAssignment.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ namespace Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation
2222
using Microsoft.WindowsAzure.Commands.Common;
2323
using Newtonsoft.Json.Linq;
2424
using Policy;
25-
using System;
2625
using System.Collections;
2726
using System.Management.Automation;
27+
using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Entities.Resources;
28+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
2829

2930
/// <summary>
3031
/// Sets the policy assignment.
@@ -91,6 +92,19 @@ public class SetAzurePolicyAssignmentCmdlet : PolicyCmdletBase
9192
[CmdletParameterBreakingChange("Sku", ChangeDescription = "The -Sku parameter is deprecated and ignored")]
9293
public Hashtable Sku { get; set; }
9394

95+
/// <summary>
96+
/// Gets or sets a flag indicating whether a system assigned identity should be added to the policy assignment.
97+
/// </summary>
98+
[Parameter(Mandatory = false, HelpMessage = PolicyHelpStrings.PolicyAssignmentAssignIdentityHelp)]
99+
public SwitchParameter AssignIdentity { get; set; }
100+
101+
/// <summary>
102+
/// Gets or sets the location of the policy assignment. Only required when assigning a resource identity to the assignment.
103+
/// </summary>
104+
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = PolicyHelpStrings.PolicyAssignmentLocationHelp)]
105+
[LocationCompleter("Microsoft.ManagedIdentity/userAssignedIdentities")]
106+
public string Location { get; set; }
107+
94108
/// <summary>
95109
/// Executes the cmdlet.
96110
/// </summary>
@@ -135,6 +149,8 @@ private JToken GetResource(string resourceId, string apiVersion)
135149
{
136150
Name = this.Name ?? resource.Name,
137151
Sku = Sku?.ToDictionary(addValueLayer: false).ToJson().FromJson<PolicySku>(), // only store Sku if it was provided by user
152+
Identity = this.AssignIdentity.IsPresent ? new ResourceIdentity { Type = ResourceIdentityType.SystemAssigned } : null,
153+
Location = this.Location ?? resource.Location,
138154
Properties = new PolicyAssignmentProperties
139155
{
140156
DisplayName = this.DisplayName ?? resource.Properties["displayName"]?.ToString(),
Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
{
2-
"listOfAllowedLocations": {
3-
"type": "array",
4-
"metadata": {
5-
"description": "An array of permitted locations for resources.",
6-
"strongType": "location",
7-
"displayName": "List of locations"
8-
}
2+
"listOfAllowedLocations": {
3+
"type": "array",
4+
"metadata": {
5+
"description": "An array of permitted locations for resources.",
6+
"strongType": "location",
7+
"displayName": "List of locations"
98
}
9+
},
10+
"effectParam": {
11+
"type": "string",
12+
"defaultValue": "Deny",
13+
"allowedValues": [ "Deny", "Disabled" ],
14+
"metadata": {
15+
"description": "The effect of the policy",
16+
"displayName": "Policy Effect"
17+
}
18+
}
1019
}

src/ResourceManager/Resources/Commands.Resources.Test/SamplePolicyDefinitionWithParameters.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
}
77
},
88
"then": {
9-
"effect": "deny"
9+
"effect": "[parameters('effectParam')]"
1010
}
1111
}

src/ResourceManager/Resources/Commands.Resources.Test/ScenarioTests/PolicyTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ public void TestPolicyAssignmentCRUD()
5959
ResourcesController.NewInstance.RunPsTest(_logger, "Test-PolicyAssignmentCRUD");
6060
}
6161

62+
[Fact]
63+
[Trait(Category.AcceptanceType, Category.CheckIn)]
64+
public void TestPolicyAssignmentIdentity()
65+
{
66+
ResourcesController.NewInstance.RunPsTest(_logger, "Test-PolicyAssignmentIdentity");
67+
}
68+
6269
[Fact]
6370
[Trait(Category.AcceptanceType, Category.CheckIn)]
6471
public void TestPolicyDefinitionWithParameters()

0 commit comments

Comments
 (0)