Skip to content

Commit b451ac1

Browse files
author
Kapil Borle
committed
Update UseIdenticalMandatoryParametersForDSC logic
This update the logic in check for properties that have the `required` attribute. Also updates the error string to report if the missing parameters is `key` or `required`.
1 parent 0ea0938 commit b451ac1

File tree

4 files changed

+72
-76
lines changed

4 files changed

+72
-76
lines changed

Rules/Strings.resx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@
619619
<value>The Get/Test/Set TargetResource functions of DSC resource must have the same mandatory parameters.</value>
620620
</data>
621621
<data name="UseIdenticalMandatoryParametersDSCError" xml:space="preserve">
622-
<value>The mandatory parameter '{0}' is not present in '{1}' DSC resource function(s).</value>
622+
<value>The '{0}' parameter '{1}' is not present in '{2}' DSC resource function(s).</value>
623623
</data>
624624
<data name="UseIdenticalMandatoryParametersDSCName" xml:space="preserve">
625625
<value>UseIdenticalMandatoryParametersForDSC</value>

Rules/UseIdenticalMandatoryParametersDSC.cs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,30 +56,27 @@ public IEnumerable<DiagnosticRecord> AnalyzeDSCResource(Ast ast, string fileName
5656
}
5757

5858
// Get the keys in the corresponding mof file
59-
var keys = GetKeys(fileName);
59+
var propAttrDict = GetKeys(fileName);
6060

6161
// Loop through Set/Test/Get TargetResource DSC cmdlets
6262
foreach (FunctionDefinitionAst functionDefinitionAst in Helper.Instance.DscResourceFunctions(ast))
6363
{
64-
var manParams = new HashSet<string>(
65-
GetMandatoryParameters(functionDefinitionAst).Select(p => p.Name.VariablePath.UserPath),
66-
StringComparer.OrdinalIgnoreCase);
64+
var manParams = GetMandatoryParameters(functionDefinitionAst)
65+
.Select(p => p.Name.VariablePath.UserPath);
6766

68-
foreach (var key in keys)
67+
foreach (var key in propAttrDict.Keys.Except(manParams))
6968
{
70-
if (!manParams.Contains(key))
71-
{
72-
yield return new DiagnosticRecord(
73-
string.Format(
74-
CultureInfo.InvariantCulture,
75-
Strings.UseIdenticalMandatoryParametersDSCError,
76-
key,
77-
functionDefinitionAst.Name),
78-
Helper.Instance.GetScriptExtentForFunctionName(functionDefinitionAst),
79-
GetName(),
80-
DiagnosticSeverity.Error,
81-
fileName);
82-
}
69+
yield return new DiagnosticRecord(
70+
string.Format(
71+
CultureInfo.InvariantCulture,
72+
Strings.UseIdenticalMandatoryParametersDSCError,
73+
propAttrDict[key],
74+
key,
75+
functionDefinitionAst.Name),
76+
Helper.Instance.GetScriptExtentForFunctionName(functionDefinitionAst),
77+
GetName(),
78+
DiagnosticSeverity.Error,
79+
fileName);
8380
}
8481
}
8582
}
@@ -175,19 +172,19 @@ private bool IsNamedAttributeArgumentMandatory(NamedAttributeArgumentAst namedAt
175172
namedAttrArgAst.GetValue();
176173
}
177174

178-
private IEnumerable<string> GetKeys(string fileName)
175+
private IDictionary<string, string> GetKeys(string fileName)
179176
{
180177
var moduleInfo = GetModuleInfo(fileName);
181-
var emptyArray = new string[0];
178+
var emptyDictionary = new Dictionary<string, string>();
182179
if (moduleInfo == null)
183180
{
184-
return emptyArray;
181+
return emptyDictionary;
185182
}
186183

187184
var mofFilepath = GetMofFilepath(fileName);
188185
if (mofFilepath == null)
189186
{
190-
return emptyArray;
187+
return emptyDictionary;
191188
}
192189

193190
var errors = new System.Collections.ObjectModel.Collection<Exception>();
@@ -208,13 +205,22 @@ private IEnumerable<string> GetKeys(string fileName)
208205
// todo log the error
209206
}
210207

211-
return cimClasses?
212-
.FirstOrDefault()?
208+
var cimClass = cimClasses?.FirstOrDefault();
209+
var cimSuperClassProperties = new HashSet<string>(
210+
cimClass?.CimSuperClass.CimClassProperties.Select(p => p.Name) ??
211+
Enumerable.Empty<string>());
212+
213+
return cimClass?
213214
.CimClassProperties?
214-
.Where(p => p.Flags.HasFlag(CimFlags.Key))
215-
.Select(p => p.Name)
216-
.ToArray() ??
217-
emptyArray;
215+
.Where(p => (p.Flags.HasFlag(CimFlags.Key) ||
216+
p.Flags.HasFlag(CimFlags.Required)) &&
217+
!cimSuperClassProperties.Contains(p.Name))
218+
.ToDictionary(
219+
p => p.Name,
220+
p => p.Flags.HasFlag(CimFlags.Key) ?
221+
CimFlags.Key.ToString() :
222+
CimFlags.Required.ToString()) ??
223+
emptyDictionary;
218224
}
219225

220226
private string GetMofFilepath(string filePath)

Tests/Rules/DSCResourceModule/DSCResources/MSFT_WaitForAnyNoIdenticalMandatoryParameter/MSFT_WaitForAnyNoIdenticalMandatoryParameter.psm1

Lines changed: 36 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
#
66
# The Get-TargetResource cmdlet.
77
#
8-
function Get-TargetResource
9-
{
8+
function Get-TargetResource {
9+
10+
# This is missing `Key` properties `ResourceName` and `Dummy`
1011
param
1112
(
1213
[parameter(Mandatory)]
@@ -17,7 +18,7 @@ function Get-TargetResource
1718
[ValidateNotNullOrEmpty()]
1819
[PSCredential] $Credential,
1920

20-
[ValidateRange(1,[Uint64]::MaxValue)]
21+
[ValidateRange(1, [Uint64]::MaxValue)]
2122
[Uint64] $RetryIntervalSec = 1,
2223

2324
[Uint32] $RetryCount = 0,
@@ -31,16 +32,13 @@ function Get-TargetResource
3132

3233
$b = @{"hash" = "table"}
3334

34-
if ($true)
35-
{
35+
if ($true) {
3636
return $b;
3737
}
38-
elseif ($c)
39-
{
40-
return @{"hash2"="table2"}
38+
elseif ($c) {
39+
return @{"hash2" = "table2"}
4140
}
42-
else
43-
{
41+
else {
4442
# can't determine type of c so error should not be raised as we're trying to be conservative
4543
return $c;
4644
}
@@ -49,8 +47,9 @@ function Get-TargetResource
4947
#
5048
# The Set-TargetResource cmdlet.
5149
#
52-
function Set-TargetResource
53-
{
50+
function Set-TargetResource {
51+
52+
# This is missing `required` property `credential` and `key` property `Dummy`
5453
param
5554
(
5655
[parameter(Mandatory)]
@@ -61,11 +60,7 @@ function Set-TargetResource
6160
[ValidateNotNullOrEmpty()]
6261
[string[]] $NodeName,
6362

64-
[parameter(Mandatory)]
65-
[ValidateNotNullOrEmpty()]
66-
[PSCredential] $Credential,
67-
68-
[ValidateRange(1,[Uint64]::MaxValue)]
63+
[ValidateRange(1, [Uint64]::MaxValue)]
6964
[Uint64] $RetryIntervalSec = 1,
7065

7166
[Uint32] $RetryCount = 0,
@@ -77,39 +72,38 @@ function Set-TargetResource
7772

7873
Import-Module $PSScriptRoot\..\..\PSDSCxMachine.psm1
7974

80-
if ($PSBoundParameters["Verbose"])
81-
{
75+
if ($PSBoundParameters["Verbose"]) {
8276
Write-Verbose "Calling xMachine with Verbose parameter"
8377

8478
PSDSCxMachine\Set-_InternalPSDscXMachineTR `
85-
-RemoteResourceId $ResourceName `
86-
-RemoteMachine $NodeName `
87-
-RemoteCredential $Credential `
88-
-MinimalNumberOfMachineInState 1 `
89-
-RetryIntervalSec $RetryIntervalSec `
90-
-RetryCount $RetryCount `
91-
-ThrottleLimit $ThrottleLimit `
92-
-Verbose
79+
-RemoteResourceId $ResourceName `
80+
-RemoteMachine $NodeName `
81+
-RemoteCredential $Credential `
82+
-MinimalNumberOfMachineInState 1 `
83+
-RetryIntervalSec $RetryIntervalSec `
84+
-RetryCount $RetryCount `
85+
-ThrottleLimit $ThrottleLimit `
86+
-Verbose
9387
}
94-
else
95-
{
88+
else {
9689
PSDSCxMachine\Set-_InternalPSDscXMachineTR `
97-
-RemoteResourceId $ResourceName `
98-
-RemoteMachine $NodeName `
99-
-RemoteCredential $Credential `
100-
-MinimalNumberOfMachineInState 1 `
101-
-RetryIntervalSec $RetryIntervalSec `
102-
-RetryCount $RetryCount `
103-
-ThrottleLimit $ThrottleLimit
90+
-RemoteResourceId $ResourceName `
91+
-RemoteMachine $NodeName `
92+
-RemoteCredential $Credential `
93+
-MinimalNumberOfMachineInState 1 `
94+
-RetryIntervalSec $RetryIntervalSec `
95+
-RetryCount $RetryCount `
96+
-ThrottleLimit $ThrottleLimit
10497
}
10598
}
10699

107100
#
108101
# Test-TargetResource
109102
#
110103
#
111-
function Test-TargetResource
112-
{
104+
function Test-TargetResource {
105+
106+
# This is missing `key` property `Dummy`
113107
param
114108
(
115109
[parameter(Mandatory)]
@@ -139,20 +133,16 @@ function Test-TargetResource
139133
$a = $true
140134
$a
141135

142-
if ($true)
143-
{
136+
if ($true) {
144137
$false;
145138
}
146-
elseif ($b)
147-
{
139+
elseif ($b) {
148140
return $a -or $true
149141
}
150-
elseif ($c)
151-
{
142+
elseif ($c) {
152143
return $false;
153144
}
154-
else
155-
{
145+
else {
156146
return $true
157147
}
158148
}

Tests/Rules/UseIdenticalMandatoryParametersForDSC.tests.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Describe "UseIdenticalMandatoryParametersForDSC" {
1616
}
1717

1818
It "Should find a violations" {
19-
$violations.Count | Should Be 4
19+
$violations.Count | Should Be 5
2020
}
2121

2222
It "Should mark only the function name" {

0 commit comments

Comments
 (0)