Repository: camunda/camunda-platform-helm
Pull request #638 (2023-05-03 12:09:01)

feat(web-modeler): add support for volume mounts to websockets deployment
### Which problem does the PR fix?
Enable users to configure the websockets app to log to an external file that is mounted into the pod.

Part of https://github.com/camunda/cawemo-laravel-websockets/issues/217.

### What's in this PR?
Add support for volume mounts to the Web Modeler `websockets` deployment (similar to what is already supported for the `restapi` and `webapp` deployments).

### Checklist

Please make sure to follow our [Contributing Guide](../blob/main/CONTRIBUTING.md).

<!-- Place an '[x]' (no spaces) in all applicable fields. Please remove unrelated fields. -->

**Before opening the PR:**

- [x] There is no other open [pull request](../pulls) for the same update/change.
- [x] The commits follow our [Commit Guidelines](../blob/main/CONTRIBUTING.md#commit-guidelines).
- [x] Tests for charts are added (if needed).
- [x] The main Helm chart and sub-chart are updated (if needed).
- [x] In-repo [documentation](../blob/main/CONTRIBUTING.md#documentation) are updated (if needed).

**After opening the PR:**

- [x] Did you sign our CLA (Contributor License Agreement)? It will show once you open the PR.
- [x] Did all checks/tests pass in the PR?


jfriedenstab: FYI @wollefitz I tested this successfully with the latest version of the websockets app.

Patch:
diff --git a/charts/camunda-platform/README.md b/charts/camunda-platform/README.md
index 65b1adc3..f7adb632 100644
--- a/charts/camunda-platform/README.md
+++ b/charts/camunda-platform/README.md
@@ -835,6 +835,8 @@ The SMTP connection can be configured with the values under `restapi.mail`.
 | | `websockets.podLabels` | Can be used to define extra websockets pod labels | `{}` |
 | | `websockets.env` | Can be used to set extra environment variables in each websockets container | `[]` |
 | | `websockets.command` | Can be used to [override the default command](ttps://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/) provided by the container image | `[]` |
+| | `websockets.extraVolumes` | Can be used to define extra volumes for the websockets pod; useful for logging to a file | `[]` |
+| | `websockets.extraVolumeMounts` | Can be used to mount extra volumes for the websockets pod; useful for logging to a file | `[]` |
 | | `websockets.podSecurityContext` | Can be used to define the security options the websockets pod should be run with | `{}` |
 | | `websockets.containerSecurityContext` | Can be used to define the security options the websockets container should be run with | `{}` |
 | | `websockets.startupProbe` | Configuration of the websockets startup probe | |
diff --git a/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml b/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
index b4275880..7ade8c53 100644
--- a/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
+++ b/charts/camunda-platform/templates/web-modeler/deployment-restapi.yaml
@@ -63,7 +63,7 @@ spec:
           - name: RESTAPI_MAIL_ENABLE_TLS
             value: {{ .Values.webModeler.restapi.mail.smtpTlsEnabled | quote }}
           - name: RESTAPI_MAIL_FROM_ADDRESS
-            value: {{ required "The value 'webModeler.restapi.mail.fromAddress' is requiered" .Values.webModeler.restapi.mail.fromAddress | quote }}
+            value: {{ required "The value 'webModeler.restapi.mail.fromAddress' is required" .Values.webModeler.restapi.mail.fromAddress | quote }}
           - name: RESTAPI_MAIL_FROM_NAME
             value: {{ .Values.webModeler.restapi.mail.fromName | quote }}
           - name: RESTAPI_SERVER_URL
diff --git a/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml b/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
index 3e771909..24717731 100644
--- a/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
+++ b/charts/camunda-platform/templates/web-modeler/deployment-websockets.yaml
@@ -95,6 +95,14 @@ spec:
           failureThreshold: {{ .Values.webModeler.websockets.livenessProbe.failureThreshold }}
           timeoutSeconds: {{ .Values.webModeler.websockets.livenessProbe.timeoutSeconds }}
         {{- end }}
+        {{- if .Values.webModeler.websockets.extraVolumeMounts }}
+        volumeMounts:
+        {{- .Values.webModeler.websockets.extraVolumeMounts | toYaml | nindent 8 }}
+        {{- end }}
+      {{- if .Values.webModeler.websockets.extraVolumes }}
+      volumes:
+      {{- .Values.webModeler.websockets.extraVolumes | toYaml | nindent 6 }}
+      {{- end }}
       {{- if .Values.webModeler.serviceAccount.name}}
       serviceAccountName: {{ .Values.webModeler.serviceAccount.name }}
       {{- end }}
diff --git a/charts/camunda-platform/values.yaml b/charts/camunda-platform/values.yaml
index c9a54ed6..ab7455f7 100644
--- a/charts/camunda-platform/values.yaml
+++ b/charts/camunda-platform/values.yaml
@@ -1615,6 +1615,10 @@ webModeler:
     env: []
     # Websockets.command can be used to override the default command provided by the container image, see https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/
     command: []
+    # Websockets.extraVolumes can be used to define extra volumes for the websockets pod; useful for logging to a file
+    extraVolumes: []
+    # Websockets.extraVolumeMounts can be used to mount extra volumes for the websockets pod; useful for logging to a file
+    extraVolumeMounts: []
 
     # Websockets.podSecurityContext can be used to define the security options the websockets pod should be run with
     podSecurityContext: {}


Test patch:
diff --git a/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go b/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go
index e3166ea2..9e735d75 100644
--- a/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go
+++ b/charts/camunda-platform/test/unit/web-modeler/deployment_restapi_test.go
@@ -220,63 +220,6 @@ func (s *restapiDeploymentTemplateTest) TestContainerShouldSetSmtpCredentials()
 		})
 }
 
-func (s *restapiDeploymentTemplateTest) TestContainerSetExtraVolumes() {
-	// given
-	options := &helm.Options{
-		SetValues: map[string]string{
-			"webModeler.enabled":                                       "true",
-			"webModeler.restapi.mail.fromAddress":                      "example@example.com",
-			"webModeler.restapi.extraVolumes[0].name":                  "extraVolume",
-			"webModeler.restapi.extraVolumes[0].configMap.name":        "otherConfigMap",
-			"webModeler.restapi.extraVolumes[0].configMap.defaultMode": "744",
-		},
-		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
-	}
-
-	// when
-	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
-	var deployment appsv1.Deployment
-	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
-
-	// then
-	volumes := deployment.Spec.Template.Spec.Volumes
-	s.Require().Equal(1, len(volumes))
-
-	extraVolume := volumes[0]
-	s.Require().Equal("extraVolume", extraVolume.Name)
-	s.Require().NotNil(*extraVolume.ConfigMap)
-	s.Require().Equal("otherConfigMap", extraVolume.ConfigMap.Name)
-	s.Require().EqualValues(744, *extraVolume.ConfigMap.DefaultMode)
-}
-
-func (s *restapiDeploymentTemplateTest) TestContainerSetExtraVolumeMounts() {
-	// given
-	options := &helm.Options{
-		SetValues: map[string]string{
-			"webModeler.enabled":                                "true",
-			"webModeler.restapi.mail.fromAddress":               "example@example.com",
-			"webModeler.restapi.extraVolumeMounts[0].name":      "otherConfigMap",
-			"webModeler.restapi.extraVolumeMounts[0].mountPath": "/usr/local/config",
-		},
-		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
-	}
-
-	// when
-	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
-	var deployment appsv1.Deployment
-	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
-
-	// then
-	containers := deployment.Spec.Template.Spec.Containers
-	s.Require().Equal(1, len(containers))
-
-	volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts
-	s.Require().Equal(1, len(volumeMounts))
-	extraVolumeMount := volumeMounts[0]
-	s.Require().Equal("otherConfigMap", extraVolumeMount.Name)
-	s.Require().Equal("/usr/local/config", extraVolumeMount.MountPath)
-}
-
 func (s *restapiDeploymentTemplateTest) TestContainerStartupProbe() {
 	// given
 	options := &helm.Options{
diff --git a/charts/camunda-platform/test/unit/web-modeler/deployment_test.go b/charts/camunda-platform/test/unit/web-modeler/deployment_test.go
index e6737fbb..baa2f39b 100644
--- a/charts/camunda-platform/test/unit/web-modeler/deployment_test.go
+++ b/charts/camunda-platform/test/unit/web-modeler/deployment_test.go
@@ -342,6 +342,63 @@ func (s *deploymentTemplateTest) TestContainerSetContainerCommand() {
 	s.Require().Equal("printenv", containers[0].Command[0])
 }
 
+func (s *deploymentTemplateTest) TestContainerSetExtraVolumes() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"webModeler.enabled":                                                   "true",
+			"webModeler.restapi.mail.fromAddress":                                  "example@example.com",
+			"webModeler." + s.component + ".extraVolumes[0].name":                  "extraVolume",
+			"webModeler." + s.component + ".extraVolumes[0].configMap.name":        "otherConfigMap",
+			"webModeler." + s.component + ".extraVolumes[0].configMap.defaultMode": "744",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	volumes := deployment.Spec.Template.Spec.Volumes
+	s.Require().Equal(1, len(volumes))
+
+	extraVolume := volumes[0]
+	s.Require().Equal("extraVolume", extraVolume.Name)
+	s.Require().NotNil(*extraVolume.ConfigMap)
+	s.Require().Equal("otherConfigMap", extraVolume.ConfigMap.Name)
+	s.Require().EqualValues(744, *extraVolume.ConfigMap.DefaultMode)
+}
+
+func (s *deploymentTemplateTest) TestContainerSetExtraVolumeMounts() {
+	// given
+	options := &helm.Options{
+		SetValues: map[string]string{
+			"webModeler.enabled":                                            "true",
+			"webModeler.restapi.mail.fromAddress":                           "example@example.com",
+			"webModeler." + s.component + ".extraVolumeMounts[0].name":      "otherConfigMap",
+			"webModeler." + s.component + ".extraVolumeMounts[0].mountPath": "/usr/local/config",
+		},
+		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
+	}
+
+	// when
+	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
+	var deployment appsv1.Deployment
+	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
+
+	// then
+	containers := deployment.Spec.Template.Spec.Containers
+	s.Require().Equal(1, len(containers))
+
+	volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts
+	s.Require().Equal(1, len(volumeMounts))
+	extraVolumeMount := volumeMounts[0]
+	s.Require().Equal("otherConfigMap", extraVolumeMount.Name)
+	s.Require().Equal("/usr/local/config", extraVolumeMount.MountPath)
+}
+
 func (s *deploymentTemplateTest) TestContainerSetServiceAccountName() {
 	// given
 	options := &helm.Options{
diff --git a/charts/camunda-platform/test/unit/web-modeler/deployment_webapp_test.go b/charts/camunda-platform/test/unit/web-modeler/deployment_webapp_test.go
index 6352378a..8028161c 100644
--- a/charts/camunda-platform/test/unit/web-modeler/deployment_webapp_test.go
+++ b/charts/camunda-platform/test/unit/web-modeler/deployment_webapp_test.go
@@ -320,63 +320,6 @@ func (s *webappDeploymentTemplateTest) TestContainerShouldSetServerHttpsOnly() {
 	s.Require().Contains(env, corev1.EnvVar{Name: "SERVER_HTTPS_ONLY", Value: "true"})
 }
 
-func (s *webappDeploymentTemplateTest) TestContainerSetExtraVolumes() {
-	// given
-	options := &helm.Options{
-		SetValues: map[string]string{
-			"webModeler.enabled":                                      "true",
-			"webModeler.restapi.mail.fromAddress":                     "example@example.com",
-			"webModeler.webapp.extraVolumes[0].name":                  "extraVolume",
-			"webModeler.webapp.extraVolumes[0].configMap.name":        "otherConfigMap",
-			"webModeler.webapp.extraVolumes[0].configMap.defaultMode": "744",
-		},
-		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
-	}
-
-	// when
-	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
-	var deployment appsv1.Deployment
-	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
-
-	// then
-	volumes := deployment.Spec.Template.Spec.Volumes
-	s.Require().Equal(1, len(volumes))
-
-	extraVolume := volumes[0]
-	s.Require().Equal("extraVolume", extraVolume.Name)
-	s.Require().NotNil(*extraVolume.ConfigMap)
-	s.Require().Equal("otherConfigMap", extraVolume.ConfigMap.Name)
-	s.Require().EqualValues(744, *extraVolume.ConfigMap.DefaultMode)
-}
-
-func (s *webappDeploymentTemplateTest) TestContainerSetExtraVolumeMounts() {
-	// given
-	options := &helm.Options{
-		SetValues: map[string]string{
-			"webModeler.enabled":                               "true",
-			"webModeler.restapi.mail.fromAddress":              "example@example.com",
-			"webModeler.webapp.extraVolumeMounts[0].name":      "otherConfigMap",
-			"webModeler.webapp.extraVolumeMounts[0].mountPath": "/usr/local/config",
-		},
-		KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
-	}
-
-	// when
-	output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
-	var deployment appsv1.Deployment
-	helm.UnmarshalK8SYaml(s.T(), output, &deployment)
-
-	// then
-	containers := deployment.Spec.Template.Spec.Containers
-	s.Require().Equal(1, len(containers))
-
-	volumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts
-	s.Require().Equal(1, len(volumeMounts))
-	extraVolumeMount := volumeMounts[0]
-	s.Require().Equal("otherConfigMap", extraVolumeMount.Name)
-	s.Require().Equal("/usr/local/config", extraVolumeMount.MountPath)
-}
-
 func (s *webappDeploymentTemplateTest) TestContainerStartupProbe() {
 	// given
 	options := &helm.Options{