public async static Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log, WebJobsExecutionContext executionContext) { log.LogInformation("C# HTTP trigger function processed a request."); log.LogInformation("function directory: " + executionContext.FunctionDirectory); log.LogInformation("function app directory: " + executionContext.FunctionAppDirectory); EvaluationRequest request; try { string requestBody = await new StreamReader(req.Body).ReadToEndAsync().ConfigureAwait(false); request = JsonConvert.DeserializeObject <EvaluationRequest>(requestBody); } catch (Exception e) { return(new BadRequestObjectResult(string.Format( CultureInfo.InvariantCulture, "Request body is invalid. Encountered error : {0}", e.ToString()))); } string imageProvenance = JsonConvert.SerializeObject(request.ImageProvenance); if (string.IsNullOrWhiteSpace(imageProvenance)) { return(new BadRequestObjectResult("Image provenance is empty")); } if (string.IsNullOrWhiteSpace(request.PolicyData)) { return(new BadRequestObjectResult("Policy data is empty")); } if (!string.IsNullOrWhiteSpace(request.AuthToken)) { TaskProperties taskProperties = CommonUtilities.CreateTaskProperties(request); new Thread(async() => await ExecuteUsingTimelineLogs( executionContext, log, imageProvenance, request.PolicyData, request.CheckSuiteId, taskProperties, request.Variables)); return(new NoContentResult()); } else { StringBuilder syncLogger = new StringBuilder(); var violations = CommonUtilities.ExecutePolicyCheck( executionContext, log, imageProvenance, request.PolicyData, null, request.Variables, syncLogger, out ViolationType violationType, out string outputLog); return(new OkObjectResult(new EvaluationResponse { Violations = violations.ToList(), Logs = syncLogger.ToString(), ViolationType = violationType })); } }
public static IEnumerable <string> ExecutePolicyCheck( WebJobsExecutionContext executionContext, ILogger log, string imageProvenance, string policy, TaskLogger taskLogger, IDictionary <string, string> variables, StringBuilder syncLogger, out ViolationType violationType, out string outputLog) { string folderName = string.Format("Policy-{0}", executionContext.InvocationId.ToString("N")); string newFolderPath = Path.Combine(executionContext.FunctionDirectory, folderName); string imageProvenancePath = Path.Combine(newFolderPath, ImageProvenanceFileName); string policyFilePath = Path.Combine(newFolderPath, PolicyFileName); string packageName = Regex.Match(policy, @"package\s([a-zA-Z0-9.]+)", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(PackageRegexMatchTimeout)).Groups?[1].Value; CommonUtilities.LogInformation(string.Format(CultureInfo.InvariantCulture, "Package name : {0}", packageName), log, taskLogger, variables, syncLogger); if (string.IsNullOrWhiteSpace(packageName)) { outputLog = "No package name could be inferred from the policy. Cannot continue execution. Ensure that policy contains a package name defined"; CommonUtilities.LogInformation(outputLog, log, taskLogger, variables, syncLogger, true); violationType = ViolationType.PackageNotDefined; return(new List <string> { outputLog }); } string output; try { Directory.CreateDirectory(newFolderPath); log.LogInformation(string.Format("Folder created : {0}", newFolderPath), log, taskLogger, variables, syncLogger); File.WriteAllText(imageProvenancePath, imageProvenance); string formattedImageProvenance = IsDebugEnabled(variables) ? JValue.Parse(imageProvenance).ToString(Formatting.Indented) : imageProvenance; CommonUtilities.LogInformation("Image provenance file created", log, taskLogger, variables, syncLogger); CommonUtilities.LogInformation($"Image provenance : \r\n{formattedImageProvenance}", log, taskLogger, variables, syncLogger); File.WriteAllText(policyFilePath, policy); CommonUtilities.LogInformation("Policy content file created", log, taskLogger, variables, syncLogger); CommonUtilities.LogInformation($"Policy definitions : \r\n{policy}", log, taskLogger, variables, syncLogger); string arguments = GetProcessArguments(log, taskLogger, variables, syncLogger, folderName, packageName); var process = new Process { StartInfo = new ProcessStartInfo { FileName = "cmd.exe", Arguments = arguments, UseShellExecute = false, RedirectStandardOutput = true, WorkingDirectory = executionContext.FunctionDirectory } }; CommonUtilities.LogInformation("Initiating evaluation", log, taskLogger, variables, syncLogger, true); process.Start(); CommonUtilities.LogInformation("Evaluation is in progress", log, taskLogger, variables, syncLogger, true); process.WaitForExit(); CommonUtilities.LogInformation("Evaluation complete. Processing result", log, taskLogger, variables, syncLogger, true); CommonUtilities.LogInformation($"Completed executing with exit code {process.ExitCode}", log, taskLogger, variables, syncLogger); output = File.ReadAllText(string.Format(CultureInfo.InvariantCulture, "{0}\\{1}", newFolderPath, OutputResultFileName)); log.LogInformation(output); if (process.ExitCode != 0) { outputLog = output; violationType = ViolationType.PolicyExecutionError; return(new List <string> { $"Policy run had issues: {output}" }); } } finally { Directory.Delete(newFolderPath, true); } return(CommonUtilities.GetViolationsFromResponse(log, taskLogger, output, variables, syncLogger, out violationType, out outputLog)); }
private static async Task ExecuteUsingTimelineLogs( WebJobsExecutionContext executionContext, ILogger log, string imageProvenance, string policy, Guid checkSuiteId, TaskProperties taskProperties, IDictionary <string, string> variables) { using (var taskClient = new TaskClient(taskProperties)) { var taskLogger = new TaskLogger(taskProperties, taskClient); try { // create timelinerecord if not provided await taskLogger.CreateTaskTimelineRecordIfRequired(taskClient, default(CancellationToken)).ConfigureAwait(false); // report task started string taskStartedLog = string.Format("Initializing evaluation. Execution id - {0}", executionContext.InvocationId); CommonUtilities.LogInformation(taskStartedLog, log, taskLogger, variables, null); string outputLog; var violations = CommonUtilities.ExecutePolicyCheck( executionContext, log, imageProvenance, policy, taskLogger, variables, null, out ViolationType violationType, out outputLog); bool succeeded = !(violations?.Any() == true); CommonUtilities.LogInformation($"Policy check succeeded: {succeeded}", log, taskLogger, variables, null); var telemetryProperties = new Dictionary <string, object>(); telemetryProperties.Add("projectId", taskProperties.ProjectId); telemetryProperties.Add("jobId", taskProperties.JobId); telemetryProperties.Add("checkSuiteId", checkSuiteId); telemetryProperties.Add("result", succeeded ? "succeeded" : "failed"); telemetryProperties.Add("layer", "Azure function"); telemetryProperties.Add(ArtifactPolicyTelemetryReasonKey, $"Found violations in evaluation. Violation type: {violationType}"); await UpdateCheckSuiteResult( taskProperties.PlanUrl, taskProperties.AuthToken, taskProperties.ProjectId, checkSuiteId, succeeded, outputLog, log, taskLogger, variables); await CustomerIntelligenceClient.GetClient(taskProperties.PlanUrl, taskProperties.AuthToken) .PublishArtifactPolicyEventAsync(telemetryProperties).ConfigureAwait(false); return; } catch (Exception e) { if (taskLogger != null) { await taskLogger.Log(e.ToString()).ConfigureAwait(false); } throw; } finally { if (taskLogger != null) { await taskLogger.End().ConfigureAwait(false); } } } }