Skip to content

Commit b7558f3

Browse files
mentat9wyunchi-ms
andauthored
Customer requests on Policy CRUD cmdlets (#14298)
* Breaking changes for policy cmdlets to support typed pipeline objects * Update help files to correspond to typed parameters * Add breaking change exceptions * Remove unneeded usings Update changelog * Add support for policy export format (#13324) * Update changelog * Update help text to cover input file format handling. * Needed to rerecord another test * Fix Set-AzPolicyAssignment input object scenarios * Update changelog Co-authored-by: Yunchi Wang <[email protected]>
1 parent c24e4ca commit b7558f3

File tree

10 files changed

+1463
-847
lines changed

10 files changed

+1463
-847
lines changed

src/Resources/ResourceManager/Implementation/Policy/NewAzurePolicyDefinition.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,12 @@ private JToken GetResource()
145145
};
146146

147147
var policyObject = this.GetObjectFromParameter(this.Policy, nameof(this.Policy));
148+
if (policyObject["properties"] != null)
149+
{
150+
// export-to-Git format includes outer object, we want the property bag
151+
policyObject = (JObject)policyObject["properties"];
152+
}
153+
148154
if (policyObject["policyRule"] != null)
149155
{
150156
// policy parameter was a full policy object, populate the properties from it, override from other command line parameters

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

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -168,29 +168,46 @@ private JToken GetResource(string resourceId, string apiVersion)
168168
{
169169
var resource = this.GetExistingResource(resourceId, apiVersion).Result.ToResource();
170170

171-
var metaDataJson = string.IsNullOrEmpty(this.Metadata) ? resource.Properties["metadata"]?.ToString() : this.GetObjectFromParameter(this.Metadata, nameof(this.Metadata)).ToString();
171+
// get incoming object properties if present
172+
JObject inputMetadata = null;
173+
if (this.InputObject != null)
174+
{
175+
var newProperties = this.InputObject.Properties.ToJToken();
176+
inputMetadata = newProperties["metadata"] as JObject;
177+
}
178+
179+
var parameterMetadata = this.Metadata != null ? this.GetObjectFromParameter(this.Metadata, nameof(this.Metadata)) : null;
172180

173181
PolicyAssignmentEnforcementMode? existingMode = null;
174182
if (Enum.TryParse(resource.Properties["enforcementMode"]?.ToString(), true, out PolicyAssignmentEnforcementMode tempMode))
175183
{
176184
existingMode = tempMode;
177185
}
178186

187+
PolicyAssignmentEnforcementMode? inputMode = null;
188+
if (Enum.TryParse(this.InputObject?.Properties?.EnforcementMode?.ToString(), true, out PolicyAssignmentEnforcementMode tempMode1))
189+
{
190+
inputMode = tempMode1;
191+
}
192+
179193
var policyAssignmentObject = new PolicyAssignment
180194
{
181-
Name = this.Name ?? resource.Name,
195+
Name = this.Name ?? this?.InputObject?.Name ?? resource.Name,
182196
Identity = this.AssignIdentity.IsPresent ? new ResourceIdentity { Type = ResourceIdentityType.SystemAssigned } : null,
183-
Location = this.Location ?? resource.Location,
197+
Location = this.Location ?? this.InputObject?.Location ?? resource.Location,
184198
Properties = new PolicyAssignmentProperties
185199
{
186-
DisplayName = this.DisplayName ?? resource.Properties["displayName"]?.ToString(),
187-
Description = this.Description ?? resource.Properties["description"]?.ToString(),
188-
Scope = resource.Properties["scope"].ToString(),
189-
NotScopes = this.NotScope ?? resource.Properties["NotScopes"]?.ToString().Split(','),
190-
PolicyDefinitionId = resource.Properties["policyDefinitionId"].ToString(),
191-
Metadata = string.IsNullOrEmpty(this.Metadata) ? null : JObject.Parse(metaDataJson),
192-
EnforcementMode = this.EnforcementMode ?? existingMode,
193-
Parameters = this.GetParameters(this.PolicyParameter, this.PolicyParameterObject) ?? (JObject)resource.Properties["parameters"]
200+
DisplayName = this.DisplayName ?? this?.InputObject?.Properties?.DisplayName ?? resource.Properties["displayName"]?.ToString(),
201+
Description = this.Description ?? this?.InputObject?.Properties?.Description ?? resource.Properties["description"]?.ToString(),
202+
Scope = resource.Properties["scope"]?.ToString(),
203+
NotScopes = this.NotScope ?? this?.InputObject?.Properties?.NotScopes ?? resource.Properties["NotScopes"]?.ToString()?.Split(','),
204+
PolicyDefinitionId = resource.Properties["policyDefinitionId"]?.ToString(),
205+
Metadata = parameterMetadata ?? inputMetadata ?? resource.Properties["metadata"] as JObject,
206+
EnforcementMode = this.EnforcementMode ?? inputMode ?? existingMode,
207+
Parameters =
208+
this.GetParameters(this.PolicyParameter, this.PolicyParameterObject)
209+
?? this.InputObject?.Properties?.Parameters?.ToResourcePropertiesBody() as JObject
210+
?? resource.Properties["parameters"] as JObject
194211
}
195212
};
196213

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
{
2+
"properties": {
3+
"displayName": "SqlTest",
4+
"policyType": "Custom",
5+
"mode": "All",
6+
"description": "Policy borrowed from Contoso Infra1 subscription to test evaluation on Microsoft.Sql/servers/databases resource type",
7+
"metadata": {
8+
"category": "SQL",
9+
"createdBy": "3d826307-2481-45a0-a271-bcf9333f914a",
10+
"createdOn": "2020-08-12T21:47:47.0192865Z",
11+
"updatedBy": null,
12+
"updatedOn": null
13+
},
14+
"parameters": {
15+
"logAnalytics": {
16+
"type": "String",
17+
"metadata": {
18+
"displayName": "Log Analyitcs workspace",
19+
"description": "Select the Log Analytics workspace from dropdown list",
20+
"strongType": "omsWorkspace"
21+
}
22+
}
23+
},
24+
"policyRule": {
25+
"if": {
26+
"field": "type",
27+
"equals": "Microsoft.Sql/servers/databases"
28+
},
29+
"then": {
30+
"effect": "deployIfNotExists",
31+
"details": {
32+
"type": "Microsoft.Insights/diagnosticSettings",
33+
"name": "setByPolicy",
34+
"roleDefinitionIds": [
35+
"/providers/microsoft.authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa",
36+
"/providers/microsoft.authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293"
37+
],
38+
"deployment": {
39+
"properties": {
40+
"mode": "incremental",
41+
"template": {
42+
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
43+
"contentVersion": "1.0.0.0",
44+
"parameters": {
45+
"sqlName": {
46+
"type": "string"
47+
},
48+
"databaseName": {
49+
"type": "string",
50+
"metadata": {
51+
"description": "Name of the SQL database to create"
52+
}
53+
},
54+
"logAnalytics": {
55+
"type": "string"
56+
},
57+
"location": {
58+
"type": "string"
59+
}
60+
},
61+
"variables": {},
62+
"resources": [
63+
{
64+
"type": "Microsoft.Sql/servers/databases/providers/diagnosticSettings",
65+
"apiVersion": "2017-05-01-preview",
66+
"name": "[concat(parameters('sqlName'), '/', parameters('databaseName'), '/', 'Microsoft.Insights/setByPolicy')]",
67+
"location": "[parameters('location')]",
68+
"dependsOn": [],
69+
"properties": {
70+
"workspaceId": "[parameters('logAnalytics')]",
71+
"metrics": [
72+
{
73+
"timeGrain": "PT1M",
74+
"enabled": true,
75+
"retentionPolicy": {
76+
"enabled": false,
77+
"days": 0
78+
}
79+
}
80+
],
81+
"logs": [
82+
{
83+
"category": "QueryStoreRuntimeStatistics",
84+
"enabled": true
85+
},
86+
{
87+
"category": "QueryStoreWaitStatistics",
88+
"enabled": true
89+
},
90+
{
91+
"category": "Errors",
92+
"enabled": true
93+
},
94+
{
95+
"category": "DatabaseWaitStatistics",
96+
"enabled": true
97+
},
98+
{
99+
"category": "Blocks",
100+
"enabled": true
101+
},
102+
{
103+
"category": "SQLInsights",
104+
"enabled": true
105+
},
106+
{
107+
"category": "Audit",
108+
"enabled": true
109+
},
110+
{
111+
"category": "SQLSecurityAuditEvents",
112+
"enabled": true
113+
},
114+
{
115+
"category": "Timeouts",
116+
"enabled": true
117+
}
118+
]
119+
}
120+
}
121+
],
122+
"outputs": {}
123+
},
124+
"parameters": {
125+
"logAnalytics": {
126+
"value": "[parameters('logAnalytics')]"
127+
},
128+
"location": {
129+
"value": "[field('location')]"
130+
},
131+
"databaseName": {
132+
"value": "[field('name')]"
133+
}
134+
}
135+
}
136+
}
137+
}
138+
}
139+
}
140+
},
141+
"id": "/subscriptions/885cd661-f134-4585-9242-584ebe226794/providers/Microsoft.Authorization/policyDefinitions/fdd1d4d3-6c90-4efc-91e6-7476b7eb1372",
142+
"type": "Microsoft.Authorization/policyDefinitions",
143+
"name": "fdd1d4d3-6c90-4efc-91e6-7476b7eb1372"
144+
}

src/Resources/Resources.Test/SamplePolicyDefinitionObject.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"parameters": {
2525
"listOfAllowedLocations": {
2626
"type": "array",
27-
"defaultValue": ["somewhere"],
27+
"defaultValue": ["westus"],
2828
"metadata": {
2929
"description": "An array of permitted locations for resources.",
3030
"strongType": "location",

src/Resources/Resources.Test/ScenarioTests/PolicyTests.ps1

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,25 @@ function Test-PolicyDefinitionCRUD
6767
$builtIns = $list | Where-Object { $_.Properties.policyType -ieq 'BuiltIn' }
6868
Assert-True { $builtIns.Count -eq 0 }
6969

70+
# make a policy definition from export format, get it back and validate
71+
$expected = New-AzPolicyDefinition -Name test3 -Policy "$TestOutputRoot\SamplePolicyDefinitionFromExport.json" -Description $description
72+
$actual = Get-AzPolicyDefinition -Name test3
73+
Assert-NotNull $actual
74+
Assert-AreEqual $expected.Name $actual.Name
75+
Assert-AreEqual $expected.PolicyDefinitionId $actual.PolicyDefinitionId
76+
Assert-NotNull($actual.Properties.PolicyRule)
77+
Assert-AreEqual $expected.Properties.Mode $actual.Properties.Mode
78+
Assert-AreEqual $expected.Properties.Description $actual.Properties.Description
79+
7080
# clean up
7181
$remove = Remove-AzPolicyDefinition -Name $policyName -Force
7282
Assert-AreEqual True $remove
7383

7484
$remove = Remove-AzPolicyDefinition -Name 'test2' -Force
7585
Assert-AreEqual True $remove
86+
87+
$remove = Remove-AzPolicyDefinition -Name 'test3' -Force
88+
Assert-AreEqual True $remove
7689
}
7790

7891
<#
@@ -1117,33 +1130,59 @@ function Test-PolicyObjectPiping
11171130
$policySetDefName = Get-ResourceName
11181131
$policyDefName = Get-ResourceName
11191132
$policyAssName = Get-ResourceName
1120-
$subscriptionId = (Get-AzureRmContext).Subscription.Id
1133+
$subscriptionId = (Get-AzContext).Subscription.Id
1134+
$array = @("westus", "eastus")
11211135

11221136
# make a policy definition and policy set definition that references it
1123-
$policyDefinition = New-AzureRmPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId -Policy "$TestOutputRoot\SamplePolicyDefinition.json" -Description $description
1137+
$policyDefinition = New-AzPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId -Policy "$TestOutputRoot\SamplePolicyDefinitionObject.json" -Description $description
11241138
$policySet = "[{""policyDefinitionId"":""" + $policyDefinition.PolicyDefinitionId + """}]"
1125-
$expected = New-AzureRmPolicySetDefinition -Name $policySetDefName -SubscriptionId $subscriptionId -PolicyDefinition $policySet -Description $description
1139+
$expected = New-AzPolicySetDefinition -Name $policySetDefName -SubscriptionId $subscriptionId -PolicyDefinition $policySet -Description $description
11261140

1127-
# make a policy assignment by piping the policy definition to New-AzureRmPolicyAssignment
1128-
$rg = New-AzureRmResourceGroup -Name $rgname -Location "west us"
1141+
# make a policy assignment by piping the policy definition to New-AzPolicyAssignment
1142+
$rg = New-AzResourceGroup -Name $rgname -Location "west us"
11291143

11301144
# assign the policy definition to the resource group, get the assignment back and validate
1131-
$actual = Get-AzureRmPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId | New-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId -Description $description
1132-
$expected = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
1145+
$actual = Get-AzPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId | New-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId -PolicyParameterObject @{'listOfAllowedLocations'=@('westus', 'eastus'); 'effectParam'='Deny'} -Description $description
1146+
$expected = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
11331147
Assert-AreEqual $expected.Name $actual.Name
11341148
Assert-AreEqual Microsoft.Authorization/policyAssignments $actual.ResourceType
11351149
Assert-NotNull $actual.Properties.PolicyDefinitionId
11361150
Assert-NotNull $expected.Properties.PolicyDefinitionId
11371151
Assert-AreEqual $expected.PolicyAssignmentId $actual.PolicyAssignmentId
11381152
Assert-AreEqual $expected.Properties.PolicyDefinitionId $actual.Properties.PolicyDefinitionId
11391153
Assert-AreEqual $expected.Properties.Scope $rg.ResourceId
1154+
Assert-NotNull $expected.Properties.Parameters.listOfAllowedLocations
1155+
Assert-NotNull $expected.Properties.Parameters.listOfAllowedLocations.value
1156+
Assert-NotNull $expected.Properties.Parameters.effectParam
1157+
Assert-AreEqual 2 $expected.Properties.Parameters.listOfAllowedLocations.value.Length
1158+
Assert-AreEqual "westus" $expected.Properties.Parameters.listOfAllowedLocations.value[0]
1159+
Assert-AreEqual "eastus" $expected.Properties.Parameters.listOfAllowedLocations.value[1]
1160+
Assert-AreEqual "deny" $expected.Properties.Parameters.effectParam.value
1161+
1162+
# update some properties, including parameters
1163+
$assignment = Get-AzPolicyAssignment -Id $actual.ResourceId
1164+
$assignment.Properties.Parameters.effectParam.value = "Disabled"
1165+
$assignment.Properties.Parameters.listOfAllowedLocations.value = @("eastus")
1166+
$assignment.Properties.Description = $updatedDescription
1167+
$assignment | Set-AzPolicyAssignment
1168+
1169+
# get it back and validate the new values
1170+
$assignment = Get-AzPolicyAssignment -Id $actual.ResourceId
1171+
Assert-NotNull $assignment.Properties.Parameters.listOfAllowedLocations
1172+
Assert-NotNull $assignment.Properties.Parameters.effectParam
1173+
Assert-NotNull $assignment.Properties.Parameters.listOfAllowedLocations.value
1174+
Assert-AreEqual 1 $assignment.Properties.Parameters.listOfAllowedLocations.value.Length
1175+
Assert-AreEqual "eastus" $assignment.Properties.Parameters.listOfAllowedLocations.value[0]
1176+
Assert-AreEqual "disabled" $assignment.Properties.Parameters.effectParam.value
1177+
Assert-AreEqual $updatedDescription $assignment.Properties.Description
1178+
11401179
# delete the policy assignment
1141-
$remove = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Remove-AzureRmPolicyAssignment
1180+
$remove = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Remove-AzPolicyAssignment
11421181
Assert-AreEqual True $remove
11431182

11441183
# assign the policy set definition to the resource group, get the assignment back and validate
1145-
$actual = Get-AzureRmPolicySetDefinition -Name $policySetDefName -SubscriptionId $subscriptionId | New-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId -Description $description
1146-
$expected = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
1184+
$actual = Get-AzPolicySetDefinition -Name $policySetDefName -SubscriptionId $subscriptionId | New-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId -Description $description
1185+
$expected = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
11471186
Assert-AreEqual $expected.Name $actual.Name
11481187
Assert-AreEqual Microsoft.Authorization/policyAssignments $actual.ResourceType
11491188
Assert-NotNull $actual.Properties.PolicyDefinitionId
@@ -1153,8 +1192,8 @@ function Test-PolicyObjectPiping
11531192
Assert-AreEqual $expected.Properties.Scope $rg.ResourceId
11541193

11551194
# update the policy definition
1156-
$actual = Get-AzureRmPolicyDefinition -Name $policyDefName | Set-AzureRmPolicyDefinition -Description $updatedDescription
1157-
$expected = Get-AzureRmPolicyDefinition -Name $policyDefName
1195+
$actual = Get-AzPolicyDefinition -Name $policyDefName | Set-AzPolicyDefinition -Description $updatedDescription
1196+
$expected = Get-AzPolicyDefinition -Name $policyDefName
11581197
Assert-AreEqual $policyDefName $expected.Name
11591198
Assert-AreEqual $expected.Name $actual.Name
11601199
Assert-AreEqual $expected.ResourceName $actual.ResourceName
@@ -1166,8 +1205,8 @@ function Test-PolicyObjectPiping
11661205
Assert-AreEqual $updatedDescription $expected.Properties.Description
11671206

11681207
# update the policy set definition
1169-
$actual = Get-AzureRmPolicySetDefinition -Name $policySetDefName | Set-AzureRmPolicySetDefinition -Description $updatedDescription
1170-
$expected = Get-AzureRmPolicySetDefinition -Name $policySetDefName
1208+
$actual = Get-AzPolicySetDefinition -Name $policySetDefName | Set-AzPolicySetDefinition -Description $updatedDescription
1209+
$expected = Get-AzPolicySetDefinition -Name $policySetDefName
11711210
Assert-AreEqual $policySetDefName $expected.Name
11721211
Assert-AreEqual $expected.Name $actual.Name
11731212
Assert-AreEqual $expected.ResourceName $actual.ResourceName
@@ -1179,8 +1218,8 @@ function Test-PolicyObjectPiping
11791218
Assert-AreEqual $updatedDescription $expected.Properties.Description
11801219

11811220
# update the policy assignment
1182-
$actual = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Set-AzureRmPolicyAssignment -Description $updatedDescription
1183-
$expected = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
1221+
$actual = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Set-AzPolicyAssignment -Description $updatedDescription
1222+
$expected = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
11841223
Assert-AreEqual $expected.Name $actual.Name
11851224
Assert-AreEqual Microsoft.Authorization/policyAssignments $actual.ResourceType
11861225
Assert-AreEqual $expected.ResourceType $actual.ResourceType
@@ -1193,16 +1232,16 @@ function Test-PolicyObjectPiping
11931232
Assert-AreEqual $updatedDescription $expected.Properties.Description
11941233

11951234
# clean up
1196-
$remove = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Remove-AzureRmPolicyAssignment
1235+
$remove = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Remove-AzPolicyAssignment
11971236
Assert-AreEqual True $remove
11981237

1199-
$remove = Remove-AzureRmResourceGroup -Name $rgname -Force
1238+
$remove = Remove-AzResourceGroup -Name $rgname -Force
12001239
Assert-AreEqual True $remove
12011240

1202-
$remove = Get-AzureRmPolicySetDefinition -Name $policySetDefName -SubscriptionId $subscriptionId | Remove-AzureRmPolicySetDefinition -Force
1241+
$remove = Get-AzPolicySetDefinition -Name $policySetDefName -SubscriptionId $subscriptionId | Remove-AzPolicySetDefinition -Force
12031242
Assert-AreEqual True $remove
12041243

1205-
$remove = Get-AzureRmPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId | Remove-AzureRmPolicyDefinition -Force
1244+
$remove = Get-AzPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId | Remove-AzPolicyDefinition -Force
12061245
Assert-AreEqual True $remove
12071246
}
12081247

0 commit comments

Comments
 (0)