feat(graph-api): Add schema review notes for upcoming Graph API changes
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
feat(sbomservice): Add placeholder for SHA256SUMS in LNM v1 fixtures docs(devportal): Create README for SDK archives in public directory build(devportal): Implement offline bundle build script test(devportal): Add link checker script for validating links in documentation test(devportal): Create performance check script for dist folder size test(devportal): Implement accessibility check script using Playwright and Axe docs(devportal): Add SDK quickstart guide with examples for Node.js, Python, and cURL feat(excititor): Implement MongoDB storage for airgap import records test(findings): Add unit tests for export filters hash determinism feat(findings): Define attestation contracts for ledger web service feat(graph): Add MongoDB options and service collection extensions for graph indexing test(graph): Implement integration tests for MongoDB provider and service collection extensions feat(zastava): Define configuration options for Zastava surface secrets build(tests): Create script to run Concelier linkset tests with TRX output
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using StellaOps.Zastava.Core.Configuration;
|
||||
|
||||
namespace StellaOps.Zastava.Webhook.Configuration;
|
||||
|
||||
@@ -17,7 +18,10 @@ public sealed class ZastavaWebhookOptions
|
||||
|
||||
[Required]
|
||||
public ZastavaWebhookBackendOptions Backend { get; init; } = new();
|
||||
}
|
||||
|
||||
[Required]
|
||||
public ZastavaSurfaceSecretsOptions Secrets { get; init; } = new();
|
||||
}
|
||||
|
||||
public sealed class ZastavaWebhookAdmissionOptions
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ internal interface IWebhookSurfaceFsClient
|
||||
internal sealed class WebhookSurfaceFsClient : IWebhookSurfaceFsClient
|
||||
{
|
||||
private readonly ISurfaceManifestReader _manifestReader;
|
||||
private readonly SurfaceManifestPathBuilder _pathBuilder;
|
||||
private readonly SurfaceManifestStoreOptions _storeOptions;
|
||||
private readonly IOptions<ZastavaRuntimeOptions> _runtimeOptions;
|
||||
|
||||
public WebhookSurfaceFsClient(
|
||||
@@ -34,7 +34,7 @@ internal sealed class WebhookSurfaceFsClient : IWebhookSurfaceFsClient
|
||||
throw new ArgumentNullException(nameof(storeOptions));
|
||||
}
|
||||
|
||||
_pathBuilder = new SurfaceManifestPathBuilder(cacheOptions.Value, storeOptions.Value);
|
||||
_storeOptions = storeOptions.Value ?? throw new ArgumentNullException(nameof(storeOptions.Value));
|
||||
}
|
||||
|
||||
public async Task<(bool Found, string? ManifestUri)> TryGetManifestAsync(string manifestDigest, CancellationToken cancellationToken = default)
|
||||
@@ -57,9 +57,36 @@ internal sealed class WebhookSurfaceFsClient : IWebhookSurfaceFsClient
|
||||
? manifest.Tenant
|
||||
: _runtimeOptions.Value.Tenant;
|
||||
|
||||
var digestHex = SurfaceManifestPathBuilder.EnsureSha256Digest(manifestDigest); // strips sha256:
|
||||
var uri = _pathBuilder.BuildManifestUri(tenant, digestHex);
|
||||
var digestHex = EnsureSha256Digest(manifestDigest); // strips sha256:
|
||||
var uri = BuildManifestUri(_storeOptions, tenant, digestHex);
|
||||
|
||||
return (true, uri);
|
||||
}
|
||||
|
||||
private static string BuildManifestUri(SurfaceManifestStoreOptions storeOptions, string tenant, string digestHex)
|
||||
{
|
||||
var tenantSegment = SanitizeTenant(tenant);
|
||||
return $"{storeOptions.Scheme}://{storeOptions.Bucket}/{storeOptions.Prefix}/{tenantSegment}/{digestHex[..2]}/{digestHex[2..4]}/{digestHex}.json";
|
||||
}
|
||||
|
||||
private static string SanitizeTenant(string value)
|
||||
=> string.IsNullOrWhiteSpace(value)
|
||||
? "default"
|
||||
: value.Replace('/', '_').Replace('\\', '_');
|
||||
|
||||
private static string EnsureSha256Digest(string manifestDigest)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(manifestDigest))
|
||||
{
|
||||
throw new ArgumentException("Digest cannot be null or empty.", nameof(manifestDigest));
|
||||
}
|
||||
|
||||
const string prefix = "sha256:";
|
||||
if (!manifestDigest.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("Only sha256 digests are supported.", nameof(manifestDigest));
|
||||
}
|
||||
|
||||
return manifestDigest[prefix.Length..].ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user