Skip to content

Commit

Permalink
Fixed loading of expansion options from non-default options #3033 (#3039
Browse files Browse the repository at this point in the history
)

* Fixed loading of expansion options from non-default options #2523

* Update change log
  • Loading branch information
BernieWhite authored Sep 15, 2024
1 parent af1d30b commit 1d4183d
Show file tree
Hide file tree
Showing 15 changed files with 500 additions and 19 deletions.
4 changes: 3 additions & 1 deletion docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

- New rules:
- Virtual Machine:
- Verify that Multitenant Hosting Rights are used for Windows client VMs by @BenjaminEngeset.
- Verify that multi-tenant Hosting Rights are used for Windows client VMs by @BenjaminEngeset.
[#432](https://github.com/Azure/PSRule.Rules.Azure/issues/432)
- Verify that availability set members are in a backend pool by @BenjaminEngeset.
[#67](https://github.com/Azure/PSRule.Rules.Azure/issues/67)
- Bug fixed:
- Fixed `Azure.AppService.AvailabilityZone` only detects premium by tier property @BenjaminEngeset.
[#3034](https://github.com/Azure/PSRule.Rules.Azure/issues/3034)
- Fixed loading of expansion options from non-default options file @BernieWhite.
[#3033](https://github.com/Azure/PSRule.Rules.Azure/issues/3033)

## v1.39.0-B0055 (pre-release)

Expand Down
18 changes: 18 additions & 0 deletions src/PSRule.Rules.Azure/Common/DictionaryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management.Automation;

namespace PSRule.Rules.Azure
{
Expand All @@ -30,6 +31,23 @@ public static bool TryPopValue<T>(this IDictionary<string, object> dictionary, s
return false;
}

public static bool TryPopHashtable(this IDictionary<string, object> dictionary, string key, out Hashtable value)
{
value = null;
if (dictionary.TryPopValue(key, out var o) && o is Hashtable result)
{
value = result;
return true;
}
if (dictionary.TryPopValue(key, out PSObject pso))
{
value = pso.ToHashtable();
return true;
}

return false;
}

[DebuggerStepThrough]
public static bool TryGetValue<T>(this IDictionary<string, object> dictionary, string key, out T value)
{
Expand Down
11 changes: 11 additions & 0 deletions src/PSRule.Rules.Azure/Common/PSObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Collections;
using System.IO;
using System.Management.Automation;

Expand Down Expand Up @@ -39,5 +40,15 @@ internal static bool GetPath(this PSObject sourceObject, out string path)
}
return false;
}

internal static Hashtable ToHashtable(this PSObject o)
{
var result = new Hashtable();
foreach (var p in o.Properties)
{
result[p.Name] = p.Value;
}
return result;
}
}
}
16 changes: 14 additions & 2 deletions src/PSRule.Rules.Azure/Configuration/DeploymentOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ internal static DeploymentOption Combine(DeploymentOption o1, DeploymentOption o
/// </summary>
[DefaultValue(null)]
public string Name { get; set; }

internal static DeploymentOption FromHashtable(Hashtable hashtable)
{
var option = new DeploymentOption();
if (hashtable != null)
{
var index = PSRuleOption.BuildIndex(hashtable);
if (index.TryPopValue("Name", out string s))
option.Name = s;
}
return option;
}
}

/// <summary>
Expand Down Expand Up @@ -153,8 +165,8 @@ public static DeploymentReference FromHashtable(Hashtable hashtable)
if (hashtable != null)
{
var index = PSRuleOption.BuildIndex(hashtable);
if (index.TryPopValue("Name", out string svalue))
option.Name = svalue;
if (index.TryPopValue("Name", out string s))
option.Name = s;
}
return option;
}
Expand Down
70 changes: 70 additions & 0 deletions src/PSRule.Rules.Azure/Configuration/ManagementGroupOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections;
using System.ComponentModel;
using YamlDotNet.Serialization;

Expand Down Expand Up @@ -92,6 +93,24 @@ internal ManagementGroupProperties(string displayName, string tenantId)
/// Additional details of the management group.
/// </summary>
public ManagementGroupDetails Details { get; internal set; }

internal static ManagementGroupProperties FromHashtable(Hashtable properties)
{
var result = new ManagementGroupProperties();
if (properties != null)
{
var index = PSRuleOption.BuildIndex(properties);
if (index.TryPopValue("DisplayName", out string displayName))
result.DisplayName = displayName;

if (index.TryPopValue("TenantId", out string tenantId))
result.TenantId = tenantId;

if (index.TryPopHashtable("Details", out var details))
result.Details = ManagementGroupDetails.FromHashtable(details);
}
return result;
}
}

/// <summary>
Expand Down Expand Up @@ -133,6 +152,27 @@ public ManagementGroupDetails()
/// </summary>
[DefaultValue(null)]
public string Version { get; set; }

internal static ManagementGroupDetails FromHashtable(Hashtable details)
{
var result = new ManagementGroupDetails();
if (details != null)
{
var index = PSRuleOption.BuildIndex(details);
if (index.TryPopHashtable("Parent", out var parent))
result.Parent = ManagementGroupParent.FromHashtable(parent);

if (index.TryPopValue("UpdatedBy", out string updatedBy))
result.UpdatedBy = updatedBy;

if (index.TryPopValue("UpdatedTime", out string updatedTime))
result.UpdatedTime = updatedTime;

if (index.TryPopValue("Version", out string version))
result.Version = version;
}
return result;
}
}

/// <summary>
Expand Down Expand Up @@ -182,6 +222,21 @@ public string Name
/// </summary>
[DefaultValue(null)]
public string DisplayName { get; set; }

internal static ManagementGroupParent FromHashtable(Hashtable parent)
{
var result = new ManagementGroupParent();
if (parent != null)
{
var index = PSRuleOption.BuildIndex(parent);
if (index.TryPopValue("Name", out string name))
result.Name = name;

if (index.TryPopValue("DisplayName", out string displayName))
result.DisplayName = displayName;
}
return result;
}
}

/// <inheritdoc/>
Expand Down Expand Up @@ -279,5 +334,20 @@ public string Name
/// Additional properties of the management group.
/// </summary>
public ManagementGroupProperties Properties { get; set; }

internal static ManagementGroupOption FromHashtable(Hashtable hashtable)
{
var option = new ManagementGroupOption();
if (hashtable != null)
{
var index = PSRuleOption.BuildIndex(hashtable);
if (index.TryPopValue("Name", out string name))
option.Name = name;

if (index.TryPopHashtable("Properties", out var properties))
option.Properties = ManagementGroupProperties.FromHashtable(properties);
}
return option;
}
}
}
14 changes: 14 additions & 0 deletions src/PSRule.Rules.Azure/Configuration/ParameterDefaultsOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ internal static ParameterDefaultsOption Combine(ParameterDefaultsOption o1, Para
return result;
}

internal static ParameterDefaultsOption FromHashtable(Hashtable hashtable)
{
if (hashtable == null || hashtable.Count == 0)
return null;

var result = new ParameterDefaultsOption();
foreach (DictionaryEntry entry in hashtable)
{
if (entry.Key is string key)
result._Defaults[key] = entry.Value;
}
return result;
}

internal bool TryGetString(string parameterName, out JToken value)
{
value = default;
Expand Down
39 changes: 39 additions & 0 deletions src/PSRule.Rules.Azure/Configuration/ResourceGroupOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ internal ResourceGroupProperties(string provisioningState)
/// The provisioning state of the resource group.
/// </summary>
public string ProvisioningState { get; }

internal static ResourceGroupProperties FromHashtable(Hashtable properties)
{
var option = new ResourceGroupProperties();
if (properties != null)
{
var index = PSRuleOption.BuildIndex(properties);
if (index.TryPopValue("ProvisioningState", out string s))
option = new ResourceGroupProperties(s);
}
return option;
}
}

/// <inheritdoc/>
Expand Down Expand Up @@ -240,6 +252,33 @@ public string Name
/// </summary>
[DefaultValue(null)]
public ResourceGroupProperties Properties { get; set; }

internal static ResourceGroupOption FromHashtable(Hashtable hashtable)
{
var option = new ResourceGroupOption();
if (hashtable != null)
{
var index = PSRuleOption.BuildIndex(hashtable);
if (index.TryPopValue("SubscriptionId", out string s))
option.SubscriptionId = s;

if (index.TryPopValue("Name", out s))
option.Name = s;

if (index.TryPopValue("Location", out s))
option.Location = s;

if (index.TryPopValue("ManagedBy", out s))
option.ManagedBy = s;

if (index.TryPopValue("Tags", out Hashtable tags))
option.Tags = tags;

if (index.TryPopHashtable("Properties", out var properties))
option.Properties = ResourceGroupProperties.FromHashtable(properties);
}
return option;
}
}

/// <summary>
Expand Down
37 changes: 29 additions & 8 deletions src/PSRule.Rules.Azure/Configuration/SubscriptionOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,27 @@ internal static SubscriptionOption Combine(SubscriptionOption o1, SubscriptionOp
return result;
}

internal static SubscriptionOption FromHashtable(Hashtable hashtable)
{
var option = new SubscriptionOption();
if (hashtable != null)
{
var index = PSRuleOption.BuildIndex(hashtable);
if (index.TryPopValue("SubscriptionId", out string subscriptionId))
option.SubscriptionId = subscriptionId;

if (index.TryPopValue("TenantId", out string tenantId))
option.TenantId = tenantId;

if (index.TryPopValue("DisplayName", out string displayName))
option.DisplayName = displayName;

if (index.TryPopValue("State", out string state))
option.State = state;
}
return option;
}

/// <summary>
/// A unique identifier for the subscription.
/// </summary>
Expand Down Expand Up @@ -232,17 +253,17 @@ public static SubscriptionReference FromHashtable(Hashtable hashtable)
if (hashtable != null)
{
var index = PSRuleOption.BuildIndex(hashtable);
if (index.TryPopValue("SubscriptionId", out string svalue))
option.SubscriptionId = svalue;
if (index.TryPopValue("SubscriptionId", out string s))
option.SubscriptionId = s;

if (index.TryPopValue("TenantId", out svalue))
option.TenantId = svalue;
if (index.TryPopValue("TenantId", out s))
option.TenantId = s;

if (index.TryPopValue("DisplayName", out svalue))
option.DisplayName = svalue;
if (index.TryPopValue("DisplayName", out s))
option.DisplayName = s;

if (index.TryPopValue("State", out svalue))
option.State = svalue;
if (index.TryPopValue("State", out s))
option.State = s;
}
return option;
}
Expand Down
19 changes: 19 additions & 0 deletions src/PSRule.Rules.Azure/Configuration/TenantOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Collections;
using System.ComponentModel;
using YamlDotNet.Serialization;

Expand Down Expand Up @@ -118,6 +119,24 @@ internal static TenantOption Combine(TenantOption o1, TenantOption o2)
return result;
}

internal static TenantOption FromHashtable(Hashtable hashtable)
{
var result = new TenantOption();
if (hashtable != null)
{
var index = PSRuleOption.BuildIndex(hashtable);
if (index.TryPopValue("CountryCode", out string countryCode))
result.CountryCode = countryCode;

if (index.TryPopValue("TenantId", out string tenantId))
result.TenantId = tenantId;

if (index.TryPopValue("DisplayName", out string displayName))
result.DisplayName = displayName;
}
return result;
}

/// <summary>
/// A country code identifier for the tenant.
/// </summary>
Expand Down
Loading

0 comments on commit 1d4183d

Please sign in to comment.