up
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-12-01 21:16:22 +02:00
parent c11d87d252
commit 909d9b6220
208 changed files with 860954 additions and 832 deletions

View File

@@ -198,16 +198,16 @@ internal sealed class RuntimePostureEvaluator : IRuntimePostureEvaluator
return posture;
}
private async Task EnrichWithManifestAsync(string? manifestDigest, List<RuntimeEvidence> evidence, CancellationToken cancellationToken)
private async Task EnrichWithManifestAsync(string? manifestPointer, List<RuntimeEvidence> evidence, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(manifestDigest))
if (string.IsNullOrWhiteSpace(manifestPointer))
{
return;
}
try
{
var manifest = await surfaceFsClient.TryGetManifestAsync(manifestDigest, cancellationToken).ConfigureAwait(false);
var manifest = await surfaceFsClient.TryGetManifestAsync(manifestPointer, cancellationToken).ConfigureAwait(false);
if (manifest is null)
{
ManifestFailuresCounter.Add(1, new KeyValuePair<string, object?>("reason", "not_found"));
@@ -216,7 +216,7 @@ internal sealed class RuntimePostureEvaluator : IRuntimePostureEvaluator
Signal = "runtime.surface.manifest",
Value = "not_found"
});
logger.LogDebug("Surface manifest {ManifestDigest} not found in local cache.", manifestDigest);
logger.LogDebug("Surface manifest {ManifestPointer} not found in local cache.", manifestPointer);
return;
}
@@ -228,8 +228,10 @@ internal sealed class RuntimePostureEvaluator : IRuntimePostureEvaluator
evidence.Add(new RuntimeEvidence
{
Signal = "runtime.surface.manifestDigest",
Value = manifestDigest
Signal = manifestPointer.StartsWith("cas://", StringComparison.OrdinalIgnoreCase)
? "runtime.surface.manifestUri"
: "runtime.surface.manifestDigest",
Value = manifestPointer
});
if (!string.IsNullOrWhiteSpace(manifest.ImageDigest))
@@ -276,7 +278,7 @@ internal sealed class RuntimePostureEvaluator : IRuntimePostureEvaluator
Signal = "runtime.surface.manifest",
Value = "fetch_error"
});
logger.LogWarning(ex, "Failed to fetch Surface manifest {ManifestDigest}.", manifestDigest);
logger.LogWarning(ex, "Failed to fetch Surface manifest {ManifestPointer}.", manifestPointer);
}
}
}

View File

@@ -5,7 +5,10 @@ namespace StellaOps.Zastava.Observer.Surface;
internal interface IRuntimeSurfaceFsClient
{
Task<SurfaceManifestDocument?> TryGetManifestAsync(string manifestDigest, CancellationToken cancellationToken = default);
/// <summary>
/// Resolve a Surface manifest from either a digest (sha256:...) or a CAS URI (cas://.../*.json).
/// </summary>
Task<SurfaceManifestDocument?> TryGetManifestAsync(string manifestPointer, CancellationToken cancellationToken = default);
}
internal sealed class RuntimeSurfaceFsClient : IRuntimeSurfaceFsClient
@@ -19,14 +22,25 @@ internal sealed class RuntimeSurfaceFsClient : IRuntimeSurfaceFsClient
_environment = environment ?? throw new ArgumentNullException(nameof(environment));
}
public async Task<SurfaceManifestDocument?> TryGetManifestAsync(string manifestDigest, CancellationToken cancellationToken = default)
public async Task<SurfaceManifestDocument?> TryGetManifestAsync(string manifestPointer, CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(manifestDigest))
if (string.IsNullOrWhiteSpace(manifestPointer))
{
return null;
}
var manifest = await _manifestReader.TryGetByDigestAsync(manifestDigest.Trim(), cancellationToken).ConfigureAwait(false);
manifestPointer = manifestPointer.Trim();
SurfaceManifestDocument? manifest = null;
if (manifestPointer.StartsWith("cas://", StringComparison.OrdinalIgnoreCase))
{
manifest = await _manifestReader.TryGetByUriAsync(manifestPointer, cancellationToken).ConfigureAwait(false);
}
else
{
manifest = await _manifestReader.TryGetByDigestAsync(manifestPointer, cancellationToken).ConfigureAwait(false);
}
if (manifest is null)
{
return null;

View File

@@ -95,6 +95,85 @@ public sealed class RuntimeSurfaceFsClientTests
}
}
[Fact]
public async Task TryGetManifestAsync_ResolvesCasUri_AndRespectsTenant()
{
var envVars = new Dictionary<string, string?>
{
["ZASTAVA_SURFACE_FS_ENDPOINT"] = "https://surface.example",
["ZASTAVA_SURFACE_TENANT"] = "team-a"
};
var originals = CaptureEnvironment(AllRelevantEnvVars);
try
{
ClearEnvironment(AllRelevantEnvVars);
foreach (var pair in envVars)
{
Environment.SetEnvironmentVariable(pair.Key, pair.Value);
}
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
[$"{ZastavaObserverOptions.SectionName}:runtimes:0:engine"] = "Containerd",
[$"{ZastavaObserverOptions.SectionName}:backend:baseAddress"] = "https://scanner.internal"
})
.Build();
var services = new ServiceCollection();
services.AddSingleton<IConfiguration>(configuration);
services.AddLogging();
services.AddZastavaObserver(configuration);
using var provider = services.BuildServiceProvider();
var manifestWriter = provider.GetRequiredService<ISurfaceManifestWriter>();
var client = provider.GetRequiredService<IRuntimeSurfaceFsClient>();
var tenantMismatchDoc = new SurfaceManifestDocument
{
Tenant = "team-b",
ImageDigest = "sha256:tenant-mismatch",
GeneratedAt = DateTimeOffset.UtcNow,
Artifacts = Array.Empty<SurfaceManifestArtifact>()
};
var matchedDoc = new SurfaceManifestDocument
{
Tenant = "team-a",
ImageDigest = "sha256:good",
GeneratedAt = DateTimeOffset.UtcNow,
Artifacts = new[]
{
new SurfaceManifestArtifact
{
Kind = "entry-trace",
Uri = "cas://surface-cache/team-a/entry-trace.ndjson",
Digest = "sha256:trace",
MediaType = "application/x-ndjson"
}
}
};
var mismatchPublished = await manifestWriter.PublishAsync(tenantMismatchDoc, default);
var matchedPublished = await manifestWriter.PublishAsync(matchedDoc, default);
// Tenant mismatch should be filtered out
var mismatch = await client.TryGetManifestAsync(mismatchPublished.ManifestUri, default);
Assert.Null(mismatch);
// cas:// URI should resolve and respect tenant
var resolved = await client.TryGetManifestAsync(matchedPublished.ManifestUri, default);
Assert.NotNull(resolved);
Assert.Equal(matchedDoc.ImageDigest, resolved!.ImageDigest);
Assert.Equal("team-a", resolved.Tenant);
}
finally
{
RestoreEnvironment(originals);
}
}
private static IReadOnlyDictionary<string, string?> CaptureEnvironment(IEnumerable<string> names)
{
var snapshot = new Dictionary<string, string?>();