Skip to content

Commit

Permalink
If management-api authentication is enabled, mount clientSecret to th…
Browse files Browse the repository at this point in the history
…e medusa container and modify medusa.ini. Update medusa to 0.19.0
  • Loading branch information
burmanm committed Feb 21, 2024
1 parent 81ab6bc commit d596d09
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG/CHANGELOG-1.13.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ When cutting a new release, update the `unreleased` heading to the tag being gen
* [ENHANCEMENT] [#1203](https://github.com/k8ssandra/k8ssandra-operator/issues/1203) Add new setting ConcurrencyPolicy to MedusaBackupSchedules
* [ENHANCEMENT] [#1209](https://github.com/k8ssandra/k8ssandra-operator/issues/1209) Expose the option to disable the cert-manager presence check in the Helm charts
* [ENHANCEMENT] [#1206](https://github.com/k8ssandra/k8ssandra-operator/issues/1206) Allow setting https proxy for CRD upgrader job in Helm charts
* [ENHANCEMENT] [#1214](https://github.com/k8ssandra/k8ssandra-operator/issues/1214) Update Medusa to 0.19.0 and support mounting clientSecret to medusa container
1 change: 1 addition & 0 deletions controllers/k8ssandra/k8ssandracluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func TestK8ssandraCluster(t *testing.T) {
t.Run("CreateMultiDcClusterWithReaper", testEnv.ControllerTest(ctx, createMultiDcClusterWithReaper))
t.Run("CreateMultiDcClusterWithMedusa", testEnv.ControllerTest(ctx, createMultiDcClusterWithMedusa))
t.Run("CreateSingleDcClusterWithMedusaConfigRef", testEnv.ControllerTest(ctx, createSingleDcClusterWithMedusaConfigRef))
t.Run("CreateSingleDcClusterWithManagementApiSecured", testEnv.ControllerTest(ctx, createSingleDcClusterWithManagementApiSecured))
t.Run("CreatingSingleDcClusterWithoutPrefixInClusterSpecFail", testEnv.ControllerTest(ctx, creatingSingleDcClusterWithoutPrefixInClusterSpecFails))
t.Run("CreateMultiDcClusterWithReplicatedSecrets", testEnv.ControllerTest(ctx, createMultiDcClusterWithReplicatedSecrets))
t.Run("CreateSingleDcClusterNoAuth", testEnv.ControllerTest(ctx, createSingleDcClusterNoAuth))
Expand Down
49 changes: 49 additions & 0 deletions controllers/k8ssandra/medusa_reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,3 +681,52 @@ func verifyBucketSecretMounted(ctx context.Context, t *testing.T, f *framework.F
// check its mount
assert.True(t, f.ContainerHasVolumeMount(medusaContainer, clusterSecretName, "/etc/medusa-secrets"), "Missing Volume Mount for Medusa bucket key")
}

func createSingleDcClusterWithManagementApiSecured(t *testing.T, ctx context.Context, f *framework.Framework, namespace string) {
require := require.New(t)
kc := &api.K8ssandraCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: k8ssandraClusterName,
},
Spec: api.K8ssandraClusterSpec{
Cassandra: &api.CassandraClusterTemplate{
DatacenterOptions: api.DatacenterOptions{
ManagementApiAuth: &cassdcapi.ManagementApiAuthConfig{
Manual: &cassdcapi.ManagementApiAuthManualConfig{
ClientSecretName: "test-client-secret",
},
},
},
Datacenters: []api.CassandraDatacenterTemplate{
dcTemplate("dc1", f.DataPlaneContexts[0]),
},
},
Medusa: medusaTemplateWithoutConfigRef(),
},
}

require.NoError(f.Client.Create(ctx, kc))
verifyReplicatedSecretReconciled(ctx, t, f, kc)

reconcileMedusaStandaloneDeployment(ctx, t, f, kc, "dc1", f.DataPlaneContexts[0])

dc1Key := framework.ClusterKey{NamespacedName: types.NamespacedName{Namespace: namespace, Name: "dc1"}, K8sContext: f.DataPlaneContexts[0]}
require.Eventually(f.DatacenterExists(ctx, dc1Key), timeout, interval)

dc := &cassdcapi.CassandraDatacenter{}
require.NoError(f.Get(ctx, dc1Key, dc))

checkMedusaObjectsCompliance(t, f, dc, kc)

containerIndex, found := cassandra.FindContainer(dc.Spec.PodTemplateSpec, "medusa")
require.True(found, fmt.Sprintf("%s doesn't have medusa container", dc.Name))
mainContainer := dc.Spec.PodTemplateSpec.Spec.Containers[containerIndex]

require.True(f.ContainerHasVolumeMount(mainContainer, "mgmt-encryption", "/etc/encryption/mgmt"))

volumeIndex, foundMgmtEncryptionClient := cassandra.FindVolume(dc.Spec.PodTemplateSpec, "mgmt-encryption")
require.True(foundMgmtEncryptionClient)
vol := dc.Spec.PodTemplateSpec.Spec.Volumes[volumeIndex]
require.Equal(kc.Spec.Cassandra.DatacenterOptions.ManagementApiAuth.Manual.ClientSecretName, vol.Secret.SecretName)
}
41 changes: 37 additions & 4 deletions pkg/medusa/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
const (
DefaultMedusaImageRepository = "k8ssandra"
DefaultMedusaImageName = "medusa"
DefaultMedusaVersion = "0.17.2"
DefaultMedusaVersion = "0.19.0"
DefaultMedusaPort = 50051
DefaultProbeInitialDelay = 10
DefaultProbeTimeout = 1
Expand Down Expand Up @@ -122,6 +122,11 @@ func CreateMedusaIni(kc *k8ss.K8ssandraCluster) string {
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`
Expand Down Expand Up @@ -171,7 +176,7 @@ func UpdateMedusaInitContainer(dcConfig *cassandra.DatacenterConfig, medusaSpec
setImage(medusaSpec.ContainerImage, restoreContainer)
restoreContainer.SecurityContext = medusaSpec.SecurityContext
restoreContainer.Env = medusaEnvVars(medusaSpec, k8cName, useExternalSecrets, "RESTORE")
restoreContainer.VolumeMounts = medusaVolumeMounts(medusaSpec, k8cName)
restoreContainer.VolumeMounts = medusaVolumeMounts(dcConfig, medusaSpec, k8cName)
restoreContainer.Resources = medusaInitContainerResources(medusaSpec)

if !found {
Expand Down Expand Up @@ -231,7 +236,7 @@ func CreateMedusaMainContainer(dcConfig *cassandra.DatacenterConfig, medusaSpec

medusaContainer.ReadinessProbe = readinessProbe
medusaContainer.LivenessProbe = livenessProbe
medusaContainer.VolumeMounts = medusaVolumeMounts(medusaSpec, k8cName)
medusaContainer.VolumeMounts = medusaVolumeMounts(dcConfig, medusaSpec, k8cName)
medusaContainer.Resources = medusaMainContainerResources(medusaSpec)
return medusaContainer, nil
}
Expand Down Expand Up @@ -265,7 +270,7 @@ func setImage(containerImage *images.Image, container *corev1.Container) {
container.ImagePullPolicy = image.PullPolicy
}

func medusaVolumeMounts(medusaSpec *api.MedusaClusterTemplate, k8cName string) []corev1.VolumeMount {
func medusaVolumeMounts(dcConfig *cassandra.DatacenterConfig, medusaSpec *api.MedusaClusterTemplate, k8cName string) []corev1.VolumeMount {
volumeMounts := []corev1.VolumeMount{
{ // Cassandra config volume
Name: "server-config",
Expand Down Expand Up @@ -301,6 +306,14 @@ func medusaVolumeMounts(medusaSpec *api.MedusaClusterTemplate, k8cName string) [
})
}

// Management-api encryption client certificates
if dcConfig.ManagementApiAuth != nil && dcConfig.ManagementApiAuth.Manual != nil {
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: "mgmt-encryption",
MountPath: "/etc/encryption/mgmt",
})
}

Check warning on line 315 in pkg/medusa/reconcile.go

View check run for this annotation

Codecov / codecov/patch

pkg/medusa/reconcile.go#L311-L315

Added lines #L311 - L315 were not covered by tests

return volumeMounts
}

Expand Down Expand Up @@ -445,6 +458,26 @@ func GenerateMedusaVolumes(dcConfig *cassandra.DatacenterConfig, medusaSpec *api
Exists: found,
})
}

// Management-api client certificates
if dcConfig.ManagementApiAuth != nil && dcConfig.ManagementApiAuth.Manual != nil {
managementApiVolumeIndex, found := cassandra.FindVolume(&dcConfig.PodTemplateSpec, "mgmt-encryption")
managementApiVolume := &corev1.Volume{
Name: "mgmt-encryption",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: dcConfig.ManagementApiAuth.Manual.ClientSecretName,
},
},
}

newVolumes = append(newVolumes, medusaVolume{
Volume: managementApiVolume,
VolumeIndex: managementApiVolumeIndex,
Exists: found,
})
}

Check warning on line 479 in pkg/medusa/reconcile.go

View check run for this annotation

Codecov / codecov/patch

pkg/medusa/reconcile.go#L463-L479

Added lines #L463 - L479 were not covered by tests

return newVolumes
}

Expand Down
42 changes: 27 additions & 15 deletions pkg/medusa/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/go-logr/logr"
cassdcapi "github.com/k8ssandra/cass-operator/apis/cassandra/v1beta1"
api "github.com/k8ssandra/k8ssandra-operator/apis/k8ssandra/v1alpha1"
medusaapi "github.com/k8ssandra/k8ssandra-operator/apis/medusa/v1alpha1"
"github.com/k8ssandra/k8ssandra-operator/pkg/cassandra"
Expand Down Expand Up @@ -160,6 +161,13 @@ func testMedusaIniSecured(t *testing.T) {
},
Spec: api.K8ssandraClusterSpec{
Cassandra: &api.CassandraClusterTemplate{
DatacenterOptions: api.DatacenterOptions{
ManagementApiAuth: &cassdcapi.ManagementApiAuthConfig{
Manual: &cassdcapi.ManagementApiAuthManualConfig{
ClientSecretName: "test-client-secret",
},
},
},
Datacenters: []api.CassandraDatacenterTemplate{
{
Meta: api.EmbeddedObjectMeta{
Expand Down Expand Up @@ -200,22 +208,26 @@ func testMedusaIniSecured(t *testing.T) {
},
}

assert := assert.New(t)
medusaIni := CreateMedusaIni(kc)
assert.Contains(t, medusaIni, "storage_provider = s3")
assert.Contains(t, medusaIni, "bucket_name = bucket")
assert.Contains(t, medusaIni, "prefix = demo")
assert.Contains(t, medusaIni, "max_backup_age = 10")
assert.Contains(t, medusaIni, "max_backup_count = 20")
assert.Contains(t, medusaIni, "api_profile = default")
assert.Contains(t, medusaIni, "transfer_max_bandwidth = 100MB/s")
assert.Contains(t, medusaIni, "concurrent_transfers = 2")
assert.Contains(t, medusaIni, "multi_part_upload_threshold = 204857600")
assert.Contains(t, medusaIni, "host = 192.168.0.1")
assert.Contains(t, medusaIni, "region = us-east-1")
assert.Contains(t, medusaIni, "port = 9001")
assert.Contains(t, medusaIni, "secure = True")
assert.Contains(t, medusaIni, "ssl_verify = True")
assert.Contains(t, medusaIni, "backup_grace_period_in_days = 7")
assert.Contains(medusaIni, "storage_provider = s3")
assert.Contains(medusaIni, "bucket_name = bucket")
assert.Contains(medusaIni, "prefix = demo")
assert.Contains(medusaIni, "max_backup_age = 10")
assert.Contains(medusaIni, "max_backup_count = 20")
assert.Contains(medusaIni, "api_profile = default")
assert.Contains(medusaIni, "transfer_max_bandwidth = 100MB/s")
assert.Contains(medusaIni, "concurrent_transfers = 2")
assert.Contains(medusaIni, "multi_part_upload_threshold = 204857600")
assert.Contains(medusaIni, "host = 192.168.0.1")
assert.Contains(medusaIni, "region = us-east-1")
assert.Contains(medusaIni, "port = 9001")
assert.Contains(medusaIni, "secure = True")
assert.Contains(medusaIni, "ssl_verify = True")
assert.Contains(medusaIni, "backup_grace_period_in_days = 7")
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) {
Expand Down

0 comments on commit d596d09

Please sign in to comment.