| File: Publishing\Constructs\ContainerEnvVarConstruct.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. #pragma warning disable ASPIRERADIUS004 // Experimental: ConfigureRadiusInfrastructure escape-hatch construct types are consumed internally by the publisher. using System.Diagnostics.CodeAnalysis; using Azure.Provisioning; using Azure.Provisioning.Primitives; namespace Aspire.Hosting.Radius.Publishing.Constructs; /// <summary> /// Represents a single environment-variable entry in a container's <c>env</c> block. /// </summary> /// <remarks> /// The Radius container schema models <c>env</c> as a map keyed by the variable name, /// where each entry is an object carrying either a <c>value</c> or a <c>valueFrom</c> source. /// The two forms are mutually exclusive: assign <see cref="Value"/> or the /// <see cref="SecretName"/>/<see cref="SecretKey"/> pair, never both. /// <para> /// The <c>value</c> form is emitted for values that carry nothing sensitive. It ends up verbatim /// in the Kubernetes <c>Deployment</c> spec, so a credential emitted this way is readable by /// anyone who can read the Deployment or its rollout history — even when the Bicep composed it /// from an <c>@secure()</c> parameter, which only keeps it out of the published <em>artifact</em>. /// </para> /// <para> /// The <c>valueFrom.secretKeyRef</c> form points at a key of a <c>Radius.Security/secrets</c> /// resource; <c>secretName</c> is that resource's <em>name</em>, which the secrets recipe also /// uses as the Kubernetes <c>Secret</c> name. The container recipe emits these entries ahead of /// the plain <c>value</c> ones so kubelet's <c>$(VAR)</c> expansion can reference them. /// </para> /// See: https://github.com/radius-project/radius/blob/main/eng/design-notes/extensibility/2025-08-container-resource-type.md /// and Compute/containers/containers.yaml in radius-project/resource-types-contrib. /// </remarks> [Experimental("ASPIRERADIUS004", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")] public sealed class ContainerEnvVarConstruct : ProvisionableConstruct { private BicepValue<string>? _value; private BicepValue<string>? _secretName; private BicepValue<string>? _secretKey; /// <summary>The environment variable value (a literal, or a reference to a Bicep parameter).</summary> public BicepValue<string> Value { get { Initialize(); return _value!; } set { Initialize(); _value!.Assign(value); } } /// <summary> /// The name of the <c>Radius.Security/secrets</c> resource supplying this value. Emitted only /// when assigned, and mutually exclusive with <see cref="Value"/>. /// </summary> public BicepValue<string> SecretName { get { Initialize(); return _secretName!; } set { Initialize(); _secretName!.Assign(value); } } /// <summary> /// The key within the secret resource's <c>data</c> map. Emitted only when assigned, and /// mutually exclusive with <see cref="Value"/>. /// </summary> public BicepValue<string> SecretKey { get { Initialize(); return _secretKey!; } set { Initialize(); _secretKey!.Assign(value); } } /// <inheritdoc /> protected override void DefineProvisionableProperties() { _value = DefineProperty<string>(nameof(Value), ["value"]); _secretName = DefineProperty<string>(nameof(SecretName), ["valueFrom", "secretKeyRef", "secretName"]); _secretKey = DefineProperty<string>(nameof(SecretKey), ["valueFrom", "secretKeyRef", "key"]); } }