using EntKube.Clusters.Domain; using EntKube.Clusters.Features.AdoptCluster.Components.Ingress; using FluentAssertions; namespace EntKube.Clusters.Tests.Features; /// /// Tests for the ingress installer's provider-aware load balancer annotation /// logic and Istio gateway Helm values generation. Each cloud provider requires /// different Service annotations to create an internal (non-public) LoadBalancer. /// These tests verify the correct annotations are produced for each provider. /// public class IngressInstallerTests { // ─── Internal LB Annotation Mapping ────────────────────────────────── [Fact] public void GetInternalLbAnnotations_Cleura_ReturnsOpenStackAnnotation() { // Cleura runs on OpenStack, which uses the openstack-internal-load-balancer // annotation to tell the cloud controller to provision a private LB. Dictionary annotations = IngressInstaller.GetInternalLbAnnotations(CloudProvider.Cleura); annotations.Should().ContainKey("service.beta.kubernetes.io/openstack-internal-load-balancer"); annotations["service.beta.kubernetes.io/openstack-internal-load-balancer"].Should().Be("true"); annotations.Should().HaveCount(1); } [Fact] public void GetInternalLbAnnotations_Aws_ReturnsAwsSchemeAnnotation() { // AWS uses the load-balancer-scheme annotation to create an internal NLB/ALB. // The newer annotation supersedes the older aws-load-balancer-internal one. Dictionary annotations = IngressInstaller.GetInternalLbAnnotations(CloudProvider.Aws); annotations.Should().ContainKey("service.beta.kubernetes.io/aws-load-balancer-scheme"); annotations["service.beta.kubernetes.io/aws-load-balancer-scheme"].Should().Be("internal"); annotations.Should().HaveCount(1); } [Fact] public void GetInternalLbAnnotations_Azure_ReturnsAzureAnnotation() { // Azure uses its own annotation to mark a LoadBalancer as internal. Dictionary annotations = IngressInstaller.GetInternalLbAnnotations(CloudProvider.Azure); annotations.Should().ContainKey("service.beta.kubernetes.io/azure-load-balancer-internal"); annotations["service.beta.kubernetes.io/azure-load-balancer-internal"].Should().Be("true"); annotations.Should().HaveCount(1); } [Fact] public void GetInternalLbAnnotations_Gcp_ReturnsGcpAnnotation() { // GCP uses the networking.gke.io annotation for internal LBs. Dictionary annotations = IngressInstaller.GetInternalLbAnnotations(CloudProvider.Gcp); annotations.Should().ContainKey("networking.gke.io/load-balancer-type"); annotations["networking.gke.io/load-balancer-type"].Should().Be("Internal"); annotations.Should().HaveCount(1); } [Fact] public void GetInternalLbAnnotations_None_ReturnsEmptyAnnotations() { // When no cloud provider is set, we can't determine the right annotation. // Return empty and let the user handle it manually if needed. Dictionary annotations = IngressInstaller.GetInternalLbAnnotations(CloudProvider.None); annotations.Should().BeEmpty(); } // ─── Istio Gateway Helm Values ─────────────────────────────────────── [Fact] public void GetIstioInternalGatewayValues_WithCleura_IncludesOpenStackAnnotation() { // When deploying to a Cleura cluster, the internal gateway's LoadBalancer // Service must carry the OpenStack internal annotation so the cloud controller // provisions a private LB accessible only from the internal network. string values = IngressInstaller.GetIstioInternalGatewayValues(CloudProvider.Cleura); values.Should().Contain("openstack-internal-load-balancer"); values.Should().NotContain("azure-load-balancer-internal"); values.Should().NotContain("aws-load-balancer"); } [Fact] public void GetIstioInternalGatewayValues_WithAws_IncludesAwsAnnotation() { string values = IngressInstaller.GetIstioInternalGatewayValues(CloudProvider.Aws); values.Should().Contain("aws-load-balancer-scheme"); values.Should().Contain("internal"); values.Should().NotContain("azure-load-balancer-internal"); } [Fact] public void GetIstioInternalGatewayValues_WithNone_HasNoAnnotationsBlock() { // When no provider is set, the values should not include any internal // LB annotations — the Service gets a plain public LoadBalancer. string values = IngressInstaller.GetIstioInternalGatewayValues(CloudProvider.None); values.Should().NotContain("annotations:"); values.Should().Contain("type: LoadBalancer"); } [Fact] public void GetIstioExternalGatewayValues_NeverIncludesInternalAnnotations() { // The external gateway should never have internal LB annotations // regardless of the cloud provider — it's meant to be public. string values = IngressInstaller.GetIstioExternalGatewayValues(); values.Should().NotContain("internal"); values.Should().Contain("type: LoadBalancer"); } }