Restructure solution layout by module
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace StellaOps.Signals.Options;
|
||||
|
||||
/// <summary>
|
||||
/// Artifact storage configuration for Signals callgraph ingestion.
|
||||
/// </summary>
|
||||
public sealed class SignalsArtifactStorageOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Root directory used to persist raw callgraph artifacts.
|
||||
/// </summary>
|
||||
public string RootPath { get; set; } = Path.Combine(AppContext.BaseDirectory, "callgraph-artifacts");
|
||||
|
||||
/// <summary>
|
||||
/// Validates the configured values.
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(RootPath))
|
||||
{
|
||||
throw new InvalidOperationException("Signals artifact storage path must be configured.");
|
||||
}
|
||||
}
|
||||
}
|
||||
101
src/Signals/StellaOps.Signals/Options/SignalsAuthorityOptions.cs
Normal file
101
src/Signals/StellaOps.Signals/Options/SignalsAuthorityOptions.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace StellaOps.Signals.Options;
|
||||
|
||||
/// <summary>
|
||||
/// Authority configuration for the Signals service.
|
||||
/// </summary>
|
||||
public sealed class SignalsAuthorityOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Enables Authority-backed authentication.
|
||||
/// </summary>
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allows header-based development fallback when Authority is disabled.
|
||||
/// </summary>
|
||||
public bool AllowAnonymousFallback { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Authority issuer URL.
|
||||
/// </summary>
|
||||
public string Issuer { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether HTTPS metadata is required.
|
||||
/// </summary>
|
||||
public bool RequireHttpsMetadata { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Optional metadata address override.
|
||||
/// </summary>
|
||||
public string? MetadataAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Back-channel timeout (seconds).
|
||||
/// </summary>
|
||||
public int BackchannelTimeoutSeconds { get; set; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Token clock skew allowance (seconds).
|
||||
/// </summary>
|
||||
public int TokenClockSkewSeconds { get; set; } = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Accepted token audiences.
|
||||
/// </summary>
|
||||
public IList<string> Audiences { get; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Required scopes.
|
||||
/// </summary>
|
||||
public IList<string> RequiredScopes { get; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Required tenants.
|
||||
/// </summary>
|
||||
public IList<string> RequiredTenants { get; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Networks allowed to bypass scope enforcement.
|
||||
/// </summary>
|
||||
public IList<string> BypassNetworks { get; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Validates the configured options.
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
{
|
||||
if (!Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Issuer))
|
||||
{
|
||||
throw new InvalidOperationException("Signals Authority issuer must be configured when Authority integration is enabled.");
|
||||
}
|
||||
|
||||
if (!Uri.TryCreate(Issuer.Trim(), UriKind.Absolute, out var issuerUri))
|
||||
{
|
||||
throw new InvalidOperationException("Signals Authority issuer must be an absolute URI.");
|
||||
}
|
||||
|
||||
if (RequireHttpsMetadata && !issuerUri.IsLoopback && !string.Equals(issuerUri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException("Signals Authority issuer must use HTTPS unless running on loopback.");
|
||||
}
|
||||
|
||||
if (BackchannelTimeoutSeconds <= 0)
|
||||
{
|
||||
throw new InvalidOperationException("Signals Authority back-channel timeout must be greater than zero seconds.");
|
||||
}
|
||||
|
||||
if (TokenClockSkewSeconds < 0 || TokenClockSkewSeconds > 300)
|
||||
{
|
||||
throw new InvalidOperationException("Signals Authority token clock skew must be between 0 and 300 seconds.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using StellaOps.Signals.Routing;
|
||||
|
||||
namespace StellaOps.Signals.Options;
|
||||
|
||||
/// <summary>
|
||||
/// Applies Signals-specific defaults to <see cref="SignalsAuthorityOptions"/>.
|
||||
/// </summary>
|
||||
internal static class SignalsAuthorityOptionsConfigurator
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures required defaults are populated.
|
||||
/// </summary>
|
||||
public static void ApplyDefaults(SignalsAuthorityOptions options)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
|
||||
if (!options.Audiences.Any())
|
||||
{
|
||||
options.Audiences.Add("api://signals");
|
||||
}
|
||||
|
||||
EnsureScope(options, SignalsPolicies.Read);
|
||||
EnsureScope(options, SignalsPolicies.Write);
|
||||
EnsureScope(options, SignalsPolicies.Admin);
|
||||
}
|
||||
|
||||
private static void EnsureScope(SignalsAuthorityOptions options, string scope)
|
||||
{
|
||||
if (options.RequiredScopes.Any(existing => string.Equals(existing, scope, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
options.RequiredScopes.Add(scope);
|
||||
}
|
||||
}
|
||||
45
src/Signals/StellaOps.Signals/Options/SignalsMongoOptions.cs
Normal file
45
src/Signals/StellaOps.Signals/Options/SignalsMongoOptions.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
|
||||
namespace StellaOps.Signals.Options;
|
||||
|
||||
/// <summary>
|
||||
/// MongoDB configuration for Signals.
|
||||
/// </summary>
|
||||
public sealed class SignalsMongoOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// MongoDB connection string.
|
||||
/// </summary>
|
||||
public string ConnectionString { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Database name to use when the connection string omits one.
|
||||
/// </summary>
|
||||
public string Database { get; set; } = "signals";
|
||||
|
||||
/// <summary>
|
||||
/// Collection name storing normalized callgraphs.
|
||||
/// </summary>
|
||||
public string CallgraphsCollection { get; set; } = "callgraphs";
|
||||
|
||||
/// <summary>
|
||||
/// Validates the configured values.
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ConnectionString))
|
||||
{
|
||||
throw new InvalidOperationException("Signals Mongo connection string must be configured.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Database))
|
||||
{
|
||||
throw new InvalidOperationException("Signals Mongo database name must be configured.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(CallgraphsCollection))
|
||||
{
|
||||
throw new InvalidOperationException("Signals callgraph collection name must be configured.");
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/Signals/StellaOps.Signals/Options/SignalsOptions.cs
Normal file
37
src/Signals/StellaOps.Signals/Options/SignalsOptions.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
namespace StellaOps.Signals.Options;
|
||||
|
||||
/// <summary>
|
||||
/// Root configuration for the Signals service.
|
||||
/// </summary>
|
||||
public sealed class SignalsOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration section name.
|
||||
/// </summary>
|
||||
public const string SectionName = "Signals";
|
||||
|
||||
/// <summary>
|
||||
/// Authority integration settings.
|
||||
/// </summary>
|
||||
public SignalsAuthorityOptions Authority { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// MongoDB configuration.
|
||||
/// </summary>
|
||||
public SignalsMongoOptions Mongo { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Artifact storage configuration.
|
||||
/// </summary>
|
||||
public SignalsArtifactStorageOptions Storage { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Validates configured options.
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
{
|
||||
Authority.Validate();
|
||||
Mongo.Validate();
|
||||
Storage.Validate();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user