too much for one commit
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
using System.Text.Json;
|
||||
using EntKube.Clusters.Features.AdoptCluster.Components.SecurityPolicies;
|
||||
using EntKube.Clusters.Features.ClusterSettings;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace EntKube.Clusters.Tests.Features;
|
||||
|
||||
/// <summary>
|
||||
/// Tests the JSON parsing logic that extracts allowed registries from a Kyverno
|
||||
/// ClusterPolicy. This is the core logic that reads the restrict-image-registries
|
||||
/// policy and returns the list of approved registries.
|
||||
/// </summary>
|
||||
public class KyvernoClusterSettingsProviderTests
|
||||
{
|
||||
[Fact]
|
||||
public void ExtractRegistries_WithValidPolicy_ReturnsRegistryList()
|
||||
{
|
||||
// Arrange — a policy JSON with three allowed registries.
|
||||
|
||||
string json = """
|
||||
{
|
||||
"spec": {
|
||||
"validationFailureAction": "Audit",
|
||||
"rules": [{
|
||||
"name": "validate-image-registry",
|
||||
"validate": {
|
||||
"foreach": [{
|
||||
"list": "request.object.spec.[initContainers, containers][]",
|
||||
"deny": {
|
||||
"conditions": {
|
||||
"all": [
|
||||
{ "key": "{{ element.image }}", "operator": "NotEquals", "value": "docker.io/*" },
|
||||
{ "key": "{{ element.image }}", "operator": "NotEquals", "value": "ghcr.io/*" },
|
||||
{ "key": "{{ element.image }}", "operator": "NotEquals", "value": "registry.k8s.io/*" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
// Act
|
||||
|
||||
List<string> registries = KyvernoClusterSettingsProvider.ExtractRegistriesFromPolicyJson(json);
|
||||
|
||||
// Assert
|
||||
|
||||
registries.Should().BeEquivalentTo(new[] { "docker.io", "ghcr.io", "registry.k8s.io" });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractRegistries_WithEmptyJson_ReturnsEmptyList()
|
||||
{
|
||||
// Act
|
||||
|
||||
List<string> registries = KyvernoClusterSettingsProvider.ExtractRegistriesFromPolicyJson("{}");
|
||||
|
||||
// Assert
|
||||
|
||||
registries.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractRegistries_WithMalformedJson_ReturnsEmptyList()
|
||||
{
|
||||
// Act
|
||||
|
||||
List<string> registries = KyvernoClusterSettingsProvider.ExtractRegistriesFromPolicyJson("not json");
|
||||
|
||||
// Assert
|
||||
|
||||
registries.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtractRegistries_WithNoPolicyRules_ReturnsEmptyList()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
string json = """{ "spec": { "rules": [] } }""";
|
||||
|
||||
// Act
|
||||
|
||||
List<string> registries = KyvernoClusterSettingsProvider.ExtractRegistriesFromPolicyJson(json);
|
||||
|
||||
// Assert
|
||||
|
||||
registries.Should().BeEmpty();
|
||||
}
|
||||
|
||||
// ─── Round-trip tests ──────────────────────────────────────────────────
|
||||
|
||||
[Fact]
|
||||
public void BuildRegistryPolicy_RoundTrip_PreservesRegistries()
|
||||
{
|
||||
// When the settings provider writes a policy and then reads it back,
|
||||
// the extracted registries should match what was written. This simulates
|
||||
// the full Kubernetes API round-trip: build → serialize → parse.
|
||||
|
||||
// Arrange — a custom list of registries.
|
||||
|
||||
List<string> registries = new() { "docker.io", "ghcr.io", "myregistry.example.com" };
|
||||
|
||||
// Act — build the policy, serialize it to JSON (simulating K8s storage),
|
||||
// then extract registries back out.
|
||||
|
||||
object policy = KyvernoClusterSettingsProvider.BuildRegistryPolicy(registries, "test message", "Audit");
|
||||
string json = JsonSerializer.Serialize(policy);
|
||||
List<string> extracted = KyvernoClusterSettingsProvider.ExtractRegistriesFromPolicyJson(json);
|
||||
|
||||
// Assert — the registries should survive the round-trip intact.
|
||||
|
||||
extracted.Should().BeEquivalentTo(registries);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildRegistryPolicy_IncludesExcludeBlock()
|
||||
{
|
||||
// The policy must include the exclude block so system namespaces
|
||||
// (kube-system, cert-manager, etc.) are not subject to registry
|
||||
// restrictions. Without this, saving registries via the Settings tab
|
||||
// would create a policy that differs from the installer's policy and
|
||||
// could break system pods.
|
||||
|
||||
// Arrange
|
||||
|
||||
List<string> registries = new() { "docker.io" };
|
||||
|
||||
// Act
|
||||
|
||||
object policy = KyvernoClusterSettingsProvider.BuildRegistryPolicy(registries, "test", "Audit");
|
||||
string json = JsonSerializer.Serialize(policy);
|
||||
using JsonDocument doc = JsonDocument.Parse(json);
|
||||
|
||||
// Assert — the rule should have an "exclude" block with namespace exclusions.
|
||||
|
||||
JsonElement rule = doc.RootElement
|
||||
.GetProperty("spec")
|
||||
.GetProperty("rules")[0];
|
||||
|
||||
rule.TryGetProperty("exclude", out JsonElement exclude).Should().BeTrue(
|
||||
"the policy rule must include an exclude block to protect system namespaces");
|
||||
|
||||
string excludeJson = exclude.GetRawText();
|
||||
excludeJson.Should().Contain("kube-system");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildRegistryPolicy_IncludesManagedByLabels()
|
||||
{
|
||||
// The policy labels must match what the SecurityPoliciesInstaller creates
|
||||
// so the installer can find and replace the policy during reconfiguration.
|
||||
|
||||
// Arrange
|
||||
|
||||
List<string> registries = new() { "docker.io" };
|
||||
|
||||
// Act
|
||||
|
||||
object policy = KyvernoClusterSettingsProvider.BuildRegistryPolicy(registries, "test", "Enforce");
|
||||
string json = JsonSerializer.Serialize(policy);
|
||||
using JsonDocument doc = JsonDocument.Parse(json);
|
||||
|
||||
// Assert — should have both managed-by and part-of labels.
|
||||
|
||||
JsonElement labels = doc.RootElement
|
||||
.GetProperty("metadata")
|
||||
.GetProperty("labels");
|
||||
|
||||
labels.GetProperty("app.kubernetes.io/managed-by").GetString().Should().Be("entkube");
|
||||
labels.GetProperty("app.kubernetes.io/part-of").GetString().Should().Be("security-policies");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user