Implement InMemory Transport Layer for StellaOps Router

- Added InMemoryTransportOptions class for configuration settings including timeouts and latency.
- Developed InMemoryTransportServer class to handle connections, frame processing, and event management.
- Created ServiceCollectionExtensions for easy registration of InMemory transport services.
- Established project structure and dependencies for InMemory transport library.
- Implemented comprehensive unit tests for endpoint discovery, connection management, request/response flow, and streaming capabilities.
- Ensured proper handling of cancellation, heartbeat, and hello frames within the transport layer.
This commit is contained in:
StellaOps Bot
2025-12-05 01:00:10 +02:00
parent 8768c27f30
commit 175b750e29
111 changed files with 25407 additions and 19242 deletions

View File

@@ -0,0 +1,249 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace StellaOps.Cli.Services.Models;
/// <summary>
/// Air-gap mirror bundle format for offline operation with DSSE signature support.
/// Maps to docs/schemas/mirror-bundle.schema.json
/// </summary>
internal sealed record MirrorBundle
{
[JsonPropertyName("schemaVersion")]
public int SchemaVersion { get; init; } = 1;
[JsonPropertyName("generatedAt")]
public DateTimeOffset GeneratedAt { get; init; }
[JsonPropertyName("targetRepository")]
public string? TargetRepository { get; init; }
[JsonPropertyName("domainId")]
public required string DomainId { get; init; }
[JsonPropertyName("displayName")]
public string? DisplayName { get; init; }
[JsonPropertyName("exports")]
public required IReadOnlyList<MirrorBundleExport> Exports { get; init; }
}
internal sealed record MirrorBundleExport
{
[JsonPropertyName("key")]
public required string Key { get; init; }
[JsonPropertyName("format")]
public required string Format { get; init; }
[JsonPropertyName("exportId")]
public required string ExportId { get; init; }
[JsonPropertyName("querySignature")]
public string? QuerySignature { get; init; }
[JsonPropertyName("createdAt")]
public required DateTimeOffset CreatedAt { get; init; }
[JsonPropertyName("artifactSizeBytes")]
public long? ArtifactSizeBytes { get; init; }
[JsonPropertyName("artifactDigest")]
public required string ArtifactDigest { get; init; }
[JsonPropertyName("consensusRevision")]
public string? ConsensusRevision { get; init; }
[JsonPropertyName("policyRevisionId")]
public string? PolicyRevisionId { get; init; }
[JsonPropertyName("policyDigest")]
public string? PolicyDigest { get; init; }
[JsonPropertyName("consensusDigest")]
public string? ConsensusDigest { get; init; }
[JsonPropertyName("scoreDigest")]
public string? ScoreDigest { get; init; }
[JsonPropertyName("sourceProviders")]
public IReadOnlyList<string>? SourceProviders { get; init; }
[JsonPropertyName("attestation")]
public MirrorAttestationDescriptor? Attestation { get; init; }
}
internal sealed record MirrorAttestationDescriptor
{
[JsonPropertyName("predicateType")]
public required string PredicateType { get; init; }
[JsonPropertyName("rekorLocation")]
public string? RekorLocation { get; init; }
[JsonPropertyName("envelopeDigest")]
public string? EnvelopeDigest { get; init; }
[JsonPropertyName("signedAt")]
public DateTimeOffset? SignedAt { get; init; }
}
internal sealed record MirrorBundleSignature
{
[JsonPropertyName("path")]
public string? Path { get; init; }
[JsonPropertyName("algorithm")]
public required string Algorithm { get; init; }
[JsonPropertyName("keyId")]
public required string KeyId { get; init; }
[JsonPropertyName("provider")]
public string? Provider { get; init; }
[JsonPropertyName("signedAt")]
public required DateTimeOffset SignedAt { get; init; }
}
internal sealed record MirrorBundleManifest
{
[JsonPropertyName("schemaVersion")]
public int SchemaVersion { get; init; } = 1;
[JsonPropertyName("generatedAt")]
public DateTimeOffset GeneratedAt { get; init; }
[JsonPropertyName("domainId")]
public required string DomainId { get; init; }
[JsonPropertyName("displayName")]
public string? DisplayName { get; init; }
[JsonPropertyName("targetRepository")]
public string? TargetRepository { get; init; }
[JsonPropertyName("bundle")]
public required MirrorFileDescriptor Bundle { get; init; }
[JsonPropertyName("exports")]
public IReadOnlyList<MirrorBundleExport>? Exports { get; init; }
}
internal sealed record MirrorFileDescriptor
{
[JsonPropertyName("path")]
public required string Path { get; init; }
[JsonPropertyName("sizeBytes")]
public required long SizeBytes { get; init; }
[JsonPropertyName("digest")]
public required string Digest { get; init; }
[JsonPropertyName("signature")]
public MirrorBundleSignature? Signature { get; init; }
}
/// <summary>
/// Request model for creating a mirror bundle.
/// </summary>
internal sealed record MirrorCreateRequest
{
/// <summary>
/// Domain identifier (e.g., "vex-advisories", "vulnerability-feeds", "policy-packs").
/// </summary>
public required string DomainId { get; init; }
/// <summary>
/// Human-readable display name for the bundle.
/// </summary>
public string? DisplayName { get; init; }
/// <summary>
/// Target OCI repository for this bundle.
/// </summary>
public string? TargetRepository { get; init; }
/// <summary>
/// Export format filter (e.g., "openvex", "csaf", "cyclonedx").
/// </summary>
public string? Format { get; init; }
/// <summary>
/// Provider filter for VEX exports.
/// </summary>
public IReadOnlyList<string>? Providers { get; init; }
/// <summary>
/// Output directory for the bundle files.
/// </summary>
public required string OutputDirectory { get; init; }
/// <summary>
/// Whether to include DSSE signatures.
/// </summary>
public bool IncludeSignatures { get; init; }
/// <summary>
/// Whether to include attestation metadata.
/// </summary>
public bool IncludeAttestations { get; init; }
/// <summary>
/// Tenant scope for the exports.
/// </summary>
public string? Tenant { get; init; }
}
/// <summary>
/// Result model for mirror bundle creation.
/// </summary>
internal sealed record MirrorCreateResult
{
/// <summary>
/// Path to the created bundle manifest.
/// </summary>
public required string ManifestPath { get; init; }
/// <summary>
/// Path to the bundle archive (if created).
/// </summary>
public string? BundlePath { get; init; }
/// <summary>
/// Path to the bundle signature (if created).
/// </summary>
public string? SignaturePath { get; init; }
/// <summary>
/// Number of exports included in the bundle.
/// </summary>
public int ExportCount { get; init; }
/// <summary>
/// Total size in bytes of all exported artifacts.
/// </summary>
public long TotalSizeBytes { get; init; }
/// <summary>
/// Bundle digest for verification.
/// </summary>
public string? BundleDigest { get; init; }
/// <summary>
/// Timestamp when the bundle was generated.
/// </summary>
public DateTimeOffset GeneratedAt { get; init; }
/// <summary>
/// Domain ID of the bundle.
/// </summary>
public required string DomainId { get; init; }
/// <summary>
/// Export details for verbose output.
/// </summary>
public IReadOnlyList<MirrorBundleExport>? Exports { get; init; }
}