diff --git a/CHANGELOG/CHANGELOG-1.21.md b/CHANGELOG/CHANGELOG-1.21.md index dcd092818..1da1c9153 100644 --- a/CHANGELOG/CHANGELOG-1.21.md +++ b/CHANGELOG/CHANGELOG-1.21.md @@ -18,3 +18,4 @@ When cutting a new release, update the `unreleased` heading to the tag being gen * [CHANGE] [#1441](https://github.com/k8ssandra/k8ssandra-operator/issues/1441) Use k8ssandra-client instead of k8ssandra-tools for CRD upgrades * [BUGFIX] [#1383](https://github.com/k8ssandra/k8ssandra-operator/issues/1383) Do not create MedusaBackup if MedusaBakupJob did not fully succeed * [ENHANCEMENT] [#1667](https://github.com/k8ssahttps://github.com/k8ssandra/k8ssandra/issues/1667) Add `skipSchemaMigration` option to `K8ssandraCluster.spec.reaper` +* [ENHANCEMENT] [#1465](https://github.com/k8ssandra/k8ssandra/issues/1465) Add `volumeMounts` option to `K8ssandraCluster.spec.medusa.storageProperties` diff --git a/apis/medusa/v1alpha1/medusa_types.go b/apis/medusa/v1alpha1/medusa_types.go index db88f7d8c..65f1c27f8 100644 --- a/apis/medusa/v1alpha1/medusa_types.go +++ b/apis/medusa/v1alpha1/medusa_types.go @@ -115,6 +115,10 @@ type Storage struct { // Pod storage settings for the local storage provider // +optional PodStorage *PodStorageSettings `json:"podStorage,omitempty"` + + // Volume mounts for Medusa container. + // +optional + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"` } type PodStorageSettings struct { diff --git a/apis/medusa/v1alpha1/zz_generated.deepcopy.go b/apis/medusa/v1alpha1/zz_generated.deepcopy.go index d9a9eaa22..d48fa31b4 100644 --- a/apis/medusa/v1alpha1/zz_generated.deepcopy.go +++ b/apis/medusa/v1alpha1/zz_generated.deepcopy.go @@ -789,6 +789,13 @@ func (in *Storage) DeepCopyInto(out *Storage) { *out = new(PodStorageSettings) (*in).DeepCopyInto(*out) } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Storage. diff --git a/charts/k8ssandra-operator/crds/k8ssandra-operator-crds.yaml b/charts/k8ssandra-operator/crds/k8ssandra-operator-crds.yaml index e95dada78..b0bc61350 100644 --- a/charts/k8ssandra-operator/crds/k8ssandra-operator-crds.yaml +++ b/charts/k8ssandra-operator/crds/k8ssandra-operator-crds.yaml @@ -26564,6 +26564,49 @@ spec: Max upload bandwidth in MB/s. Defaults to 50 MB/s. type: string + volumeMounts: + description: Volume mounts for Medusa container. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array type: object type: object reaper: @@ -32242,6 +32285,49 @@ spec: Max upload bandwidth in MB/s. Defaults to 50 MB/s. type: string + volumeMounts: + description: Volume mounts for Medusa container. + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array type: object type: object status: diff --git a/config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml b/config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml index 3cb1f2a13..1a56e68a8 100644 --- a/config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml +++ b/config/crd/bases/k8ssandra.io_k8ssandraclusters.yaml @@ -26502,6 +26502,49 @@ spec: Max upload bandwidth in MB/s. Defaults to 50 MB/s. type: string + volumeMounts: + description: Volume mounts for Medusa container. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array type: object type: object reaper: diff --git a/config/crd/bases/medusa.k8ssandra.io_medusaconfigurations.yaml b/config/crd/bases/medusa.k8ssandra.io_medusaconfigurations.yaml index 66a913472..35f55aed6 100644 --- a/config/crd/bases/medusa.k8ssandra.io_medusaconfigurations.yaml +++ b/config/crd/bases/medusa.k8ssandra.io_medusaconfigurations.yaml @@ -161,6 +161,49 @@ spec: Max upload bandwidth in MB/s. Defaults to 50 MB/s. type: string + volumeMounts: + description: Volume mounts for Medusa container. + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: |- + Path within the container at which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: |- + mountPropagation determines how mounts are propagated from the host + to container and the other way around. + When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: |- + Mounted read-only if true, read-write otherwise (false or unspecified). + Defaults to false. + type: boolean + subPath: + description: |- + Path within the volume from which the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: |- + Expanded path within the volume from which the container's volume should be mounted. + Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. + Defaults to "" (volume's root). + SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array type: object type: object status: diff --git a/pkg/medusa/reconcile.go b/pkg/medusa/reconcile.go index 929c1459b..46ac3cdb2 100644 --- a/pkg/medusa/reconcile.go +++ b/pkg/medusa/reconcile.go @@ -323,6 +323,10 @@ func medusaVolumeMounts(dcConfig *cassandra.DatacenterConfig, medusaSpec *api.Me }) } + if medusaSpec.StorageProperties.VolumeMounts != nil { + volumeMounts = append(volumeMounts, medusaSpec.StorageProperties.VolumeMounts...) + } + return volumeMounts } diff --git a/pkg/medusa/reconcile_test.go b/pkg/medusa/reconcile_test.go index 9d75d31cd..2633182ba 100644 --- a/pkg/medusa/reconcile_test.go +++ b/pkg/medusa/reconcile_test.go @@ -2,6 +2,7 @@ package medusa import ( "fmt" + "slices" "testing" "github.com/go-logr/logr" @@ -706,3 +707,39 @@ func TestPurgeCronJobNameTooLong(t *testing.T) { _, err := PurgeCronJob(dcConfig, clusterName, namespace, logger) assert.NotNil(t, err) } + +func TestMedusaVolumeMounts(t *testing.T) { + mountName := "testMount" + mountPath := "/home/cassandra/config" + + medusaSpec := &medusaapi.MedusaClusterTemplate{ + StorageProperties: medusaapi.Storage{ + StorageProvider: "s3", + BucketName: "bucket", + VolumeMounts: []corev1.VolumeMount{{ + Name: mountName, + MountPath: mountPath, + }}, + }, + CassandraUserSecretRef: corev1.LocalObjectReference{ + Name: "test-superuser", + }, + } + + dcConfig := cassandra.DatacenterConfig{} + + logger := logr.New(logr.Discard().GetSink()) + + medusaContainer, err := CreateMedusaMainContainer(&dcConfig, medusaSpec, true, "test", logger) + + assert.NoError(t, err) + + volumeMounts := medusaContainer.VolumeMounts + + assert.NotNil(t, volumeMounts) + + idx := slices.IndexFunc(volumeMounts, func(c corev1.VolumeMount) bool { return c.Name == mountName }) + assert.NotEqual(t, idx, -1) + + assert.Equal(t, volumeMounts[idx].MountPath, mountPath) +}