Support for providing Tenant client certificates (#2294)

This commit is contained in:
Lenin Alevski
2022-09-06 08:20:16 -07:00
committed by GitHub
parent 2f81b750a3
commit 989f041658
20 changed files with 1008 additions and 346 deletions

View File

@@ -2651,7 +2651,7 @@ func init() {
"logSearchConfiguration": {
"$ref": "#/definitions/logSearchConfiguration"
},
"mounth_path": {
"mount_path": {
"type": "string"
},
"name": {
@@ -4757,6 +4757,12 @@ func init() {
"customCertificates": {
"type": "object",
"properties": {
"client": {
"type": "array",
"items": {
"$ref": "#/definitions/certificateInfo"
}
},
"minio": {
"type": "array",
"items": {
@@ -4861,13 +4867,19 @@ func init() {
"tlsConfiguration": {
"type": "object",
"properties": {
"ca_certificates": {
"minioCAsCertificates": {
"type": "array",
"items": {
"type": "string"
}
},
"minio": {
"minioClientCertificates": {
"type": "array",
"items": {
"$ref": "#/definitions/keyPairConfiguration"
}
},
"minioServerCertificates": {
"type": "array",
"items": {
"$ref": "#/definitions/keyPairConfiguration"
@@ -4930,16 +4942,22 @@ func init() {
"customCertificates": {
"type": "object",
"properties": {
"minio": {
"minioCAsCertificates": {
"type": "array",
"items": {
"type": "string"
}
},
"minioClientCertificates": {
"type": "array",
"items": {
"$ref": "#/definitions/keyPairConfiguration"
}
},
"minioCAs": {
"minioServerCertificates": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/keyPairConfiguration"
}
},
"secretsToBeDeleted": {
@@ -8128,6 +8146,12 @@ func init() {
"TenantSecurityResponseCustomCertificates": {
"type": "object",
"properties": {
"client": {
"type": "array",
"items": {
"$ref": "#/definitions/certificateInfo"
}
},
"minio": {
"type": "array",
"items": {
@@ -8166,16 +8190,22 @@ func init() {
"UpdateTenantSecurityRequestCustomCertificates": {
"type": "object",
"properties": {
"minio": {
"minioCAsCertificates": {
"type": "array",
"items": {
"type": "string"
}
},
"minioClientCertificates": {
"type": "array",
"items": {
"$ref": "#/definitions/keyPairConfiguration"
}
},
"minioCAs": {
"minioServerCertificates": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/keyPairConfiguration"
}
},
"secretsToBeDeleted": {
@@ -8576,7 +8606,7 @@ func init() {
"logSearchConfiguration": {
"$ref": "#/definitions/logSearchConfiguration"
},
"mounth_path": {
"mount_path": {
"type": "string"
},
"name": {
@@ -10535,6 +10565,12 @@ func init() {
"customCertificates": {
"type": "object",
"properties": {
"client": {
"type": "array",
"items": {
"$ref": "#/definitions/certificateInfo"
}
},
"minio": {
"type": "array",
"items": {
@@ -10639,13 +10675,19 @@ func init() {
"tlsConfiguration": {
"type": "object",
"properties": {
"ca_certificates": {
"minioCAsCertificates": {
"type": "array",
"items": {
"type": "string"
}
},
"minio": {
"minioClientCertificates": {
"type": "array",
"items": {
"$ref": "#/definitions/keyPairConfiguration"
}
},
"minioServerCertificates": {
"type": "array",
"items": {
"$ref": "#/definitions/keyPairConfiguration"
@@ -10708,16 +10750,22 @@ func init() {
"customCertificates": {
"type": "object",
"properties": {
"minio": {
"minioCAsCertificates": {
"type": "array",
"items": {
"type": "string"
}
},
"minioClientCertificates": {
"type": "array",
"items": {
"$ref": "#/definitions/keyPairConfiguration"
}
},
"minioCAs": {
"minioServerCertificates": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/definitions/keyPairConfiguration"
}
},
"secretsToBeDeleted": {

View File

@@ -256,7 +256,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
}
}
isEncryptionEnabled := false
canEncryptionBeEnabled := false
if tenantReq.EnableTLS != nil {
// if enableTLS is defined in the create tenant request we assign the value
@@ -264,25 +264,35 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
minInst.Spec.RequestAutoCert = tenantReq.EnableTLS
if *tenantReq.EnableTLS {
// requestAutoCert is enabled, MinIO will be deployed with TLS enabled and encryption can be enabled
isEncryptionEnabled = true
canEncryptionBeEnabled = true
}
}
// External TLS certificates for MinIO
if tenantReq.TLS != nil && len(tenantReq.TLS.Minio) > 0 {
isEncryptionEnabled = true
// External server TLS certificates for MinIO
if tenantReq.TLS != nil && len(tenantReq.TLS.MinioServerCertificates) > 0 {
canEncryptionBeEnabled = true
// Certificates used by the MinIO instance
externalCertSecretName := fmt.Sprintf("%s-instance-external-certificates", secretName)
externalCertSecret, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, tenantReq.TLS.Minio, externalCertSecretName, tenantName)
externalCertSecretName := fmt.Sprintf("%s-external-server-certificate", tenantName)
externalCertSecret, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, tenantReq.TLS.MinioServerCertificates, externalCertSecretName, tenantName)
if err != nil {
return nil, restapi.ErrorWithContext(ctx, err)
}
minInst.Spec.ExternalCertSecret = externalCertSecret
}
// External client TLS certificates for MinIO
if tenantReq.TLS != nil && len(tenantReq.TLS.MinioClientCertificates) > 0 {
// Client certificates used by the MinIO instance
externalClientCertSecretName := fmt.Sprintf("%s-external-client-certificate", tenantName)
externalClientCertSecret, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, tenantReq.TLS.MinioClientCertificates, externalClientCertSecretName, tenantName)
if err != nil {
return nil, restapi.ErrorWithContext(ctx, err)
}
minInst.Spec.ExternalClientCertSecrets = externalClientCertSecret
}
// If encryption configuration is present and TLS will be enabled (using AutoCert or External certificates)
if tenantReq.Encryption != nil && isEncryptionEnabled {
if tenantReq.Encryption != nil && canEncryptionBeEnabled {
// KES client mTLSCertificates used by MinIO instance
if tenantReq.Encryption.Client != nil {
tenantExternalClientCertSecretName := fmt.Sprintf("%s-tenant-external-client-cert", secretName)
tenantExternalClientCertSecretName := fmt.Sprintf("%s-external-client-certificate-kes", tenantName)
certificates := []*models.KeyPairConfiguration{tenantReq.Encryption.Client}
certificateSecrets, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, certificates, tenantExternalClientCertSecretName, tenantName)
if err != nil {
@@ -312,15 +322,15 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
}
}
// External TLS CA certificates for MinIO
if tenantReq.TLS != nil && len(tenantReq.TLS.CaCertificates) > 0 {
if tenantReq.TLS != nil && len(tenantReq.TLS.MinioCAsCertificates) > 0 {
var caCertificates []tenantSecret
for i, caCertificate := range tenantReq.TLS.CaCertificates {
for i, caCertificate := range tenantReq.TLS.MinioCAsCertificates {
certificateContent, err := base64.StdEncoding.DecodeString(caCertificate)
if err != nil {
return nil, restapi.ErrorWithContext(ctx, restapi.ErrDefault, nil, err)
}
caCertificates = append(caCertificates, tenantSecret{
Name: fmt.Sprintf("ca-certificate-%d", i),
Name: fmt.Sprintf("%s-ca-certificate-%d", tenantName, i),
Content: map[string][]byte{
"public.crt": certificateContent,
},
@@ -353,8 +363,8 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre
}
// Set Mount Path if provided
if tenantReq.MounthPath != "" {
minInst.Spec.Mountpath = tenantReq.MounthPath
if tenantReq.MountPath != "" {
minInst.Spec.Mountpath = tenantReq.MountPath
}
// We accept either `image_pull_secret` or the individual details of the `image_registry` but not both

View File

@@ -71,7 +71,7 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten
// detect if encryption is enabled
info.EncryptionEnabled = minTenant.HasKESEnabled() || tenantConfiguration["MINIO_KMS_SECRET_KEY"] != ""
info.LogEnabled = minTenant.HasLogEnabled()
info.LogEnabled = minTenant.HasLogSearchAPIEnabled()
info.MonitoringEnabled = minTenant.HasPrometheusEnabled()
info.IdpAdEnabled = ldapEnabled
info.IdpOidcEnabled = oidcEnabled

View File

@@ -614,65 +614,70 @@ func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespac
if err != nil {
return nil, err
}
if v, ok := secretTypePublicKeyNameMap[secret.Type]; ok {
publicKey = v
}
// Extract public key from certificate TLS secret
if rawCert, ok := keyPair.Data[publicKey]; ok {
var blocks []byte
for {
var block *pem.Block
block, rawCert = pem.Decode(rawCert)
if block == nil {
break
}
if block.Type == "CERTIFICATE" {
blocks = append(blocks, block.Bytes...)
var rawCert []byte
if _, ok := keyPair.Data[publicKey]; !ok {
return nil, fmt.Errorf("public key: %v not found inside certificate secret %v", publicKey, secret.Name)
}
rawCert = keyPair.Data[publicKey]
var blocks []byte
for {
var block *pem.Block
block, rawCert = pem.Decode(rawCert)
if block == nil {
break
}
if block.Type == "CERTIFICATE" {
blocks = append(blocks, block.Bytes...)
}
}
// parse all certificates we found on this k8s secret
certs, err := x509.ParseCertificates(blocks)
if err != nil {
return nil, err
}
for _, cert := range certs {
var domains []string
if cert.Subject.CommonName != "" {
domains = append(domains, cert.Subject.CommonName)
}
// append certificate domain names
if len(cert.DNSNames) > 0 {
domains = append(domains, cert.DNSNames...)
}
// append certificate IPs
if len(cert.IPAddresses) > 0 {
for _, ip := range cert.IPAddresses {
domains = append(domains, ip.String())
}
}
// parse all certificates we found on this k8s secret
certs, err := x509.ParseCertificates(blocks)
if err != nil {
return nil, err
}
for _, cert := range certs {
var domains []string
if cert.Subject.CommonName != "" {
domains = append(domains, cert.Subject.CommonName)
}
// append certificate domain names
if len(cert.DNSNames) > 0 {
domains = append(domains, cert.DNSNames...)
}
// append certificate IPs
if len(cert.IPAddresses) > 0 {
for _, ip := range cert.IPAddresses {
domains = append(domains, ip.String())
}
}
certificates = append(certificates, &models.CertificateInfo{
SerialNumber: cert.SerialNumber.String(),
Name: secret.Name,
Domains: domains,
Expiry: cert.NotAfter.Format(time.RFC3339),
})
}
certificates = append(certificates, &models.CertificateInfo{
SerialNumber: cert.SerialNumber.String(),
Name: secret.Name,
Domains: domains,
Expiry: cert.NotAfter.Format(time.RFC3339),
})
}
}
return certificates, nil
}
func getTenantSecurity(ctx context.Context, clientSet K8sClientI, tenant *miniov2.Tenant) (response *models.TenantSecurityResponse, err error) {
var minioExternalCertificates []*models.CertificateInfo
var minioExternalServerCertificates []*models.CertificateInfo
var minioExternalClientCertificates []*models.CertificateInfo
var minioExternalCaCertificates []*models.CertificateInfo
var tenantSecurityContext *models.SecurityContext
// Certificates used by MinIO server
if minioExternalCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalCertSecret); err != nil {
// Server certificates used by MinIO
if minioExternalServerCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalCertSecret); err != nil {
return nil, err
}
// CA Certificates used by MinIO server
// Client certificates used by MinIO
if minioExternalClientCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalClientCertSecrets); err != nil {
return nil, err
}
// CA Certificates used by MinIO
if minioExternalCaCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalCaCertSecret); err != nil {
return nil, err
}
@@ -683,8 +688,9 @@ func getTenantSecurity(ctx context.Context, clientSet K8sClientI, tenant *miniov
return &models.TenantSecurityResponse{
AutoCert: tenant.AutoCert(),
CustomCertificates: &models.TenantSecurityResponseCustomCertificates{
Minio: minioExternalCertificates,
Minio: minioExternalServerCertificates,
MinioCAs: minioExternalCaCertificates,
Client: minioExternalClientCertificates,
},
SecurityContext: tenantSecurityContext,
}, nil
@@ -857,13 +863,6 @@ func updateTenantIdentityProvider(ctx context.Context, operatorClient OperatorCl
if err != nil {
return err
}
// restart all MinIO pods at the same time
err = client.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, tenant.Name),
})
if err != nil {
return err
}
return nil
}
@@ -1034,47 +1033,55 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c
}
// Update AutoCert
minInst.Spec.RequestAutoCert = &params.Body.AutoCert
var newMinIOExternalCertSecret []*miniov2.LocalCertificateReference
var newMinIOExternalCaCertSecret []*miniov2.LocalCertificateReference
// Remove Certificate Secrets from MinIO (Tenant.Spec.ExternalCertSecret)
for _, certificate := range minInst.Spec.ExternalCertSecret {
skip := false
for _, certificateToBeDeleted := range params.Body.CustomCertificates.SecretsToBeDeleted {
if certificate.Name == certificateToBeDeleted {
skip = true
break
var newExternalCertSecret []*miniov2.LocalCertificateReference
var newExternalClientCertSecrets []*miniov2.LocalCertificateReference
var newExternalCaCertSecret []*miniov2.LocalCertificateReference
secretsToBeRemoved := map[string]bool{}
if params.Body.CustomCertificates != nil {
// Copy certificate secrets to be deleted into map
for _, secret := range params.Body.CustomCertificates.SecretsToBeDeleted {
secretsToBeRemoved[secret] = true
}
// Remove certificates from Tenant.Spec.ExternalCertSecret
for _, certificate := range minInst.Spec.ExternalCertSecret {
if _, ok := secretsToBeRemoved[certificate.Name]; !ok {
newExternalCertSecret = append(newExternalCertSecret, certificate)
}
}
if skip {
continue
}
newMinIOExternalCertSecret = append(newMinIOExternalCertSecret, certificate)
}
// Remove Certificate Secrets from MinIO CAs (Tenant.Spec.ExternalCaCertSecret)
for _, certificate := range minInst.Spec.ExternalCaCertSecret {
skip := false
for _, certificateToBeDeleted := range params.Body.CustomCertificates.SecretsToBeDeleted {
if certificate.Name == certificateToBeDeleted {
skip = true
break
// Remove certificates from Tenant.Spec.ExternalClientCertSecrets
for _, certificate := range minInst.Spec.ExternalClientCertSecrets {
if _, ok := secretsToBeRemoved[certificate.Name]; !ok {
newExternalClientCertSecrets = append(newExternalClientCertSecrets, certificate)
}
}
if skip {
continue
// Remove certificates from Tenant.Spec.ExternalCaCertSecret
for _, certificate := range minInst.Spec.ExternalCaCertSecret {
if _, ok := secretsToBeRemoved[certificate.Name]; !ok {
newExternalCaCertSecret = append(newExternalCaCertSecret, certificate)
}
}
newMinIOExternalCaCertSecret = append(newMinIOExternalCaCertSecret, certificate)
}
// Create new Certificate Secrets for MinIO
secretName := fmt.Sprintf("%s-%s", minInst.Name, strings.ToLower(utils.RandomCharString(5)))
externalCertSecretName := fmt.Sprintf("%s-external-certificates", secretName)
externalCertSecrets, err := createOrReplaceExternalCertSecrets(ctx, client, minInst.Namespace, params.Body.CustomCertificates.Minio, externalCertSecretName, minInst.Name)
// Create new Server Certificate Secrets for MinIO
externalServerCertSecretName := fmt.Sprintf("%s-external-server-certificate", secretName)
externalServerCertSecrets, err := createOrReplaceExternalCertSecrets(ctx, client, minInst.Namespace, params.Body.CustomCertificates.MinioServerCertificates, externalServerCertSecretName, minInst.Name)
if err != nil {
return err
}
newMinIOExternalCertSecret = append(newMinIOExternalCertSecret, externalCertSecrets...)
newExternalCertSecret = append(newExternalCertSecret, externalServerCertSecrets...)
// Create new Client Certificate Secrets for MinIO
externalClientCertSecretName := fmt.Sprintf("%s-external-client-certificate", secretName)
externalClientCertSecrets, err := createOrReplaceExternalCertSecrets(ctx, client, minInst.Namespace, params.Body.CustomCertificates.MinioClientCertificates, externalClientCertSecretName, minInst.Name)
if err != nil {
return err
}
newExternalClientCertSecrets = append(newExternalClientCertSecrets, externalClientCertSecrets...)
// Create new CAs Certificate Secrets for MinIO
var caCertificates []tenantSecret
for i, caCertificate := range params.Body.CustomCertificates.MinioCAs {
for i, caCertificate := range params.Body.CustomCertificates.MinioCAsCertificates {
certificateContent, err := base64.StdEncoding.DecodeString(caCertificate)
if err != nil {
return err
@@ -1091,7 +1098,7 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c
if err != nil {
return err
}
newMinIOExternalCaCertSecret = append(newMinIOExternalCaCertSecret, certificateSecrets...)
newExternalCaCertSecret = append(newExternalCaCertSecret, certificateSecrets...)
}
// set Security Context
@@ -1105,20 +1112,13 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c
}
// Update External Certificates
minInst.Spec.ExternalCertSecret = newMinIOExternalCertSecret
minInst.Spec.ExternalCaCertSecret = newMinIOExternalCaCertSecret
minInst.Spec.ExternalCertSecret = newExternalCertSecret
minInst.Spec.ExternalClientCertSecrets = newExternalClientCertSecrets
minInst.Spec.ExternalCaCertSecret = newExternalCaCertSecret
_, err = operatorClient.TenantUpdate(ctx, minInst, metav1.UpdateOptions{})
if err != nil {
return err
}
// restart all MinIO pods at the same time
err = client.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, minInst.Name),
})
if err != nil {
return err
}
return nil
}

View File

@@ -99,20 +99,12 @@ func tenantUpdateCertificates(ctx context.Context, operatorClient OperatorClient
if err != nil {
return err
}
secretName := fmt.Sprintf("%s-secret", tenantName)
body := params.Body
// check if MinIO is deployed with external certs and user provided new MinIO keypair
if tenant.ExternalCert() && body.Minio != nil {
minioCertSecretName := fmt.Sprintf("%s-instance-external-certificates", secretName)
if tenant.ExternalCert() && body.MinioServerCertificates != nil {
minioCertSecretName := fmt.Sprintf("%s-instance-external-certificates", tenantName)
// update certificates
if _, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, body.Minio, minioCertSecretName, tenantName); err != nil {
return err
}
// restart MinIO pods
err := clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, tenantName),
})
if err != nil {
if _, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, body.MinioServerCertificates, minioCertSecretName, tenantName); err != nil {
return err
}
}

View File

@@ -99,7 +99,7 @@ func Test_tenantUpdateCertificates(t *testing.T) {
namespace: "",
params: operator_api.TenantUpdateCertificateParams{
Body: &models.TLSConfiguration{
Minio: []*models.KeyPairConfiguration{
MinioServerCertificates: []*models.KeyPairConfiguration{
{
Crt: nil,
Key: nil,
@@ -133,7 +133,7 @@ func Test_tenantUpdateCertificates(t *testing.T) {
namespace: "",
params: operator_api.TenantUpdateCertificateParams{
Body: &models.TLSConfiguration{
Minio: []*models.KeyPairConfiguration{
MinioServerCertificates: []*models.KeyPairConfiguration{
{
Crt: &badCrt,
Key: &badKey,
@@ -167,7 +167,7 @@ func Test_tenantUpdateCertificates(t *testing.T) {
namespace: "",
params: operator_api.TenantUpdateCertificateParams{
Body: &models.TLSConfiguration{
Minio: []*models.KeyPairConfiguration{
MinioServerCertificates: []*models.KeyPairConfiguration{
{
Crt: &crt,
Key: &key,
@@ -195,46 +195,6 @@ func Test_tenantUpdateCertificates(t *testing.T) {
},
wantErr: true,
},
{
name: "certificates replaced but error during deleting existing tenant pods",
args: args{
ctx: context.Background(),
opClient: opClient,
clientSet: k8sClient,
namespace: "",
params: operator_api.TenantUpdateCertificateParams{
Body: &models.TLSConfiguration{
Minio: []*models.KeyPairConfiguration{
{
Crt: &crt,
Key: &key,
},
},
},
},
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
return &miniov2.Tenant{
Spec: miniov2.TenantSpec{
ExternalCertSecret: []*miniov2.LocalCertificateReference{
{
Name: "secret",
},
},
},
}, nil
},
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
return nil
},
mockCreateSecret: func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
return &v1.Secret{}, nil
},
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
return errors.New("error deleting minio pods")
},
},
wantErr: true,
},
}
for _, tt := range tests {
opClientTenantGetMock = tt.args.mockTenantGet

View File

@@ -28,6 +28,8 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
xhttp "github.com/minio/console/pkg/http"
"github.com/minio/console/operatorapi/operations/operator_api"
@@ -41,7 +43,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/fake"
)
@@ -1215,3 +1217,140 @@ func Test_UpdateDomainsResponse(t *testing.T) {
})
}
}
func Test_parseTenantCertificates(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
kClient := k8sClientMock{}
type args struct {
ctx context.Context
clientSet K8sClientI
namespace string
secrets []*miniov2.LocalCertificateReference
}
tests := []struct {
name string
args args
want []*models.CertificateInfo
mockGetSecret func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error)
wantErr bool
}{
{
name: "empty secrets list",
args: args{
ctx: ctx,
clientSet: kClient,
secrets: nil,
},
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
return nil, nil
},
want: nil,
wantErr: false,
},
{
name: "error getting secret",
args: args{
ctx: ctx,
clientSet: kClient,
secrets: []*miniov2.LocalCertificateReference{
{
Name: "certificate-1",
},
},
},
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
return nil, errors.New("error getting secret")
},
want: nil,
wantErr: true,
},
{
name: "error getting certificate because of missing public key",
args: args{
ctx: ctx,
clientSet: kClient,
secrets: []*miniov2.LocalCertificateReference{
{
Name: "certificate-1",
Type: "Opaque",
},
},
},
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
certificateSecret := &corev1.Secret{
Data: map[string][]byte{
"eaeaeae": []byte(`
-----BEGIN CERTIFICATE-----
MIIBUDCCAQKgAwIBAgIRALdFZh8hLU348ho9wYzlZbAwBQYDK2VwMBIxEDAOBgNV
BAoTB0FjbWUgQ28wHhcNMjIwODE4MjAxMzUzWhcNMjMwODE4MjAxMzUzWjASMRAw
DgYDVQQKEwdBY21lIENvMCowBQYDK2VwAyEAct5c3dzzbNOTi+C62w7QHoSivEWD
MYAheDXZWHC55tGjbTBrMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggrBgEF
BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs0At8sTSLCjiM24AZhxFY
a2CswjAUBgNVHREEDTALgglsb2NhbGhvc3QwBQYDK2VwA0EABan+d16CeN8UD+QF
a8HBhPAiOpaZeEF6+EqTlq9VfL3eSVd7CLRI+/KtY7ptwomuTeYzuV73adKdE9N2
ZrJuAw==
-----END CERTIFICATE-----
`),
},
Type: "Opaque",
}
return certificateSecret, nil
},
want: nil,
wantErr: true,
},
{
name: "return certificate from existing secret",
args: args{
ctx: ctx,
clientSet: kClient,
secrets: []*miniov2.LocalCertificateReference{
{
Name: "certificate-1",
Type: "Opaque",
},
},
},
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
certificateSecret := &corev1.Secret{
Data: map[string][]byte{
"public.crt": []byte(`
-----BEGIN CERTIFICATE-----
MIIBUDCCAQKgAwIBAgIRALdFZh8hLU348ho9wYzlZbAwBQYDK2VwMBIxEDAOBgNV
BAoTB0FjbWUgQ28wHhcNMjIwODE4MjAxMzUzWhcNMjMwODE4MjAxMzUzWjASMRAw
DgYDVQQKEwdBY21lIENvMCowBQYDK2VwAyEAct5c3dzzbNOTi+C62w7QHoSivEWD
MYAheDXZWHC55tGjbTBrMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggrBgEF
BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs0At8sTSLCjiM24AZhxFY
a2CswjAUBgNVHREEDTALgglsb2NhbGhvc3QwBQYDK2VwA0EABan+d16CeN8UD+QF
a8HBhPAiOpaZeEF6+EqTlq9VfL3eSVd7CLRI+/KtY7ptwomuTeYzuV73adKdE9N2
ZrJuAw==
-----END CERTIFICATE-----
`),
},
Type: "Opaque",
}
return certificateSecret, nil
},
want: []*models.CertificateInfo{
{
SerialNumber: "243609062983998893460787085129017550256",
Name: "certificate-1",
Expiry: "2023-08-18T20:13:53Z",
Domains: []string{"localhost"},
},
},
wantErr: false,
},
}
for _, tt := range tests {
k8sclientGetSecretMock = tt.mockGetSecret
t.Run(tt.name, func(t *testing.T) {
got, err := parseTenantCertificates(tt.args.ctx, tt.args.clientSet, tt.args.namespace, tt.args.secrets)
if (err != nil) != tt.wantErr {
t.Errorf("parseTenantCertificates(%v, %v, %v, %v)error = %v, wantErr %v", tt.args.ctx, tt.args.clientSet, tt.args.namespace, tt.args.secrets, err, tt.wantErr)
}
assert.Equalf(t, tt.want, got, "parseTenantCertificates(%v, %v, %v, %v)", tt.args.ctx, tt.args.clientSet, tt.args.namespace, tt.args.secrets)
})
}
}