Skip to content

Commit cdc6b70

Browse files
authored
feat(web-modeler): add support for configuring Zeebe clusters (#2489)
1 parent e6d2cb6 commit cdc6b70

File tree

6 files changed

+266
-10
lines changed

6 files changed

+266
-10
lines changed

charts/camunda-platform-alpha/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,7 @@ Please see the corresponding [release guide](../../docs/release.md) to find out
14921492
| `webModeler.restapi.mail.existingSecretPasswordKey` | can be used to provide the name of an existing secret key containing the SMTP password | `smtp-password` |
14931493
| `webModeler.restapi.mail.fromAddress` | defines the email address that will be displayed as the sender of emails sent by WebModeler | `""` |
14941494
| `webModeler.restapi.mail.fromName` | defines the name that will be displayed as the sender of emails sent by WebModeler | `Camunda 8` |
1495+
| `webModeler.restapi.clusters` | can be used to configure Camunda 8 clusters that will be available in Web Modeler (will override default cluster configuration that is used if `zeebe.enabled=true`) | `[]` |
14951496
| `webModeler.restapi.podAnnotations` | can be used to define extra restapi pod annotations | `{}` |
14961497
| `webModeler.restapi.podLabels` | can be used to define extra restapi pod labels | `{}` |
14971498
| `webModeler.restapi.env` | can be used to set extra environment variables in each restapi container | `[]` |

charts/camunda-platform-alpha/templates/camunda/_helpers.tpl

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,10 @@ Usage: {{ include "camundaPlatform.getExternalURL" (dict "component" "operate" "
364364
{{- if (index .context.Values .component "enabled") -}}
365365
{{- if (index .context.Values .component "ingress" "enabled") }}
366366
{{- $proto := ternary "https" "http" (index .context.Values .component "ingress" "tls" "enabled") -}}
367-
{{- printf "%s://%s" $proto (index .context.Values .component "ingress" "host") -}}
367+
{{- printf "%s://%s" $proto (index .context.Values .component "ingress" "host") -}}
368368
{{- else if $.context.Values.global.ingress.enabled -}}
369369
{{ $proto := ternary "https" "http" .context.Values.global.ingress.tls.enabled -}}
370-
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (index .context.Values .component "contextPath") -}}
370+
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (index .context.Values .component "contextPath") -}}
371371
{{- else -}}
372372
{{- $portMapping := (dict
373373
"operate" "8081"
@@ -380,7 +380,7 @@ Usage: {{ include "camundaPlatform.getExternalURL" (dict "component" "operate" "
380380
"connectors" "8086"
381381
"zeebeGateway" "26500"
382382
) -}}
383-
{{- printf "http://localhost:%s" (get $portMapping .component) -}}
383+
{{- printf "http://localhost:%s" (get $portMapping .component) -}}
384384
{{- end -}}
385385
{{- end -}}
386386
{{- end -}}
@@ -411,6 +411,17 @@ Optimize templates.
411411
Tasklist templates.
412412
********************************************************************************
413413
*/}}
414+
415+
{{/*
416+
[camunda-platform] Tasklist internal URL.
417+
*/}}
418+
{{ define "camundaPlatform.tasklistURL" }}
419+
{{- if .Values.tasklist.enabled -}}
420+
{{- print "http://" -}}{{- include "tasklist.fullname" . -}}:{{- .Values.tasklist.service.port -}}
421+
{{- .Values.tasklist.contextPath -}}
422+
{{- end -}}
423+
{{- end -}}
424+
414425
{{/*
415426
[camunda-platform] Tasklist external URL.
416427
*/}}
@@ -433,13 +444,13 @@ Web Modeler templates.
433444
{{- $ingress := .context.Values.webModeler.ingress }}
434445
{{- if index $ingress "enabled" }}
435446
{{- $proto := ternary "https" "http" (index $ingress .component "tls" "enabled") -}}
436-
{{- printf "%s://%s" $proto (index $ingress .component "host") -}}
447+
{{- printf "%s://%s" $proto (index $ingress .component "host") -}}
437448
{{- else if $.context.Values.global.ingress.enabled -}}
438449
{{ $proto := ternary "https" "http" .context.Values.global.ingress.tls.enabled -}}
439450
{{- if eq .component "websockets" }}
440-
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (include "webModeler.websocketContextPath" .context) -}}
451+
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (include "webModeler.websocketContextPath" .context) -}}
441452
{{- else -}}
442-
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (index .context.Values.webModeler "contextPath") -}}
453+
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (index .context.Values.webModeler "contextPath") -}}
443454
{{- end -}}
444455
{{- end -}}
445456
{{- end -}}
@@ -518,7 +529,7 @@ Zeebe templates.
518529
{{- printf "%s://%s%s" $proto .Values.global.ingress.host .Values.zeebeGateway.contextPath -}}
519530
{{- else if .Values.zeebeGateway.ingress.rest.enabled -}}
520531
{{ $proto := ternary "https" "http" .Values.zeebeGateway.ingress.rest.tls.enabled -}}
521-
{{- printf "%s://%s%s" $proto .Values.zeebeGateway.ingress.rest.host .Values.zeebeGateway.contextPath -}}
532+
{{- printf "%s://%s%s" $proto .Values.zeebeGateway.ingress.rest.host .Values.zeebeGateway.contextPath -}}
522533
{{- else -}}
523534
{{- printf "http://localhost:8088" -}}
524535
{{- end -}}
@@ -539,7 +550,7 @@ Zeebe templates.
539550
{{- if .Values.zeebe.enabled -}}
540551
{{-
541552
printf "http://%s:%v%s"
542-
(include "zeebe.fullname.gateway" .)
553+
(include "zeebe.names.gateway" .)
543554
.Values.zeebeGateway.service.restPort
544555
(.Values.zeebeGateway.contextPath | default "")
545556
-}}

charts/camunda-platform-alpha/templates/web-modeler/configmap-restapi.yaml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ data:
2626
pusher:
2727
host: {{ include "webModeler.websockets.fullname" . | quote }}
2828
port: {{ .Values.webModeler.websockets.service.port }}
29-
29+
3030
security:
3131
jwt:
3232
issuer:
@@ -40,6 +40,32 @@ data:
4040
4141
server:
4242
url: {{ tpl .Values.global.identity.auth.webModeler.redirectUrl $ | quote }}
43+
44+
{{- if or .Values.zeebe.enabled .Values.webModeler.restapi.clusters }}
45+
clusters:
46+
{{- if .Values.webModeler.restapi.clusters }}
47+
{{- .Values.webModeler.restapi.clusters | toYaml | nindent 10 }}
48+
{{- else}}
49+
- id: "default-cluster"
50+
name: {{ tpl .Values.global.zeebeClusterName . | quote }}
51+
version: {{ include "camundaPlatform.imageTagByParams" (dict "base" .Values.global "overlay" .Values.zeebe) | quote }}
52+
authentication: {{ .Values.global.identity.auth.enabled | ternary "OAUTH" "NONE" | quote }}
53+
url:
54+
zeebe:
55+
grpc: "grpc://{{ tpl .Values.global.zeebeClusterName . }}-gateway:{{ .Values.zeebeGateway.service.grpcPort }}"
56+
rest: {{ include "camundaPlatform.zeebeGatewayRESTURL" . | quote }}
57+
operate: {{ include "camundaPlatform.operateURL" . | quote }}
58+
tasklist: {{ include "camundaPlatform.tasklistURL" . | quote }}
59+
oauth:
60+
url: {{ include "camundaPlatform.authIssuerBackendUrlTokenEndpoint" . | quote }}
61+
audience:
62+
zeebe: {{ include "zeebe.audience" . | quote }}
63+
operate: {{ include "operate.authAudience" . | quote }}
64+
tasklist: {{ include "tasklist.authAudience" . | quote }}
65+
scope: {{ include "zeebe.tokenScope" . | quote }}
66+
{{- end }}
67+
{{- end }}
68+
4369
spring:
4470
datasource:
4571
url: {{ include "webModeler.restapi.databaseUrl" . | quote }}

charts/camunda-platform-alpha/test/unit/web-modeler/configmap_restapi_test.go

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ func (s *configmapRestAPITemplateTest) TestContainerShouldSetCorrectKeycloakServ
194194
// then
195195
s.Require().Equal("http://keycloak:80/auth/realms/camunda-platform", configmapApplication.Camunda.Modeler.Security.JWT.Issuer.BackendUrl)
196196
}
197+
197198
func (s *configmapRestAPITemplateTest) TestContainerShouldSetCorrectKeycloakServiceUrlWithCustomPort() {
198199
// given
199200
options := &helm.Options{
@@ -221,6 +222,7 @@ func (s *configmapRestAPITemplateTest) TestContainerShouldSetCorrectKeycloakServ
221222
// then
222223
s.Require().Equal("http://keycloak:8888/auth/realms/camunda-platform", configmapApplication.Camunda.Modeler.Security.JWT.Issuer.BackendUrl)
223224
}
225+
224226
func (s *configmapRestAPITemplateTest) TestContainerShouldSetSmtpCredentials() {
225227
// given
226228
options := &helm.Options{
@@ -247,6 +249,7 @@ func (s *configmapRestAPITemplateTest) TestContainerShouldSetSmtpCredentials() {
247249
// then
248250
s.Require().Equal("modeler-user", configmapApplication.Spring.Mail.Username)
249251
}
252+
250253
func (s *configmapRestAPITemplateTest) TestContainerShouldSetExternalDatabaseConfiguration() {
251254
// given
252255
options := &helm.Options{
@@ -276,3 +279,182 @@ func (s *configmapRestAPITemplateTest) TestContainerShouldSetExternalDatabaseCon
276279
s.Require().Equal("jdbc:postgresql://postgres.example.com:65432/modeler-database", configmapApplication.Spring.Datasource.Url)
277280
s.Require().Equal("modeler-user", configmapApplication.Spring.Datasource.Username)
278281
}
282+
283+
func (s *configmapRestAPITemplateTest) TestContainerShouldConfigureClusterFromSameHelmInstallationWithDefaultValues() {
284+
// given
285+
options := &helm.Options{
286+
SetValues: map[string]string{
287+
"webModeler.enabled": "true",
288+
"webModeler.restapi.mail.fromAddress": "[email protected]",
289+
"postgresql.enabled": "false",
290+
},
291+
KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
292+
}
293+
294+
// when
295+
output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
296+
var configmap corev1.ConfigMap
297+
var configmapApplication WebModelerRestAPIApplicationYAML
298+
helm.UnmarshalK8SYaml(s.T(), output, &configmap)
299+
300+
err := yaml.Unmarshal([]byte(configmap.Data["application.yaml"]), &configmapApplication)
301+
if err != nil {
302+
s.Fail("Failed to unmarshal yaml. error=", err)
303+
}
304+
305+
// then
306+
s.Require().Equal(1, len(configmapApplication.Camunda.Modeler.Clusters))
307+
s.Require().Equal("default-cluster", configmapApplication.Camunda.Modeler.Clusters[0].Id)
308+
s.Require().Equal("camunda-platform-test-zeebe", configmapApplication.Camunda.Modeler.Clusters[0].Name)
309+
s.Require().Equal("SNAPSHOT", configmapApplication.Camunda.Modeler.Clusters[0].Version)
310+
s.Require().Equal("OAUTH", configmapApplication.Camunda.Modeler.Clusters[0].Authentication)
311+
s.Require().Equal("grpc://camunda-platform-test-zeebe-gateway:26500", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Grpc)
312+
s.Require().Equal("http://camunda-platform-test-zeebe-gateway:8080", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Rest)
313+
s.Require().Equal("http://camunda-platform-test-operate:80", configmapApplication.Camunda.Modeler.Clusters[0].Url.Operate)
314+
s.Require().Equal("http://camunda-platform-test-tasklist:80", configmapApplication.Camunda.Modeler.Clusters[0].Url.Tasklist)
315+
s.Require().Equal("http://camunda-platform-test-keycloak:80/auth/realms/camunda-platform/protocol/openid-connect/token", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Url)
316+
s.Require().Equal("zeebe-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Zeebe)
317+
s.Require().Equal("operate-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Operate)
318+
s.Require().Equal("tasklist-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Tasklist)
319+
s.Require().Equal("", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Scope)
320+
}
321+
322+
func (s *configmapRestAPITemplateTest) TestContainerShouldConfigureClusterFromSameHelmInstallationWithCustomValues() {
323+
// given
324+
options := &helm.Options{
325+
SetValues: map[string]string{
326+
"webModeler.enabled": "true",
327+
"webModeler.restapi.mail.fromAddress": "[email protected]",
328+
"postgresql.enabled": "false",
329+
"global.zeebeClusterName": "test-zeebe",
330+
"global.identity.auth.zeebe.tokenScope": "test-scope",
331+
"global.identity.auth.zeebe.audience": "test-zeebe-api",
332+
"global.identity.auth.operate.audience": "test-operate-api",
333+
"global.identity.auth.tasklist.audience": "test-tasklist-api",
334+
"global.identity.auth.tokenUrl": "https://example.com/auth/realms/test/protocol/openid-connect/token",
335+
"zeebe.image.tag": "8.7.0-alpha1",
336+
"zeebeGateway.contextPath": "/zeebe",
337+
"zeebeGateway.service.grpcPort": "26600",
338+
"zeebeGateway.service.restPort": "8090",
339+
"operate.contextPath": "/operate",
340+
"operate.service.port": "8080",
341+
"tasklist.contextPath": "/tasklist",
342+
"tasklist.service.port": "8080",
343+
},
344+
KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
345+
}
346+
347+
// when
348+
output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
349+
var configmap corev1.ConfigMap
350+
var configmapApplication WebModelerRestAPIApplicationYAML
351+
helm.UnmarshalK8SYaml(s.T(), output, &configmap)
352+
353+
err := yaml.Unmarshal([]byte(configmap.Data["application.yaml"]), &configmapApplication)
354+
if err != nil {
355+
s.Fail("Failed to unmarshal yaml. error=", err)
356+
}
357+
358+
// then
359+
s.Require().Equal(1, len(configmapApplication.Camunda.Modeler.Clusters))
360+
s.Require().Equal("default-cluster", configmapApplication.Camunda.Modeler.Clusters[0].Id)
361+
s.Require().Equal("test-zeebe", configmapApplication.Camunda.Modeler.Clusters[0].Name)
362+
s.Require().Equal("8.7.0-alpha1", configmapApplication.Camunda.Modeler.Clusters[0].Version)
363+
s.Require().Equal("OAUTH", configmapApplication.Camunda.Modeler.Clusters[0].Authentication)
364+
s.Require().Equal("grpc://test-zeebe-gateway:26600", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Grpc)
365+
s.Require().Equal("http://test-zeebe-gateway:8090/zeebe", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Rest)
366+
s.Require().Equal("http://camunda-platform-test-operate:8080/operate", configmapApplication.Camunda.Modeler.Clusters[0].Url.Operate)
367+
s.Require().Equal("http://camunda-platform-test-tasklist:8080/tasklist", configmapApplication.Camunda.Modeler.Clusters[0].Url.Tasklist)
368+
s.Require().Equal("https://example.com/auth/realms/test/protocol/openid-connect/token", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Url)
369+
s.Require().Equal("test-zeebe-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Zeebe)
370+
s.Require().Equal("test-operate-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Operate)
371+
s.Require().Equal("test-tasklist-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Tasklist)
372+
s.Require().Equal("test-scope", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Scope)
373+
}
374+
375+
func (s *configmapRestAPITemplateTest) TestContainerShouldUseClustersFromCustomConfiguration() {
376+
// given
377+
options := &helm.Options{
378+
SetValues: map[string]string{
379+
"webModeler.enabled": "true",
380+
"webModeler.restapi.mail.fromAddress": "[email protected]",
381+
"webModeler.restapi.clusters[0].id": "test-cluster-1",
382+
"webModeler.restapi.clusters[0].name": "test cluster 1",
383+
"webModeler.restapi.clusters[0].version": "8.6.0",
384+
"webModeler.restapi.clusters[0].authentication": "NONE",
385+
"webModeler.restapi.clusters[0].url.zeebe.grpc": "grpc://zeebe-gateway.test-1:26500",
386+
"webModeler.restapi.clusters[0].url.zeebe.rest": "http://zeebe-gateway.test-1:8080",
387+
"webModeler.restapi.clusters[0].url.operate": "http://operate.test-1:8080",
388+
"webModeler.restapi.clusters[0].url.tasklist": "http://tasklist.test-1:8080",
389+
"webModeler.restapi.clusters[1].id": "test-cluster-2",
390+
"webModeler.restapi.clusters[1].name": "test cluster 2",
391+
"webModeler.restapi.clusters[1].version": "8.7.0-alpha1",
392+
"webModeler.restapi.clusters[1].authentication": "OAUTH",
393+
"webModeler.restapi.clusters[1].url.zeebe.grpc": "grpc://zeebe-gateway.test-2:26500",
394+
"webModeler.restapi.clusters[1].url.zeebe.rest": "http://zeebe-gateway.test-2:8080",
395+
"webModeler.restapi.clusters[1].url.operate": "http://operate.test-2:8080",
396+
"webModeler.restapi.clusters[1].url.tasklist": "http://tasklist.test-2:8080",
397+
"webModeler.restapi.clusters[1].oauth.url": "http://test-keycloak:80/auth/realms/camunda-platform/protocol/openid-connect/token",
398+
"postgresql.enabled": "false",
399+
},
400+
KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
401+
}
402+
403+
// when
404+
output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
405+
var configmap corev1.ConfigMap
406+
var configmapApplication WebModelerRestAPIApplicationYAML
407+
helm.UnmarshalK8SYaml(s.T(), output, &configmap)
408+
409+
err := yaml.Unmarshal([]byte(configmap.Data["application.yaml"]), &configmapApplication)
410+
if err != nil {
411+
s.Fail("Failed to unmarshal yaml. error=", err)
412+
}
413+
414+
// then
415+
s.Require().Equal(2, len(configmapApplication.Camunda.Modeler.Clusters))
416+
s.Require().Equal("test-cluster-1", configmapApplication.Camunda.Modeler.Clusters[0].Id)
417+
s.Require().Equal("test cluster 1", configmapApplication.Camunda.Modeler.Clusters[0].Name)
418+
s.Require().Equal("8.6.0", configmapApplication.Camunda.Modeler.Clusters[0].Version)
419+
s.Require().Equal("NONE", configmapApplication.Camunda.Modeler.Clusters[0].Authentication)
420+
s.Require().Equal("grpc://zeebe-gateway.test-1:26500", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Grpc)
421+
s.Require().Equal("http://zeebe-gateway.test-1:8080", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Rest)
422+
s.Require().Equal("http://operate.test-1:8080", configmapApplication.Camunda.Modeler.Clusters[0].Url.Operate)
423+
s.Require().Equal("http://tasklist.test-1:8080", configmapApplication.Camunda.Modeler.Clusters[0].Url.Tasklist)
424+
s.Require().Equal("test-cluster-2", configmapApplication.Camunda.Modeler.Clusters[1].Id)
425+
s.Require().Equal("test cluster 2", configmapApplication.Camunda.Modeler.Clusters[1].Name)
426+
s.Require().Equal("8.7.0-alpha1", configmapApplication.Camunda.Modeler.Clusters[1].Version)
427+
s.Require().Equal("OAUTH", configmapApplication.Camunda.Modeler.Clusters[1].Authentication)
428+
s.Require().Equal("grpc://zeebe-gateway.test-2:26500", configmapApplication.Camunda.Modeler.Clusters[1].Url.Zeebe.Grpc)
429+
s.Require().Equal("http://zeebe-gateway.test-2:8080", configmapApplication.Camunda.Modeler.Clusters[1].Url.Zeebe.Rest)
430+
s.Require().Equal("http://operate.test-2:8080", configmapApplication.Camunda.Modeler.Clusters[1].Url.Operate)
431+
s.Require().Equal("http://tasklist.test-2:8080", configmapApplication.Camunda.Modeler.Clusters[1].Url.Tasklist)
432+
s.Require().Equal("http://test-keycloak:80/auth/realms/camunda-platform/protocol/openid-connect/token", configmapApplication.Camunda.Modeler.Clusters[1].Oauth.Url)
433+
}
434+
435+
func (s *configmapRestAPITemplateTest) TestContainerShouldNotConfigureClustersIfZeebeDisabledAndNoCustomConfiguration() {
436+
// given
437+
options := &helm.Options{
438+
SetValues: map[string]string{
439+
"webModeler.enabled": "true",
440+
"webModeler.restapi.mail.fromAddress": "[email protected]",
441+
"postgresql.enabled": "false",
442+
"zeebe.enabled": "false",
443+
},
444+
KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
445+
}
446+
447+
// when
448+
output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
449+
var configmap corev1.ConfigMap
450+
var configmapApplication WebModelerRestAPIApplicationYAML
451+
helm.UnmarshalK8SYaml(s.T(), output, &configmap)
452+
453+
err := yaml.Unmarshal([]byte(configmap.Data["application.yaml"]), &configmapApplication)
454+
if err != nil {
455+
s.Fail("Failed to unmarshal yaml. error=", err)
456+
}
457+
458+
// then
459+
s.Require().Empty(configmapApplication.Camunda.Modeler.Clusters)
460+
}

0 commit comments

Comments
 (0)