microsoft / PSRule

Validate infrastructure as code (IaC) and objects using PowerShell rules.
https://microsoft.github.io/PSRule/v2/
MIT License
385 stars 49 forks source link

Get-PSRule does not specify the cause of the error #185

Closed LaurentDardenne closed 5 years ago

LaurentDardenne commented 5 years ago

Powershell version 5.1 , Windows 10 1803 PSRule version 0.7.0

With this wrong rule file:

$Path='C:\temp'
$File='Test.Rule.ps1'
@'
Rule {}
'@ >"$Path\$File"

cd $path
get-psrule

I get an exception (it is correct):

get-psrule : Impossible de lier l'argument au paramètre « Name », car il s'agit d'une chaîne vide.
Au caractère Ligne:1 : 1
+ get-psrule
+ ~~~~~~~~~~
    + CategoryInfo          : InvalidData : (:) [Get-PSRule], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Get-PSRule

But as beginner I dont known if the error is raised by the cmdlet Get-PSRule or one rule file.

$error[0].exception.CommandInvocation|select *

MyCommand             : New-RuleDefinition
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 1
OffsetInLine          : 1
HistoryId             : 1
ScriptName            : C:\temp\Test.Rule.ps1
Line                  : Rule {}

PositionMessage       : Au caractère C:\temp\Test.Rule.ps1:1 : 1
                        + Rule {}
                        + ~~~~~~~
PSScriptRoot          : C:\temp
PSCommandPath         : C:\temp\Test.Rule.ps1
InvocationName        : Rule
PipelineLength        : 1
PipelinePosition      : 1
ExpectingInput        : False
CommandOrigin         : Internal
DisplayScriptPosition :

Same remark here:

cd ..\PSRule-master\tests\PSRule.Tests
get-psrule
get-psrule : Impossible d’appeler une méthode dans une expression Null.
Au caractère Ligne:1 : 1
+ get-psrule
+ ~~~~~~~~~~
    + CategoryInfo          : InvalidOperation : (:) [Get-PSRule], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull,Get-PSRule

AVERTISSEMENT : Script warning message
Should fail

RuleName                            Synopsis                                  ModuleName
--------                            --------                                  ----------
M1.Rule1                            This is the default
M1.Rule2                            This is the default
...

The file 'FromFileWithException.Rule.ps1' raise this exception, But I do not know. May be add a specific exception with the rule file name into the error message.

I have two question related to this case

BernieWhite commented 5 years ago

@LaurentDardenne Thanks for the feedback again.

The first issue is related to the rule not having a name i.e.

rule 'rulename' {
  # conditions go here
}

Each rule must have a unique name.

The second exception is designed to fail. It's a unit test that is designed to raise an exception to make sure PSRule correctly returned the exception to the user.

To answer your questions:

  1. Yes rule files can contain code outside of the rule block, there are a number of reasons why you might want to do this currently, although the long term plan is to provide alternatives.
  2. Currently AST analysis alone is not feasible while code outside of rule blocks in still required for certain scenarios. However there may be some pre-validation that can be done to improve error reporting.

For example, you can write a helper function such as here.

BernieWhite commented 5 years ago

@LaurentDardenne hope that helps.

LaurentDardenne commented 5 years ago

Yes Thanks.

Yes rule files can contain code outside of the rule block, there are a number of reasons why you might want to do this currently, although the long term plan is to provide alternatives.

In my opinion the fact that Get-PSrule executes the code of the rules found can have an edge effect in the caller. Am I wrong?

BernieWhite commented 5 years ago

@LaurentDardenne Each call of Invoke-PSRule or Get-PSRule is executed in a separate runspace. So code included in rules can't contaminate the environment of the caller. Configuration and output is proxied in and out of the runspace by PSRule as required.

After execution is complete the runspace is cleaned up and a new runspace is used for the next execution.

So for all intents and purposes there isn't any edge effect on the caller, because they are isolated from each other.

LaurentDardenne commented 5 years ago

Thank you, I was wrong :-)