Skip to content

Commit

Permalink
Merge patch v1.39.2 (#3128)
Browse files Browse the repository at this point in the history
* Fixes UDF reference to exported variable #3120 (#3125)

* Fixes name expand of existing resource references #3123 (#3126)

* Release v1.39.2 (#3127)
  • Loading branch information
BernieWhite authored Oct 16, 2024
1 parent a3c6ae5 commit ab90306
Show file tree
Hide file tree
Showing 14 changed files with 310 additions and 38 deletions.
12 changes: 11 additions & 1 deletion docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,24 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

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

- 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.2

What's changed since v1.39.1:

- Bug fixes:
- Fixed user-defined function reference to exported variable by @BernieWhite.
[#3120](https://github.com/Azure/PSRule.Rules.Azure/issues/3120)
- Fixed name expand of existing resource references by @BernieWhite.
[#3123](https://github.com/Azure/PSRule.Rules.Azure/issues/3123)

## v1.39.1

What's changed since v1.39.0:
Expand Down
8 changes: 3 additions & 5 deletions src/PSRule.Rules.Azure/Data/Template/ExistingResourceValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ public string Name
/// <returns></returns>
private string GetId()
{
if (!Value.TryResourceScope(_Context, out var scopeId))
throw new TemplateSymbolException(SymbolicName);
if (!Value.TryResourceScope(_Context, out var scopeId)) throw new TemplateSymbolException(SymbolicName);

return _Id = ResourceHelper.ResourceId(Type, Name, scopeId);
}
Expand All @@ -81,10 +80,9 @@ private string GetId()
/// </summary>
private string GetName()
{
if (!Value.TryResourceName(out var name) || string.IsNullOrEmpty(name))
throw new TemplateSymbolException(SymbolicName);
if (!Value.TryResourceName(out var name) || string.IsNullOrEmpty(name)) throw new TemplateSymbolException(SymbolicName);

return _Name = name.IsExpressionString() ? name.ToString() : name;
return _Name = ExpandString(_Context, name);
}
}

Expand Down
32 changes: 0 additions & 32 deletions src/PSRule.Rules.Azure/Data/Template/TemplateVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -769,37 +769,6 @@ internal void TrackDependencies(IResourceValue resource, string[] dependencies)
}
}

internal sealed class UserDefinedFunctionContext : NestedTemplateContext
{
private readonly Dictionary<string, object> _Parameters;

public UserDefinedFunctionContext(ITemplateContext context)
: base(context)
{
_Parameters = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
}

public override bool TryParameter(string parameterName, out object value)
{
return _Parameters.TryGetValue(parameterName, out value);
}

public override bool TryVariable(string variableName, out object value)
{
value = null;
return false;
}

internal void SetParameters(JObject[] parameters, object[] args)
{
if (parameters == null || parameters.Length == 0 || args == null || args.Length == 0)
return;

for (var i = 0; i < parameters.Length; i++)
_Parameters.Add(parameters[i]["name"].Value<string>(), args[i]);
}
}

internal interface IParameterValue
{
string Name { get; }
Expand Down Expand Up @@ -1169,7 +1138,6 @@ protected virtual void Function(TemplateContext context, string ns, string name,
return;

TryArrayProperty(function, PROPERTY_PARAMETERS, out var parameters);
//var outputFn = context.Expression.Build(outputValue);
ExpressionFn fn = (ctx, args) =>
{
var fnContext = new UserDefinedFunctionContext(ctx);
Expand Down
48 changes: 48 additions & 0 deletions src/PSRule.Rules.Azure/Data/Template/UserDefinedFunctionContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;

namespace PSRule.Rules.Azure.Data.Template;

#nullable enable

/// <summary>
/// A nested context for user-defined functions.
/// </summary>
/// <param name="context">The parent <see cref="ITemplateContext"/> context.</param>
internal sealed class UserDefinedFunctionContext(ITemplateContext context) : NestedTemplateContext(context)
{
private const string PROPERTY_NAME = "name";

private readonly Dictionary<string, object> _Parameters = new(StringComparer.OrdinalIgnoreCase);

public override bool TryParameter(string parameterName, out object? value)
{
return _Parameters.TryGetValue(parameterName, out value);
}

public override bool TryVariable(string variableName, out object? value)
{
return base.TryVariable(variableName, out value);
}

internal void SetParameters(JObject[] parameters, object[]? args)
{
if (parameters == null || parameters.Length == 0 || args == null || args.Length == 0)
return;

for (var i = 0; i < parameters.Length; i++)
{
var name = parameters[i][PROPERTY_NAME]?.Value<string>();
if (!string.IsNullOrEmpty(name))
{
_Parameters.Add(name!, args[i]);
}
}
}
}

#nullable restore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/2922
// Based on work contributed by @GABRIELNGBTUC

module child_loop './Tests.Bicep.1.child.bicep' = [
for (item, index) in range(0, 2): {
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.

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

var webAppsNames = [
'example1'
'example2'
]

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

#disable-next-line no-unused-existing-resources
resource webAppSettings 'Microsoft.Web/sites/config@2022-09-01' existing = [
for i in range(0, length(webAppsNames)): {
name: 'appsettings'
parent: webApps[i]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"$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": "3757483382650491065"
}
},
"variables": {
"webAppsNames": [
"example1",
"example2"
]
},
"resources": {
"webApps": {
"copy": {
"name": "webApps",
"count": "[length(variables('webAppsNames'))]"
},
"existing": true,
"type": "Microsoft.Web/sites",
"apiVersion": "2022-09-01",
"name": "[variables('webAppsNames')[copyIndex()]]"
},
"webAppSettings": {
"copy": {
"name": "webAppSettings",
"count": "[length(range(0, length(variables('webAppsNames'))))]"
},
"existing": true,
"type": "Microsoft.Web/sites/config",
"apiVersion": "2022-09-01",
"name": "[format('{0}/{1}', variables('webAppsNames')[range(0, length(variables('webAppsNames')))[copyIndex()]], 'appsettings')]",
"dependsOn": [
"[format('webApps[{0}]', range(0, length(variables('webAppsNames')))[copyIndex()])]"
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// Test case for https://github.com/Azure/PSRule.Rules.Azure/issues/3120
// Based on work contributed by @GABRIELNGBTUC

import * as child from './Tests.Bicep.1.child.bicep'

var v1 = []
var v2 = [
2
]

func getV3() array => union(v1, v2)

output o1 array = getV3()
output o2 array = child.getV3()
output o3 array = union(child.v1, child.v2)
output o4 array = union(v2, child.v2)
output o5 array = child.getV4()
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

@export()
var v1 = []

@export()
var v2 = [
1
]

@export()
func getV3() array => union(v1, v2)

import * as child2 from './Tests.Bicep.1.child2.bicep'

@export()
func getV4() array => union(child2.v1, child2.v2)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

@export()
var v1 = []

@export()
var v2 = [
3
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{
"$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": "3104036790319433669"
}
},
"functions": [
{
"namespace": "__bicep",
"members": {
"getV3": {
"parameters": [],
"output": {
"type": "array",
"value": "[union(variables('v1'), variables('v2'))]"
}
}
}
},
{
"namespace": "_1",
"members": {
"getV3": {
"parameters": [],
"output": {
"type": "array",
"value": "[union(variables('_1.v1'), variables('_1.v2'))]"
},
"metadata": {
"__bicep_imported_from!": {
"sourceTemplate": "Tests.Bicep.1.child.bicep"
}
}
},
"getV4": {
"parameters": [],
"output": {
"type": "array",
"value": "[union(variables('_2.v1'), variables('_2.v2'))]"
},
"metadata": {
"__bicep_imported_from!": {
"sourceTemplate": "Tests.Bicep.1.child.bicep"
}
}
}
}
}
],
"variables": {
"v1": [],
"v2": [
2
],
"_1.v1": [],
"_1.v2": [
1
],
"_2.v1": [],
"_2.v2": [
3
]
},
"resources": {},
"outputs": {
"o1": {
"type": "array",
"value": "[__bicep.getV3()]"
},
"o2": {
"type": "array",
"value": "[_1.getV3()]"
},
"o3": {
"type": "array",
"value": "[union(variables('_1.v1'), variables('_1.v2'))]"
},
"o4": {
"type": "array",
"value": "[union(variables('v2'), variables('_1.v2'))]"
},
"o5": {
"type": "array",
"value": "[_1.getV4()]"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,12 @@
<None Update="Bicep\SecretTestCases\Tests.Bicep.1.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Bicep\UserDefinedFunctionTestCases\Tests.Bicep.1.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Bicep\SymbolicNameTestCases\Tests.Bicep.3.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Loading

0 comments on commit ab90306

Please sign in to comment.