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,209 @@
using EntKube.Provisioning.Features.MinioTenants;
using FluentAssertions;
namespace EntKube.Provisioning.Tests.Features;
/// <summary>
/// Tests for parsing MinIO tenant credentials from the various secret formats
/// used by different MinIO Operator versions. The operator has changed its
/// credential storage format over time:
///
/// - Legacy (v4): separate "accesskey" and "secretkey" keys in the K8s secret
/// - v5+: a single "config.env" key containing export statements
/// - Console: "CONSOLE_ACCESS_KEY" and "CONSOLE_SECRET_KEY" keys
///
/// The credential parser must handle all formats so mc commands can authenticate
/// against tenants provisioned by any operator version.
/// </summary>
public class MinioTenantCredentialParsingTests
{
// ─── config.env format (MinIO Operator v5+) ────────────────────────────
[Fact]
public void ParseConfigEnv_WithQuotedValues_ExtractsCredentials()
{
// The most common format — double-quoted values with export prefix.
string configEnv = """
export MINIO_ROOT_USER="minio-admin"
export MINIO_ROOT_PASSWORD="super-secret-password"
""";
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().NotBeNull();
result!.Value.accessKey.Should().Be("minio-admin");
result!.Value.secretKey.Should().Be("super-secret-password");
}
[Fact]
public void ParseConfigEnv_WithSingleQuotedValues_ExtractsCredentials()
{
// Some installations use single quotes.
string configEnv = """
export MINIO_ROOT_USER='admin'
export MINIO_ROOT_PASSWORD='p@ssw0rd'
""";
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().NotBeNull();
result!.Value.accessKey.Should().Be("admin");
result!.Value.secretKey.Should().Be("p@ssw0rd");
}
[Fact]
public void ParseConfigEnv_WithUnquotedValues_ExtractsCredentials()
{
// Unquoted values — less common but valid.
string configEnv = """
export MINIO_ROOT_USER=minio
export MINIO_ROOT_PASSWORD=minio123
""";
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().NotBeNull();
result!.Value.accessKey.Should().Be("minio");
result!.Value.secretKey.Should().Be("minio123");
}
[Fact]
public void ParseConfigEnv_WithAdditionalEnvVars_IgnoresExtras()
{
// The config.env may contain other env vars beyond credentials.
// We should extract only the root user/password.
string configEnv = """
export MINIO_ROOT_USER="minio"
export MINIO_ROOT_PASSWORD="secret"
export MINIO_BROWSER="on"
export MINIO_STORAGE_CLASS_STANDARD="EC:2"
""";
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().NotBeNull();
result!.Value.accessKey.Should().Be("minio");
result!.Value.secretKey.Should().Be("secret");
}
[Fact]
public void ParseConfigEnv_MissingUser_ReturnsNull()
{
// If the user key is missing, we can't authenticate.
string configEnv = """
export MINIO_ROOT_PASSWORD="secret"
""";
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().BeNull();
}
[Fact]
public void ParseConfigEnv_MissingPassword_ReturnsNull()
{
// If the password key is missing, we can't authenticate.
string configEnv = """
export MINIO_ROOT_USER="admin"
""";
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().BeNull();
}
[Fact]
public void ParseConfigEnv_EmptyString_ReturnsNull()
{
// An empty config.env should not crash — just return null.
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials("");
result.Should().BeNull();
}
[Fact]
public void ParseConfigEnv_WithWhitespaceAndEmptyLines_ExtractsCredentials()
{
// Real config files often have trailing newlines and inconsistent whitespace.
string configEnv = "\n export MINIO_ROOT_USER=\"root-user\" \n\n export MINIO_ROOT_PASSWORD=\"root-pass\" \n\n";
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().NotBeNull();
result!.Value.accessKey.Should().Be("root-user");
result!.Value.secretKey.Should().Be("root-pass");
}
[Fact]
public void ParseConfigEnv_SingleLine_ExtractsCredentials()
{
// Some environments produce config.env as a single line with all exports
// separated by spaces. This happens with MinIO Operator v6 in some configurations.
string configEnv = """export MINIO_ROOT_USER="minio-admin" export MINIO_ROOT_PASSWORD="sXmLAnMLX3yGoDrKOxUF1C992FWfDBQjVh6HJJU7" export MINIO_BROWSER="on" export MINIO_PROMETHEUS_AUTH_TYPE="public" """;
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().NotBeNull();
result!.Value.accessKey.Should().Be("minio-admin");
result!.Value.secretKey.Should().Be("sXmLAnMLX3yGoDrKOxUF1C992FWfDBQjVh6HJJU7");
}
[Fact]
public void ParseConfigEnv_RealWorldV6Format_ExtractsCredentials()
{
// Exact format from a real MinIO Operator v6 installation.
string configEnv = "export MINIO_ROOT_USER=\"minio-admin\"\nexport MINIO_ROOT_PASSWORD=\"sXmLAnMLX3yGoDrKOxUF1C992FWfDBQjVh6HJJU7\"\nexport MINIO_BROWSER=\"on\"\nexport MINIO_PROMETHEUS_AUTH_TYPE=\"public\"\n";
// Act
(string accessKey, string secretKey)? result = KubernetesMinioTenantClient.ParseConfigEnvCredentials(configEnv);
// Assert
result.Should().NotBeNull();
result!.Value.accessKey.Should().Be("minio-admin");
result!.Value.secretKey.Should().Be("sXmLAnMLX3yGoDrKOxUF1C992FWfDBQjVh6HJJU7");
}
}