using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using StellaOps.Configuration;
namespace StellaOps.Concelier.WebService.Options;
public sealed class ConcelierOptions
{
[Obsolete("Legacy storage has been removed; use PostgresStorage.")]
public LegacyStorageOptions LegacyStorage { get; set; } = new();
public PostgresStorageOptions? PostgresStorage { get; set; } = new PostgresStorageOptions
{
Enabled = true
};
public PluginOptions Plugins { get; set; } = new();
public TelemetryOptions Telemetry { get; set; } = new();
public AuthorityOptions Authority { get; set; } = new();
public MirrorOptions Mirror { get; set; } = new();
public FeaturesOptions Features { get; set; } = new();
public AdvisoryChunkOptions AdvisoryChunks { get; set; } = new();
public EvidenceBundleOptions Evidence { get; set; } = new();
public StellaOpsCryptoOptions Crypto { get; } = new();
///
/// Air-gap mode configuration.
/// Per CONCELIER-WEB-AIRGAP-56-001.
///
public AirGapOptions AirGap { get; set; } = new();
[Obsolete("Legacy storage has been removed; use PostgresStorage.")]
public sealed class LegacyStorageOptions
{
public string Driver { get; set; } = "postgres";
public string Dsn { get; set; } = string.Empty;
public string? Database { get; set; }
public int CommandTimeoutSeconds { get; set; } = 30;
}
///
/// PostgreSQL storage options for the LNM linkset cache.
///
public sealed class PostgresStorageOptions
{
///
/// Enable PostgreSQL storage for LNM linkset cache.
///
public bool Enabled { get; set; }
///
/// PostgreSQL connection string.
///
public string ConnectionString { get; set; } = string.Empty;
///
/// Command timeout in seconds. Default is 30 seconds.
///
public int CommandTimeoutSeconds { get; set; } = 30;
///
/// Maximum number of connections in the pool. Default is 100.
///
public int MaxPoolSize { get; set; } = 100;
///
/// Minimum number of connections in the pool. Default is 1.
///
public int MinPoolSize { get; set; } = 1;
///
/// Connection idle lifetime in seconds. Default is 300 seconds (5 minutes).
///
public int ConnectionIdleLifetimeSeconds { get; set; } = 300;
///
/// Enable connection pooling. Default is true.
///
public bool Pooling { get; set; } = true;
///
/// Schema name for LNM tables. Default is "vuln".
///
public string SchemaName { get; set; } = "vuln";
///
/// Enable automatic migration on startup. Default is false for production safety.
///
public bool AutoMigrate { get; set; }
///
/// Path to SQL migration files. Required if AutoMigrate is true.
///
public string? MigrationsPath { get; set; }
}
public sealed class PluginOptions
{
public string? BaseDirectory { get; set; }
public string? Directory { get; set; }
public IList SearchPatterns { get; set; } = new List();
}
public sealed class TelemetryOptions
{
public bool Enabled { get; set; } = true;
public bool EnableTracing { get; set; } = true;
public bool EnableMetrics { get; set; } = true;
public bool EnableLogging { get; set; } = true;
public string MinimumLogLevel { get; set; } = "Information";
public string? ServiceName { get; set; }
public string? OtlpEndpoint { get; set; }
public IDictionary OtlpHeaders { get; set; } = new Dictionary(StringComparer.OrdinalIgnoreCase);
public IDictionary ResourceAttributes { get; set; } = new Dictionary(StringComparer.OrdinalIgnoreCase);
public bool ExportConsole { get; set; }
}
public sealed class AuthorityOptions
{
public bool Enabled { get; set; }
public bool AllowAnonymousFallback { get; set; } = true;
public string Issuer { get; set; } = string.Empty;
public string? MetadataAddress { get; set; }
public bool RequireHttpsMetadata { get; set; } = true;
public int BackchannelTimeoutSeconds { get; set; } = 30;
public int TokenClockSkewSeconds { get; set; } = 60;
public IList Audiences { get; set; } = new List();
public IList RequiredScopes { get; set; } = new List();
public IList RequiredTenants { get; set; } = new List();
public IList BypassNetworks { get; set; } = new List();
public string? ClientId { get; set; }
public string? ClientSecret { get; set; }
public string? ClientSecretFile { get; set; }
public string? TestSigningSecret { get; set; }
public IList ClientScopes { get; set; } = new List();
public ResilienceOptions Resilience { get; set; } = new();
public sealed class ResilienceOptions
{
public bool? EnableRetries { get; set; }
public IList RetryDelays { get; set; } = new List();
public bool? AllowOfflineCacheFallback { get; set; }
public TimeSpan? OfflineCacheTolerance { get; set; }
}
}
public sealed class MirrorOptions
{
public bool Enabled { get; set; }
public string ExportRoot { get; set; } = System.IO.Path.Combine("exports", "json");
public string? ActiveExportId { get; set; }
public string LatestDirectoryName { get; set; } = "latest";
public string MirrorDirectoryName { get; set; } = "mirror";
public bool RequireAuthentication { get; set; }
public int MaxIndexRequestsPerHour { get; set; } = 600;
public IList Domains { get; } = new List();
[JsonIgnore]
public string ExportRootAbsolute { get; internal set; } = string.Empty;
}
public sealed class MirrorDomainOptions
{
public string Id { get; set; } = string.Empty;
public string? DisplayName { get; set; }
public bool RequireAuthentication { get; set; }
public int MaxDownloadRequestsPerHour { get; set; } = 1200;
}
public sealed class FeaturesOptions
{
public bool NoMergeEnabled { get; set; } = true;
public bool LnmShadowWrites { get; set; } = true;
public IList MergeJobAllowlist { get; } = new List();
}
public sealed class AdvisoryChunkOptions
{
public int DefaultChunkLimit { get; set; } = 200;
public int MaxChunkLimit { get; set; } = 400;
public int DefaultObservationLimit { get; set; } = 24;
public int MaxObservationLimit { get; set; } = 48;
public int DefaultMinimumLength { get; set; } = 64;
public int MaxMinimumLength { get; set; } = 512;
public int CacheDurationSeconds { get; set; } = 30;
}
public sealed class EvidenceBundleOptions
{
public bool Enabled { get; set; } = true;
public string Root { get; set; } = System.IO.Path.Combine("out", "evidence", "bundles");
public string? DefaultManifestFileName { get; set; } = "manifest.json";
public string? DefaultTransparencyFileName { get; set; } = "transparency.json";
public string PipelineVersion { get; set; } = "git:unknown";
[JsonIgnore]
public string RootAbsolute { get; internal set; } = string.Empty;
}
}