using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using StellaOps.Scanner.Surface.Env; using StellaOps.Scanner.Surface.Secrets; namespace StellaOps.Scanner.WebService.Options; internal sealed class ScannerSurfaceSecretConfigurator : IConfigureOptions { private const string ComponentName = "Scanner.WebService"; private readonly ISurfaceSecretProvider _secretProvider; private readonly ISurfaceEnvironment _surfaceEnvironment; private readonly ILogger _logger; public ScannerSurfaceSecretConfigurator( ISurfaceSecretProvider secretProvider, ISurfaceEnvironment surfaceEnvironment, ILogger logger) { _secretProvider = secretProvider ?? throw new ArgumentNullException(nameof(secretProvider)); _surfaceEnvironment = surfaceEnvironment ?? throw new ArgumentNullException(nameof(surfaceEnvironment)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public void Configure(ScannerWebServiceOptions options) { ArgumentNullException.ThrowIfNull(options); var tenant = _surfaceEnvironment.Settings.Secrets.Tenant; var request = new SurfaceSecretRequest( Tenant: tenant, Component: ComponentName, SecretType: "cas-access"); CasAccessSecret? secret = null; try { using var handle = _secretProvider.GetAsync(request).AsTask().GetAwaiter().GetResult(); secret = SurfaceSecretParser.ParseCasAccessSecret(handle); } catch (SurfaceSecretNotFoundException) { _logger.LogDebug("Surface secret 'cas-access' not found for {Component}; retaining configured artifact store settings.", ComponentName); } catch (Exception ex) { _logger.LogWarning(ex, "Failed to resolve surface secret 'cas-access' for {Component}.", ComponentName); } if (secret is null) { return; } ApplySecret(options.ArtifactStore ??= new ScannerWebServiceOptions.ArtifactStoreOptions(), secret); } private void ApplySecret(ScannerWebServiceOptions.ArtifactStoreOptions artifactStore, CasAccessSecret secret) { if (!string.IsNullOrWhiteSpace(secret.Driver)) { artifactStore.Driver = secret.Driver; } if (!string.IsNullOrWhiteSpace(secret.Endpoint)) { artifactStore.Endpoint = secret.Endpoint!; } if (secret.AllowInsecureTls is { } insecure) { artifactStore.AllowInsecureTls = insecure; artifactStore.UseTls = !insecure; } if (!string.IsNullOrWhiteSpace(secret.Region)) { artifactStore.Region = secret.Region; } if (!string.IsNullOrWhiteSpace(secret.Bucket)) { artifactStore.Bucket = secret.Bucket!; } if (!string.IsNullOrWhiteSpace(secret.RootPrefix)) { artifactStore.RootPrefix = secret.RootPrefix!; } if (!string.IsNullOrWhiteSpace(secret.ApiKeyHeader)) { artifactStore.ApiKeyHeader = secret.ApiKeyHeader!; } if (!string.IsNullOrWhiteSpace(secret.ApiKey)) { artifactStore.ApiKey = secret.ApiKey; } if (!string.IsNullOrWhiteSpace(secret.AccessKeyId) && !string.IsNullOrWhiteSpace(secret.SecretAccessKey)) { artifactStore.AccessKey = secret.AccessKeyId!; artifactStore.SecretKey = secret.SecretAccessKey!; } foreach (var header in secret.Headers) { if (string.IsNullOrWhiteSpace(header.Key) || string.IsNullOrWhiteSpace(header.Value)) { continue; } artifactStore.Headers[header.Key] = header.Value; } _logger.LogInformation( "Surface secret 'cas-access' applied for {Component} (driver: {Driver}, bucket: {Bucket}).", ComponentName, artifactStore.Driver, artifactStore.Bucket); } }