release orchestrator v1 draft and build fixes

This commit is contained in:
master
2026-01-12 12:24:17 +02:00
parent f3de858c59
commit 9873f80830
1598 changed files with 240385 additions and 5944 deletions

View File

@@ -30,11 +30,16 @@ internal sealed class AttestationReader : IAttestationReader
private readonly ILogger<AttestationReader> _logger;
private readonly IForensicVerifier _verifier;
private readonly TimeProvider _timeProvider;
public AttestationReader(ILogger<AttestationReader> logger, IForensicVerifier verifier)
public AttestationReader(
ILogger<AttestationReader> logger,
IForensicVerifier verifier,
TimeProvider? timeProvider = null)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_verifier = verifier ?? throw new ArgumentNullException(nameof(verifier));
_timeProvider = timeProvider ?? TimeProvider.System;
}
public async Task<AttestationShowResult> ReadAttestationAsync(
@@ -127,7 +132,7 @@ internal sealed class AttestationReader : IAttestationReader
if (matchingRoot is not null)
{
var isValid = VerifySignature(envelope, sig, matchingRoot);
var now = DateTimeOffset.UtcNow;
var now = _timeProvider.GetUtcNow();
var timeValid = (!matchingRoot.NotBefore.HasValue || now >= matchingRoot.NotBefore.Value) &&
(!matchingRoot.NotAfter.HasValue || now <= matchingRoot.NotAfter.Value);

View File

@@ -26,6 +26,7 @@ internal sealed class OrchestratorClient : IOrchestratorClient
private readonly IStellaOpsTokenClient _tokenClient;
private readonly StellaOpsCliOptions _options;
private readonly ILogger<OrchestratorClient> _logger;
private readonly TimeProvider _timeProvider;
private static readonly JsonSerializerOptions JsonOptions = new()
{
@@ -37,12 +38,14 @@ internal sealed class OrchestratorClient : IOrchestratorClient
HttpClient httpClient,
IStellaOpsTokenClient tokenClient,
IOptions<StellaOpsCliOptions> options,
ILogger<OrchestratorClient> logger)
ILogger<OrchestratorClient> logger,
TimeProvider? timeProvider = null)
{
_httpClient = httpClient;
_tokenClient = tokenClient;
_options = options.Value;
_logger = logger;
_timeProvider = timeProvider ?? TimeProvider.System;
}
public async Task<SourceListResponse> ListSourcesAsync(
@@ -171,7 +174,7 @@ internal sealed class OrchestratorClient : IOrchestratorClient
SourceId = request.SourceId,
Reachable = false,
ErrorMessage = $"Failed to test source: {response.StatusCode} - {errorContent}",
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
};
}
@@ -181,7 +184,7 @@ internal sealed class OrchestratorClient : IOrchestratorClient
Success = true,
SourceId = request.SourceId,
Reachable = true,
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
};
}

View File

@@ -32,12 +32,18 @@ internal sealed partial class PromotionAssembler : IPromotionAssembler
private readonly HttpClient _httpClient;
private readonly ICryptoHash _cryptoHash;
private readonly ILogger<PromotionAssembler> _logger;
private readonly TimeProvider _timeProvider;
public PromotionAssembler(HttpClient httpClient, ICryptoHash cryptoHash, ILogger<PromotionAssembler> logger)
public PromotionAssembler(
HttpClient httpClient,
ICryptoHash cryptoHash,
ILogger<PromotionAssembler> logger,
TimeProvider? timeProvider = null)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_cryptoHash = cryptoHash ?? throw new ArgumentNullException(nameof(cryptoHash));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_timeProvider = timeProvider ?? TimeProvider.System;
}
public async Task<PromotionAssembleResult> AssembleAsync(
@@ -171,7 +177,7 @@ internal sealed partial class PromotionAssembler : IPromotionAssembler
From = request.FromEnvironment,
To = request.ToEnvironment,
Actor = request.Actor ?? Environment.UserName,
Timestamp = DateTimeOffset.UtcNow,
Timestamp = _timeProvider.GetUtcNow(),
Pipeline = request.Pipeline,
Ticket = request.Ticket,
Notes = request.Notes
@@ -527,7 +533,7 @@ internal sealed partial class PromotionAssembler : IPromotionAssembler
RekorEntry = rekorEntry,
AuditId = auditId,
SignerKeyId = signerKeyId,
SignedAt = DateTimeOffset.UtcNow,
SignedAt = _timeProvider.GetUtcNow(),
Warnings = warnings
};
}

View File

@@ -13,10 +13,12 @@ namespace StellaOps.Cli.Services;
internal sealed class ScannerExecutor : IScannerExecutor
{
private readonly ILogger<ScannerExecutor> _logger;
private readonly TimeProvider _timeProvider;
public ScannerExecutor(ILogger<ScannerExecutor> logger)
public ScannerExecutor(ILogger<ScannerExecutor> logger, TimeProvider? timeProvider = null)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_timeProvider = timeProvider ?? TimeProvider.System;
}
public async Task<ScannerExecutionResult> RunAsync(
@@ -47,7 +49,7 @@ internal sealed class ScannerExecutor : IScannerExecutor
: Path.GetFullPath(resultsDirectory);
Directory.CreateDirectory(resultsDirectory);
var executionTimestamp = DateTimeOffset.UtcNow;
var executionTimestamp = _timeProvider.GetUtcNow();
var baselineFiles = Directory.GetFiles(resultsDirectory, "*", SearchOption.AllDirectories);
var baseline = new HashSet<string>(baselineFiles, StringComparer.OrdinalIgnoreCase);
@@ -92,7 +94,7 @@ internal sealed class ScannerExecutor : IScannerExecutor
process.BeginErrorReadLine();
await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false);
var completionTimestamp = DateTimeOffset.UtcNow;
var completionTimestamp = _timeProvider.GetUtcNow();
if (process.ExitCode == 0)
{
@@ -279,9 +281,9 @@ internal sealed class ScannerExecutor : IScannerExecutor
return newest ?? string.Empty;
}
private static string CreatePlaceholderResult(string resultsDirectory)
private string CreatePlaceholderResult(string resultsDirectory)
{
var fileName = $"scan-{DateTimeOffset.UtcNow:yyyyMMddHHmmss}.json";
var fileName = $"scan-{_timeProvider.GetUtcNow():yyyyMMddHHmmss}.json";
var path = Path.Combine(resultsDirectory, fileName);
File.WriteAllText(path, "{\"status\":\"placeholder\"}");
return path;

View File

@@ -94,25 +94,29 @@ internal static class TenantProfileStore
.ConfigureAwait(false);
}
public static async Task SetActiveTenantAsync(string tenantId, string? displayName = null, CancellationToken cancellationToken = default)
public static async Task SetActiveTenantAsync(
string tenantId,
string? displayName = null,
DateTimeOffset? asOf = null,
CancellationToken cancellationToken = default)
{
var profile = new TenantProfile
{
ActiveTenant = tenantId?.Trim().ToLowerInvariant(),
ActiveTenantDisplayName = displayName?.Trim(),
LastUpdated = DateTimeOffset.UtcNow
LastUpdated = asOf ?? DateTimeOffset.UtcNow
};
await SaveAsync(profile, cancellationToken).ConfigureAwait(false);
}
public static async Task ClearActiveTenantAsync(CancellationToken cancellationToken = default)
public static async Task ClearActiveTenantAsync(DateTimeOffset? asOf = null, CancellationToken cancellationToken = default)
{
var profile = new TenantProfile
{
ActiveTenant = null,
ActiveTenantDisplayName = null,
LastUpdated = DateTimeOffset.UtcNow
LastUpdated = asOf ?? DateTimeOffset.UtcNow
};
await SaveAsync(profile, cancellationToken).ConfigureAwait(false);