up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-26 07:47:08 +02:00
parent 56e2f64d07
commit 1c782897f7
184 changed files with 8991 additions and 649 deletions

View File

@@ -0,0 +1,53 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using StellaOps.Scanner.WebService.Contracts;
using StellaOps.Scanner.WebService.Domain;
using StellaOps.Scanner.WebService.Services;
namespace StellaOps.Scanner.WebService.Endpoints;
internal static class ReplayEndpoints
{
public static void MapReplayEndpoints(this RouteGroupBuilder apiGroup)
{
var replay = apiGroup.MapGroup("/replay");
replay.MapPost("/{scanId}/attach", HandleAttachAsync)
.WithName("scanner.replay.attach")
.Produces<ReplayAttachResponse>(StatusCodes.Status200OK)
.Produces(StatusCodes.Status404NotFound)
.Produces(StatusCodes.Status400BadRequest);
}
private static async Task<IResult> HandleAttachAsync(
string scanId,
ReplayAttachRequest request,
IScanCoordinator coordinator,
HttpContext context,
CancellationToken cancellationToken)
{
if (!ScanId.TryParse(scanId, out var parsed))
{
return Results.BadRequest("invalid scan id");
}
if (string.IsNullOrWhiteSpace(request.ManifestHash) || request.Bundles is null || request.Bundles.Count == 0)
{
return Results.BadRequest("manifest hash and bundles are required");
}
var replay = new ReplayArtifacts(
request.ManifestHash,
request.Bundles
.Select(b => new ReplayBundleSummary(b.Type, b.Digest, b.CasUri, b.SizeBytes))
.ToList());
var attached = await coordinator.AttachReplayAsync(parsed, replay, cancellationToken).ConfigureAwait(false);
if (!attached)
{
return Results.NotFound();
}
return Results.Ok(new ReplayAttachResponse("attached"));
}
}

View File

@@ -203,7 +203,8 @@ internal static class ScanEndpoints
CreatedAt: snapshot.CreatedAt,
UpdatedAt: snapshot.UpdatedAt,
FailureReason: snapshot.FailureReason,
Surface: surfacePointers);
Surface: surfacePointers,
Replay: snapshot.Replay is null ? null : MapReplay(snapshot.Replay));
return Json(response, StatusCodes.Status200OK);
}
@@ -283,6 +284,15 @@ internal static class ScanEndpoints
return Results.Empty;
}
private static ReplayStatusDto MapReplay(ReplayArtifacts replay)
{
return new ReplayStatusDto(
ManifestHash: replay.ManifestHash,
Bundles: replay.Bundles
.Select(b => new ReplayBundleStatusDto(b.Type, b.Digest, b.CasUri, b.SizeBytes))
.ToList());
}
private static async Task<IResult> HandleEntryTraceAsync(
string scanId,