Skip to content

Customer requests on Policy CRUD cmdlets #14298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ private JToken GetResource()
};

var policyObject = this.GetObjectFromParameter(this.Policy, nameof(this.Policy));
if (policyObject["properties"] != null)
{
// export-to-Git format includes outer object, we want the property bag
policyObject = (JObject)policyObject["properties"];
}

if (policyObject["policyRule"] != null)
{
// policy parameter was a full policy object, populate the properties from it, override from other command line parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,29 +168,46 @@ private JToken GetResource(string resourceId, string apiVersion)
{
var resource = this.GetExistingResource(resourceId, apiVersion).Result.ToResource();

var metaDataJson = string.IsNullOrEmpty(this.Metadata) ? resource.Properties["metadata"]?.ToString() : this.GetObjectFromParameter(this.Metadata, nameof(this.Metadata)).ToString();
// get incoming object properties if present
JObject inputMetadata = null;
if (this.InputObject != null)
{
var newProperties = this.InputObject.Properties.ToJToken();
inputMetadata = newProperties["metadata"] as JObject;
}

var parameterMetadata = this.Metadata != null ? this.GetObjectFromParameter(this.Metadata, nameof(this.Metadata)) : null;

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

PolicyAssignmentEnforcementMode? inputMode = null;
if (Enum.TryParse(this.InputObject?.Properties?.EnforcementMode?.ToString(), true, out PolicyAssignmentEnforcementMode tempMode1))
{
inputMode = tempMode1;
}

var policyAssignmentObject = new PolicyAssignment
{
Name = this.Name ?? resource.Name,
Name = this.Name ?? this?.InputObject?.Name ?? resource.Name,
Identity = this.AssignIdentity.IsPresent ? new ResourceIdentity { Type = ResourceIdentityType.SystemAssigned } : null,
Location = this.Location ?? resource.Location,
Location = this.Location ?? this.InputObject?.Location ?? resource.Location,
Properties = new PolicyAssignmentProperties
{
DisplayName = this.DisplayName ?? resource.Properties["displayName"]?.ToString(),
Description = this.Description ?? resource.Properties["description"]?.ToString(),
Scope = resource.Properties["scope"].ToString(),
NotScopes = this.NotScope ?? resource.Properties["NotScopes"]?.ToString().Split(','),
PolicyDefinitionId = resource.Properties["policyDefinitionId"].ToString(),
Metadata = string.IsNullOrEmpty(this.Metadata) ? null : JObject.Parse(metaDataJson),
EnforcementMode = this.EnforcementMode ?? existingMode,
Parameters = this.GetParameters(this.PolicyParameter, this.PolicyParameterObject) ?? (JObject)resource.Properties["parameters"]
DisplayName = this.DisplayName ?? this?.InputObject?.Properties?.DisplayName ?? resource.Properties["displayName"]?.ToString(),
Description = this.Description ?? this?.InputObject?.Properties?.Description ?? resource.Properties["description"]?.ToString(),
Scope = resource.Properties["scope"]?.ToString(),
NotScopes = this.NotScope ?? this?.InputObject?.Properties?.NotScopes ?? resource.Properties["NotScopes"]?.ToString()?.Split(','),
PolicyDefinitionId = resource.Properties["policyDefinitionId"]?.ToString(),
Metadata = parameterMetadata ?? inputMetadata ?? resource.Properties["metadata"] as JObject,
EnforcementMode = this.EnforcementMode ?? inputMode ?? existingMode,
Parameters =
this.GetParameters(this.PolicyParameter, this.PolicyParameterObject)
?? this.InputObject?.Properties?.Parameters?.ToResourcePropertiesBody() as JObject
?? resource.Properties["parameters"] as JObject
}
};

Expand Down
144 changes: 144 additions & 0 deletions src/Resources/Resources.Test/SamplePolicyDefinitionFromExport.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
{
"properties": {
"displayName": "SqlTest",
"policyType": "Custom",
"mode": "All",
"description": "Policy borrowed from Contoso Infra1 subscription to test evaluation on Microsoft.Sql/servers/databases resource type",
"metadata": {
"category": "SQL",
"createdBy": "3d826307-2481-45a0-a271-bcf9333f914a",
"createdOn": "2020-08-12T21:47:47.0192865Z",
"updatedBy": null,
"updatedOn": null
},
"parameters": {
"logAnalytics": {
"type": "String",
"metadata": {
"displayName": "Log Analyitcs workspace",
"description": "Select the Log Analytics workspace from dropdown list",
"strongType": "omsWorkspace"
}
}
},
"policyRule": {
"if": {
"field": "type",
"equals": "Microsoft.Sql/servers/databases"
},
"then": {
"effect": "deployIfNotExists",
"details": {
"type": "Microsoft.Insights/diagnosticSettings",
"name": "setByPolicy",
"roleDefinitionIds": [
"/providers/microsoft.authorization/roleDefinitions/749f88d5-cbae-40b8-bcfc-e573ddc772fa",
"/providers/microsoft.authorization/roleDefinitions/92aaf0da-9dab-42b6-94a3-d43ce8d16293"
],
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"sqlName": {
"type": "string"
},
"databaseName": {
"type": "string",
"metadata": {
"description": "Name of the SQL database to create"
}
},
"logAnalytics": {
"type": "string"
},
"location": {
"type": "string"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Sql/servers/databases/providers/diagnosticSettings",
"apiVersion": "2017-05-01-preview",
"name": "[concat(parameters('sqlName'), '/', parameters('databaseName'), '/', 'Microsoft.Insights/setByPolicy')]",
"location": "[parameters('location')]",
"dependsOn": [],
"properties": {
"workspaceId": "[parameters('logAnalytics')]",
"metrics": [
{
"timeGrain": "PT1M",
"enabled": true,
"retentionPolicy": {
"enabled": false,
"days": 0
}
}
],
"logs": [
{
"category": "QueryStoreRuntimeStatistics",
"enabled": true
},
{
"category": "QueryStoreWaitStatistics",
"enabled": true
},
{
"category": "Errors",
"enabled": true
},
{
"category": "DatabaseWaitStatistics",
"enabled": true
},
{
"category": "Blocks",
"enabled": true
},
{
"category": "SQLInsights",
"enabled": true
},
{
"category": "Audit",
"enabled": true
},
{
"category": "SQLSecurityAuditEvents",
"enabled": true
},
{
"category": "Timeouts",
"enabled": true
}
]
}
}
],
"outputs": {}
},
"parameters": {
"logAnalytics": {
"value": "[parameters('logAnalytics')]"
},
"location": {
"value": "[field('location')]"
},
"databaseName": {
"value": "[field('name')]"
}
}
}
}
}
}
}
},
"id": "/subscriptions/885cd661-f134-4585-9242-584ebe226794/providers/Microsoft.Authorization/policyDefinitions/fdd1d4d3-6c90-4efc-91e6-7476b7eb1372",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "fdd1d4d3-6c90-4efc-91e6-7476b7eb1372"
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"parameters": {
"listOfAllowedLocations": {
"type": "array",
"defaultValue": ["somewhere"],
"defaultValue": ["westus"],
"metadata": {
"description": "An array of permitted locations for resources.",
"strongType": "location",
Expand Down
79 changes: 59 additions & 20 deletions src/Resources/Resources.Test/ScenarioTests/PolicyTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,25 @@ function Test-PolicyDefinitionCRUD
$builtIns = $list | Where-Object { $_.Properties.policyType -ieq 'BuiltIn' }
Assert-True { $builtIns.Count -eq 0 }

# make a policy definition from export format, get it back and validate
$expected = New-AzPolicyDefinition -Name test3 -Policy "$TestOutputRoot\SamplePolicyDefinitionFromExport.json" -Description $description
$actual = Get-AzPolicyDefinition -Name test3
Assert-NotNull $actual
Assert-AreEqual $expected.Name $actual.Name
Assert-AreEqual $expected.PolicyDefinitionId $actual.PolicyDefinitionId
Assert-NotNull($actual.Properties.PolicyRule)
Assert-AreEqual $expected.Properties.Mode $actual.Properties.Mode
Assert-AreEqual $expected.Properties.Description $actual.Properties.Description

# clean up
$remove = Remove-AzPolicyDefinition -Name $policyName -Force
Assert-AreEqual True $remove

$remove = Remove-AzPolicyDefinition -Name 'test2' -Force
Assert-AreEqual True $remove

$remove = Remove-AzPolicyDefinition -Name 'test3' -Force
Assert-AreEqual True $remove
}

<#
Expand Down Expand Up @@ -1117,33 +1130,59 @@ function Test-PolicyObjectPiping
$policySetDefName = Get-ResourceName
$policyDefName = Get-ResourceName
$policyAssName = Get-ResourceName
$subscriptionId = (Get-AzureRmContext).Subscription.Id
$subscriptionId = (Get-AzContext).Subscription.Id
$array = @("westus", "eastus")

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

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

# assign the policy definition to the resource group, get the assignment back and validate
$actual = Get-AzureRmPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId | New-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId -Description $description
$expected = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
$actual = Get-AzPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId | New-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId -PolicyParameterObject @{'listOfAllowedLocations'=@('westus', 'eastus'); 'effectParam'='Deny'} -Description $description
$expected = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
Assert-AreEqual $expected.Name $actual.Name
Assert-AreEqual Microsoft.Authorization/policyAssignments $actual.ResourceType
Assert-NotNull $actual.Properties.PolicyDefinitionId
Assert-NotNull $expected.Properties.PolicyDefinitionId
Assert-AreEqual $expected.PolicyAssignmentId $actual.PolicyAssignmentId
Assert-AreEqual $expected.Properties.PolicyDefinitionId $actual.Properties.PolicyDefinitionId
Assert-AreEqual $expected.Properties.Scope $rg.ResourceId
Assert-NotNull $expected.Properties.Parameters.listOfAllowedLocations
Assert-NotNull $expected.Properties.Parameters.listOfAllowedLocations.value
Assert-NotNull $expected.Properties.Parameters.effectParam
Assert-AreEqual 2 $expected.Properties.Parameters.listOfAllowedLocations.value.Length
Assert-AreEqual "westus" $expected.Properties.Parameters.listOfAllowedLocations.value[0]
Assert-AreEqual "eastus" $expected.Properties.Parameters.listOfAllowedLocations.value[1]
Assert-AreEqual "deny" $expected.Properties.Parameters.effectParam.value

# update some properties, including parameters
$assignment = Get-AzPolicyAssignment -Id $actual.ResourceId
$assignment.Properties.Parameters.effectParam.value = "Disabled"
$assignment.Properties.Parameters.listOfAllowedLocations.value = @("eastus")
$assignment.Properties.Description = $updatedDescription
$assignment | Set-AzPolicyAssignment

# get it back and validate the new values
$assignment = Get-AzPolicyAssignment -Id $actual.ResourceId
Assert-NotNull $assignment.Properties.Parameters.listOfAllowedLocations
Assert-NotNull $assignment.Properties.Parameters.effectParam
Assert-NotNull $assignment.Properties.Parameters.listOfAllowedLocations.value
Assert-AreEqual 1 $assignment.Properties.Parameters.listOfAllowedLocations.value.Length
Assert-AreEqual "eastus" $assignment.Properties.Parameters.listOfAllowedLocations.value[0]
Assert-AreEqual "disabled" $assignment.Properties.Parameters.effectParam.value
Assert-AreEqual $updatedDescription $assignment.Properties.Description

# delete the policy assignment
$remove = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Remove-AzureRmPolicyAssignment
$remove = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Remove-AzPolicyAssignment
Assert-AreEqual True $remove

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

# update the policy definition
$actual = Get-AzureRmPolicyDefinition -Name $policyDefName | Set-AzureRmPolicyDefinition -Description $updatedDescription
$expected = Get-AzureRmPolicyDefinition -Name $policyDefName
$actual = Get-AzPolicyDefinition -Name $policyDefName | Set-AzPolicyDefinition -Description $updatedDescription
$expected = Get-AzPolicyDefinition -Name $policyDefName
Assert-AreEqual $policyDefName $expected.Name
Assert-AreEqual $expected.Name $actual.Name
Assert-AreEqual $expected.ResourceName $actual.ResourceName
Expand All @@ -1166,8 +1205,8 @@ function Test-PolicyObjectPiping
Assert-AreEqual $updatedDescription $expected.Properties.Description

# update the policy set definition
$actual = Get-AzureRmPolicySetDefinition -Name $policySetDefName | Set-AzureRmPolicySetDefinition -Description $updatedDescription
$expected = Get-AzureRmPolicySetDefinition -Name $policySetDefName
$actual = Get-AzPolicySetDefinition -Name $policySetDefName | Set-AzPolicySetDefinition -Description $updatedDescription
$expected = Get-AzPolicySetDefinition -Name $policySetDefName
Assert-AreEqual $policySetDefName $expected.Name
Assert-AreEqual $expected.Name $actual.Name
Assert-AreEqual $expected.ResourceName $actual.ResourceName
Expand All @@ -1179,8 +1218,8 @@ function Test-PolicyObjectPiping
Assert-AreEqual $updatedDescription $expected.Properties.Description

# update the policy assignment
$actual = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Set-AzureRmPolicyAssignment -Description $updatedDescription
$expected = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
$actual = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Set-AzPolicyAssignment -Description $updatedDescription
$expected = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId
Assert-AreEqual $expected.Name $actual.Name
Assert-AreEqual Microsoft.Authorization/policyAssignments $actual.ResourceType
Assert-AreEqual $expected.ResourceType $actual.ResourceType
Expand All @@ -1193,16 +1232,16 @@ function Test-PolicyObjectPiping
Assert-AreEqual $updatedDescription $expected.Properties.Description

# clean up
$remove = Get-AzureRmPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Remove-AzureRmPolicyAssignment
$remove = Get-AzPolicyAssignment -Name $policyAssName -Scope $rg.ResourceId | Remove-AzPolicyAssignment
Assert-AreEqual True $remove

$remove = Remove-AzureRmResourceGroup -Name $rgname -Force
$remove = Remove-AzResourceGroup -Name $rgname -Force
Assert-AreEqual True $remove

$remove = Get-AzureRmPolicySetDefinition -Name $policySetDefName -SubscriptionId $subscriptionId | Remove-AzureRmPolicySetDefinition -Force
$remove = Get-AzPolicySetDefinition -Name $policySetDefName -SubscriptionId $subscriptionId | Remove-AzPolicySetDefinition -Force
Assert-AreEqual True $remove

$remove = Get-AzureRmPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId | Remove-AzureRmPolicyDefinition -Force
$remove = Get-AzPolicyDefinition -Name $policyDefName -SubscriptionId $subscriptionId | Remove-AzPolicyDefinition -Force
Assert-AreEqual True $remove
}

Expand Down
Loading