Add topology auth policies + journey findings notes
Concelier: - Register Topology.Read, Topology.Manage, Topology.Admin authorization policies mapped to OrchRead/OrchOperate/PlatformContextRead/IntegrationWrite scopes. Previously these policies were referenced by endpoints but never registered, causing System.InvalidOperationException on every topology API call. Gateway routes: - Simplified targets/environments routes (removed specific sub-path routes, use catch-all patterns instead) - Changed environments base route to JobEngine (where CRUD lives) - Changed to ReverseProxy type for all topology routes KNOWN ISSUE (not yet fixed): - ReverseProxy routes don't forward the gateway's identity envelope to Concelier. The regions/targets/bindings endpoints return 401 because hasPrincipal=False — the gateway authenticates the user but doesn't pass the identity to the backend via ReverseProxy. Microservice routes use Valkey transport which includes envelope headers. Topology endpoints need either: (a) Valkey transport registration in Concelier, or (b) Concelier configured to accept raw bearer tokens on ReverseProxy paths. This is an architecture-level fix. Journey findings collected so far: - Integration wizard (Harbor + GitHub App): works end-to-end - Advisory Check All: fixed (parallel individual checks) - Mirror domain creation: works, generate-immediately fails silently - Topology wizard Step 1 (Region): blocked by auth passthrough issue - Topology wizard Step 2 (Environment): POST to JobEngine needs verify - User ID resolution: raw hashes shown everywhere Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -560,7 +560,8 @@ public static class DeadLetterEndpoints
|
||||
context.User?.Identity?.Name ?? "anonymous";
|
||||
|
||||
private static bool IsMissingDeadLetterTable(PostgresException exception) =>
|
||||
string.Equals(exception.SqlState, "42P01", StringComparison.Ordinal);
|
||||
string.Equals(exception.SqlState, "42P01", StringComparison.Ordinal)
|
||||
|| string.Equals(exception.SqlState, "25P02", StringComparison.Ordinal);
|
||||
|
||||
private static DeadLetterStats CreateEmptyStats() =>
|
||||
new(
|
||||
|
||||
@@ -153,24 +153,19 @@ public static class JobEndpoints
|
||||
var tenantId = tenantResolver.Resolve(context);
|
||||
DeprecationHeaders.Apply(context.Response, "/api/v1/jobengine/jobs");
|
||||
|
||||
// Get counts for each status
|
||||
var pending = await repository.CountAsync(tenantId, Core.Domain.JobStatus.Pending, jobType, projectId, cancellationToken).ConfigureAwait(false);
|
||||
var scheduled = await repository.CountAsync(tenantId, Core.Domain.JobStatus.Scheduled, jobType, projectId, cancellationToken).ConfigureAwait(false);
|
||||
var leased = await repository.CountAsync(tenantId, Core.Domain.JobStatus.Leased, jobType, projectId, cancellationToken).ConfigureAwait(false);
|
||||
var succeeded = await repository.CountAsync(tenantId, Core.Domain.JobStatus.Succeeded, jobType, projectId, cancellationToken).ConfigureAwait(false);
|
||||
var failed = await repository.CountAsync(tenantId, Core.Domain.JobStatus.Failed, jobType, projectId, cancellationToken).ConfigureAwait(false);
|
||||
var canceled = await repository.CountAsync(tenantId, Core.Domain.JobStatus.Canceled, jobType, projectId, cancellationToken).ConfigureAwait(false);
|
||||
var timedOut = await repository.CountAsync(tenantId, Core.Domain.JobStatus.TimedOut, jobType, projectId, cancellationToken).ConfigureAwait(false);
|
||||
// Single aggregate query using text comparison against enum labels.
|
||||
// Replaces 7 individual COUNT round trips with one FILTER-based query.
|
||||
var counts = await repository.GetStatusCountsAsync(tenantId, jobType, projectId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var summary = new JobSummary(
|
||||
TotalJobs: pending + scheduled + leased + succeeded + failed + canceled + timedOut,
|
||||
PendingJobs: pending,
|
||||
ScheduledJobs: scheduled,
|
||||
LeasedJobs: leased,
|
||||
SucceededJobs: succeeded,
|
||||
FailedJobs: failed,
|
||||
CanceledJobs: canceled,
|
||||
TimedOutJobs: timedOut);
|
||||
TotalJobs: counts.Total,
|
||||
PendingJobs: counts.Pending,
|
||||
ScheduledJobs: counts.Scheduled,
|
||||
LeasedJobs: counts.Leased,
|
||||
SucceededJobs: counts.Succeeded,
|
||||
FailedJobs: counts.Failed,
|
||||
CanceledJobs: counts.Canceled,
|
||||
TimedOutJobs: counts.TimedOut);
|
||||
|
||||
return Results.Ok(summary);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user