Skip to content
Merged
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
7 changes: 6 additions & 1 deletion helm/flowfuse/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ To use STMP to send email
- `forge.broker.public_url` URL to access the broker from outside the cluster (default `ws://mqtt.[forge.domain]`, uses `wss://` if `forge.https` is `true`)
- `forge.broker.hostname` the custom Fully Qualified Domain Name (FQDN) where the broker will be hosted (default `mqtt.[forge.domain]`)
- `forge.broker.teamBroker.enabled` Enables Team Broker feature (default `false`)
- `forge.broker.teamBroker.api.url` URL for the Team Broker API (default `http://emqx-dashboard.<release-namespace>:18083`)
- `forge.broker.teamBroker.api.key` API key for the Team Broker API (default not set)
- `forge.broker.teamBroker.api.secret` API secret for the Team Broker API (default not set)
- `forge.broker.createMetricsUser` defines if a dedicated MQTT user with broker metrics collection permissions should be created (default `true`)
- `forge.broker.affinity` allows to configure [affinity or anti-affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) for the broker pod
- `forge.broker.resources` allows to configure [resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the broker container
Expand Down Expand Up @@ -304,7 +307,9 @@ Everything under `forge.rate_limits` is used as input to Fastify Rate Limit plug
- `forge.expert.enabled` Enable/disable the FlowFuse Expert feature (default `false`)
- `forge.expert.service.url` URL for the FlowFuse Expert service (default not set)
- `forge.expert.service.token` Token for the FlowFuse Expert service (default not set)
- `forge.expert.service.requestTimeout` Timeout for the FlowFuse Expert service (default `60000`)
- `forge.expert.service.requestTimeout` Timeout for the FlowFuse Expert service (default `60000`)
- `forge.expert.broker.address` Address of the MQTT broker to use for communication with the Expert service (default not set). Requires `forge.broker.teamBroker.enabled=true`, since the local team broker bridges to this central broker.
- `forge.expert.broker.port` Port of the MQTT broker to use for communication with the Expert service (default `8883`)

### Ingress
- `ingress.annotations` ingress annotations (default is `{}`). This value is also applied to Editor instances created by FlowFuse.
Expand Down
36 changes: 34 additions & 2 deletions helm/flowfuse/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,11 @@ Note: The value for key .Values.postgresql.auth.existingSecret is inherited from
*/}}

{{- define "forge.createSecret" -}}
{{- if not (and .Values.postgresql.auth.existingSecret
{{- if not (and .Values.postgresql.auth.existingSecret
(not (and .Values.forge.email ((and .Values.forge.email.smtp (not .Values.forge.email.smtp.existingSecret)))))
(not ((.Values.forge.assistant).enabled))
(not ((.Values.forge.expert).enabled))) -}}
(not ((.Values.forge.expert).enabled))
(not ((.Values.forge.broker.teamBroker).enabled))) -}}
true
{{- else -}}
false
Expand Down Expand Up @@ -346,4 +347,35 @@ Get the name from the release name.
*/}}
{{- define "forge.name" -}}
{{- .Release.Name -}}
{{- end -}}

{{/*
Get the secret object name with Team Broker secret.
*/}}
{{- define "forge.teamBrokerSecretName" -}}
{{- if (.Values.forge.broker.teamBroker).enabled -}}
{{- printf "flowfuse-secrets" -}}
{{- end -}}
{{- end -}}

{{/*
Resolve Team Broker API URL: user-provided value, or default to the in-cluster EMQX dashboard service.
*/}}
{{- define "forge.teamBrokerApiUrl" -}}
{{- if ((.Values.forge.broker.teamBroker).api).url -}}
{{- .Values.forge.broker.teamBroker.api.url -}}
{{- else -}}
{{- printf "http://emqx-dashboard.%s:18083" .Release.Namespace -}}
{{- end -}}
{{- end -}}

{{/*
Create Team Broker API secret
*/}}
{{- define "forge.teamBrokerApiSecret" -}}
{{- if (.Values.forge.broker.teamBroker).enabled -}}
{{- $_ := required "A valid .Values.forge.broker.teamBroker.api.key is required!" ((.Values.forge.broker.teamBroker).api).key -}}
{{- $token := required "A valid .Values.forge.broker.teamBroker.api.secret is required!" ((.Values.forge.broker.teamBroker).api).secret -}}
teamBrokerApiSecret: {{ $token | b64enc | quote }}
{{- end -}}
{{- end -}}
11 changes: 11 additions & 0 deletions helm/flowfuse/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ data:
teamBroker:
enabled: true
host: {{ include "forge.teamBrokerHost" . }}
api:
url: {{ include "forge.teamBrokerApiUrl" . }}
key: {{ .Values.forge.broker.teamBroker.api.key }}
secret: <%= ENV['TEAM_BROKER_API_SECRET'] %>
{{ end -}}
{{- end }}
logging:
Expand Down Expand Up @@ -334,6 +338,13 @@ data:
token: <%= ENV['EXPERT_TOKEN'] %>
url: {{ ((.Values.forge.expert).service).url }}
requestTimeout: {{ .Values.forge.expert.requestTimeout | default 60000 }}
{{- if ((.Values.forge.expert).broker).address }}
{{- if not ((.Values.forge.broker.teamBroker).enabled) }}
{{- fail "forge.expert.broker requires the Team Broker to be enabled (forge.broker.teamBroker.enabled=true)" -}}
{{- end }}
centralBroker:
server: {{ printf "%s:%v" .Values.forge.expert.broker.address (.Values.forge.expert.broker.port | default 8883) }}
{{- end }}
{{- end }}
{{- end }}
{{- if and (hasKey .Values.forge "npmRegistry") (hasKey .Values.forge.npmRegistry "enabled") }}
Expand Down
8 changes: 8 additions & 0 deletions helm/flowfuse/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ spec:
key: expertToken
optional: true
{{- end }}
{{- if (.Values.forge.broker.teamBroker).enabled }}
- name: TEAM_BROKER_API_SECRET
valueFrom:
secretKeyRef:
name: {{ include "forge.teamBrokerSecretName" . }}
key: teamBrokerApiSecret
optional: true
{{- end }}
{{- if .Values.forge.localPostgresql }}
- name: wait-for-local-db
{{- $initWaitForLocalDbRegistry := (or .Values.forge.initContainers.waitForLocalDb.image.registry .Values.forge.registry) }}
Expand Down
3 changes: 3 additions & 0 deletions helm/flowfuse/templates/secrets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ data:
{{- if (include "forge.expertToken" . | trim) }}
{{- include "forge.expertToken" . | nindent 2 -}}
{{- end }}
{{- if (include "forge.teamBrokerApiSecret" . | trim) }}
{{- include "forge.teamBrokerApiSecret" . | nindent 2 -}}
{{- end }}
{{- end }}
123 changes: 123 additions & 0 deletions helm/flowfuse/tests/expert_central_broker_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/helm-unittest/helm-unittest/main/schema/helm-testsuite.json
suite: test expert central broker configuration
templates:
- configmap.yaml
set:
forge.domain: "chart-unit-tests.com"
tests:
- it: should not include central broker block when expert is disabled
template: configmap.yaml
set:
forge.expert:
enabled: false
asserts:
- notMatchRegex:
path: data["flowforge.yml"]
pattern: "centralBroker:"

- it: should not include central broker block when expert key is absent
template: configmap.yaml
asserts:
- notMatchRegex:
path: data["flowforge.yml"]
pattern: "centralBroker:"

- it: should not include central broker block when expert is enabled but broker.address is not set
template: configmap.yaml
set:
forge.expert:
enabled: true
service:
url: "https://expert.example.com"
token: "expert-token"
asserts:
- matchRegex:
path: data["flowforge.yml"]
pattern: "expert:"
- notMatchRegex:
path: data["flowforge.yml"]
pattern: "centralBroker:"

- it: should render central broker server when expert is enabled with broker address and port
template: configmap.yaml
set:
forge.broker.teamBroker.enabled: true
forge.expert:
enabled: true
service:
url: "https://expert.example.com"
token: "expert-token"
broker:
address: "central-broker.example.com"
port: 1883
asserts:
- matchRegex:
path: data["flowforge.yml"]
pattern: "centralBroker:"
- matchRegex:
path: data["flowforge.yml"]
pattern: "server: central-broker\\.example\\.com:1883"

- it: should render central broker server with custom port
template: configmap.yaml
set:
forge.broker.teamBroker.enabled: true
forge.expert:
enabled: true
service:
url: "https://expert.example.com"
token: "expert-token"
broker:
address: "10.0.0.5"
port: 1883
asserts:
- matchRegex:
path: data["flowforge.yml"]
pattern: "server: 10\\.0\\.0\\.5:1883"

- it: should default the central broker port to 8883 when not provided
template: configmap.yaml
set:
forge.broker.teamBroker.enabled: true
forge.expert:
enabled: true
service:
url: "https://expert.example.com"
token: "expert-token"
broker:
address: "central-broker.example.com"
asserts:
- matchRegex:
path: data["flowforge.yml"]
pattern: "server: central-broker\\.example\\.com:8883"

- it: should fail when expert broker address is set but team broker is not enabled
template: configmap.yaml
set:
forge.expert:
enabled: true
service:
url: "https://expert.example.com"
token: "expert-token"
broker:
address: "central-broker.example.com"
port: 1883
asserts:
- failedTemplate:
errorMessage: "forge.expert.broker requires the Team Broker to be enabled (forge.broker.teamBroker.enabled=true)"

- it: should fail when expert broker address is set and team broker is explicitly disabled
template: configmap.yaml
set:
forge.broker.teamBroker.enabled: false
forge.expert:
enabled: true
service:
url: "https://expert.example.com"
token: "expert-token"
broker:
address: "central-broker.example.com"
port: 1883
asserts:
- failedTemplate:
errorMessage: "forge.expert.broker requires the Team Broker to be enabled (forge.broker.teamBroker.enabled=true)"
Loading
Loading