| File: Secrets\RadiusSecretStorePopulation.cs | Web Access |
| Project: src\src\Aspire.Hosting.Radius\Aspire.Hosting.Radius.csproj (Aspire.Hosting.Radius) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Hosting.ApplicationModel; namespace Aspire.Hosting.Radius.Secrets; /// <summary> /// One inline <c>data</c> key binding: an Aspire secret <see cref="ParameterResource"/> /// plus an optional explicit per-key <c>encoding</c> (<see langword="null"/> ⇒ the store /// type's default, applied at emission). /// </summary> internal sealed record RadiusSecretKeyBinding(ParameterResource Parameter, string? Encoding); /// <summary> /// The single population mode of a <see cref="RadiusSecretStoreResource"/>. Exactly one /// of the three modes must be declared; the fail-fast validation gate rejects zero or /// more than one (<c>ASPIRERADIUS041</c>). This type accumulates whatever the fluent /// methods set so the gate can count the declared modes. /// </summary> internal sealed class RadiusSecretStorePopulation { /// <summary><see langword="true"/> when <c>WithData(...)</c> was called (inline, Radius-created).</summary> public bool HasInlineData { get; set; } /// <summary>Inline <c>data</c> key → secret-parameter binding (ordinal-keyed).</summary> public Dictionary<string, RadiusSecretKeyBinding> Data { get; } = new(StringComparer.Ordinal); /// <summary><see langword="true"/> when <c>WithExistingSecret(...)</c> was called.</summary> public bool HasExistingSecret { get; set; } /// <summary><see langword="true"/> when <c>WithSealedSecret(...)</c> was called.</summary> public bool HasSealedSecret { get; set; } /// <summary> /// The <c><namespace>/<name></c> or bare <c><name></c> reference for the /// existing/sealed modes; <see langword="null"/> for inline. /// </summary> public string? ResourceReference { get; set; } /// <summary>The <c>SealedSecret</c> manifest path for the sealed mode; <see langword="null"/> otherwise.</summary> public string? SealedManifestPath { get; set; } /// <summary>The keys to expose from the referenced <c>Secret</c> (existing/sealed modes).</summary> public List<string> Keys { get; } = []; /// <summary>The number of declared population modes (must be exactly 1 — else <c>ASPIRERADIUS041</c>).</summary> public int DeclaredModeCount => (HasInlineData ? 1 : 0) + (HasExistingSecret ? 1 : 0) + (HasSealedSecret ? 1 : 0); /// <summary> /// <see langword="true"/> once any population mode has been declared. Used to reject a /// <b>second</b> population call (<c>ASPIRERADIUS065</c>): because each mode sets its own flag, /// this catches both a repeated same-mode call and a cross-mode call, neither of which /// <see cref="DeclaredModeCount"/> alone can distinguish from a single legitimate call. /// </summary> public bool IsPopulated => HasInlineData || HasExistingSecret || HasSealedSecret; /// <summary><see langword="true"/> when the store references a cluster <c>Secret</c> (existing or sealed).</summary> public bool IsSecretReference => HasExistingSecret || HasSealedSecret; }