Skip to content

Commit 1d1cf68

Browse files
committed
cluster, helm: Add new Helm-chart "splice-info"
This helm charts runs a simple web-server to provide static deployment and dynamic runtime information as JSON files. - Static deployment configuration is published as JSON under / - Runtime part supports fetching DSO information from Scan and publishes it under /runtime/dso.json Signed-off-by: Stanislav German-Evtushenko <[email protected]>
1 parent c0061a0 commit 1d1cf68

8 files changed

+328
-1
lines changed

cluster/helm/local.mk

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ app_charts := \
1616
splice-splitwell-app \
1717
splice-splitwell-web-ui \
1818
splice-sv-node \
19-
splice-validator
19+
splice-validator \
20+
splice-info
2021

2122
HELM_VERSION_TAG := cluster/helm/.version-tag
2223
IMAGE_DIGESTS := cluster/helm/.image-digests
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: v2
2+
name: splice-info
3+
version: VERSION_NUMBER
4+
appVersion: VERSION_NUMBER
5+
6+
description: "A simple web server that serves JSON files with deployment and runtime information."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: {{ .Release.Name }}-config
5+
namespace: {{ .Release.Namespace }}
6+
data:
7+
staticfile.conf: |
8+
add_header Cache-Control no-cache;
9+
10+
types {
11+
{{ .Values.contentType }} html;
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{{- define "configmap-content-static" }}
2+
deploymentInfo:
3+
network: {{ .Values.deploymentDetails.network | quote }}
4+
sv:
5+
version: {{ .Values.deploymentDetails.sv.version | quote }}
6+
configDigest:
7+
{{- with .Values.deploymentDetails.configDigest }}
8+
allowed-ip-ranges: {{ printf "%s:%s" .allowedIpRanges.type .allowedIpRanges.value | quote }}
9+
approved-sv-id-values: {{ printf "%s:%s" .approvedSvIdentities.type .approvedSvIdentities.value | quote }}
10+
{{- end }}
11+
synchronizer:
12+
{{- with .Values.deploymentDetails.synchronizer }}
13+
active:
14+
version: {{ .active.version | quote }}
15+
migrationId: {{ .active.migrationId }}
16+
chainIdSuffix: {{ .active.chainIdSuffix | quote }}
17+
staging:
18+
{{- if .staging }}
19+
version: {{ .staging.version | quote }}
20+
migrationId: {{ .staging.migrationId }}
21+
chainIdSuffix: {{ .staging.chainIdSuffix | quote }}
22+
{{- end }}
23+
legacy:
24+
{{- if .legacy }}
25+
version: {{ .legacy.version | quote }}
26+
migrationId: {{ .legacy.migrationId }}
27+
chainIdSuffix: {{ .legacy.chainIdSuffix | quote }}
28+
{{- end }}
29+
{{- end }}
30+
{{- end }}
31+
32+
{{- if .Values.deploymentDetails }}
33+
apiVersion: v1
34+
kind: ConfigMap
35+
metadata:
36+
name: {{ .Release.Name }}-content-static
37+
namespace: {{ .Release.Namespace }}
38+
data:
39+
index.html: {{ include "configmap-content-static" . | fromYaml | toJson | quote }}
40+
{{- end }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ .Release.Name }}
5+
namespace: {{ .Release.Namespace }}
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: {{ .Release.Name }}
11+
template:
12+
metadata:
13+
labels:
14+
app: {{ .Release.Name }}
15+
spec:
16+
containers:
17+
- name: nginx
18+
image: {{ .Values.nginxImage }}
19+
ports:
20+
- containerPort: 80
21+
volumeMounts:
22+
- name: config
23+
mountPath: /etc/nginx/conf.d/staticfile.conf
24+
subPath: staticfile.conf
25+
{{- if .Values.deploymentDetails }}
26+
- name: content-static
27+
mountPath: /usr/share/nginx/html
28+
{{- end }}
29+
{{- if .Values.runtimeDetails }}
30+
- name: content-runtime
31+
mountPath: /usr/share/nginx/html/runtime
32+
readOnly: true
33+
{{- end }}
34+
resources:
35+
{{ toYaml .Values.resources | nindent 12 }}
36+
{{- if .Values.runtimeDetails }}
37+
- name: content-runtime-updater
38+
image: {{ .Values.nginxImage }}
39+
command: ["/bin/sh", "-c"]
40+
args:
41+
- |
42+
set -eu;
43+
44+
period=60;
45+
46+
html_dir=/usr/share/nginx/html;
47+
runtime_index_file="$html_dir/runtime/index.html";
48+
49+
dso_json_path=runtime/dso.json;
50+
dso_json_file="$html_dir/$dso_json_path";
51+
52+
echo "{\"dso\": \"/$dso_json_path\"}" > "$runtime_index_file";
53+
54+
while true; do
55+
start_time=$(date +%s);
56+
exit_code=0;
57+
58+
if curl -m 10 -fsS "$SCAN_URL/api/scan/v0/dso" > "$dso_json_file.new"; then
59+
mv "$dso_json_file.new" "$dso_json_file";
60+
else
61+
echo "ERROR: Failed to fetch DSO from $SCAN_URL";
62+
exit_code=$?;
63+
fi;
64+
65+
end_time=$(date +%s);
66+
sleep "$((period - (end_time - start_time)))";
67+
68+
if [ "$exit_code" -ne 0 ]; then
69+
exit $exit_code;
70+
fi;
71+
done;
72+
env:
73+
- name: SCAN_URL
74+
value: {{ .Values.runtimeDetails.scanUrl | quote }}
75+
volumeMounts:
76+
- name: content-runtime
77+
mountPath: /usr/share/nginx/html/runtime
78+
{{- end }}
79+
volumes:
80+
- name: config
81+
configMap:
82+
name: {{ .Release.Name }}-config
83+
{{- if .Values.deploymentDetails }}
84+
- name: content-static
85+
configMap:
86+
name: {{ .Release.Name }}-content-static
87+
{{- end }}
88+
{{- if .Values.runtimeDetails }}
89+
- name: content-runtime
90+
emptyDir:
91+
sizeLimit: 10Mi
92+
medium: Memory
93+
{{- end }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: {{ .Release.Name }}
5+
namespace: {{ .Release.Namespace }}
6+
spec:
7+
selector:
8+
app: {{ .Release.Name }}
9+
ports:
10+
- protocol: TCP
11+
port: 80
12+
targetPort: 80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
nginxImage: nginx:latest # Replace `:latest` with `@sha256:digest` of a chosen image for security reasons
2+
contentType: "application/json"
3+
4+
# runtimeDetails: # optional, exposes the runtime configuration under path /runtime/
5+
# scanUrl: https://scan.sv.global.canton.network.xxx
6+
7+
# deploymentDetails: # optional, exposes static configuration under path /
8+
# network: "dev"
9+
# configDigest:
10+
# allowedIpRanges:
11+
# type: "md5"
12+
# value: "AAA"
13+
# approvedSvIdentities:
14+
# type: "sha256"
15+
# value: "BBB"
16+
# sv:
17+
# version: "0.3.3"
18+
# synchronizer:
19+
# active:
20+
# chainIdSuffix: "id0"
21+
# migrationId: 4
22+
# version: "0.3.3"
23+
# staging:
24+
# chainIdSuffix: "id1"
25+
# migrationId: 5
26+
# version: "0.3.4"
27+
# legacy: null
28+
29+
resources:
30+
limits:
31+
cpu: 500m
32+
memory: 512Mi
33+
requests:
34+
cpu: 250m
35+
memory: 256Mi
+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$defs": {
4+
"synchronizer": {
5+
"type": "object",
6+
"required": [ "chainIdSuffix", "migrationId", "version" ],
7+
"additionalProperties": false,
8+
"properties": {
9+
"chainIdSuffix": { "type": "string", "minLength": 1 },
10+
"migrationId": { "type": "integer", "minimum": 0, "maximum": 9 },
11+
"version": { "type": "string", "minLength": 1 }
12+
}
13+
},
14+
"digest": {
15+
"type": "object",
16+
"required": [ "type", "value" ],
17+
"additionalProperties": false,
18+
"properties": {
19+
"type": { "type": "string", "enum": ["md5", "sha1", "sha256"] },
20+
"value": { "type": "string", "minLength": 1 }
21+
}
22+
}
23+
},
24+
"type": "object",
25+
"required": [ "resources", "nginxImage", "contentType" ],
26+
"properties": {
27+
"nginxImage": {
28+
"type": "string",
29+
"description": "The Docker image to use for Nginx. Defaults to 'nginx:latest' if not present."
30+
},
31+
"contentType": {
32+
"type": "string",
33+
"description": "The content type for the Nginx server. Defaults to 'application/json' if not present."
34+
},
35+
"runtimeDetails": {
36+
"type": "object",
37+
"required": [ "scanUrl" ],
38+
"additionalProperties": false,
39+
"properties": {
40+
"scanUrl": { "type": "string", "minLength": 1 }
41+
}
42+
},
43+
"deploymentDetails": {
44+
"type": "object",
45+
"required": [ "network", "configDigest", "sv", "synchronizer" ],
46+
"additionalProperties": false,
47+
"properties": {
48+
"network": {
49+
"type": "string",
50+
"enum": ["dev", "test", "main"]
51+
},
52+
"configDigest": {
53+
"type": "object",
54+
"required": [ "allowedIpRanges", "approvedSvIdentities" ],
55+
"additionalProperties": false,
56+
"properties": {
57+
"allowedIpRanges": { "$ref": "#/$defs/digest" },
58+
"approvedSvIdentities": { "$ref": "#/$defs/digest" }
59+
}
60+
},
61+
"sv": {
62+
"type": "object",
63+
"required": ["version"],
64+
"additionalProperties": false,
65+
"properties": {
66+
"version": { "type": "string", "minLength": 1 }
67+
}
68+
},
69+
"synchronizer": {
70+
"type": "object",
71+
"required": ["active"],
72+
"additionalProperties": false,
73+
"properties": {
74+
"active": {
75+
"$ref": "#/$defs/synchronizer"
76+
},
77+
"legacy": {
78+
"oneOf": [
79+
{ "type": "null" },
80+
{ "$ref": "#/$defs/synchronizer" }
81+
]
82+
},
83+
"staging": {
84+
"oneOf": [
85+
{ "type": "null" },
86+
{ "$ref": "#/$defs/synchronizer" }
87+
]
88+
}
89+
}
90+
}
91+
}
92+
},
93+
"resources": {
94+
"type": "object",
95+
"required": [ "limits", "requests" ],
96+
"properties": {
97+
"limits": {
98+
"type": "object",
99+
"required": [ "cpu", "memory" ],
100+
"properties": {
101+
"cpu": {
102+
"type": "string",
103+
"description": "CPU limit (e.g., 500m)."
104+
},
105+
"memory": {
106+
"type": "string",
107+
"description": "Memory limit (e.g., 512Mi)."
108+
}
109+
}
110+
},
111+
"requests": {
112+
"type": "object",
113+
"required": [ "cpu", "memory" ],
114+
"properties": {
115+
"cpu": {
116+
"type": "string",
117+
"description": "CPU request (e.g., 250m)."
118+
},
119+
"memory": {
120+
"type": "string",
121+
"description": "Memory request (e.g., 256Mi)."
122+
}
123+
}
124+
}
125+
}
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)