Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Changelog for Cass Operator, new PRs should update the `main / unreleased` secti

## unreleased

* [ENHANCEMENT] [#922](https://github.com/k8ssandra/cass-operator/issues/922) Allow VolumeAttributesClassName changes in storageConfig webhook to support in-place EBS volume performance class updates on AWS
* [ENHANCEMENT] [#912](https://github.com/k8ssandra/cass-operator/issues/912) Add new webhook validations for maxUnavailable string format as well as PVC sizes
* [ENHANCEMENT] [#902](https://github.com/k8ssandra/cass-operator/issues/902) If scaling down or scaling up process is still ongoing, the webhook will prevent changing the cluster size.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,15 @@ func ValidateDatacenterFieldChanges(oldDc *api.CassandraDatacenter, newDc *api.C
return attemptedTo(
"shrink storageConfig.CassandraDataVolumeClaimSpec from %s to %s", oldStorageRequest.String(), newStorageRequest.String())
}
}

// CassandraDataVolumeClaimSpec changes are disallowed
if metav1.HasAnnotation(newDc.ObjectMeta, api.AllowStorageChangesAnnotation) && newDc.Annotations[api.AllowStorageChangesAnnotation] == "true" {
// If the AllowStorageChangesAnnotation is set, we allow changes to the CassandraDataVolumeClaimSpec sizes, but not other fields
oldClaimSpec.Resources.Requests = newClaimSpec.Resources.Requests
if metav1.HasAnnotation(newDc.ObjectMeta, api.AllowStorageChangesAnnotation) && newDc.Annotations[api.AllowStorageChangesAnnotation] == "true" {
// If the AllowStorageChangesAnnotation is set, we allow changes to the CassandraDataVolumeClaimSpec sizes, but not other fields
oldClaimSpec.Resources.Requests = newClaimSpec.Resources.Requests
}

// VolumeAttributesClassName changes are always allowed as they represent in-place volume
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't strictly true, the StorageClass must support ModifyVolume. Also, did you verify if the StatefulSet controller accepts these changes and applies them?

There is also no monitoring in here that the VolumeAttributesClass change has been approved as the CSI driver can reject it. That would require changes like the resizing parameter checks and correct reconciliation until the change has been approved.

This is relevant because in some drivers such as AWS, one can change from gp2 to gp3 and this operation might not be instant and as such will require the operator to correctly wait for the changes to be applied. There are also restrictions on how many times per day such operations can be done and we can't set the datacenter to a ready state if the changes haven't been applied (or for example incorrect / outdated parameters are used).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats fair, I have made the PR a draft. Current PR only bypasses the validation and does not make any changes.
Can I make it a gated feature with more checks in place?

// performance class changes (e.g. AWS EBS VolumeAttributesClass) and do not replace the PVC.
oldClaimSpec.VolumeAttributesClassName = newClaimSpec.VolumeAttributesClassName
}

if !apiequality.Semantic.DeepEqual(oldClaimSpec, newClaimSpec) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,82 @@ func Test_ValidateDatacenterFieldChanges(t *testing.T) {
},
errString: "",
},
{
name: "VolumeAttributesClassName change is allowed",
oldDc: &api.CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
},
Spec: api.CassandraDatacenterSpec{
StorageConfig: api.StorageConfig{
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: storageName,
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
VolumeAttributesClassName: ptr.To[string]("gp3-cassandra-general"),
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize},
},
},
},
},
},
newDc: &api.CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
},
Spec: api.CassandraDatacenterSpec{
StorageConfig: api.StorageConfig{
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: storageName,
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
VolumeAttributesClassName: ptr.To[string]("gp3-cassandra"),
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize},
},
},
},
},
},
errString: "",
},
{
name: "VolumeAttributesClassName change with other field change is rejected",
oldDc: &api.CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
},
Spec: api.CassandraDatacenterSpec{
StorageConfig: api.StorageConfig{
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: storageName,
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
VolumeAttributesClassName: ptr.To[string]("gp3-cassandra-general"),
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize},
},
},
},
},
},
newDc: &api.CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Name: "exampleDC",
},
Spec: api.CassandraDatacenterSpec{
StorageConfig: api.StorageConfig{
CassandraDataVolumeClaimSpec: &corev1.PersistentVolumeClaimSpec{
StorageClassName: storageName,
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteMany"},
VolumeAttributesClassName: ptr.To[string]("gp3-cassandra"),
Resources: corev1.VolumeResourceRequirements{
Requests: map[corev1.ResourceName]resource.Quantity{"storage": storageSize},
},
},
},
},
},
errString: "change storageConfig.CassandraDataVolumeClaimSpec",
},
{
name: "Removing a rack",
oldDc: &api.CassandraDatacenter{
Expand Down
Loading