@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.
- package/README.md +53 -0
- package/charts/scada/Chart.yaml +2 -2
- package/charts/scada/templates/_helpers.tpl +12 -4
- package/charts/scada/templates/clickhouse.yaml +3 -3
- package/charts/scada/templates/collector.yaml +2 -2
- package/charts/scada/templates/namespace.yaml +6 -0
- package/charts/scada/templates/postgres.yaml +3 -3
- package/charts/scada/templates/processes.yaml +88 -0
- package/charts/scada/templates/rabbitmq-config.yaml +91 -0
- package/charts/scada/templates/rabbitmq.yaml +54 -107
- package/charts/scada/templates/site-server.yaml +5 -3
- package/charts/scada/templates/supervisor-sink.yaml +8 -2
- package/charts/scada/values.schema.json +22 -0
- package/charts/scada/values.yaml +22 -0
- package/index.js +3 -0
- package/package.json +5 -3
- package/src/application/deploy/collectorProcesses.js +42 -0
- package/src/application/deploy/expandFlows.js +21 -10
- package/src/application/deploy/publishedStreams.js +30 -0
- package/src/application/deploy/releaseEdges.js +13 -16
- package/src/application/deploy/releaseNodes.js +13 -0
- package/src/application/deploy/releaseValues.js +5 -15
- package/src/application/deploy/releases.js +3 -1
- package/src/application/deploy/subscriptions.js +20 -0
- package/src/application/supervisorSink.js +6 -0
- package/src/domain/segment/segmentCoalesce.js +26 -10
- package/src/infrastructure/deploy/executeRelease.js +60 -0
- package/src/infrastructure/ingest/codecs/segmentCodec.js +10 -3
- package/src/infrastructure/ingest/pipelines/segmentPipeline.js +3 -1
- package/src/infrastructure/messaging/rabbitmq/definitions.js +24 -0
- 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.
|
package/charts/scada/Chart.yaml
CHANGED
|
@@ -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" .
|
|
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" .
|
|
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" .
|
|
88
|
+
value: {{ printf "%s-clickhouse" (include "scada.prefix" .) | quote }}
|
|
85
89
|
- name: CLICKHOUSE_URL
|
|
86
|
-
value: {{ printf "http://%s-clickhouse:8123" .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{
|
|
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"
|
|
100
|
+
value: {{ printf "mqtt://%s-rabbitmq:1883" (include "scada.prefix" $) | quote }}
|
|
101
101
|
{{- end }}
|
|
102
102
|
resources:
|
|
103
103
|
{{- toYaml $.Values.resources | nindent 12 }}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
apiVersion: v1
|
|
3
3
|
kind: Service
|
|
4
4
|
metadata:
|
|
5
|
-
name: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
{{
|
|
95
|
-
{{-
|
|
96
|
-
nodePort: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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: {{ .
|
|
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
|
+
}
|