Skip to content

Commit

Permalink
Merge patch v1.39.3 (#3135)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Oct 19, 2024
1 parent 70bdfd9 commit cebf93b
Show file tree
Hide file tree
Showing 13 changed files with 296 additions and 149 deletions.
10 changes: 9 additions & 1 deletion docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,22 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

What's changed since v1.39.2:
What's changed since v1.39.3:

- Engineering:
- Migrated Azure samples into PSRule for Azure by @BernieWhite.
[#3085](https://github.com/Azure/PSRule.Rules.Azure/issues/3085)
- Quality updates to rule documentation by @BernieWhite.
[#3102](https://github.com/Azure/PSRule.Rules.Azure/issues/3102)

## v1.39.3

What's changed since v1.39.2:

- Bug fixes:
- Fixed index out of bounds for existing symbolic name reference by @BernieWhite.
[#3129](https://github.com/Azure/PSRule.Rules.Azure/issues/3129)

## v1.39.2

What's changed since v1.39.1:
Expand Down
3 changes: 3 additions & 0 deletions src/PSRule.Rules.Azure/Data/Template/DeploymentSymbol.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Diagnostics;

namespace PSRule.Rules.Azure.Data.Template;

#nullable enable

[DebuggerDisplay("{Name}")]
internal abstract class DeploymentSymbol(string name)
{
public string Name { get; } = name;
Expand Down
3 changes: 2 additions & 1 deletion src/PSRule.Rules.Azure/Data/Template/TemplateHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using PSRule.Rules.Azure.Configuration;
using PSRule.Rules.Azure.Pipeline;
using PSRule.Rules.Azure.Resources;
using static PSRule.Rules.Azure.Data.Template.TemplateVisitor;

namespace PSRule.Rules.Azure.Data.Template
{
Expand All @@ -25,7 +26,7 @@ public TemplateHelper(PipelineContext context)
_DeploymentName = context.Option.Configuration.Deployment.Name;
}

internal PSObject[] ProcessTemplate(string templateFile, string parameterFile, out TemplateVisitor.TemplateContext templateContext)
internal PSObject[] ProcessTemplate(string templateFile, string parameterFile, out TemplateContext templateContext)
{
var rootedTemplateFile = PSRuleOption.GetRootedPath(templateFile);
if (!File.Exists(rootedTemplateFile))
Expand Down
5 changes: 5 additions & 0 deletions src/PSRule.Rules.Azure/Data/Template/TemplateVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,11 @@ private static void Reference(TemplateContext context, string symbolicName, JObj
if (symbol != null && symbol.Kind == DeploymentSymbolKind.Array)
context.AddSymbol(DeploymentSymbol.NewObject(string.Concat(symbolicName, '[', copyIndex.Index, ']'), r));
}

if (copyIndex.IsCopy())
context.CopyIndex.Pop();

context.AddSymbol(symbol);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Newtonsoft.Json.Linq;

namespace PSRule.Rules.Azure.Bicep.ExtensibilityTestCases;

public sealed class BicepExtensibilityTests : TemplateVisitorTestsBase
{
/// <summary>
/// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/3062
/// </summary>
[Fact]
public void ProcessTemplate_WhenMicrosoftGraphType_ShouldIgnoreExtensibilityResources()
{
var resources = ProcessTemplate(GetSourcePath("Bicep/ExtensibilityTestCases/Tests.Bicep.1.json"), null, out _);

Assert.Single(resources);

var actual = resources[0];
Assert.Equal("Microsoft.Resources/deployments", actual["type"].Value<string>());
Assert.Equal("ps-rule-test-deployment", actual["name"].Value<string>());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Linq;
using Newtonsoft.Json.Linq;

namespace PSRule.Rules.Azure.Bicep.SecretTestCases;

public sealed class BicepSecretTests : TemplateVisitorTestsBase
{
/// <summary>
/// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/2054
/// </summary>
[Fact]
public void ProcessTemplate_WhenConditionalSecretParameter_ShouldReturnSecretsPlaceholders()
{
var resources = ProcessTemplate(GetSourcePath("Bicep/SecretTestCases/Tests.Bicep.1.json"), null, out _);

Assert.NotNull(resources);

var actual = resources.Where(r => r["name"].Value<string>() == "vault1/toSet1").FirstOrDefault();
Assert.Equal("Microsoft.KeyVault/vaults/secrets", actual["type"].Value<string>());
Assert.Equal("{{SecretReference:supersecret1}}", actual["properties"]["value"].Value<string>());

actual = resources.Where(r => r["name"].Value<string>() == "vault1/toSet2").FirstOrDefault();
Assert.Equal("Microsoft.KeyVault/vaults/secrets", actual["type"].Value<string>());
Assert.Equal("placeholder", actual["properties"]["value"].Value<string>());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Newtonsoft.Json.Linq;
using PSRule.Rules.Azure.Data.Template;

namespace PSRule.Rules.Azure.Bicep.SymbolicNameTestCases;

public sealed class BicepSymbolicNameTests : TemplateVisitorTestsBase
{
/// <summary>
/// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/2922
/// </summary>
[Fact]
public void ProcessTemplate_WhenReferencesUsed_ReturnsItems()
{
_ = ProcessTemplate(GetSourcePath("Bicep/SymbolicNameTestCases/Tests.Bicep.1.json"), null, out var templateContext);

Assert.True(templateContext.RootDeployment.TryOutput("items", out JObject output));
var items = output["value"].Value<JArray>();

Assert.Equal("child-0", items[0].Value<string>());
Assert.Equal("child-1", items[1].Value<string>());

Assert.True(templateContext.RootDeployment.TryOutput("itemsAsString", out output));
items = output["value"].Value<JArray>();

Assert.Equal("child-0", items[0].Value<string>());
Assert.Equal("child-1", items[1].Value<string>());
}

/// <summary>
/// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/2917
/// </summary>
[Fact]
public void ProcessTemplate_WhenConditionalExistingReference_IgnoresExpand()
{
var resources = ProcessTemplate(GetSourcePath("Bicep/SymbolicNameTestCases/Tests.Bicep.2.json"), null, out _);

Assert.Equal(3, resources.Length);

var actual = resources[0];
Assert.Equal("Microsoft.Resources/deployments", actual["type"].Value<string>());
Assert.Equal("ps-rule-test-deployment", actual["name"].Value<string>());

actual = resources[1];
Assert.Equal("Microsoft.Resources/deployments", actual["type"].Value<string>());
Assert.Equal("child2", actual["name"].Value<string>());

actual = resources[2];
Assert.Equal("Microsoft.Authorization/roleAssignments", actual["type"].Value<string>());
Assert.Equal("02041802-66a9-0a85-7330-8186e16422c7", actual["name"].Value<string>());
}

/// <summary>
/// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/3123
/// </summary>
[Fact]
public void ProcessTemplate_WhenExistingReferenceNameUsesExpression_ShouldExpandExpression()
{
_ = ProcessTemplate(GetSourcePath("Bicep/SymbolicNameTestCases/Tests.Bicep.3.json"), null, out _);
}

/// <summary>
/// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/3129
/// </summary>
[Fact]
public void ProcessTemplate_WhenExistingReferenceNameUsesExpression_nn()
{
_ = ProcessTemplate(GetSourcePath("Bicep/SymbolicNameTestCases/Tests.Bicep.4.json"), null, out var templateContext);

Assert.True(templateContext.RootDeployment.TryOutput("ids", out JObject output));
var actual = output["value"].Value<JArray>().Values<string>();

Assert.Equal([
"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Web/sites/example1-webapp",
"/subscriptions/ffffffff-ffff-ffff-ffff-ffffffffffff/resourceGroups/ps-rule-test-rg/providers/Microsoft.Web/sites/example2-webapp"
], actual);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/3129
// Contributed by @CharlesToniolo

var names = [
'example1-webapp'
'example2-webapp'
]

resource app 'Microsoft.Web/sites@2022-09-01' existing = [
for name in names: {
name: name
}
]

output ids array = [for i in range(0, length(names)): app[i].id]
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"languageVersion": "2.0",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.30.23.60470",
"templateHash": "845472047423845594"
}
},
"variables": {
"names": [
"example1-webapp",
"example2-webapp"
]
},
"resources": {
"app": {
"copy": {
"name": "app",
"count": "[length(variables('names'))]"
},
"existing": true,
"type": "Microsoft.Web/sites",
"apiVersion": "2022-09-01",
"name": "[variables('names')[copyIndex()]]"
}
},
"outputs": {
"ids": {
"type": "array",
"copy": {
"count": "[length(range(0, length(variables('names'))))]",
"input": "[resourceId('Microsoft.Web/sites', variables('names')[range(0, length(variables('names')))[copyIndex()]])]"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Newtonsoft.Json.Linq;
using PSRule.Rules.Azure.Data.Template;

namespace PSRule.Rules.Azure.Bicep.UserDefinedFunctionTestCases;

public sealed class BicepUserDefinedFunctionTests : TemplateVisitorTestsBase
{
/// <summary>
/// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/3120
/// </summary>
[Fact]
public void ProcessTemplate_WhenUserDefinedFunctionReferencesExportedVariables_ShouldFindVariable()
{
_ = ProcessTemplate(GetSourcePath("Bicep/UserDefinedFunctionTestCases/Tests.Bicep.1.json"), null, out var templateContext);

Assert.True(templateContext.RootDeployment.TryOutput("o1", out JObject o1));
Assert.Equal([2], o1["value"].Values<int>());

Assert.True(templateContext.RootDeployment.TryOutput("o2", out JObject o2));
Assert.Equal([1], o2["value"].Values<int>());

Assert.True(templateContext.RootDeployment.TryOutput("o3", out JObject o3));
Assert.Equal([1], o3["value"].Values<int>());

Assert.True(templateContext.RootDeployment.TryOutput("o4", out JObject o4));
Assert.Equal([2, 1], o4["value"].Values<int>());

Assert.True(templateContext.RootDeployment.TryOutput("o5", out JObject o5));
Assert.Equal([3], o5["value"].Values<int>());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
<None Update="Bicep\SymbolicNameTestCases\Tests.Bicep.2.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Bicep\SymbolicNameTestCases\Tests.Bicep.4.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="environments.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
Loading

0 comments on commit cebf93b

Please sign in to comment.