feat: Initialize Zastava Webhook service with TLS and Authority authentication

- Added Program.cs to set up the web application with Serilog for logging, health check endpoints, and a placeholder admission endpoint.
- Configured Kestrel server to use TLS 1.3 and handle client certificates appropriately.
- Created StellaOps.Zastava.Webhook.csproj with necessary dependencies including Serilog and Polly.
- Documented tasks in TASKS.md for the Zastava Webhook project, outlining current work and exit criteria for each task.
This commit is contained in:
master
2025-10-19 18:36:22 +03:00
parent 2062da7a8b
commit d099a90f9b
966 changed files with 91038 additions and 1850 deletions

View File

@@ -3,7 +3,8 @@ using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using StellaOps.Concelier.Core.Jobs;
namespace StellaOps.Concelier.Core.Tests;
@@ -311,10 +312,11 @@ public sealed class JobCoordinatorTests
public TaskCompletionSource<JobRunSnapshot> Completion { get; } = new(TaskCreationOptions.RunContinuationsAsynchronously);
public List<JobRunSnapshot> CreatedRuns { get; } = new();
public Task<JobRunSnapshot> CreateAsync(JobRunCreateRequest request, CancellationToken cancellationToken)
{
var run = new JobRunSnapshot(
Guid.NewGuid(),
public Task<JobRunSnapshot> CreateAsync(JobRunCreateRequest request, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_ = session;
var run = new JobRunSnapshot(
Guid.NewGuid(),
request.Kind,
JobRunStatus.Pending,
request.CreatedAt,
@@ -331,9 +333,10 @@ public sealed class JobCoordinatorTests
return Task.FromResult(run);
}
public Task<JobRunSnapshot?> TryStartAsync(Guid runId, DateTimeOffset startedAt, CancellationToken cancellationToken)
{
if (_runs.TryGetValue(runId, out var run))
public Task<JobRunSnapshot?> TryStartAsync(Guid runId, DateTimeOffset startedAt, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_ = session;
if (_runs.TryGetValue(runId, out var run))
{
var updated = run with { Status = JobRunStatus.Running, StartedAt = startedAt };
_runs[runId] = updated;
@@ -343,9 +346,10 @@ public sealed class JobCoordinatorTests
return Task.FromResult<JobRunSnapshot?>(null);
}
public Task<JobRunSnapshot?> TryCompleteAsync(Guid runId, JobRunCompletion completion, CancellationToken cancellationToken)
{
if (_runs.TryGetValue(runId, out var run))
public Task<JobRunSnapshot?> TryCompleteAsync(Guid runId, JobRunCompletion completion, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_ = session;
if (_runs.TryGetValue(runId, out var run))
{
var updated = run with { Status = completion.Status, CompletedAt = completion.CompletedAt, Error = completion.Error };
_runs[runId] = updated;
@@ -356,15 +360,17 @@ public sealed class JobCoordinatorTests
return Task.FromResult<JobRunSnapshot?>(null);
}
public Task<JobRunSnapshot?> FindAsync(Guid runId, CancellationToken cancellationToken)
{
_runs.TryGetValue(runId, out var run);
return Task.FromResult<JobRunSnapshot?>(run);
}
public Task<JobRunSnapshot?> FindAsync(Guid runId, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_ = session;
_runs.TryGetValue(runId, out var run);
return Task.FromResult<JobRunSnapshot?>(run);
}
public Task<IReadOnlyList<JobRunSnapshot>> GetRecentRunsAsync(string? kind, int limit, CancellationToken cancellationToken)
{
var query = _runs.Values.AsEnumerable();
public Task<IReadOnlyList<JobRunSnapshot>> GetRecentRunsAsync(string? kind, int limit, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_ = session;
var query = _runs.Values.AsEnumerable();
if (!string.IsNullOrWhiteSpace(kind))
{
query = query.Where(r => r.Kind == kind);
@@ -373,23 +379,26 @@ public sealed class JobCoordinatorTests
return Task.FromResult<IReadOnlyList<JobRunSnapshot>>(query.OrderByDescending(r => r.CreatedAt).Take(limit).ToArray());
}
public Task<IReadOnlyList<JobRunSnapshot>> GetActiveRunsAsync(CancellationToken cancellationToken)
{
return Task.FromResult<IReadOnlyList<JobRunSnapshot>>(_runs.Values.Where(r => r.Status is JobRunStatus.Pending or JobRunStatus.Running).ToArray());
}
public Task<IReadOnlyList<JobRunSnapshot>> GetActiveRunsAsync(CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_ = session;
return Task.FromResult<IReadOnlyList<JobRunSnapshot>>(_runs.Values.Where(r => r.Status is JobRunStatus.Pending or JobRunStatus.Running).ToArray());
}
public Task<JobRunSnapshot?> GetLastRunAsync(string kind, CancellationToken cancellationToken)
{
var run = _runs.Values
.Where(r => r.Kind == kind)
.OrderByDescending(r => r.CreatedAt)
public Task<JobRunSnapshot?> GetLastRunAsync(string kind, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_ = session;
var run = _runs.Values
.Where(r => r.Kind == kind)
.OrderByDescending(r => r.CreatedAt)
.FirstOrDefault();
return Task.FromResult<JobRunSnapshot?>(run);
}
public Task<IReadOnlyDictionary<string, JobRunSnapshot>> GetLastRunsAsync(IEnumerable<string> kinds, CancellationToken cancellationToken)
{
var results = new Dictionary<string, JobRunSnapshot>(StringComparer.Ordinal);
public Task<IReadOnlyDictionary<string, JobRunSnapshot>> GetLastRunsAsync(IEnumerable<string> kinds, CancellationToken cancellationToken, IClientSessionHandle? session = null)
{
_ = session;
var results = new Dictionary<string, JobRunSnapshot>(StringComparer.Ordinal);
foreach (var kind in kinds.Distinct(StringComparer.Ordinal))
{
var run = _runs.Values