Restructure solution layout by module

This commit is contained in:
master
2025-10-28 15:10:40 +02:00
parent 95daa159c4
commit d870da18ce
4103 changed files with 192899 additions and 187024 deletions

View File

@@ -0,0 +1,175 @@
using System.ComponentModel.DataAnnotations;
namespace StellaOps.Zastava.Webhook.Configuration;
public sealed class ZastavaWebhookOptions
{
public const string SectionName = "zastava:webhook";
[Required]
public ZastavaWebhookTlsOptions Tls { get; init; } = new();
[Required]
public ZastavaWebhookAuthorityOptions Authority { get; init; } = new();
[Required]
public ZastavaWebhookAdmissionOptions Admission { get; init; } = new();
[Required]
public ZastavaWebhookBackendOptions Backend { get; init; } = new();
}
public sealed class ZastavaWebhookAdmissionOptions
{
/// <summary>
/// Namespaces that default to fail-open when backend calls fail.
/// </summary>
public HashSet<string> FailOpenNamespaces { get; init; } = new(StringComparer.Ordinal);
/// <summary>
/// Namespaces that must fail-closed even if the global default is fail-open.
/// </summary>
public HashSet<string> FailClosedNamespaces { get; init; } = new(StringComparer.Ordinal);
/// <summary>
/// Global fail-open toggle. When true, namespaces not in <see cref="FailClosedNamespaces"/> will allow requests on backend failures.
/// </summary>
public bool FailOpenByDefault { get; init; }
/// <summary>
/// Enables tag resolution to immutable digests when set.
/// </summary>
public bool ResolveTags { get; init; } = true;
/// <summary>
/// Optional cache seed path for pre-computed runtime verdicts.
/// </summary>
public string? CacheSeedPath { get; init; }
}
public enum ZastavaWebhookTlsMode
{
Secret = 0,
CertificateSigningRequest = 1
}
public sealed class ZastavaWebhookTlsOptions
{
[Required]
public ZastavaWebhookTlsMode Mode { get; init; } = ZastavaWebhookTlsMode.Secret;
/// <summary>
/// PEM certificate path when using <see cref="ZastavaWebhookTlsMode.Secret"/>.
/// </summary>
public string? CertificatePath { get; init; }
/// <summary>
/// PEM private key path when using <see cref="ZastavaWebhookTlsMode.Secret"/>.
/// </summary>
public string? PrivateKeyPath { get; init; }
/// <summary>
/// Optional PFX bundle path; takes precedence over PEM values when provided.
/// </summary>
public string? PfxPath { get; init; }
/// <summary>
/// Optional password for the PFX bundle.
/// </summary>
public string? PfxPassword { get; init; }
/// <summary>
/// Optional CA bundle path to present to Kubernetes when configuring webhook registration.
/// </summary>
public string? CaBundlePath { get; init; }
/// <summary>
/// CSR related settings when <see cref="Mode"/> equals <see cref="ZastavaWebhookTlsMode.CertificateSigningRequest"/>.
/// </summary>
public ZastavaWebhookTlsCsrOptions Csr { get; init; } = new();
}
public sealed class ZastavaWebhookTlsCsrOptions
{
/// <summary>
/// Kubernetes namespace that owns the <c>CertificateSigningRequest</c> object.
/// </summary>
[Required(AllowEmptyStrings = false)]
public string Namespace { get; init; } = "stellaops";
/// <summary>
/// CSR object name; defaults to <c>zastava-webhook</c>.
/// </summary>
[Required(AllowEmptyStrings = false)]
[MaxLength(253)]
public string Name { get; init; } = "zastava-webhook";
/// <summary>
/// DNS names placed in the CSR <c>subjectAltName</c>.
/// </summary>
[MinLength(1)]
public string[] DnsNames { get; init; } = Array.Empty<string>();
/// <summary>
/// Where the signed certificate is persisted after approval (mounted emptyDir).
/// </summary>
[Required(AllowEmptyStrings = false)]
public string PersistPath { get; init; } = "/var/run/zastava-webhook/certs";
}
public sealed class ZastavaWebhookAuthorityOptions
{
/// <summary>
/// Authority issuer URL for token acquisition.
/// </summary>
[Required(AllowEmptyStrings = false)]
public Uri Issuer { get; init; } = new("https://authority.internal");
/// <summary>
/// Audience that tokens must target.
/// </summary>
[MinLength(1)]
public string[] Audience { get; init; } = new[] { "scanner", "zastava" };
/// <summary>
/// Optional path to static OpTok for bootstrap environments.
/// </summary>
public string? StaticTokenPath { get; init; }
/// <summary>
/// Optional literal token value (test only). Takes precedence over <see cref="StaticTokenPath"/>.
/// </summary>
public string? StaticTokenValue { get; init; }
/// <summary>
/// Interval for refreshing cached tokens before expiry.
/// </summary>
[Range(typeof(double), "1", "3600")]
public double RefreshSkewSeconds { get; init; } = TimeSpan.FromMinutes(5).TotalSeconds;
}
public sealed class ZastavaWebhookBackendOptions
{
/// <summary>
/// Base address for Scanner WebService policy requests.
/// </summary>
[Required]
public Uri BaseAddress { get; init; } = new("https://scanner.internal");
/// <summary>
/// Relative path for runtime policy endpoint.
/// </summary>
[Required(AllowEmptyStrings = false)]
public string PolicyPath { get; init; } = "/api/v1/scanner/policy/runtime";
/// <summary>
/// Timeout in seconds for backend calls (default 5 s).
/// </summary>
[Range(typeof(double), "1", "120")]
public double RequestTimeoutSeconds { get; init; } = 5;
/// <summary>
/// Allows HTTP (non-TLS) endpoints when set. Defaults to false for safety.
/// </summary>
public bool AllowInsecureHttp { get; init; }
}