@yarkivaev/scada 2.3.113 → 2.3.115

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +53 -0
  2. package/charts/scada/Chart.yaml +2 -2
  3. package/charts/scada/templates/_helpers.tpl +12 -4
  4. package/charts/scada/templates/clickhouse.yaml +3 -3
  5. package/charts/scada/templates/collector.yaml +2 -2
  6. package/charts/scada/templates/namespace.yaml +6 -0
  7. package/charts/scada/templates/postgres.yaml +3 -3
  8. package/charts/scada/templates/processes.yaml +88 -0
  9. package/charts/scada/templates/rabbitmq-config.yaml +91 -0
  10. package/charts/scada/templates/rabbitmq.yaml +54 -107
  11. package/charts/scada/templates/site-server.yaml +5 -3
  12. package/charts/scada/templates/supervisor-sink.yaml +8 -2
  13. package/charts/scada/values.schema.json +22 -0
  14. package/charts/scada/values.yaml +22 -0
  15. package/index.js +3 -0
  16. package/package.json +5 -3
  17. package/src/application/deploy/collectorProcesses.js +42 -0
  18. package/src/application/deploy/expandFlows.js +21 -10
  19. package/src/application/deploy/publishedStreams.js +30 -0
  20. package/src/application/deploy/releaseEdges.js +13 -16
  21. package/src/application/deploy/releaseNodes.js +13 -0
  22. package/src/application/deploy/releaseValues.js +5 -15
  23. package/src/application/deploy/releases.js +3 -1
  24. package/src/application/deploy/subscriptions.js +20 -0
  25. package/src/application/supervisorSink.js +6 -0
  26. package/src/domain/segment/segmentCoalesce.js +26 -10
  27. package/src/infrastructure/deploy/executeRelease.js +60 -0
  28. package/src/infrastructure/ingest/codecs/segmentCodec.js +10 -3
  29. package/src/infrastructure/ingest/pipelines/segmentPipeline.js +3 -1
  30. package/src/infrastructure/messaging/rabbitmq/definitions.js +24 -0
  31. package/src/infrastructure/messaging/rabbitmq/reconcile.js +104 -0
package/README.md CHANGED
@@ -274,3 +274,56 @@ Depend on a pinned version (`"@yarkivaev/scada": "…#v2.3.46"`), not a local pa
274
274
  ## CI/CD
275
275
 
276
276
  GitHub Actions via `yarkivaev/npm-workflows` (lint, test, version check). This repo publishes an npm package only; container images are built in downstream deploy repos.
277
+
278
+ ### Ingest delivery and quarantine
279
+
280
+ `STOMP_PREFETCH` sets a positive, bounded segment delivery window (default 128).
281
+ `SEGMENTS_DEAD_LETTER_ENABLED=true` opts into rejecting malformed segment records
282
+ without requeue; transient persistence failures are retried. Enable this only with
283
+ a durable DLQ and routing policy. In the deployment DSL, configure
284
+ `profiles.<profile>.modules.message_bus.dead_letter.queue: scada.ingest.dlq`.
285
+ The scada chart declares the queue and applies an ingest-only dead-letter policy,
286
+ without changing existing queue arguments. The profile `env` is passed to both
287
+ site-server and supervisor-sink. DLQ records retain the original body and RabbitMQ
288
+ `x-death` metadata for inspection and deliberate replay; they are not auto-expired.
289
+
290
+ ### Deploy a node with named processes
291
+
292
+ A profile can expose deployment coordinates in `target`, set
293
+ `apps.scada.site.enabled` and `apps.scada.sink.enabled` independently, and
294
+ provide RabbitMQ chart settings in `modules.message_bus.chart`. The
295
+ `releases(document, cluster)` projection returns the target and chart values.
296
+ The default profile still renders the existing site and sink.
297
+
298
+ `subscriptions(expandedDocument, sourceId)` returns the outgoing server
299
+ subscriptions as `{ from, to, name, api? }`. It combines sender `fan_out` and
300
+ receiver `fan_in` declarations, keeping each expanded stream path and any
301
+ explicit service selected by the receiver. Declaring the same subscription on
302
+ both sides produces a single row.
303
+
304
+ Use `collectorProcesses(machines, describe, project)` to derive workloads from
305
+ the selected server's source rows. For each row, `describe(row)` returns a
306
+ process name, command and optional environment and resources. Rows with the
307
+ same name must describe the same process. `project(descriptor, rows)` converts
308
+ its sources into adapter-specific environment variables and host devices. Process
309
+ order follows the first occurrence of each name in the source rows.
310
+ The packaged `charts/scada` chart renders the resulting `processes` as
311
+ named Deployments. A configured broker claim name selects a standalone PVC.
312
+ The default storage mode uses StatefulSet claim templates.
313
+
314
+ `executeRelease(plan, action)` renders the chart or runs check, diff, adopt
315
+ and apply against the explicitly supplied Kubernetes context and namespace.
316
+ During `adopt`, the legacy client-side manager migrates the resources first.
317
+ The release's server-side manager then applies the same rendered manifest before
318
+ the executor waits for the workloads. This restores declared fields that a
319
+ legacy three-way merge can drop, such as an environment entry whose name was
320
+ duplicated in the old last-applied annotation. Each apply gets its own server
321
+ dry-run. `check-adoption` previews the client-side phase only. The server-side
322
+ phase must run against the migrated state. An ownership conflict stops adoption
323
+ before rollout waits and the afterReady hook. Resolve the field ownership and
324
+ rerun `apply` after the client-side migration has completed.
325
+ A caller can supply prerequisites, rollout resources and an afterReady hook.
326
+ The RabbitMQ definitions builder and management reconciler are exported as
327
+ `@yarkivaev/scada/rabbitmq/definitions` and `@yarkivaev/scada/rabbitmq/reconcile`.
328
+ The caller supplies the vhost, connection settings and ownership policy for
329
+ retired routes. Reconciliation retains stored queues.
@@ -2,5 +2,5 @@ apiVersion: v2
2
2
  name: scada
3
3
  description: Generic SCADA site — site-server, supervisor-sink, collectors, Postgres, RabbitMQ, optional ClickHouse
4
4
  type: application
5
- version: 0.2.3
6
- appVersion: "2.3.113"
5
+ version: 0.3.0
6
+ appVersion: "2.3.115"
@@ -1,3 +1,7 @@
1
+ {{- define "scada.prefix" -}}
2
+ {{- default .Release.Name .Values.prefix -}}
3
+ {{- end }}
4
+
1
5
  {{- define "scada.labels" -}}
2
6
  app.kubernetes.io/name: scada
3
7
  app.kubernetes.io/instance: {{ .Release.Name }}
@@ -69,7 +73,7 @@ volumeMode: Filesystem
69
73
  {{- end }}
70
74
  {{- if .Values.rabbitmq.enabled }}
71
75
  - name: STOMP_URL
72
- value: {{ printf "stomp://%s-rabbitmq:61613" .Release.Name | quote }}
76
+ value: {{ printf "stomp://%s-rabbitmq:61613" (include "scada.prefix" .) | quote }}
73
77
  - name: STOMP_LOGIN
74
78
  value: guest
75
79
  - name: STOMP_PASSCODE
@@ -77,12 +81,16 @@ volumeMode: Filesystem
77
81
  - name: STOMP_HOST
78
82
  value: /
79
83
  - name: AMQP_URL
80
- value: {{ printf "amqp://guest:guest@%s-rabbitmq:5672" .Release.Name | quote }}
84
+ value: {{ printf "amqp://guest:guest@%s-rabbitmq:5672" (include "scada.prefix" .) | quote }}
81
85
  {{- end }}
82
86
  {{- if .Values.clickhouse.enabled }}
83
87
  - name: CLICKHOUSE_HOST
84
- value: {{ printf "%s-clickhouse" .Release.Name | quote }}
88
+ value: {{ printf "%s-clickhouse" (include "scada.prefix" .) | quote }}
85
89
  - name: CLICKHOUSE_URL
86
- value: {{ printf "http://%s-clickhouse:8123" .Release.Name | quote }}
90
+ value: {{ printf "http://%s-clickhouse:8123" (include "scada.prefix" .) | quote }}
87
91
  {{- end }}
88
92
  {{- end }}
93
+
94
+ {{- define "scada.brokerConfigName" -}}
95
+ {{- default (printf "%s-rabbitmq" (include "scada.prefix" .)) .Values.rabbitmq.configName -}}
96
+ {{- end }}
@@ -2,7 +2,7 @@
2
2
  apiVersion: v1
3
3
  kind: Service
4
4
  metadata:
5
- name: {{ .Release.Name }}-clickhouse
5
+ name: {{ include "scada.prefix" . }}-clickhouse
6
6
  namespace: {{ .Release.Namespace }}
7
7
  labels:
8
8
  {{- include "scada.labels" . | nindent 4 }}
@@ -24,13 +24,13 @@ spec:
24
24
  apiVersion: apps/v1
25
25
  kind: StatefulSet
26
26
  metadata:
27
- name: {{ .Release.Name }}-clickhouse
27
+ name: {{ include "scada.prefix" . }}-clickhouse
28
28
  namespace: {{ .Release.Namespace }}
29
29
  labels:
30
30
  {{- include "scada.labels" . | nindent 4 }}
31
31
  app: clickhouse
32
32
  spec:
33
- serviceName: {{ .Release.Name }}-clickhouse
33
+ serviceName: {{ include "scada.prefix" . }}-clickhouse
34
34
  replicas: 1
35
35
  selector:
36
36
  matchLabels:
@@ -53,7 +53,7 @@
53
53
  apiVersion: apps/v1
54
54
  kind: Deployment
55
55
  metadata:
56
- name: {{ $.Release.Name }}-collector-{{ $slug }}
56
+ name: {{ include "scada.prefix" $ }}-collector-{{ $slug }}
57
57
  namespace: {{ $.Release.Namespace }}
58
58
  labels:
59
59
  {{- include "scada.labels" $ | nindent 4 }}
@@ -97,7 +97,7 @@ spec:
97
97
  value: {{ $maps | toJson | quote }}
98
98
  {{- if $.Values.rabbitmq.enabled }}
99
99
  - name: MQTT_URL
100
- value: {{ printf "mqtt://%s-rabbitmq:1883" $.Release.Name | quote }}
100
+ value: {{ printf "mqtt://%s-rabbitmq:1883" (include "scada.prefix" $) | quote }}
101
101
  {{- end }}
102
102
  resources:
103
103
  {{- toYaml $.Values.resources | nindent 12 }}
@@ -0,0 +1,6 @@
1
+ {{- if .Values.createNamespace }}
2
+ apiVersion: v1
3
+ kind: Namespace
4
+ metadata:
5
+ name: {{ .Release.Namespace }}
6
+ {{- end }}
@@ -2,7 +2,7 @@
2
2
  apiVersion: v1
3
3
  kind: Service
4
4
  metadata:
5
- name: {{ .Release.Name }}-postgres
5
+ name: {{ include "scada.prefix" . }}-postgres
6
6
  namespace: {{ .Release.Namespace }}
7
7
  labels:
8
8
  {{- include "scada.labels" . | nindent 4 }}
@@ -18,13 +18,13 @@ spec:
18
18
  apiVersion: apps/v1
19
19
  kind: StatefulSet
20
20
  metadata:
21
- name: {{ .Release.Name }}-postgres
21
+ name: {{ include "scada.prefix" . }}-postgres
22
22
  namespace: {{ .Release.Namespace }}
23
23
  labels:
24
24
  {{- include "scada.labels" . | nindent 4 }}
25
25
  app: postgres
26
26
  spec:
27
- serviceName: {{ .Release.Name }}-postgres
27
+ serviceName: {{ include "scada.prefix" . }}-postgres
28
28
  replicas: 1
29
29
  selector:
30
30
  matchLabels:
@@ -0,0 +1,88 @@
1
+ {{- $names := dict }}
2
+ {{- $devices := dict }}
3
+ {{- range .Values.processes }}
4
+ {{- $name := required "process name is required" .name }}
5
+ {{- if hasKey $names $name }}
6
+ {{- fail (printf "duplicate process name %s" $name) }}
7
+ {{- end }}
8
+ {{- $_ := set $names $name true }}
9
+ {{- range .hostDevices }}
10
+ {{- if hasKey $devices . }}
11
+ {{- fail (printf "processes %s and %s both claim %s" $name (get $devices .) .) }}
12
+ {{- end }}
13
+ {{- $_ := set $devices . $name }}
14
+ {{- end }}
15
+ ---
16
+ apiVersion: apps/v1
17
+ kind: Deployment
18
+ metadata:
19
+ name: {{ include "scada.prefix" $ }}-{{ $name }}
20
+ namespace: {{ $.Release.Namespace }}
21
+ labels:
22
+ {{- include "scada.labels" $ | nindent 4 }}
23
+ app: {{ $name }}
24
+ {{- with $.Values.workloadLabels }}
25
+ {{- toYaml . | nindent 4 }}
26
+ {{- end }}
27
+ spec:
28
+ replicas: 1
29
+ strategy:
30
+ type: Recreate
31
+ rollingUpdate: null
32
+ selector:
33
+ matchLabels:
34
+ {{- include "scada.match" (dict "app" $name "ctx" $) | nindent 6 }}
35
+ template:
36
+ metadata:
37
+ labels:
38
+ {{- include "scada.labels" $ | nindent 8 }}
39
+ app: {{ $name }}
40
+ {{- with $.Values.workloadLabels }}
41
+ {{- toYaml . | nindent 8 }}
42
+ {{- end }}
43
+ {{- if and $.Values.rabbitmq.enabled $.Values.rabbitmq.rolloutOnConfigChange }}
44
+ annotations:
45
+ checksum/broker: {{ include (print $.Template.BasePath "/rabbitmq-config.yaml") $ | sha256sum }}
46
+ {{- end }}
47
+ spec:
48
+ {{- with $.Values.pullSecret }}
49
+ imagePullSecrets:
50
+ - name: {{ . }}
51
+ {{- end }}
52
+ {{- with .podSecurityContext }}
53
+ securityContext:
54
+ {{- toYaml . | nindent 8 }}
55
+ {{- end }}
56
+ containers:
57
+ - name: {{ $name }}
58
+ image: {{ required "process image is required" (default $.Values.image .image) | quote }}
59
+ imagePullPolicy: IfNotPresent
60
+ command: {{ required "process command is required" .command | toJson }}
61
+ {{- if .hostDevices }}
62
+ securityContext:
63
+ privileged: true
64
+ volumeMounts:
65
+ {{- range $index, $path := .hostDevices }}
66
+ - name: serial-{{ add1 $index }}
67
+ mountPath: {{ $path | quote }}
68
+ {{- end }}
69
+ {{- end }}
70
+ {{- with .env }}
71
+ env:
72
+ {{- range $key, $value := . }}
73
+ - name: {{ $key }}
74
+ value: {{ $value | quote }}
75
+ {{- end }}
76
+ {{- end }}
77
+ resources:
78
+ {{- toYaml (default $.Values.resources .resources) | nindent 12 }}
79
+ {{- with .hostDevices }}
80
+ volumes:
81
+ {{- range $index, $path := . }}
82
+ - name: serial-{{ add1 $index }}
83
+ hostPath:
84
+ path: {{ $path | quote }}
85
+ type: CharDevice
86
+ {{- end }}
87
+ {{- end }}
88
+ {{- end }}
@@ -0,0 +1,91 @@
1
+ {{- if .Values.rabbitmq.enabled }}
2
+ {{- $ingest := list -}}
3
+ {{- $outgoing := list -}}
4
+ {{- range .Values.collectors }}
5
+ {{- if .path }}
6
+ {{- $ingest = append $ingest (include "scada.routingKey" .path | trim) -}}
7
+ {{- end }}
8
+ {{- end }}
9
+ {{- range $item := concat (.Values.buses | default (list)) (.Values.bus | default (list)) }}
10
+ {{- range $name := ($item.names | default (list)) }}
11
+ {{- $routed := include "scada.routingKey" $name | trim -}}
12
+ {{- $ingest = append $ingest $routed -}}
13
+ {{- $outgoing = append $outgoing $routed -}}
14
+ {{- end }}
15
+ {{- end }}
16
+ {{- $outgoing = $outgoing | uniq -}}
17
+ {{- if $ingest }}
18
+ {{- $ingest = $ingest | uniq -}}
19
+ {{- else }}
20
+ {{- $ingest = list "#" -}}
21
+ {{- end }}
22
+ {{- $exchange := list
23
+ (dict "name" "scada.alerts" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
24
+ (dict "name" "scada.segments" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
25
+ (dict "name" "scada.telemetry" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
26
+ (dict "name" "scada.operations" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
27
+ (dict "name" "scada.user_decisions" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
28
+ -}}
29
+ {{- $queue := list
30
+ (dict "name" "scada.segments.ingest" "vhost" "/" "durable" true "auto_delete" false)
31
+ (dict "name" "scada.telemetry.ingest" "vhost" "/" "durable" true "auto_delete" false)
32
+ (dict "name" "scada.operations.ingest" "vhost" "/" "durable" true "auto_delete" false)
33
+ (dict "name" "scada.user_decisions" "vhost" "/" "durable" true "auto_delete" false)
34
+ -}}
35
+ {{- if $outgoing }}
36
+ {{- $queue = append $queue (dict "name" "scada.telemetry.outbox" "vhost" "/" "durable" true "auto_delete" false) -}}
37
+ {{- end }}
38
+ {{- $policies := list -}}
39
+ {{- with .Values.rabbitmq.deadLetter }}
40
+ {{- $queue = append $queue (dict "name" .queue "vhost" "/" "durable" true "auto_delete" false) -}}
41
+ {{- $policies = append $policies (dict "name" "ingest-dlq" "vhost" "/" "pattern" "^scada\\.(segments|operations|telemetry)\\.ingest$" "apply-to" "queues" "priority" 10 "definition" (dict "dead-letter-exchange" "" "dead-letter-routing-key" .queue)) -}}
42
+ {{- end }}
43
+ {{- $binding := list -}}
44
+ {{- range $key := $ingest }}
45
+ {{- $binding = append $binding (dict "source" "scada.telemetry" "vhost" "/" "destination" "scada.telemetry.ingest" "destination_type" "queue" "routing_key" $key) -}}
46
+ {{- end }}
47
+ {{- range $pair := (list
48
+ (dict "source" "scada.operations" "destination" "scada.operations.ingest")
49
+ (dict "source" "scada.segments" "destination" "scada.segments.ingest")
50
+ (dict "source" "scada.user_decisions" "destination" "scada.user_decisions")) }}
51
+ {{- $binding = append $binding (dict "source" $pair.source "vhost" "/" "destination" $pair.destination "destination_type" "queue" "routing_key" "#") -}}
52
+ {{- end }}
53
+ {{- range $key := $outgoing }}
54
+ {{- $binding = append $binding (dict "source" "scada.telemetry" "vhost" "/" "destination" "scada.telemetry.outbox" "destination_type" "queue" "routing_key" $key) -}}
55
+ {{- end }}
56
+ {{- $definitions := dict
57
+ "vhosts" (list (dict "name" "/"))
58
+ "users" (list (dict "name" "guest" "password" "guest" "tags" (list "administrator")))
59
+ "permissions" (list (dict "user" "guest" "vhost" "/" "configure" ".*" "write" ".*" "read" ".*"))
60
+ "exchanges" $exchange
61
+ "queues" $queue
62
+ "policies" $policies
63
+ "bindings" $binding
64
+ -}}
65
+ apiVersion: v1
66
+ kind: ConfigMap
67
+ metadata:
68
+ name: {{ include "scada.brokerConfigName" . }}
69
+ namespace: {{ .Release.Namespace }}
70
+ labels:
71
+ {{- include "scada.labels" . | nindent 4 }}
72
+ app: rabbitmq
73
+ data:
74
+ enabled_plugins: |
75
+ [{{ join ", " .Values.rabbitmq.plugins }}].
76
+ rabbitmq.conf: |
77
+ load_definitions = /etc/rabbitmq/definitions.json
78
+ mqtt.listeners.tcp.default = 1883
79
+ mqtt.allow_anonymous = true
80
+ mqtt.vhost = /
81
+ mqtt.exchange = scada.telemetry
82
+ {{- range $key, $value := .Values.rabbitmq.extraConfig }}
83
+ {{ $key }} = {{ $value }}
84
+ {{- end }}
85
+ definitions.json: |
86
+ {{- if ne .Values.rabbitmq.definitions nil }}
87
+ {{ .Values.rabbitmq.definitions | toPrettyJson | nindent 4 }}
88
+ {{- else }}
89
+ {{ $definitions | toPrettyJson | nindent 4 }}
90
+ {{- end }}
91
+ {{- end }}
@@ -1,85 +1,8 @@
1
1
  {{- if .Values.rabbitmq.enabled }}
2
- {{- $ingest := list -}}
3
- {{- $outgoing := list -}}
4
- {{- range .Values.collectors }}
5
- {{- if .path }}
6
- {{- $ingest = append $ingest (include "scada.routingKey" .path | trim) -}}
7
- {{- end }}
8
- {{- end }}
9
- {{- range $item := concat (.Values.buses | default (list)) (.Values.bus | default (list)) }}
10
- {{- range $name := ($item.names | default (list)) }}
11
- {{- $routed := include "scada.routingKey" $name | trim -}}
12
- {{- $ingest = append $ingest $routed -}}
13
- {{- $outgoing = append $outgoing $routed -}}
14
- {{- end }}
15
- {{- end }}
16
- {{- $outgoing = $outgoing | uniq -}}
17
- {{- if $ingest }}
18
- {{- $ingest = $ingest | uniq -}}
19
- {{- else }}
20
- {{- $ingest = list "#" -}}
21
- {{- end }}
22
- {{- $exchange := list
23
- (dict "name" "scada.alerts" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
24
- (dict "name" "scada.segments" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
25
- (dict "name" "scada.telemetry" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
26
- (dict "name" "scada.operations" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
27
- (dict "name" "scada.user_decisions" "vhost" "/" "type" "topic" "durable" true "auto_delete" false)
28
- -}}
29
- {{- $queue := list
30
- (dict "name" "scada.segments.ingest" "vhost" "/" "durable" true "auto_delete" false)
31
- (dict "name" "scada.telemetry.ingest" "vhost" "/" "durable" true "auto_delete" false)
32
- (dict "name" "scada.operations.ingest" "vhost" "/" "durable" true "auto_delete" false)
33
- (dict "name" "scada.user_decisions" "vhost" "/" "durable" true "auto_delete" false)
34
- -}}
35
- {{- if $outgoing }}
36
- {{- $queue = append $queue (dict "name" "scada.telemetry.outbox" "vhost" "/" "durable" true "auto_delete" false) -}}
37
- {{- end }}
38
- {{- $binding := list -}}
39
- {{- range $key := $ingest }}
40
- {{- $binding = append $binding (dict "source" "scada.telemetry" "vhost" "/" "destination" "scada.telemetry.ingest" "destination_type" "queue" "routing_key" $key) -}}
41
- {{- end }}
42
- {{- range $pair := (list
43
- (dict "source" "scada.operations" "destination" "scada.operations.ingest")
44
- (dict "source" "scada.segments" "destination" "scada.segments.ingest")
45
- (dict "source" "scada.user_decisions" "destination" "scada.user_decisions")) }}
46
- {{- $binding = append $binding (dict "source" $pair.source "vhost" "/" "destination" $pair.destination "destination_type" "queue" "routing_key" "#") -}}
47
- {{- end }}
48
- {{- range $key := $outgoing }}
49
- {{- $binding = append $binding (dict "source" "scada.telemetry" "vhost" "/" "destination" "scada.telemetry.outbox" "destination_type" "queue" "routing_key" $key) -}}
50
- {{- end }}
51
- {{- $definitions := dict
52
- "vhosts" (list (dict "name" "/"))
53
- "users" (list (dict "name" "guest" "password" "guest" "tags" (list "administrator")))
54
- "permissions" (list (dict "user" "guest" "vhost" "/" "configure" ".*" "write" ".*" "read" ".*"))
55
- "exchanges" $exchange
56
- "queues" $queue
57
- "bindings" $binding
58
- -}}
59
- apiVersion: v1
60
- kind: ConfigMap
61
- metadata:
62
- name: {{ .Release.Name }}-rabbitmq
63
- namespace: {{ .Release.Namespace }}
64
- labels:
65
- {{- include "scada.labels" . | nindent 4 }}
66
- app: rabbitmq
67
- data:
68
- enabled_plugins: |
69
- [rabbitmq_stomp, rabbitmq_mqtt, rabbitmq_management].
70
- rabbitmq.conf: |
71
- load_definitions = /etc/rabbitmq/definitions.json
72
- mqtt.listeners.tcp.default = 1883
73
- mqtt.allow_anonymous = true
74
- mqtt.vhost = /
75
- mqtt.exchange = scada.telemetry
76
- definitions.json: |
77
- {{ $definitions | toPrettyJson | nindent 4 }}
78
- ---
79
2
  apiVersion: v1
80
3
  kind: Service
81
4
  metadata:
82
- name: {{ .Release.Name }}-rabbitmq
5
+ name: {{ include "scada.prefix" . }}-rabbitmq
83
6
  namespace: {{ .Release.Namespace }}
84
7
  labels:
85
8
  {{- include "scada.labels" . | nindent 4 }}
@@ -88,46 +11,30 @@ spec:
88
11
  {{- $svc := .Values.rabbitmq.service | default dict }}
89
12
  type: {{ $svc.type | default "ClusterIP" }}
90
13
  ports:
91
- - name: amqp
92
- port: 5672
93
- targetPort: amqp
94
- {{- with $svc.nodePorts }}
95
- {{- if .amqp }}
96
- nodePort: {{ .amqp }}
97
- {{- end }}
98
- {{- end }}
99
- - name: mqtt
100
- port: 1883
101
- targetPort: mqtt
102
- - name: stomp
103
- port: 61613
104
- targetPort: stomp
105
- {{- with $svc.nodePorts }}
106
- {{- if .stomp }}
107
- nodePort: {{ .stomp }}
108
- {{- end }}
109
- {{- end }}
110
- - name: management
111
- port: 15672
112
- targetPort: management
113
- {{- with $svc.nodePorts }}
114
- {{- if .management }}
115
- nodePort: {{ .management }}
116
- {{- end }}
14
+ {{- range $entry := list (dict "name" "amqp" "port" 5672) (dict "name" "mqtt" "port" 1883) (dict "name" "stomp" "port" 61613) (dict "name" "management" "port" 15672) }}
15
+ - name: {{ $entry.name }}
16
+ port: {{ $entry.port }}
17
+ targetPort: {{ ternary $entry.port $entry.name ($svc.numericTargetPorts | default false) }}
18
+ {{- with get ($svc.nodePorts | default dict) $entry.name }}
19
+ nodePort: {{ . }}
117
20
  {{- end }}
21
+ {{- end }}
118
22
  selector:
119
23
  {{- include "scada.match" (dict "app" "rabbitmq" "ctx" .) | nindent 4 }}
120
24
  ---
121
25
  apiVersion: apps/v1
122
26
  kind: StatefulSet
123
27
  metadata:
124
- name: {{ .Release.Name }}-rabbitmq
28
+ name: {{ include "scada.prefix" . }}-rabbitmq
125
29
  namespace: {{ .Release.Namespace }}
126
30
  labels:
127
31
  {{- include "scada.labels" . | nindent 4 }}
128
32
  app: rabbitmq
33
+ {{- with .Values.workloadLabels }}
34
+ {{- toYaml . | nindent 4 }}
35
+ {{- end }}
129
36
  spec:
130
- serviceName: {{ .Release.Name }}-rabbitmq
37
+ serviceName: {{ include "scada.prefix" . }}-rabbitmq
131
38
  replicas: 1
132
39
  selector:
133
40
  matchLabels:
@@ -137,10 +44,24 @@ spec:
137
44
  labels:
138
45
  {{- include "scada.labels" . | nindent 8 }}
139
46
  {{- include "scada.match" (dict "app" "rabbitmq" "ctx" .) | nindent 8 }}
47
+ {{- with .Values.workloadLabels }}
48
+ {{- toYaml . | nindent 8 }}
49
+ {{- end }}
50
+ {{- if .Values.rabbitmq.rolloutOnConfigChange }}
51
+ annotations:
52
+ checksum/config: {{ include (print $.Template.BasePath "/rabbitmq-config.yaml") . | sha256sum }}
53
+ {{- end }}
140
54
  spec:
55
+ {{- with .Values.pullSecret }}
56
+ imagePullSecrets:
57
+ - name: {{ . }}
58
+ {{- end }}
141
59
  containers:
142
60
  - name: rabbitmq
143
61
  image: {{ .Values.rabbitmq.image | quote }}
62
+ {{- with .Values.rabbitmq.imagePullPolicy }}
63
+ imagePullPolicy: {{ . }}
64
+ {{- end }}
144
65
  ports:
145
66
  - name: amqp
146
67
  containerPort: 5672
@@ -150,6 +71,18 @@ spec:
150
71
  containerPort: 61613
151
72
  - name: management
152
73
  containerPort: 15672
74
+ {{- with .Values.rabbitmq.readinessProbe }}
75
+ readinessProbe:
76
+ {{- toYaml . | nindent 12 }}
77
+ {{- end }}
78
+ {{- with .Values.rabbitmq.livenessProbe }}
79
+ livenessProbe:
80
+ {{- toYaml . | nindent 12 }}
81
+ {{- end }}
82
+ {{- with .Values.rabbitmq.resources }}
83
+ resources:
84
+ {{- toYaml . | nindent 12 }}
85
+ {{- end }}
153
86
  volumeMounts:
154
87
  - name: config
155
88
  mountPath: /etc/rabbitmq/enabled_plugins
@@ -165,10 +98,24 @@ spec:
165
98
  volumes:
166
99
  - name: config
167
100
  configMap:
168
- name: {{ .Release.Name }}-rabbitmq
101
+ name: {{ include "scada.brokerConfigName" . }}
102
+ {{- with .Values.rabbitmq.claimName }}
103
+ - name: data
104
+ persistentVolumeClaim:
105
+ claimName: {{ . }}
106
+ ---
107
+ apiVersion: v1
108
+ kind: PersistentVolumeClaim
109
+ metadata:
110
+ name: {{ . }}
111
+ namespace: {{ $.Release.Namespace }}
112
+ spec:
113
+ {{- include "scada.claim" (dict "size" $.Values.rabbitmq.storage "class" $.Values.rabbitmq.storageClass) | nindent 2 }}
114
+ {{- else }}
169
115
  volumeClaimTemplates:
170
116
  - metadata:
171
117
  name: data
172
118
  spec:
173
119
  {{- include "scada.claim" (dict "size" .Values.rabbitmq.storage "class" .Values.rabbitmq.storageClass) | nindent 8 }}
174
120
  {{- end }}
121
+ {{- end }}
@@ -1,7 +1,8 @@
1
+ {{- if .Values.site.enabled }}
1
2
  apiVersion: apps/v1
2
3
  kind: Deployment
3
4
  metadata:
4
- name: {{ .Release.Name }}-site-server
5
+ name: {{ include "scada.prefix" . }}-site-server
5
6
  namespace: {{ .Release.Namespace }}
6
7
  labels:
7
8
  {{- include "scada.labels" . | nindent 4 }}
@@ -70,7 +71,7 @@ spec:
70
71
  apiVersion: v1
71
72
  kind: Service
72
73
  metadata:
73
- name: {{ .Release.Name }}-site-server
74
+ name: {{ include "scada.prefix" . }}-site-server
74
75
  namespace: {{ .Release.Namespace }}
75
76
  labels:
76
77
  {{- include "scada.labels" . | nindent 4 }}
@@ -90,7 +91,7 @@ spec:
90
91
  apiVersion: v1
91
92
  kind: Service
92
93
  metadata:
93
- name: {{ .Release.Name }}-site-server-plant-lan
94
+ name: {{ include "scada.prefix" . }}-site-server-plant-lan
94
95
  namespace: {{ .Release.Namespace }}
95
96
  labels:
96
97
  {{- include "scada.labels" . | nindent 4 }}
@@ -105,3 +106,4 @@ spec:
105
106
  selector:
106
107
  {{- include "scada.match" (dict "app" "site-server" "ctx" .) | nindent 4 }}
107
108
  {{- end }}
109
+ {{- end }}
@@ -1,7 +1,8 @@
1
+ {{- if .Values.sink.enabled }}
1
2
  apiVersion: apps/v1
2
3
  kind: Deployment
3
4
  metadata:
4
- name: {{ .Release.Name }}-supervisor-sink
5
+ name: {{ include "scada.prefix" . }}-supervisor-sink
5
6
  namespace: {{ .Release.Namespace }}
6
7
  labels:
7
8
  {{- include "scada.labels" . | nindent 4 }}
@@ -32,6 +33,10 @@ spec:
32
33
  - name: STATE_HTTP_PORT
33
34
  value: {{ .Values.service.internalPort | quote }}
34
35
  {{- include "scada.linkEnv" . | nindent 12 }}
36
+ {{- range .Values.env }}
37
+ - name: {{ .name }}
38
+ value: {{ .value | quote }}
39
+ {{- end }}
35
40
  readinessProbe:
36
41
  tcpSocket:
37
42
  port: state
@@ -48,7 +53,7 @@ spec:
48
53
  apiVersion: v1
49
54
  kind: Service
50
55
  metadata:
51
- name: {{ .Release.Name }}-supervisor-sink
56
+ name: {{ include "scada.prefix" . }}-supervisor-sink
52
57
  namespace: {{ .Release.Namespace }}
53
58
  labels:
54
59
  {{- include "scada.labels" . | nindent 4 }}
@@ -60,3 +65,4 @@ spec:
60
65
  targetPort: state
61
66
  selector:
62
67
  {{- include "scada.match" (dict "app" "supervisor-sink" "ctx" .) | nindent 4 }}
68
+ {{- end }}
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "processes": {
6
+ "type": "array",
7
+ "items": {
8
+ "type": "object",
9
+ "required": ["name", "command"],
10
+ "properties": {
11
+ "name": { "type": "string", "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$" },
12
+ "command": { "type": "array", "minItems": 1, "items": { "type": "string" } },
13
+ "env": { "type": "object", "additionalProperties": { "type": ["string", "number", "boolean"] } },
14
+ "hostDevices": {
15
+ "type": "array", "uniqueItems": true,
16
+ "items": { "type": "string", "pattern": "^/dev/([a-zA-Z0-9_-][a-zA-Z0-9_.-]*/)*[a-zA-Z0-9_-][a-zA-Z0-9_.-]*$" }
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }