Refactor code structure for improved readability and maintainability; optimize performance in key functions.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using System.Collections.Immutable;
|
||||
using StellaOps.DeltaVerdict.Models;
|
||||
|
||||
namespace StellaOps.DeltaVerdict.Policy;
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates delta verdicts against risk budgets for release gates.
|
||||
/// </summary>
|
||||
public sealed class RiskBudgetEvaluator : IRiskBudgetEvaluator
|
||||
{
|
||||
public RiskBudgetResult Evaluate(DeltaVerdict.Models.DeltaVerdict delta, RiskBudget budget)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(delta);
|
||||
ArgumentNullException.ThrowIfNull(budget);
|
||||
|
||||
var violations = new List<RiskBudgetViolation>();
|
||||
|
||||
var criticalAdded = delta.AddedVulnerabilities
|
||||
.Count(v => string.Equals(v.Severity, "critical", StringComparison.OrdinalIgnoreCase));
|
||||
if (criticalAdded > budget.MaxNewCriticalVulnerabilities)
|
||||
{
|
||||
violations.Add(new RiskBudgetViolation(
|
||||
"CriticalVulnerabilities",
|
||||
$"Added {criticalAdded} critical vulnerabilities (budget: {budget.MaxNewCriticalVulnerabilities})"));
|
||||
}
|
||||
|
||||
var highAdded = delta.AddedVulnerabilities
|
||||
.Count(v => string.Equals(v.Severity, "high", StringComparison.OrdinalIgnoreCase));
|
||||
if (highAdded > budget.MaxNewHighVulnerabilities)
|
||||
{
|
||||
violations.Add(new RiskBudgetViolation(
|
||||
"HighVulnerabilities",
|
||||
$"Added {highAdded} high vulnerabilities (budget: {budget.MaxNewHighVulnerabilities})"));
|
||||
}
|
||||
|
||||
if (delta.RiskScoreDelta.Change > budget.MaxRiskScoreIncrease)
|
||||
{
|
||||
violations.Add(new RiskBudgetViolation(
|
||||
"RiskScoreIncrease",
|
||||
$"Risk score increased by {delta.RiskScoreDelta.Change} (budget: {budget.MaxRiskScoreIncrease})"));
|
||||
}
|
||||
|
||||
if ((int)delta.Summary.Magnitude > (int)budget.MaxMagnitude)
|
||||
{
|
||||
violations.Add(new RiskBudgetViolation(
|
||||
"DeltaMagnitude",
|
||||
$"Delta magnitude {delta.Summary.Magnitude} exceeds budget {budget.MaxMagnitude}"));
|
||||
}
|
||||
|
||||
foreach (var vuln in delta.AddedVulnerabilities)
|
||||
{
|
||||
if (budget.BlockedVulnerabilities.Contains(vuln.VulnerabilityId))
|
||||
{
|
||||
violations.Add(new RiskBudgetViolation(
|
||||
"BlockedVulnerability",
|
||||
$"Added blocked vulnerability {vuln.VulnerabilityId}"));
|
||||
}
|
||||
}
|
||||
|
||||
return new RiskBudgetResult(
|
||||
IsWithinBudget: violations.Count == 0,
|
||||
Violations: violations,
|
||||
Delta: delta,
|
||||
Budget: budget);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IRiskBudgetEvaluator
|
||||
{
|
||||
RiskBudgetResult Evaluate(DeltaVerdict.Models.DeltaVerdict delta, RiskBudget budget);
|
||||
}
|
||||
|
||||
public sealed record RiskBudget
|
||||
{
|
||||
public int MaxNewCriticalVulnerabilities { get; init; } = 0;
|
||||
public int MaxNewHighVulnerabilities { get; init; } = 3;
|
||||
public decimal MaxRiskScoreIncrease { get; init; } = 10;
|
||||
public DeltaMagnitude MaxMagnitude { get; init; } = DeltaMagnitude.Medium;
|
||||
public ImmutableHashSet<string> BlockedVulnerabilities { get; init; }
|
||||
= ImmutableHashSet<string>.Empty.WithComparer(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public sealed record RiskBudgetResult(
|
||||
bool IsWithinBudget,
|
||||
IReadOnlyList<RiskBudgetViolation> Violations,
|
||||
DeltaVerdict.Models.DeltaVerdict Delta,
|
||||
RiskBudget Budget);
|
||||
|
||||
public sealed record RiskBudgetViolation(string Category, string Message);
|
||||
Reference in New Issue
Block a user