too much for one commit

This commit is contained in:
Nils Blomgren
2026-05-13 14:01:32 +02:00
parent a96dd33039
commit 328d494530
394 changed files with 98104 additions and 78 deletions

View File

@@ -0,0 +1,194 @@
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;
}
}