Skip to content

Commit

Permalink
feat(web-modeler): add support for configuring Zeebe clusters (#2489)
Browse files Browse the repository at this point in the history
  • Loading branch information
jfriedenstab authored Oct 25, 2024
1 parent e6d2cb6 commit cdc6b70
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 10 deletions.
1 change: 1 addition & 0 deletions charts/camunda-platform-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,7 @@ Please see the corresponding [release guide](../../docs/release.md) to find out
| `webModeler.restapi.mail.existingSecretPasswordKey` | can be used to provide the name of an existing secret key containing the SMTP password | `smtp-password` |
| `webModeler.restapi.mail.fromAddress` | defines the email address that will be displayed as the sender of emails sent by WebModeler | `""` |
| `webModeler.restapi.mail.fromName` | defines the name that will be displayed as the sender of emails sent by WebModeler | `Camunda 8` |
| `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`) | `[]` |
| `webModeler.restapi.podAnnotations` | can be used to define extra restapi pod annotations | `{}` |
| `webModeler.restapi.podLabels` | can be used to define extra restapi pod labels | `{}` |
| `webModeler.restapi.env` | can be used to set extra environment variables in each restapi container | `[]` |
Expand Down
27 changes: 19 additions & 8 deletions charts/camunda-platform-alpha/templates/camunda/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,10 @@ Usage: {{ include "camundaPlatform.getExternalURL" (dict "component" "operate" "
{{- if (index .context.Values .component "enabled") -}}
{{- if (index .context.Values .component "ingress" "enabled") }}
{{- $proto := ternary "https" "http" (index .context.Values .component "ingress" "tls" "enabled") -}}
{{- printf "%s://%s" $proto (index .context.Values .component "ingress" "host") -}}
{{- printf "%s://%s" $proto (index .context.Values .component "ingress" "host") -}}
{{- else if $.context.Values.global.ingress.enabled -}}
{{ $proto := ternary "https" "http" .context.Values.global.ingress.tls.enabled -}}
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (index .context.Values .component "contextPath") -}}
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (index .context.Values .component "contextPath") -}}
{{- else -}}
{{- $portMapping := (dict
"operate" "8081"
Expand All @@ -380,7 +380,7 @@ Usage: {{ include "camundaPlatform.getExternalURL" (dict "component" "operate" "
"connectors" "8086"
"zeebeGateway" "26500"
) -}}
{{- printf "http://localhost:%s" (get $portMapping .component) -}}
{{- printf "http://localhost:%s" (get $portMapping .component) -}}
{{- end -}}
{{- end -}}
{{- end -}}
Expand Down Expand Up @@ -411,6 +411,17 @@ Optimize templates.
Tasklist templates.
********************************************************************************
*/}}

{{/*
[camunda-platform] Tasklist internal URL.
*/}}
{{ define "camundaPlatform.tasklistURL" }}
{{- if .Values.tasklist.enabled -}}
{{- print "http://" -}}{{- include "tasklist.fullname" . -}}:{{- .Values.tasklist.service.port -}}
{{- .Values.tasklist.contextPath -}}
{{- end -}}
{{- end -}}

{{/*
[camunda-platform] Tasklist external URL.
*/}}
Expand All @@ -433,13 +444,13 @@ Web Modeler templates.
{{- $ingress := .context.Values.webModeler.ingress }}
{{- if index $ingress "enabled" }}
{{- $proto := ternary "https" "http" (index $ingress .component "tls" "enabled") -}}
{{- printf "%s://%s" $proto (index $ingress .component "host") -}}
{{- printf "%s://%s" $proto (index $ingress .component "host") -}}
{{- else if $.context.Values.global.ingress.enabled -}}
{{ $proto := ternary "https" "http" .context.Values.global.ingress.tls.enabled -}}
{{- if eq .component "websockets" }}
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (include "webModeler.websocketContextPath" .context) -}}
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (include "webModeler.websocketContextPath" .context) -}}
{{- else -}}
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (index .context.Values.webModeler "contextPath") -}}
{{- printf "%s://%s%s" $proto .context.Values.global.ingress.host (index .context.Values.webModeler "contextPath") -}}
{{- end -}}
{{- end -}}
{{- end -}}
Expand Down Expand Up @@ -518,7 +529,7 @@ Zeebe templates.
{{- printf "%s://%s%s" $proto .Values.global.ingress.host .Values.zeebeGateway.contextPath -}}
{{- else if .Values.zeebeGateway.ingress.rest.enabled -}}
{{ $proto := ternary "https" "http" .Values.zeebeGateway.ingress.rest.tls.enabled -}}
{{- printf "%s://%s%s" $proto .Values.zeebeGateway.ingress.rest.host .Values.zeebeGateway.contextPath -}}
{{- printf "%s://%s%s" $proto .Values.zeebeGateway.ingress.rest.host .Values.zeebeGateway.contextPath -}}
{{- else -}}
{{- printf "http://localhost:8088" -}}
{{- end -}}
Expand All @@ -539,7 +550,7 @@ Zeebe templates.
{{- if .Values.zeebe.enabled -}}
{{-
printf "http://%s:%v%s"
(include "zeebe.fullname.gateway" .)
(include "zeebe.names.gateway" .)
.Values.zeebeGateway.service.restPort
(.Values.zeebeGateway.contextPath | default "")
-}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ data:
pusher:
host: {{ include "webModeler.websockets.fullname" . | quote }}
port: {{ .Values.webModeler.websockets.service.port }}
security:
jwt:
issuer:
Expand All @@ -40,6 +40,32 @@ data:
server:
url: {{ tpl .Values.global.identity.auth.webModeler.redirectUrl $ | quote }}
{{- if or .Values.zeebe.enabled .Values.webModeler.restapi.clusters }}
clusters:
{{- if .Values.webModeler.restapi.clusters }}
{{- .Values.webModeler.restapi.clusters | toYaml | nindent 10 }}
{{- else}}
- id: "default-cluster"
name: {{ tpl .Values.global.zeebeClusterName . | quote }}
version: {{ include "camundaPlatform.imageTagByParams" (dict "base" .Values.global "overlay" .Values.zeebe) | quote }}
authentication: {{ .Values.global.identity.auth.enabled | ternary "OAUTH" "NONE" | quote }}
url:
zeebe:
grpc: "grpc://{{ tpl .Values.global.zeebeClusterName . }}-gateway:{{ .Values.zeebeGateway.service.grpcPort }}"
rest: {{ include "camundaPlatform.zeebeGatewayRESTURL" . | quote }}
operate: {{ include "camundaPlatform.operateURL" . | quote }}
tasklist: {{ include "camundaPlatform.tasklistURL" . | quote }}
oauth:
url: {{ include "camundaPlatform.authIssuerBackendUrlTokenEndpoint" . | quote }}
audience:
zeebe: {{ include "zeebe.audience" . | quote }}
operate: {{ include "operate.authAudience" . | quote }}
tasklist: {{ include "tasklist.authAudience" . | quote }}
scope: {{ include "zeebe.tokenScope" . | quote }}
{{- end }}
{{- end }}
spring:
datasource:
url: {{ include "webModeler.restapi.databaseUrl" . | quote }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ func (s *configmapRestAPITemplateTest) TestContainerShouldSetCorrectKeycloakServ
// then
s.Require().Equal("http://keycloak:80/auth/realms/camunda-platform", configmapApplication.Camunda.Modeler.Security.JWT.Issuer.BackendUrl)
}

func (s *configmapRestAPITemplateTest) TestContainerShouldSetCorrectKeycloakServiceUrlWithCustomPort() {
// given
options := &helm.Options{
Expand Down Expand Up @@ -221,6 +222,7 @@ func (s *configmapRestAPITemplateTest) TestContainerShouldSetCorrectKeycloakServ
// then
s.Require().Equal("http://keycloak:8888/auth/realms/camunda-platform", configmapApplication.Camunda.Modeler.Security.JWT.Issuer.BackendUrl)
}

func (s *configmapRestAPITemplateTest) TestContainerShouldSetSmtpCredentials() {
// given
options := &helm.Options{
Expand All @@ -247,6 +249,7 @@ func (s *configmapRestAPITemplateTest) TestContainerShouldSetSmtpCredentials() {
// then
s.Require().Equal("modeler-user", configmapApplication.Spring.Mail.Username)
}

func (s *configmapRestAPITemplateTest) TestContainerShouldSetExternalDatabaseConfiguration() {
// given
options := &helm.Options{
Expand Down Expand Up @@ -276,3 +279,182 @@ func (s *configmapRestAPITemplateTest) TestContainerShouldSetExternalDatabaseCon
s.Require().Equal("jdbc:postgresql://postgres.example.com:65432/modeler-database", configmapApplication.Spring.Datasource.Url)
s.Require().Equal("modeler-user", configmapApplication.Spring.Datasource.Username)
}

func (s *configmapRestAPITemplateTest) TestContainerShouldConfigureClusterFromSameHelmInstallationWithDefaultValues() {
// given
options := &helm.Options{
SetValues: map[string]string{
"webModeler.enabled": "true",
"webModeler.restapi.mail.fromAddress": "example@example.com",
"postgresql.enabled": "false",
},
KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
}

// when
output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
var configmap corev1.ConfigMap
var configmapApplication WebModelerRestAPIApplicationYAML
helm.UnmarshalK8SYaml(s.T(), output, &configmap)

err := yaml.Unmarshal([]byte(configmap.Data["application.yaml"]), &configmapApplication)
if err != nil {
s.Fail("Failed to unmarshal yaml. error=", err)
}

// then
s.Require().Equal(1, len(configmapApplication.Camunda.Modeler.Clusters))
s.Require().Equal("default-cluster", configmapApplication.Camunda.Modeler.Clusters[0].Id)
s.Require().Equal("camunda-platform-test-zeebe", configmapApplication.Camunda.Modeler.Clusters[0].Name)
s.Require().Equal("SNAPSHOT", configmapApplication.Camunda.Modeler.Clusters[0].Version)
s.Require().Equal("OAUTH", configmapApplication.Camunda.Modeler.Clusters[0].Authentication)
s.Require().Equal("grpc://camunda-platform-test-zeebe-gateway:26500", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Grpc)
s.Require().Equal("http://camunda-platform-test-zeebe-gateway:8080", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Rest)
s.Require().Equal("http://camunda-platform-test-operate:80", configmapApplication.Camunda.Modeler.Clusters[0].Url.Operate)
s.Require().Equal("http://camunda-platform-test-tasklist:80", configmapApplication.Camunda.Modeler.Clusters[0].Url.Tasklist)
s.Require().Equal("http://camunda-platform-test-keycloak:80/auth/realms/camunda-platform/protocol/openid-connect/token", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Url)
s.Require().Equal("zeebe-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Zeebe)
s.Require().Equal("operate-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Operate)
s.Require().Equal("tasklist-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Tasklist)
s.Require().Equal("", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Scope)
}

func (s *configmapRestAPITemplateTest) TestContainerShouldConfigureClusterFromSameHelmInstallationWithCustomValues() {
// given
options := &helm.Options{
SetValues: map[string]string{
"webModeler.enabled": "true",
"webModeler.restapi.mail.fromAddress": "example@example.com",
"postgresql.enabled": "false",
"global.zeebeClusterName": "test-zeebe",
"global.identity.auth.zeebe.tokenScope": "test-scope",
"global.identity.auth.zeebe.audience": "test-zeebe-api",
"global.identity.auth.operate.audience": "test-operate-api",
"global.identity.auth.tasklist.audience": "test-tasklist-api",
"global.identity.auth.tokenUrl": "https://example.com/auth/realms/test/protocol/openid-connect/token",
"zeebe.image.tag": "8.7.0-alpha1",
"zeebeGateway.contextPath": "/zeebe",
"zeebeGateway.service.grpcPort": "26600",
"zeebeGateway.service.restPort": "8090",
"operate.contextPath": "/operate",
"operate.service.port": "8080",
"tasklist.contextPath": "/tasklist",
"tasklist.service.port": "8080",
},
KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
}

// when
output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
var configmap corev1.ConfigMap
var configmapApplication WebModelerRestAPIApplicationYAML
helm.UnmarshalK8SYaml(s.T(), output, &configmap)

err := yaml.Unmarshal([]byte(configmap.Data["application.yaml"]), &configmapApplication)
if err != nil {
s.Fail("Failed to unmarshal yaml. error=", err)
}

// then
s.Require().Equal(1, len(configmapApplication.Camunda.Modeler.Clusters))
s.Require().Equal("default-cluster", configmapApplication.Camunda.Modeler.Clusters[0].Id)
s.Require().Equal("test-zeebe", configmapApplication.Camunda.Modeler.Clusters[0].Name)
s.Require().Equal("8.7.0-alpha1", configmapApplication.Camunda.Modeler.Clusters[0].Version)
s.Require().Equal("OAUTH", configmapApplication.Camunda.Modeler.Clusters[0].Authentication)
s.Require().Equal("grpc://test-zeebe-gateway:26600", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Grpc)
s.Require().Equal("http://test-zeebe-gateway:8090/zeebe", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Rest)
s.Require().Equal("http://camunda-platform-test-operate:8080/operate", configmapApplication.Camunda.Modeler.Clusters[0].Url.Operate)
s.Require().Equal("http://camunda-platform-test-tasklist:8080/tasklist", configmapApplication.Camunda.Modeler.Clusters[0].Url.Tasklist)
s.Require().Equal("https://example.com/auth/realms/test/protocol/openid-connect/token", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Url)
s.Require().Equal("test-zeebe-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Zeebe)
s.Require().Equal("test-operate-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Operate)
s.Require().Equal("test-tasklist-api", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Audience.Tasklist)
s.Require().Equal("test-scope", configmapApplication.Camunda.Modeler.Clusters[0].Oauth.Scope)
}

func (s *configmapRestAPITemplateTest) TestContainerShouldUseClustersFromCustomConfiguration() {
// given
options := &helm.Options{
SetValues: map[string]string{
"webModeler.enabled": "true",
"webModeler.restapi.mail.fromAddress": "example@example.com",
"webModeler.restapi.clusters[0].id": "test-cluster-1",
"webModeler.restapi.clusters[0].name": "test cluster 1",
"webModeler.restapi.clusters[0].version": "8.6.0",
"webModeler.restapi.clusters[0].authentication": "NONE",
"webModeler.restapi.clusters[0].url.zeebe.grpc": "grpc://zeebe-gateway.test-1:26500",
"webModeler.restapi.clusters[0].url.zeebe.rest": "http://zeebe-gateway.test-1:8080",
"webModeler.restapi.clusters[0].url.operate": "http://operate.test-1:8080",
"webModeler.restapi.clusters[0].url.tasklist": "http://tasklist.test-1:8080",
"webModeler.restapi.clusters[1].id": "test-cluster-2",
"webModeler.restapi.clusters[1].name": "test cluster 2",
"webModeler.restapi.clusters[1].version": "8.7.0-alpha1",
"webModeler.restapi.clusters[1].authentication": "OAUTH",
"webModeler.restapi.clusters[1].url.zeebe.grpc": "grpc://zeebe-gateway.test-2:26500",
"webModeler.restapi.clusters[1].url.zeebe.rest": "http://zeebe-gateway.test-2:8080",
"webModeler.restapi.clusters[1].url.operate": "http://operate.test-2:8080",
"webModeler.restapi.clusters[1].url.tasklist": "http://tasklist.test-2:8080",
"webModeler.restapi.clusters[1].oauth.url": "http://test-keycloak:80/auth/realms/camunda-platform/protocol/openid-connect/token",
"postgresql.enabled": "false",
},
KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
}

// when
output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
var configmap corev1.ConfigMap
var configmapApplication WebModelerRestAPIApplicationYAML
helm.UnmarshalK8SYaml(s.T(), output, &configmap)

err := yaml.Unmarshal([]byte(configmap.Data["application.yaml"]), &configmapApplication)
if err != nil {
s.Fail("Failed to unmarshal yaml. error=", err)
}

// then
s.Require().Equal(2, len(configmapApplication.Camunda.Modeler.Clusters))
s.Require().Equal("test-cluster-1", configmapApplication.Camunda.Modeler.Clusters[0].Id)
s.Require().Equal("test cluster 1", configmapApplication.Camunda.Modeler.Clusters[0].Name)
s.Require().Equal("8.6.0", configmapApplication.Camunda.Modeler.Clusters[0].Version)
s.Require().Equal("NONE", configmapApplication.Camunda.Modeler.Clusters[0].Authentication)
s.Require().Equal("grpc://zeebe-gateway.test-1:26500", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Grpc)
s.Require().Equal("http://zeebe-gateway.test-1:8080", configmapApplication.Camunda.Modeler.Clusters[0].Url.Zeebe.Rest)
s.Require().Equal("http://operate.test-1:8080", configmapApplication.Camunda.Modeler.Clusters[0].Url.Operate)
s.Require().Equal("http://tasklist.test-1:8080", configmapApplication.Camunda.Modeler.Clusters[0].Url.Tasklist)
s.Require().Equal("test-cluster-2", configmapApplication.Camunda.Modeler.Clusters[1].Id)
s.Require().Equal("test cluster 2", configmapApplication.Camunda.Modeler.Clusters[1].Name)
s.Require().Equal("8.7.0-alpha1", configmapApplication.Camunda.Modeler.Clusters[1].Version)
s.Require().Equal("OAUTH", configmapApplication.Camunda.Modeler.Clusters[1].Authentication)
s.Require().Equal("grpc://zeebe-gateway.test-2:26500", configmapApplication.Camunda.Modeler.Clusters[1].Url.Zeebe.Grpc)
s.Require().Equal("http://zeebe-gateway.test-2:8080", configmapApplication.Camunda.Modeler.Clusters[1].Url.Zeebe.Rest)
s.Require().Equal("http://operate.test-2:8080", configmapApplication.Camunda.Modeler.Clusters[1].Url.Operate)
s.Require().Equal("http://tasklist.test-2:8080", configmapApplication.Camunda.Modeler.Clusters[1].Url.Tasklist)
s.Require().Equal("http://test-keycloak:80/auth/realms/camunda-platform/protocol/openid-connect/token", configmapApplication.Camunda.Modeler.Clusters[1].Oauth.Url)
}

func (s *configmapRestAPITemplateTest) TestContainerShouldNotConfigureClustersIfZeebeDisabledAndNoCustomConfiguration() {
// given
options := &helm.Options{
SetValues: map[string]string{
"webModeler.enabled": "true",
"webModeler.restapi.mail.fromAddress": "example@example.com",
"postgresql.enabled": "false",
"zeebe.enabled": "false",
},
KubectlOptions: k8s.NewKubectlOptions("", "", s.namespace),
}

// when
output := helm.RenderTemplate(s.T(), options, s.chartPath, s.release, s.templates)
var configmap corev1.ConfigMap
var configmapApplication WebModelerRestAPIApplicationYAML
helm.UnmarshalK8SYaml(s.T(), output, &configmap)

err := yaml.Unmarshal([]byte(configmap.Data["application.yaml"]), &configmapApplication)
if err != nil {
s.Fail("Failed to unmarshal yaml. error=", err)
}

// then
s.Require().Empty(configmapApplication.Camunda.Modeler.Clusters)
}
Loading

0 comments on commit cdc6b70

Please sign in to comment.