Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Created project for StellaOps.Scanner.Analyzers.Native.Tests with necessary dependencies. - Documented roles and guidelines in AGENTS.md for Scheduler module. - Implemented IResolverJobService interface and InMemoryResolverJobService for handling resolver jobs. - Added ResolverBacklogNotifier and ResolverBacklogService for monitoring job metrics. - Developed API endpoints for managing resolver jobs and retrieving metrics. - Defined models for resolver job requests and responses. - Integrated dependency injection for resolver job services. - Implemented ImpactIndexSnapshot for persisting impact index data. - Introduced SignalsScoringOptions for configurable scoring weights in reachability scoring. - Added unit tests for ReachabilityScoringService and RuntimeFactsIngestionService. - Created dotnet-filter.sh script to handle command-line arguments for dotnet. - Established nuget-prime project for managing package downloads.
102 lines
4.1 KiB
C#
102 lines
4.1 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using StellaOps.Auth.Abstractions;
|
|
using StellaOps.Scheduler.WebService.Auth;
|
|
|
|
namespace StellaOps.Scheduler.WebService.VulnerabilityResolverJobs;
|
|
|
|
public static class ResolverJobEndpointExtensions
|
|
{
|
|
private const string ScopeWrite = StellaOpsScopes.EffectiveWrite;
|
|
private const string ScopeRead = StellaOpsScopes.FindingsRead;
|
|
|
|
public static void MapResolverJobEndpoints(this IEndpointRouteBuilder builder)
|
|
{
|
|
var group = builder.MapGroup("/api/v1/scheduler/vuln/resolver");
|
|
group.MapPost("/jobs", CreateJobAsync);
|
|
group.MapGet("/jobs/{jobId}", GetJobAsync);
|
|
group.MapGet("/metrics", GetLagMetricsAsync);
|
|
}
|
|
|
|
internal static async Task<IResult> CreateJobAsync(
|
|
[FromBody] ResolverJobRequest request,
|
|
HttpContext httpContext,
|
|
[FromServices] ITenantContextAccessor tenantAccessor,
|
|
[FromServices] IScopeAuthorizer authorizer,
|
|
[FromServices] IResolverJobService jobService,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
authorizer.EnsureScope(httpContext, ScopeWrite);
|
|
var tenant = tenantAccessor.GetTenant(httpContext);
|
|
var job = await jobService.CreateAsync(tenant.TenantId, request, cancellationToken).ConfigureAwait(false);
|
|
return Results.Created($"/api/v1/scheduler/vuln/resolver/jobs/{job.Id}", job);
|
|
}
|
|
catch (UnauthorizedAccessException ex)
|
|
{
|
|
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status401Unauthorized);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status403Forbidden);
|
|
}
|
|
catch (ValidationException ex)
|
|
{
|
|
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status400BadRequest);
|
|
}
|
|
}
|
|
|
|
internal static async Task<IResult> GetJobAsync(
|
|
string jobId,
|
|
HttpContext httpContext,
|
|
[FromServices] ITenantContextAccessor tenantAccessor,
|
|
[FromServices] IScopeAuthorizer authorizer,
|
|
[FromServices] IResolverJobService jobService,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
authorizer.EnsureScope(httpContext, ScopeRead);
|
|
var tenant = tenantAccessor.GetTenant(httpContext);
|
|
var job = await jobService.GetAsync(tenant.TenantId, jobId, cancellationToken).ConfigureAwait(false);
|
|
return job is null ? Results.NotFound() : Results.Ok(job);
|
|
}
|
|
catch (UnauthorizedAccessException ex)
|
|
{
|
|
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status401Unauthorized);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status403Forbidden);
|
|
}
|
|
}
|
|
|
|
internal static IResult GetLagMetricsAsync(
|
|
HttpContext httpContext,
|
|
[FromServices] ITenantContextAccessor tenantAccessor,
|
|
[FromServices] IScopeAuthorizer authorizer,
|
|
[FromServices] IResolverJobService jobService,
|
|
[FromServices] IResolverBacklogService backlogService,
|
|
[FromServices] IResolverBacklogNotifier backlogNotifier)
|
|
{
|
|
try
|
|
{
|
|
authorizer.EnsureScope(httpContext, ScopeRead);
|
|
var tenant = tenantAccessor.GetTenant(httpContext);
|
|
var metrics = jobService.ComputeMetrics(tenant.TenantId);
|
|
var backlog = backlogService.GetSummary();
|
|
backlogNotifier.NotifyIfBreached(metrics with { Pending = (int)backlog.TotalDepth });
|
|
return Results.Ok(new { jobs = metrics, backlog });
|
|
}
|
|
catch (UnauthorizedAccessException ex)
|
|
{
|
|
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status401Unauthorized);
|
|
}
|
|
catch (InvalidOperationException ex)
|
|
{
|
|
return Results.Json(new { error = ex.Message }, statusCode: StatusCodes.Status403Forbidden);
|
|
}
|
|
}
|
|
}
|