| File: KubernetesGatewayResource.cs | Web Access |
| Project: src\src\Aspire.Hosting.Kubernetes\Aspire.Hosting.Kubernetes.csproj (Aspire.Hosting.Kubernetes) |
// 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.Kubernetes; /// <summary> /// Represents a Kubernetes Gateway API Gateway as a first-class resource in the Aspire application model. /// A Gateway defines listeners (ports, protocols, TLS) and HTTPRoutes attach to it for routing. /// </summary> /// <param name="name">The name of the gateway resource.</param> /// <param name="environment">The parent Kubernetes environment resource.</param> /// <remarks> /// <para> /// Create a gateway using <see cref="KubernetesGatewayExtensions.AddGateway"/> and configure /// routes using <see cref="KubernetesGatewayExtensions.WithRoute(IResourceBuilder{KubernetesGatewayResource}, string, EndpointReference, GatewayPathMatchType)"/>. /// </para> /// <para> /// At publish time, the gateway generates a <c>gateway.networking.k8s.io/v1 Gateway</c> resource /// with auto-inferred listeners and one or more <c>HTTPRoute</c> resources in the Helm chart output. /// </para> /// </remarks> /// <ats-remarks /> /// <example> /// <code> /// var k8s = builder.AddKubernetesEnvironment("k8s"); /// var gateway = k8s.AddGateway("public") /// .WithGatewayClass("azure-alb-external"); /// /// var api = builder.AddProject<MyApi>("api"); /// gateway.WithRoute("/api", api.GetEndpoint("http")); /// </code> /// </example> [AspireExport] public class KubernetesGatewayResource( string name, KubernetesEnvironmentResource environment) : Resource(name), IResourceWithParent<KubernetesEnvironmentResource> { /// <summary> /// Gets the parent Kubernetes environment resource. /// </summary> public KubernetesEnvironmentResource Parent { get; } = environment ?? throw new ArgumentNullException(nameof(environment)); /// <summary> /// Gets or sets the GatewayClass name that selects which controller implementation /// handles this gateway. /// </summary> /// <remarks> /// Common values include <c>"azure-alb-external"</c> (for AKS with AGC), /// <c>"istio"</c>, or controller-specific class names. /// </remarks> public ReferenceExpression? GatewayClassName { get; set; } /// <summary> /// Gets the list of hostnames this gateway matches. /// </summary> internal List<ReferenceExpression> Hostnames { get; } = []; /// <summary> /// Gets the list of routing rules configured for this gateway. /// </summary> internal List<GatewayRouteConfig> Routes { get; } = []; /// <summary> /// Gets the list of TLS configurations. Each creates an HTTPS listener on the gateway. /// </summary> internal List<GatewayTlsConfig> TlsConfigs { get; } = []; /// <summary> /// Gets the Kubernetes metadata annotations to add to the generated Gateway resource. /// </summary> internal Dictionary<string, ReferenceExpression> GatewayAnnotations { get; } = []; /// <summary> /// Gets the generated K8S Gateway object, populated during infrastructure processing. /// </summary> internal Resources.GatewayV1? GeneratedGateway { get; set; } /// <summary> /// Gets the generated K8S HTTPRoute objects, populated during infrastructure processing. /// </summary> internal List<Resources.HttpRouteV1> GeneratedHttpRoutes { get; } = []; /// <summary> /// Gets a value indicating whether this gateway is emitted into the deployment artifacts. /// A gateway with no routes is skipped, so nothing downstream (TLS bootstrap, FQDN discovery, /// field-manager cleanup, cert-manager solver parentRefs) may select it — those steps would /// otherwise act on a Gateway that never exists in the cluster. /// </summary> internal bool ShouldMaterialize => Routes.Count > 0; } /// <summary> /// Stores a single routing rule for a <see cref="KubernetesGatewayResource"/>. /// </summary> internal sealed record GatewayRouteConfig( string? Host, string Path, GatewayPathMatchType PathType, EndpointReference Endpoint); /// <summary> /// Specifies the type of path matching used in a Kubernetes Gateway API <c>HTTPRoute</c> rule. /// The values map directly to the <c>matches[].path.type</c> field defined by the Gateway API /// (see <see href="https://gateway-api.sigs.k8s.io/api-types/httproute/#path"/>) and are distinct /// from the Ingress-flavoured <see cref="IngressPathType"/> because the two specs use different /// vocabularies (Ingress: <c>Prefix</c>, Gateway: <c>PathPrefix</c>). /// </summary> public enum GatewayPathMatchType { /// <summary> /// Matches based on a URL path prefix split by <c>/</c>. Equivalent to the Gateway API /// <c>PathPrefix</c> match type. /// </summary> PathPrefix, /// <summary> /// Matches the URL path exactly and with case sensitivity. /// </summary> Exact, /// <summary> /// Matches the URL path against an implementation-defined regular expression. Support is /// optional in the Gateway API spec; check your controller's documentation before using it. /// </summary> RegularExpression } /// <summary> /// Stores TLS configuration for a <see cref="KubernetesGatewayResource"/>. /// Configures an HTTPS listener on the Gateway with TLS termination. The set of hostnames /// the listener applies to is resolved from the gateway's <see cref="KubernetesGatewayResource.Hostnames"/> /// at manifest-emit time, so callers can register hostnames before or after WithTls without /// affecting the generated listener. /// </summary> internal sealed record GatewayTlsConfig( ReferenceExpression SecretName);