in src/Analyzer.PowerShellRuleEngine/PowerShellRuleEngine.cs [69:158]
public IEnumerable<IEvaluation> AnalyzeTemplate(TemplateContext templateContext)
{
if (templateContext?.TemplateIdentifier == null)
{
throw new ArgumentException($"{nameof(TemplateContext.TemplateIdentifier)} must not be null.", nameof(templateContext));
}
if (templateContext?.ExpandedTemplate == null)
{
throw new ArgumentException($"{nameof(TemplateContext.ExpandedTemplate)} must not be null.", nameof(templateContext));
}
if (templateContext?.ResourceMappings == null)
{
throw new ArgumentException($"{nameof(TemplateContext.ResourceMappings)} must not be null.", nameof(templateContext));
}
// TODO: Temporary work-around: write template to disk so PSRule will analyze it
var tempFile = Path.GetTempFileName();
var tempTemplateFile = Path.ChangeExtension(tempFile, ".json");
File.WriteAllText(tempTemplateFile, templateContext.ExpandedTemplate.ToString());
PSRuleHostContext hostContext;
try
{
var fileOptions = PSRuleOption.FromFileOrEmpty();
hostContext = new PSRuleHostContext(templateContext, logger);
var modules = new string[] { PSRuleModuleName };
var optionsForFileAnalysis = new PSRuleOption
{
Input = new InputOption
{
Format = InputFormat.File
},
Output = new OutputOption
{
Outcome = RuleOutcome.Fail,
Culture = new string[] { "en-US" } // To avoid warning messages when running tests in Linux
},
Include = new IncludeOption
{
Path = new string[]
{
".ps-rule",
Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), "baselines", "SecurityBaseline.Rule.json"),
Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory), "baselines", "RepeatedRulesBaseline.Rule.json")
}
},
Execution = new ExecutionOption
{
UnprocessedObject = ExecutionActionPreference.Ignore,
// PSRule internally creates a PowerShell initial state with InitialSessionState.CreateDefault().
// SessionState.Minimal causes PSRule to use CreateDefault2 instead of CreateDefault.
InitialSessionState = SessionState.Minimal
}
};
// placeholder value for location is westus2
optionsForFileAnalysis.Configuration["AZURE_RESOURCE_ALLOWED_LOCATIONS"] = new[] { "westus2" };
var resources = templateContext.ExpandedTemplate.InsensitiveToken("resources").Values<JObject>();
var builder = CommandLineBuilder.Invoke(modules, optionsForFileAnalysis, hostContext);
builder.InputPath(new string[] { tempTemplateFile });
if (includeNonSecurityRules)
{
builder.Baseline(BaselineOption.FromString("RepeatedRulesBaseline"));
}
else
{
builder.Baseline(BaselineOption.FromString("SecurityBaseline"));
}
var pipeline = builder.Build();
pipeline.Begin();
foreach (var resource in resources)
{
pipeline.Process(resource);
}
pipeline.End();
}
finally
{
File.Delete(tempTemplateFile);
}
return hostContext.Evaluations;
}