Skip to content

Commit

Permalink
Fixed symbolic references with Azure.Deployment.AdminUsername #3146 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Nov 2, 2024
1 parent f42d4a9 commit 3907935
Show file tree
Hide file tree
Showing 7 changed files with 3,855 additions and 19 deletions.
2 changes: 2 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers
- Bug fixes:
- Fixed evaluation of `Azure.NSG.LateralTraversal` with empty string properties by @BernieWhite.
[#3130](https://github.com/Azure/PSRule.Rules.Azure/issues/3130)
- Fixed evaluation of `Azure.Deployment.AdminUsername` with symbolic references by @BernieWhite.
[#3146](https://github.com/Azure/PSRule.Rules.Azure/issues/3146)

## v1.40.0-B0029 (pre-release)

Expand Down
6 changes: 4 additions & 2 deletions src/PSRule.Rules.Azure/Runtime/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ public static string CompressExpression(string expression)
/// </summary>
public static bool HasLiteralValue(string expression)
{
return !IsTemplateExpression(expression) ||
TokenStreamValidator.HasLiteralValue(ExpressionParser.Parse(expression));
return !string.IsNullOrEmpty(expression) && (
!IsTemplateExpression(expression) ||
TokenStreamValidator.HasLiteralValue(ExpressionParser.Parse(expression))
);
}

/// <summary>
Expand Down
17 changes: 13 additions & 4 deletions src/PSRule.Rules.Azure/rules/Azure.Deployment.Rule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,17 @@ function global:RecurseDeploymentSensitive {
[PSObject]$Deployment
)
process {
Write-Debug "Deployment is: $($Deployment.name)";
$propertyNames = $Configuration.GetStringValues('AZURE_DEPLOYMENT_SENSITIVE_PROPERTY_NAMES');

# Resources could be an object or an array. Check if it is an object and enumerate properties instead.
$resources = @($Deployment.properties.template.resources);
if ($Deployment.properties.template.resources -is [System.Management.Automation.PSObject]) {
$resources = @($Deployment.properties.template.resources.PSObject.Properties.GetEnumerator() | ForEach-Object {
$_.Value
});
}

if ($resources.Length -eq 0) {
return $Assert.Pass();
}
Expand All @@ -140,7 +149,7 @@ function global:RecurseDeploymentSensitive {
$Assert.Pass();
}
else {
Write-Debug "Found property name: $propertyName";
Write-Debug "Found property name: $propertyName, value: $found";
foreach ($value in $found) {
$Assert.Create(![PSRule.Rules.Azure.Runtime.Helper]::HasLiteralValue($value), $LocalizedData.LiteralSensitiveProperty, $propertyName);
}
Expand All @@ -167,9 +176,9 @@ function global:RecursivePropertiesSecretEvaluation {
[Bool]$ShouldUseSecret = $True
)
process {
$PropertyName = $Property.psObject.properties.Name
foreach ($NestedProperty in $Property.PSObject.Properties.Value.PSObject.Properties ) {
if($NestedProperty.MemberType -eq 'NoteProperty'){
$PropertyName = $Property.PSObject.properties.Name
foreach ($NestedProperty in $Property.PSObject.Properties.Value.PSObject.Properties) {
if($NestedProperty.MemberType -eq 'NoteProperty') {
RecursivePropertiesSecretEvaluation -Resource $Resource -SecureParameters $SecureParameters -Property $NestedProperty -ShouldUseSecret $ShouldUseSecret
} else {
CheckPropertyUsesSecureParameter -Resource $Resource -SecureParameters $SecureParameters -PropertyPath "properties.$($PropertyName)" -ShouldUseSecret $ShouldUseSecret
Expand Down
37 changes: 34 additions & 3 deletions tests/PSRule.Rules.Azure.Tests/Azure.Deployment.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,28 @@ Describe 'Azure.Deployment' -Tag 'Deployment' {
$targetNames | Should -BeIn 'secret_good', 'streaming_jobs_good', 'reference_good';
}
}

Context 'With Template' {
BeforeAll {
$templatePath = Join-Path -Path $here -ChildPath 'deployment.tests.json';
$outputFile = Join-Path -Path $rootPath -ChildPath out/tests/Resources.Deployment.json;
Export-AzRuleTemplateData -TemplateFile $templatePath -OutputPath $outputFile;
$result = Invoke-PSRule -Module PSRule.Rules.Azure -InputPath $outputFile -Outcome All -WarningAction Ignore -ErrorAction Stop;
}

It 'Azure.Deployment.Name' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.Deployment.Name' };

# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -BeNullOrEmpty;

# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 2;
}
}
}

Describe 'Azure.Deployment' -Tag 'Deployment' {
Expand Down Expand Up @@ -162,9 +184,18 @@ Describe 'Azure.Deployment.AdminUsername' -Tag 'Deployment' {
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 3;
}
}

It 'Azure.Deployment.Name' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.Deployment.Name' };
Context 'With Bicep with symbolic names' {
BeforeAll {
$templatePath = Join-Path -Path $here -ChildPath 'Bicep/SymbolicNameTestCases/Tests.Bicep.5.json';
$outputFile = Join-Path -Path $rootPath -ChildPath out/tests/Resources.Deployment.json;
Export-AzRuleTemplateData -TemplateFile $templatePath -OutputPath $outputFile;
$result = Invoke-PSRule -Module PSRule.Rules.Azure -InputPath $outputFile -Outcome All -WarningAction Ignore -ErrorAction Stop;
}

It 'Azure.Deployment.AdminUsername' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.Deployment.AdminUsername' };

# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
Expand All @@ -173,7 +204,7 @@ Describe 'Azure.Deployment.AdminUsername' -Tag 'Deployment' {
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 2;
$ruleResult.Length | Should -Be 10;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

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

param rgName string = 'rg-test'
param location string = 'eastus'
param sqlServerName string = 's1'
param sqlAdministrators object = {
azureADOnlyAuthentication: true
login: 'group1'
sid: 'sid'
principalType: 'Group'
}
param sqlDatabase object = {
name: 'sqldb'
tier: 'Basic'
sku: 'Basic'
maxSizeBytes: 2147483648
collation: 'SQL_Latin1_General_CP1_CI_AS'
}

// Azure SQL DB
module sqlDb 'br/public:avm/res/sql/server:0.8.0' = {
name: 'abc'
scope: resourceGroup(rgName)
params: {
name: sqlServerName
location: location
minimalTlsVersion: '1.2'
managedIdentities: {
systemAssigned: true
}
privateEndpoints: [
{
name: 'pe'
customNetworkInterfaceName: 'pe-sql-nic'
subnetResourceId: ''
privateDnsZoneGroup: {
privateDnsZoneGroupConfigs: [
{
privateDnsZoneResourceId: ''
}
]
}
}
]
publicNetworkAccess: 'Disabled'
securityAlertPolicies: [
{
name: 'Default'
state: 'Enabled'
emailAccountAdmins: true
}
]
administrators: {
azureADOnlyAuthentication: sqlAdministrators.azureADOnlyAuthentication
login: sqlAdministrators.login
sid: sqlAdministrators.sid
principalType: sqlAdministrators.principalType
}
databases: [
{
name: sqlDatabase.name
collation: sqlDatabase.collation
maxSizeBytes: sqlDatabase.maxSizeBytes
skuTier: sqlDatabase.tier
skuName: sqlDatabase.sku
}
]
}
}
Loading

0 comments on commit 3907935

Please sign in to comment.