save progress

This commit is contained in:
StellaOps Bot
2026-01-04 19:08:47 +02:00
parent f7d27c6fda
commit 75611a505f
97 changed files with 4531 additions and 293 deletions

View File

@@ -24,6 +24,7 @@ public sealed class CliSourceHandler : ISourceTypeHandler
{
private readonly ISourceConfigValidator _configValidator;
private readonly ILogger<CliSourceHandler> _logger;
private readonly TimeProvider _timeProvider;
private static readonly JsonSerializerOptions JsonOptions = new()
{
@@ -38,10 +39,12 @@ public sealed class CliSourceHandler : ISourceTypeHandler
public CliSourceHandler(
ISourceConfigValidator configValidator,
ILogger<CliSourceHandler> logger)
ILogger<CliSourceHandler> logger,
TimeProvider? timeProvider = null)
{
_configValidator = configValidator;
_logger = logger;
_timeProvider = timeProvider ?? TimeProvider.System;
}
/// <summary>
@@ -102,7 +105,7 @@ public sealed class CliSourceHandler : ISourceTypeHandler
{
Success = false,
Message = "Invalid configuration",
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
});
}
@@ -112,7 +115,7 @@ public sealed class CliSourceHandler : ISourceTypeHandler
{
Success = true,
Message = "CLI source configuration is valid",
TestedAt = DateTimeOffset.UtcNow,
TestedAt = _timeProvider.GetUtcNow(),
Details = new Dictionary<string, object>
{
["allowedTools"] = config.AllowedTools,
@@ -242,8 +245,8 @@ public sealed class CliSourceHandler : ISourceTypeHandler
Token = token,
TokenHash = Convert.ToHexString(tokenHash).ToLowerInvariant(),
SourceId = source.SourceId,
ExpiresAt = DateTimeOffset.UtcNow.Add(validity),
CreatedAt = DateTimeOffset.UtcNow
ExpiresAt = _timeProvider.GetUtcNow().Add(validity),
CreatedAt = _timeProvider.GetUtcNow()
};
}

View File

@@ -21,6 +21,7 @@ public sealed class DockerSourceHandler : ISourceTypeHandler
private readonly ISourceConfigValidator _configValidator;
private readonly IImageDiscoveryService _discoveryService;
private readonly ILogger<DockerSourceHandler> _logger;
private readonly TimeProvider _timeProvider;
private static readonly JsonSerializerOptions JsonOptions = new()
{
@@ -38,13 +39,15 @@ public sealed class DockerSourceHandler : ISourceTypeHandler
ICredentialResolver credentialResolver,
ISourceConfigValidator configValidator,
IImageDiscoveryService discoveryService,
ILogger<DockerSourceHandler> logger)
ILogger<DockerSourceHandler> logger,
TimeProvider? timeProvider = null)
{
_clientFactory = clientFactory;
_credentialResolver = credentialResolver;
_configValidator = configValidator;
_discoveryService = discoveryService;
_logger = logger;
_timeProvider = timeProvider ?? TimeProvider.System;
}
public async Task<IReadOnlyList<ScanTarget>> DiscoverTargetsAsync(
@@ -136,7 +139,7 @@ public sealed class DockerSourceHandler : ISourceTypeHandler
// Apply age filter if specified
if (imageSpec.MaxAgeHours.HasValue)
{
var cutoff = DateTimeOffset.UtcNow.AddHours(-imageSpec.MaxAgeHours.Value);
var cutoff = _timeProvider.GetUtcNow().AddHours(-imageSpec.MaxAgeHours.Value);
sortedTags = sortedTags
.Where(t => t.LastUpdated == null || t.LastUpdated >= cutoff)
.ToList();
@@ -181,7 +184,7 @@ public sealed class DockerSourceHandler : ISourceTypeHandler
{
Success = false,
Message = "Invalid configuration",
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
};
}
@@ -198,7 +201,7 @@ public sealed class DockerSourceHandler : ISourceTypeHandler
{
Success = false,
Message = "Registry ping failed",
TestedAt = DateTimeOffset.UtcNow,
TestedAt = _timeProvider.GetUtcNow(),
Details = new Dictionary<string, object>
{
["registryUrl"] = config.RegistryUrl
@@ -216,7 +219,7 @@ public sealed class DockerSourceHandler : ISourceTypeHandler
{
Success = true,
Message = "Successfully connected to registry",
TestedAt = DateTimeOffset.UtcNow,
TestedAt = _timeProvider.GetUtcNow(),
Details = new Dictionary<string, object>
{
["registryUrl"] = config.RegistryUrl,
@@ -230,7 +233,7 @@ public sealed class DockerSourceHandler : ISourceTypeHandler
{
Success = true,
Message = "Successfully connected to registry",
TestedAt = DateTimeOffset.UtcNow,
TestedAt = _timeProvider.GetUtcNow(),
Details = new Dictionary<string, object>
{
["registryUrl"] = config.RegistryUrl
@@ -244,7 +247,7 @@ public sealed class DockerSourceHandler : ISourceTypeHandler
{
Success = false,
Message = $"Connection failed: {ex.Message}",
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
};
}
}

View File

@@ -19,6 +19,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
private readonly ICredentialResolver _credentialResolver;
private readonly ISourceConfigValidator _configValidator;
private readonly ILogger<GitSourceHandler> _logger;
private readonly TimeProvider _timeProvider;
private static readonly JsonSerializerOptions JsonOptions = new()
{
@@ -35,12 +36,14 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
IGitClientFactory gitClientFactory,
ICredentialResolver credentialResolver,
ISourceConfigValidator configValidator,
ILogger<GitSourceHandler> logger)
ILogger<GitSourceHandler> logger,
TimeProvider? timeProvider = null)
{
_gitClientFactory = gitClientFactory;
_credentialResolver = credentialResolver;
_configValidator = configValidator;
_logger = logger;
_timeProvider = timeProvider ?? TimeProvider.System;
}
public async Task<IReadOnlyList<ScanTarget>> DiscoverTargetsAsync(
@@ -160,7 +163,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
{
Success = false,
Message = "Invalid configuration",
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
};
}
@@ -176,7 +179,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
{
Success = false,
Message = "Repository not found or inaccessible",
TestedAt = DateTimeOffset.UtcNow,
TestedAt = _timeProvider.GetUtcNow(),
Details = new Dictionary<string, object>
{
["repositoryUrl"] = config.RepositoryUrl,
@@ -189,7 +192,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
{
Success = true,
Message = "Successfully connected to repository",
TestedAt = DateTimeOffset.UtcNow,
TestedAt = _timeProvider.GetUtcNow(),
Details = new Dictionary<string, object>
{
["repositoryUrl"] = config.RepositoryUrl,
@@ -206,7 +209,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
{
Success = false,
Message = $"Connection failed: {ex.Message}",
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
};
}
}
@@ -270,7 +273,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
sender.TryGetProperty("login", out var login)
? login.GetString()
: null,
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}
@@ -303,7 +306,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
? num.GetInt32().ToString()
: ""
},
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}
@@ -330,7 +333,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
Actor = root.TryGetProperty("user_name", out var userName)
? userName.GetString()
: null,
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}
@@ -361,7 +364,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
? mrAction.GetString() ?? ""
: ""
},
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}
}
@@ -371,7 +374,7 @@ public sealed class GitSourceHandler : ISourceTypeHandler, IWebhookCapableHandle
{
EventType = "unknown",
Reference = "",
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}

View File

@@ -20,6 +20,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
private readonly ICredentialResolver _credentialResolver;
private readonly ISourceConfigValidator _configValidator;
private readonly ILogger<ZastavaSourceHandler> _logger;
private readonly TimeProvider _timeProvider;
private static readonly JsonSerializerOptions JsonOptions = new()
{
@@ -36,12 +37,14 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
IRegistryClientFactory clientFactory,
ICredentialResolver credentialResolver,
ISourceConfigValidator configValidator,
ILogger<ZastavaSourceHandler> logger)
ILogger<ZastavaSourceHandler> logger,
TimeProvider? timeProvider = null)
{
_clientFactory = clientFactory;
_credentialResolver = credentialResolver;
_configValidator = configValidator;
_logger = logger;
_timeProvider = timeProvider ?? TimeProvider.System;
}
public async Task<IReadOnlyList<ScanTarget>> DiscoverTargetsAsync(
@@ -167,7 +170,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
{
Success = false,
Message = "Invalid configuration",
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
};
}
@@ -183,7 +186,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
{
Success = false,
Message = "Registry ping failed",
TestedAt = DateTimeOffset.UtcNow,
TestedAt = _timeProvider.GetUtcNow(),
Details = new Dictionary<string, object>
{
["registryUrl"] = config.RegistryUrl,
@@ -199,7 +202,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
{
Success = true,
Message = "Successfully connected to registry",
TestedAt = DateTimeOffset.UtcNow,
TestedAt = _timeProvider.GetUtcNow(),
Details = new Dictionary<string, object>
{
["registryUrl"] = config.RegistryUrl,
@@ -215,7 +218,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
{
Success = false,
Message = $"Connection failed: {ex.Message}",
TestedAt = DateTimeOffset.UtcNow
TestedAt = _timeProvider.GetUtcNow()
};
}
}
@@ -281,7 +284,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
: repository.GetProperty("name").GetString()!,
Tag = pushData.TryGetProperty("tag", out var tag) ? tag.GetString() : "latest",
Actor = pushData.TryGetProperty("pusher", out var pusher) ? pusher.GetString() : null,
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}
@@ -309,7 +312,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
? digest.GetString()
: null,
Actor = eventData.TryGetProperty("operator", out var op) ? op.GetString() : null,
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}
@@ -338,7 +341,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
actor.TryGetProperty("name", out var actorName)
? actorName.GetString()
: null,
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}
@@ -347,7 +350,7 @@ public sealed class ZastavaSourceHandler : ISourceTypeHandler, IWebhookCapableHa
{
EventType = "unknown",
Reference = "",
Timestamp = DateTimeOffset.UtcNow
Timestamp = _timeProvider.GetUtcNow()
};
}