Restructure solution layout by module
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using StellaOps.Scanner.Core.Contracts;
|
||||
using StellaOps.Scanner.Core.Utility;
|
||||
|
||||
namespace StellaOps.Scanner.Emit.Composition;
|
||||
|
||||
public sealed record ImageArtifactDescriptor
|
||||
{
|
||||
public string ImageDigest { get; init; } = string.Empty;
|
||||
|
||||
public string? ImageReference { get; init; }
|
||||
= null;
|
||||
|
||||
public string? Repository { get; init; }
|
||||
= null;
|
||||
|
||||
public string? Tag { get; init; }
|
||||
= null;
|
||||
|
||||
public string? Architecture { get; init; }
|
||||
= null;
|
||||
}
|
||||
|
||||
public sealed record SbomCompositionRequest
|
||||
{
|
||||
public required ImageArtifactDescriptor Image { get; init; }
|
||||
|
||||
public required ImmutableArray<LayerComponentFragment> LayerFragments { get; init; }
|
||||
|
||||
public DateTimeOffset GeneratedAt { get; init; }
|
||||
= ScannerTimestamps.UtcNow();
|
||||
|
||||
public string? GeneratorName { get; init; }
|
||||
= null;
|
||||
|
||||
public string? GeneratorVersion { get; init; }
|
||||
= null;
|
||||
|
||||
public IReadOnlyDictionary<string, string>? AdditionalProperties { get; init; }
|
||||
= null;
|
||||
|
||||
public ImmutableArray<SbomPolicyFinding> PolicyFindings { get; init; }
|
||||
= ImmutableArray<SbomPolicyFinding>.Empty;
|
||||
|
||||
public static SbomCompositionRequest Create(
|
||||
ImageArtifactDescriptor image,
|
||||
IEnumerable<LayerComponentFragment> fragments,
|
||||
DateTimeOffset generatedAt,
|
||||
string? generatorName = null,
|
||||
string? generatorVersion = null,
|
||||
IReadOnlyDictionary<string, string>? properties = null,
|
||||
IEnumerable<SbomPolicyFinding>? policyFindings = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(image);
|
||||
ArgumentNullException.ThrowIfNull(fragments);
|
||||
|
||||
var normalizedImage = new ImageArtifactDescriptor
|
||||
{
|
||||
ImageDigest = ScannerIdentifiers.NormalizeDigest(image.ImageDigest) ?? throw new ArgumentException("Image digest is required.", nameof(image)),
|
||||
ImageReference = Normalize(image.ImageReference),
|
||||
Repository = Normalize(image.Repository),
|
||||
Tag = Normalize(image.Tag),
|
||||
Architecture = Normalize(image.Architecture),
|
||||
};
|
||||
|
||||
return new SbomCompositionRequest
|
||||
{
|
||||
Image = normalizedImage,
|
||||
LayerFragments = fragments.ToImmutableArray(),
|
||||
GeneratedAt = ScannerTimestamps.Normalize(generatedAt),
|
||||
GeneratorName = Normalize(generatorName),
|
||||
GeneratorVersion = Normalize(generatorVersion),
|
||||
AdditionalProperties = properties,
|
||||
PolicyFindings = NormalizePolicyFindings(policyFindings),
|
||||
};
|
||||
}
|
||||
|
||||
private static string? Normalize(string? value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return value.Trim();
|
||||
}
|
||||
|
||||
private static ImmutableArray<SbomPolicyFinding> NormalizePolicyFindings(IEnumerable<SbomPolicyFinding>? policyFindings)
|
||||
{
|
||||
if (policyFindings is null)
|
||||
{
|
||||
return ImmutableArray<SbomPolicyFinding>.Empty;
|
||||
}
|
||||
|
||||
var builder = ImmutableArray.CreateBuilder<SbomPolicyFinding>();
|
||||
foreach (var finding in policyFindings)
|
||||
{
|
||||
if (finding is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SbomPolicyFinding normalized;
|
||||
try
|
||||
{
|
||||
normalized = finding.Normalize();
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(normalized.FindingId) || string.IsNullOrWhiteSpace(normalized.ComponentKey))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Add(normalized);
|
||||
}
|
||||
|
||||
if (builder.Count == 0)
|
||||
{
|
||||
return ImmutableArray<SbomPolicyFinding>.Empty;
|
||||
}
|
||||
|
||||
return builder
|
||||
.ToImmutable()
|
||||
.OrderBy(static finding => finding.FindingId, StringComparer.Ordinal)
|
||||
.ThenBy(static finding => finding.ComponentKey, StringComparer.Ordinal)
|
||||
.ThenBy(static finding => finding.VulnerabilityId ?? string.Empty, StringComparer.Ordinal)
|
||||
.ToImmutableArray();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user