Skip to content

Commit

Permalink
Preserve existing SecurityContext when ReadOnlyRootFilesystem is set (f…
Browse files Browse the repository at this point in the history
…ixes #708) (#709)
  • Loading branch information
olim7t authored Sep 19, 2024
1 parent 8e29896 commit 0283e32
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Changelog for Cass Operator, new PRs should update the `main / unreleased` secti

* [FEATURE] [#651](https://github.com/k8ssandra/cass-operator/issues/651) Add tsreload task for DSE deployments and ability to check if sync operation is available on the mgmt-api side
* [FEATURE] [#701](https://github.com/k8ssandra/cass-operator/issues/701) Allow ReadOnlyRootFilesystem for DSE also with extra mounts to provide support for cass-config-builder setups
* [BUGFIX] [#708](https://github.com/k8ssandra/cass-operator/issues/708) Preserve existing SecurityContext when ReadOnlyRootFilesystem is set

## v1.22.2

Expand Down
5 changes: 3 additions & 2 deletions pkg/reconciliation/construct_podtemplatespec.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,9 +706,10 @@ func buildContainers(dc *api.CassandraDatacenter, baseTemplate *corev1.PodTempla
}

if dc.ReadOnlyFs() {
cassContainer.SecurityContext = &corev1.SecurityContext{
ReadOnlyRootFilesystem: ptr.To[bool](true),
if cassContainer.SecurityContext == nil {
cassContainer.SecurityContext = &corev1.SecurityContext{}
}
cassContainer.SecurityContext.ReadOnlyRootFilesystem = ptr.To[bool](true)
}

// Combine env vars
Expand Down
87 changes: 87 additions & 0 deletions pkg/reconciliation/construct_podtemplatespec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2310,3 +2310,90 @@ func TestReadOnlyRootFilesystemVolumeChangesDSEWithClient(t *testing.T) {
mcacDisabled := corev1.EnvVar{Name: "MGMT_API_DISABLE_MCAC", Value: "true"}
assert.True(envVarsContains(containers[0].Env, mcacDisabled))
}

func TestReadOnlyRootFilesystemWithSecurityContext(t *testing.T) {
assert := assert.New(t)
dc := &api.CassandraDatacenter{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
api.UseClientBuilderAnnotation: "true",
},
},
Spec: api.CassandraDatacenterSpec{
ClusterName: "bob",
ServerType: "dse",
ServerVersion: "6.9.2",
PodTemplateSpec: &corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
InitContainers: []corev1.Container{
{
Name: ServerBaseConfigContainerName,
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
},
},
{
Name: ServerConfigContainerName,
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
},
},
},
Containers: []corev1.Container{
{
Name: CassandraContainerName,
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
},
},
{
Name: SystemLoggerContainerName,
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
},
},
},
},
},
ReadOnlyRootFilesystem: ptr.To[bool](true),
Racks: []api.Rack{
{
Name: "r1",
},
},
},
}

podTemplateSpec, err := buildPodTemplateSpec(dc, dc.Spec.Racks[0], false)
assert.NoError(err, "failed to build PodTemplateSpec")

initContainers := podTemplateSpec.Spec.InitContainers
assert.Len(initContainers, 2, "Unexpected number of init containers returned")

containers := podTemplateSpec.Spec.Containers
assert.Len(containers, 2, "Unexpected number of containers returned")

// The cassandra container should get readOnlyRootFilesystem from the top-level field, but also retain the
// capabilities from the podTemplateSpec.
assert.Equal(CassandraContainerName, containers[0].Name)
assert.True(reflect.DeepEqual(containers[0].SecurityContext, &corev1.SecurityContext{
ReadOnlyRootFilesystem: ptr.To[bool](true),
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
}))

// Other containers should just get the podTemplateSpec contents.
assert.Equal(ServerBaseConfigContainerName, initContainers[0].Name)
assert.True(reflect.DeepEqual(initContainers[0].SecurityContext, &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
}))

assert.Equal(ServerConfigContainerName, initContainers[1].Name)
assert.True(reflect.DeepEqual(initContainers[1].SecurityContext, &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
}))

assert.Equal(SystemLoggerContainerName, containers[1].Name)
assert.True(reflect.DeepEqual(containers[1].SecurityContext, &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
}))
}

0 comments on commit 0283e32

Please sign in to comment.