diff --git a/controllers/k8ssandra/medusa_reconciler.go b/controllers/k8ssandra/medusa_reconciler.go index 6af00614e..f23690347 100644 --- a/controllers/k8ssandra/medusa_reconciler.go +++ b/controllers/k8ssandra/medusa_reconciler.go @@ -3,6 +3,7 @@ package k8ssandra import ( "context" "fmt" + "github.com/adutra/goalesce" "github.com/go-logr/logr" api "github.com/k8ssandra/k8ssandra-operator/apis/k8ssandra/v1alpha1" @@ -59,7 +60,7 @@ func (r *K8ssandraClusterReconciler) reconcileMedusa( return result.Error(fmt.Errorf("medusa storage secret is not defined for storage provider %s", medusaSpec.StorageProperties.StorageProvider)) } } - if res := r.reconcileMedusaConfigMap(ctx, remoteClient, kc, logger, namespace); res.Completed() { + if res := r.reconcileMedusaConfigMap(ctx, remoteClient, kc, dcConfig, logger, namespace); res.Completed() { return res } @@ -204,12 +205,13 @@ func (r *K8ssandraClusterReconciler) reconcileMedusaConfigMap( ctx context.Context, remoteClient client.Client, kc *api.K8ssandraCluster, + dcConfig *cassandra.DatacenterConfig, logger logr.Logger, namespace string, ) result.ReconcileResult { logger.Info("Reconciling Medusa configMap on namespace : " + namespace) if kc.Spec.Medusa != nil { - medusaIni := medusa.CreateMedusaIni(kc) + medusaIni := medusa.CreateMedusaIni(kc, dcConfig) desiredConfigMap := medusa.CreateMedusaConfigMap(namespace, kc.SanitizedName(), medusaIni) kcKey := utils.GetKey(kc) desiredConfigMap.SetLabels(labels.CleanedUpByLabels(kcKey)) diff --git a/pkg/medusa/reconcile.go b/pkg/medusa/reconcile.go index 70d0384cb..ebae372f6 100644 --- a/pkg/medusa/reconcile.go +++ b/pkg/medusa/reconcile.go @@ -56,7 +56,7 @@ var ( } ) -func CreateMedusaIni(kc *k8ss.K8ssandraCluster) string { +func CreateMedusaIni(kc *k8ss.K8ssandraCluster, dcConfig *cassandra.DatacenterConfig) string { medusaIniTemplate := ` [cassandra] use_sudo = false @@ -118,18 +118,13 @@ func CreateMedusaIni(kc *k8ss.K8ssandraCluster) string { [grpc] enabled = 1 + [logging] + level = DEBUG + [kubernetes] cassandra_url = http://127.0.0.1:8080/api/v0/ops/node/snapshots use_mgmt_api = 1 - enabled = 1 - {{- if and .Spec.Cassandra.DatacenterOptions.ManagementApiAuth .Spec.Cassandra.DatacenterOptions.ManagementApiAuth.Manual }} - ca_cert = /etc/encryption/mgmt/ca.crt - tls_cert = /etc/encryption/mgmt/tls.crt - tls_key = /etc/encryption/mgmt/tls.key - {{- end }} - - [logging] - level = DEBUG` + enabled = 1` t, err := template.New("ini").Parse(medusaIniTemplate) if err != nil { @@ -141,7 +136,17 @@ func CreateMedusaIni(kc *k8ss.K8ssandraCluster) string { panic(err) } - return medusaIni.String() + medusaConfiig := medusaIni.String() + + // Create Kubernetes config here and append it + if dcConfig.ManagementApiAuth != nil && dcConfig.ManagementApiAuth.Manual != nil { + medusaConfiig += ` + ca_cert = /etc/encryption/mgmt/ca.crt + tls_cert = /etc/encryption/mgmt/tls.crt + tls_key = /etc/encryption/mgmt/tls.key` + } + + return medusaConfiig } func CreateMedusaConfigMap(namespace, k8cName, medusaIni string) *corev1.ConfigMap { diff --git a/pkg/medusa/reconcile_test.go b/pkg/medusa/reconcile_test.go index 9f1796ceb..372555791 100644 --- a/pkg/medusa/reconcile_test.go +++ b/pkg/medusa/reconcile_test.go @@ -21,6 +21,7 @@ func TestMedusaIni(t *testing.T) { t.Run("Secured", testMedusaIniSecured) t.Run("Unsecured", testMedusaIniUnsecured) t.Run("MissingOptional", testMedusaIniMissingOptionalSettings) + t.Run("SecuredDcLevelSetting", testMedusaIniSecuredDcLevelSetting) } func testMedusaIniFull(t *testing.T) { @@ -71,7 +72,8 @@ func testMedusaIniFull(t *testing.T) { }, } - medusaIni := CreateMedusaIni(kc) + dcConfig := cassandra.Coalesce(kc.CassClusterName(), kc.Spec.Cassandra.DeepCopy(), kc.Spec.Cassandra.Datacenters[0].DeepCopy()) + medusaIni := CreateMedusaIni(kc, dcConfig) assert.Contains(t, medusaIni, "storage_provider = s3") assert.Contains(t, medusaIni, "bucket_name = bucket") @@ -136,7 +138,9 @@ func testMedusaIniNoPrefix(t *testing.T) { }, } - medusaIni := CreateMedusaIni(kc) + dcConfig := cassandra.Coalesce(kc.CassClusterName(), kc.Spec.Cassandra.DeepCopy(), kc.Spec.Cassandra.Datacenters[0].DeepCopy()) + medusaIni := CreateMedusaIni(kc, dcConfig) + assert.Contains(t, medusaIni, "storage_provider = s3") assert.Contains(t, medusaIni, "bucket_name = bucket") assert.Contains(t, medusaIni, "prefix = demo") @@ -209,7 +213,9 @@ func testMedusaIniSecured(t *testing.T) { } assert := assert.New(t) - medusaIni := CreateMedusaIni(kc) + dcConfig := cassandra.Coalesce(kc.CassClusterName(), kc.Spec.Cassandra.DeepCopy(), kc.Spec.Cassandra.Datacenters[0].DeepCopy()) + medusaIni := CreateMedusaIni(kc, dcConfig) + assert.Contains(medusaIni, "storage_provider = s3") assert.Contains(medusaIni, "bucket_name = bucket") assert.Contains(medusaIni, "prefix = demo") @@ -230,6 +236,68 @@ func testMedusaIniSecured(t *testing.T) { assert.Contains(medusaIni, "tls_key = /etc/encryption/mgmt/tls.key") } +func testMedusaIniSecuredDcLevelSetting(t *testing.T) { + kc := &api.K8ssandraCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "demo", + }, + Spec: api.K8ssandraClusterSpec{ + Cassandra: &api.CassandraClusterTemplate{ + Datacenters: []api.CassandraDatacenterTemplate{ + { + Meta: api.EmbeddedObjectMeta{ + Name: "dc1", + }, + K8sContext: "k8sCtx0", + Size: 3, + DatacenterOptions: api.DatacenterOptions{ + ManagementApiAuth: &cassdcapi.ManagementApiAuthConfig{ + Manual: &cassdcapi.ManagementApiAuthManualConfig{ + ClientSecretName: "test-client-secret", + }, + }, + ServerVersion: "3.11.14", + }, + }, + }, + }, + Medusa: &medusaapi.MedusaClusterTemplate{ + StorageProperties: medusaapi.Storage{ + StorageProvider: "s3", + StorageSecretRef: corev1.LocalObjectReference{ + Name: "secret", + }, + BucketName: "bucket", + MaxBackupAge: 10, + MaxBackupCount: 20, + ApiProfile: "default", + TransferMaxBandwidth: "100MB/s", + ConcurrentTransfers: 2, + MultiPartUploadThreshold: 204857600, + Host: "192.168.0.1", + Region: "us-east-1", + Port: 9001, + Secure: true, + SslVerify: true, + BackupGracePeriodInDays: 7, + }, + CassandraUserSecretRef: corev1.LocalObjectReference{ + Name: "test-superuser", + }, + }, + }, + } + + assert := assert.New(t) + dcConfig := cassandra.Coalesce(kc.CassClusterName(), kc.Spec.Cassandra.DeepCopy(), kc.Spec.Cassandra.Datacenters[0].DeepCopy()) + medusaIni := CreateMedusaIni(kc, dcConfig) + + assert.Contains(medusaIni, "ca_cert = /etc/encryption/mgmt/ca.crt") + assert.Contains(medusaIni, "tls_cert = /etc/encryption/mgmt/tls.crt") + assert.Contains(medusaIni, "tls_key = /etc/encryption/mgmt/tls.key") +} + func testMedusaIniUnsecured(t *testing.T) { kc := &api.K8ssandraCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -277,7 +345,9 @@ func testMedusaIniUnsecured(t *testing.T) { }, } - medusaIni := CreateMedusaIni(kc) + dcConfig := cassandra.Coalesce(kc.CassClusterName(), kc.Spec.Cassandra.DeepCopy(), kc.Spec.Cassandra.Datacenters[0].DeepCopy()) + medusaIni := CreateMedusaIni(kc, dcConfig) + assert.Contains(t, medusaIni, "storage_provider = s3") assert.Contains(t, medusaIni, "bucket_name = bucket") assert.Contains(t, medusaIni, "prefix = demo") @@ -331,7 +401,9 @@ func testMedusaIniMissingOptionalSettings(t *testing.T) { }, } - medusaIni := CreateMedusaIni(kc) + dcConfig := cassandra.Coalesce(kc.CassClusterName(), kc.Spec.Cassandra.DeepCopy(), kc.Spec.Cassandra.Datacenters[0].DeepCopy()) + medusaIni := CreateMedusaIni(kc, dcConfig) + assert.Contains(t, medusaIni, "storage_provider = s3") assert.Contains(t, medusaIni, "bucket_name = bucket") assert.Contains(t, medusaIni, "prefix = demo")