195 lines
7.0 KiB
C#
195 lines
7.0 KiB
C#
using EntKube.Clusters.Domain;
|
|
using EntKube.Clusters.Features.AdoptCluster;
|
|
using EntKube.Clusters.Features.AdoptCluster.Components.Ingress;
|
|
using FluentAssertions;
|
|
|
|
namespace EntKube.Clusters.Tests.Features;
|
|
|
|
/// <summary>
|
|
/// Tests for IngressCheck.DetectProvider — the static method that determines
|
|
/// which ingress provider is installed on a cluster by examining its component
|
|
/// list. This drives the auto-detection behavior so users never have to
|
|
/// manually select "istio" or "traefik" when configuring ingress.
|
|
/// </summary>
|
|
public class IngressCheckTests
|
|
{
|
|
[Fact]
|
|
public void DetectProvider_IstioInstalled_ReturnsIstio()
|
|
{
|
|
// When the cluster has an Istio component marked as Installed,
|
|
// the detector should pick Istio as the provider.
|
|
|
|
KubernetesCluster cluster = CreateClusterWithComponent("istio", ComponentStatus.Installed);
|
|
|
|
string? provider = IngressCheck.DetectProvider(cluster);
|
|
|
|
provider.Should().Be("istio");
|
|
}
|
|
|
|
[Fact]
|
|
public void DetectProvider_TraefikInstalled_ReturnsTraefik()
|
|
{
|
|
// When the cluster has a Traefik component marked as Installed,
|
|
// the detector should pick Traefik as the provider.
|
|
|
|
KubernetesCluster cluster = CreateClusterWithComponent("traefik", ComponentStatus.Installed);
|
|
|
|
string? provider = IngressCheck.DetectProvider(cluster);
|
|
|
|
provider.Should().Be("traefik");
|
|
}
|
|
|
|
[Fact]
|
|
public void DetectProvider_IstioDegraded_StillReturnsIstio()
|
|
{
|
|
// Even if Istio is degraded (partially working), we should still
|
|
// detect it as the provider — the gateway infra can still be deployed.
|
|
|
|
KubernetesCluster cluster = CreateClusterWithComponent("istio", ComponentStatus.Degraded);
|
|
|
|
string? provider = IngressCheck.DetectProvider(cluster);
|
|
|
|
provider.Should().Be("istio");
|
|
}
|
|
|
|
[Fact]
|
|
public void DetectProvider_NeitherInstalled_ReturnsNull()
|
|
{
|
|
// When no ingress controller is installed, the detector returns null
|
|
// so the installer can report "install Istio or Traefik first."
|
|
|
|
KubernetesCluster cluster = CreateClusterWithComponent("kyverno", ComponentStatus.Installed);
|
|
|
|
string? provider = IngressCheck.DetectProvider(cluster);
|
|
|
|
provider.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void DetectProvider_BothInstalled_PrefersIstio()
|
|
{
|
|
// If both Istio and Traefik are installed (unusual but possible),
|
|
// Istio takes priority because it requires dedicated gateway infrastructure.
|
|
|
|
KubernetesCluster cluster = CreateClusterWithComponents(
|
|
("istio", ComponentStatus.Installed),
|
|
("traefik", ComponentStatus.Installed));
|
|
|
|
string? provider = IngressCheck.DetectProvider(cluster);
|
|
|
|
provider.Should().Be("istio");
|
|
}
|
|
|
|
// ─── Gateway resolution from ingress component ───────────────────────
|
|
|
|
[Fact]
|
|
public void IngressComponent_WithIstioGateways_ExposesGatewayInfo()
|
|
{
|
|
// When the ingress component is installed with Istio and has discovered
|
|
// internal and external gateways, the component's configuration should
|
|
// contain the gateway details that services can use to auto-resolve.
|
|
|
|
KubernetesCluster cluster = CreateClusterWithIngressConfig(
|
|
provider: "istio",
|
|
hasInternalGateway: true,
|
|
hasExternalGateway: true);
|
|
|
|
ClusterComponent? ingress = cluster.Components.FirstOrDefault(
|
|
c => c.ComponentName == "ingress");
|
|
|
|
ingress.Should().NotBeNull();
|
|
ingress!.Configuration["provider"].Should().Be("istio");
|
|
ingress.Configuration["hasInternalGateway"].Should().Be("True");
|
|
ingress.Configuration["hasExternalGateway"].Should().Be("True");
|
|
}
|
|
|
|
[Fact]
|
|
public void IngressComponent_WithTraefik_NoGatewayRefs()
|
|
{
|
|
// Traefik manages its own ingress — no Gateway API gateway refs needed.
|
|
// The component config should show traefik as provider.
|
|
|
|
KubernetesCluster cluster = CreateClusterWithIngressConfig(
|
|
provider: "traefik",
|
|
hasInternalGateway: false,
|
|
hasExternalGateway: false);
|
|
|
|
ClusterComponent? ingress = cluster.Components.FirstOrDefault(
|
|
c => c.ComponentName == "ingress");
|
|
|
|
ingress.Should().NotBeNull();
|
|
ingress!.Configuration["provider"].Should().Be("traefik");
|
|
ingress.Configuration.ContainsKey("hasInternalGateway").Should().BeFalse();
|
|
}
|
|
|
|
// ─── Helpers ─────────────────────────────────────────────────────────
|
|
|
|
private static KubernetesCluster CreateClusterWithComponent(string componentName, ComponentStatus status)
|
|
{
|
|
return CreateClusterWithComponents((componentName, status));
|
|
}
|
|
|
|
private static KubernetesCluster CreateClusterWithComponents(params (string Name, ComponentStatus Status)[] componentDefs)
|
|
{
|
|
KubernetesCluster cluster = KubernetesCluster.Register(
|
|
"test-cluster", "https://k8s.example.com", "fake-kubeconfig",
|
|
Guid.NewGuid(), "test-context", Guid.NewGuid());
|
|
|
|
List<ComponentCheckResult> results = componentDefs
|
|
.Select(c => new ComponentCheckResult(
|
|
c.Name, c.Status,
|
|
Details: new List<string>(),
|
|
MissingItems: new List<string>()))
|
|
.ToList();
|
|
|
|
cluster.UpdateComponents(results);
|
|
|
|
return cluster;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a cluster with an ingress component that has discovered
|
|
/// configuration values — provider, gateway presence flags. This mimics
|
|
/// what the real IngressCheck discovers during an adoption scan.
|
|
/// </summary>
|
|
private static KubernetesCluster CreateClusterWithIngressConfig(
|
|
string provider, bool hasInternalGateway, bool hasExternalGateway)
|
|
{
|
|
KubernetesCluster cluster = KubernetesCluster.Register(
|
|
"test-cluster", "https://k8s.example.com", "fake-kubeconfig",
|
|
Guid.NewGuid(), "test-context", Guid.NewGuid());
|
|
|
|
Dictionary<string, string> configValues = new()
|
|
{
|
|
["provider"] = provider
|
|
};
|
|
|
|
if (hasInternalGateway)
|
|
{
|
|
configValues["hasInternalGateway"] = "True";
|
|
}
|
|
|
|
if (hasExternalGateway)
|
|
{
|
|
configValues["hasExternalGateway"] = "True";
|
|
}
|
|
|
|
List<ComponentCheckResult> results = new()
|
|
{
|
|
new ComponentCheckResult(
|
|
"ingress", ComponentStatus.Installed,
|
|
Details: new List<string>(),
|
|
MissingItems: new List<string>(),
|
|
Configuration: new DiscoveredConfiguration(
|
|
Version: null,
|
|
Namespace: "internal-ingress",
|
|
HelmReleaseName: null,
|
|
Values: configValues))
|
|
};
|
|
|
|
cluster.UpdateComponents(results);
|
|
|
|
return cluster;
|
|
}
|
|
}
|