Skip to content

Commit 77b6af4

Browse files
authored
Merge branch 'main' into lfriedman/add-priorityclassname-support
2 parents 91b86e1 + f26ce9e commit 77b6af4

20 files changed

Lines changed: 406 additions & 189 deletions

File tree

distros/kubernetes/nvsentinel/charts/mongodb-store/templates/_helpers.tpl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
{{/*
2+
Manual-PV size: mongodb.persistence.size, or Percona rs0 volumeSpec when usePerconaOperator.
3+
*/}}
4+
{{- define "mongodb-store.persistenceSize" -}}
5+
{{- if .Values.usePerconaOperator -}}
6+
{{- index .Values "psmdb-db" "replsets" "rs0" "volumeSpec" "pvc" "resources" "requests" "storage" | default "8Gi" -}}
7+
{{- else -}}
8+
{{- .Values.mongodb.persistence.size | default "8Gi" -}}
9+
{{- end -}}
10+
{{- end }}
11+
12+
{{/*
13+
TTL expireAfterSeconds. Nil/empty → 2592000. int(nil)/int("abc") is 0 (immediate expiry).
14+
Strings must be base-10 digits; range 0–2147483647 is checked before int for strings.
15+
*/}}
16+
{{- define "mongodb-store.collectionExpirySeconds" -}}
17+
{{- $raw := .Values.collectionExpirySeconds -}}
18+
{{- if or (kindIs "invalid" $raw) (eq ($raw | toString) "") -}}
19+
{{- $raw = 2592000 -}}
20+
{{- end -}}
21+
{{- if kindIs "string" $raw -}}
22+
{{- if not (regexMatch "^[0-9]+$" $raw) -}}
23+
{{- fail (printf "mongodb-store.collectionExpirySeconds must be an integer from 0 through 2147483647, got %v" $raw) -}}
24+
{{- end -}}
25+
{{- if or (gt (len $raw) 10) (and (eq (len $raw) 10) (gt $raw "2147483647")) -}}
26+
{{- fail (printf "mongodb-store.collectionExpirySeconds must be an integer from 0 through 2147483647, got %v" $raw) -}}
27+
{{- end -}}
28+
{{- end -}}
29+
{{- $v := int $raw -}}
30+
{{- if or (lt $v 0) (gt $v 2147483647) -}}
31+
{{- fail (printf "mongodb-store.collectionExpirySeconds must be an integer from 0 through 2147483647, got %v" $raw) -}}
32+
{{- end -}}
33+
{{- $v -}}
34+
{{- end }}
35+
36+
{{/*
37+
create-mongodb-database-<ttl>-<scriptHash> so a TTL or init-script change
38+
(new index, etc.) is a new Job, not a patch on a completed one.
39+
*/}}
40+
{{- define "mongodb-store.initJobName" -}}
41+
{{- $ttl := include "mongodb-store.collectionExpirySeconds" . | toString -}}
42+
{{- $hash := include "mongodb-store.initEval" . | sha256sum | trunc 8 -}}
43+
{{- printf "create-mongodb-database-%s-%s" $ttl $hash | trunc 63 -}}
44+
{{- end }}
45+
146
{{/*
247
Expand the name of the chart.
348
*/}}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
{{/*
2+
Mongosh --eval body for the in-cluster setup Job.
3+
Hashed into the Job name so an index/script change creates a new Job.
4+
*/}}
5+
{{- define "mongodb-store.initEval" -}}
6+
db = db.getSiblingDB('$MONGODB_DATABASE_NAME');
7+
8+
// Create collections if they don't exist
9+
if (!db.getCollectionNames().includes('$MONGODB_COLLECTION_NAME')) {
10+
db.createCollection('$MONGODB_COLLECTION_NAME');
11+
print('Created collection: $MONGODB_COLLECTION_NAME');
12+
} else {
13+
print('Collection already exists: $MONGODB_COLLECTION_NAME');
14+
}
15+
16+
if (!db.getCollectionNames().includes('$MONGODB_TOKEN_COLLECTION_NAME')) {
17+
db.createCollection('$MONGODB_TOKEN_COLLECTION_NAME');
18+
print('Created collection: $MONGODB_TOKEN_COLLECTION_NAME');
19+
} else {
20+
print('Collection already exists: $MONGODB_TOKEN_COLLECTION_NAME');
21+
}
22+
23+
if (!db.getCollectionNames().includes('$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME')) {
24+
db.createCollection('$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME');
25+
print('Created collection: $MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME');
26+
} else {
27+
print('Collection already exists: $MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME');
28+
}
29+
30+
// createIndex if missing; collMod if expireAfterSeconds changed
31+
function ensureTTL(collName, field) {
32+
var raw = '$MONGODB_COLLECTION_EXPIRY_SECONDS';
33+
var secs = Number(raw);
34+
if (raw === '' || !Number.isInteger(secs) || secs < 0) {
35+
throw new Error('MONGODB_COLLECTION_EXPIRY_SECONDS must be a non-negative integer, got ' + JSON.stringify(raw));
36+
}
37+
var key = {};
38+
key[field] = 1;
39+
var existing = db.getCollection(collName).getIndexes().find(function(idx) {
40+
return idx.key && idx.key[field] === 1 && Object.keys(idx.key).length === 1;
41+
});
42+
if (!existing) {
43+
db.getCollection(collName).createIndex(key, { expireAfterSeconds: secs });
44+
print('Created TTL index ' + collName + '.' + field + '=' + secs);
45+
} else if (existing.expireAfterSeconds != secs) {
46+
var res = db.runCommand({
47+
collMod: collName,
48+
index: { name: existing.name, expireAfterSeconds: secs }
49+
});
50+
if (res.ok !== 1) {
51+
throw new Error('collMod failed for ' + collName + ': ' + tojson(res));
52+
}
53+
print('Updated TTL index ' + collName + '.' + field + '=' + secs);
54+
} else {
55+
print('TTL index ' + collName + '.' + field + ' already ' + secs);
56+
}
57+
}
58+
ensureTTL('$MONGODB_COLLECTION_NAME', 'createdAt');
59+
ensureTTL('$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME', 'actualEndTime');
60+
61+
// Non-TTL indexes (MongoDB handles identical duplicates gracefully)
62+
db.$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME.createIndex(
63+
{ 'scheduledStartTime': 1 },
64+
);
65+
db.$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME.createIndex(
66+
{ 'cspStatus': 1 },
67+
);
68+
db.$MONGODB_COLLECTION_NAME.createIndex({
69+
'healthevent.nodename': 1,
70+
'healthevent.entitiesimpacted.entitytype': 1,
71+
'healthevent.entitiesimpacted.entityvalue': 1,
72+
'healthevent.generatedtimestamp.seconds': 1
73+
});
74+
{{- if .Values.mongodb.tls.enabled }}
75+
// Create X.509 users (TLS only)
76+
var userExists = db.getSiblingDB('\$external').getUser('$MONGODB_APPLICATION_USER_DN');
77+
if (userExists) {
78+
print('User already exists, skipping creation.');
79+
} else {
80+
print('Creating new X.509 user...');
81+
db.getSiblingDB('\$external').runCommand({
82+
createUser: '$MONGODB_APPLICATION_USER_DN',
83+
roles: [{ role: 'readWrite', db: '$MONGODB_DATABASE_NAME' }]
84+
});
85+
print('X.509 user created successfully.');
86+
}
87+
var dgxcopsUserExists = db.getSiblingDB('\$external').getUser('$MONGODB_DGXCOPS_USER_DN');
88+
if (dgxcopsUserExists) {
89+
print('Dgxcops user already exists, skipping creation.');
90+
} else {
91+
print('Creating new dgxcops X.509 user...');
92+
db.getSiblingDB('\$external').runCommand({
93+
createUser: '$MONGODB_DGXCOPS_USER_DN',
94+
roles: [{ role: 'read', db: '$MONGODB_DATABASE_NAME' }]
95+
});
96+
print('Dgxcops X.509 user created successfully.');
97+
}
98+
{{- else }}
99+
// Create SCRAM application user (non-TLS mode)
100+
var scramUser = db.getUser('$MONGODB_SCRAM_APP_USERNAME');
101+
if (scramUser) {
102+
print('SCRAM application user already exists, updating password...');
103+
db.changeUserPassword('$MONGODB_SCRAM_APP_USERNAME', '$MONGODB_SCRAM_APP_PASSWORD');
104+
print('SCRAM application user password updated.');
105+
} else {
106+
print('Creating SCRAM application user...');
107+
db.createUser({
108+
user: '$MONGODB_SCRAM_APP_USERNAME',
109+
pwd: '$MONGODB_SCRAM_APP_PASSWORD',
110+
roles: [{ role: 'readWrite', db: '$MONGODB_DATABASE_NAME' }]
111+
});
112+
print('SCRAM application user created successfully.');
113+
}
114+
{{- end }}
115+
{{- end }}

distros/kubernetes/nvsentinel/charts/mongodb-store/templates/configmap.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,4 @@ data:
4848
MONGODB_CHANGE_STREAM_RETRY_DEADLINE_SECONDS: "300"
4949
MONGODB_CHANGE_STREAM_RETRY_INTERVAL_SECONDS: "5"
5050
UNPROCESSED_EVENTS_METRIC_UPDATE_INTERVAL_SECONDS: "25"
51-
MONGODB_COLLECTION_EXPIRY_SECONDS: "2592000"
51+
MONGODB_COLLECTION_EXPIRY_SECONDS: {{ include "mongodb-store.collectionExpirySeconds" . | quote }}

distros/kubernetes/nvsentinel/charts/mongodb-store/templates/jobs.yaml

Lines changed: 11 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,18 @@ subjects:
5555
apiVersion: batch/v1
5656
kind: Job
5757
metadata:
58-
name: create-mongodb-database
58+
# Name is create-mongodb-database-<ttl>-<scriptHash>. Label: create-mongodb-database
59+
name: {{ include "mongodb-store.initJobName" . }}
60+
labels:
61+
app.kubernetes.io/name: create-mongodb-database
62+
app.kubernetes.io/component: mongodb-init
63+
app.kubernetes.io/instance: {{ .Release.Name }}
5964
annotations:
65+
# Argo: recreate this immutable Job on sync if the first run Failed and TTL
66+
# did not change. Do not add helm.sh/hook (stuck Argo Application deletes).
6067
argocd.argoproj.io/sync-options: Force=true,Replace=true
6168
spec:
69+
ttlSecondsAfterFinished: 86400
6270
activeDeadlineSeconds: 600
6371
template:
6472
spec:
@@ -260,92 +268,8 @@ spec:
260268
--tlsCertificateKeyFile /tmp/tls.pem \
261269
{{- end }}
262270
--eval "
263-
db = db.getSiblingDB('$MONGODB_DATABASE_NAME');
264-
265-
// Create collections if they don't exist
266-
if (!db.getCollectionNames().includes('$MONGODB_COLLECTION_NAME')) {
267-
db.createCollection('$MONGODB_COLLECTION_NAME');
268-
print('Created collection: $MONGODB_COLLECTION_NAME');
269-
} else {
270-
print('Collection already exists: $MONGODB_COLLECTION_NAME');
271-
}
272-
273-
if (!db.getCollectionNames().includes('$MONGODB_TOKEN_COLLECTION_NAME')) {
274-
db.createCollection('$MONGODB_TOKEN_COLLECTION_NAME');
275-
print('Created collection: $MONGODB_TOKEN_COLLECTION_NAME');
276-
} else {
277-
print('Collection already exists: $MONGODB_TOKEN_COLLECTION_NAME');
278-
}
279-
280-
if (!db.getCollectionNames().includes('$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME')) {
281-
db.createCollection('$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME');
282-
print('Created collection: $MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME');
283-
} else {
284-
print('Collection already exists: $MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME');
285-
}
286-
287-
// Create indexes (MongoDB handles duplicates gracefully)
288-
db.$MONGODB_COLLECTION_NAME.createIndex(
289-
{ 'createdAt': 1 },
290-
{ expireAfterSeconds: $MONGODB_COLLECTION_EXPIRY_SECONDS }
291-
);
292-
db.$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME.createIndex(
293-
{ 'actualEndTime': 1 },
294-
{ expireAfterSeconds: $MONGODB_COLLECTION_EXPIRY_SECONDS }
295-
);
296-
db.$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME.createIndex(
297-
{ 'scheduledStartTime': 1 },
298-
);
299-
db.$MONGODB_MAINTENANCE_EVENT_COLLECTION_NAME.createIndex(
300-
{ 'cspStatus': 1 },
301-
);
302-
db.$MONGODB_COLLECTION_NAME.createIndex({
303-
'healthevent.nodename': 1,
304-
'healthevent.entitiesimpacted.entitytype': 1,
305-
'healthevent.entitiesimpacted.entityvalue': 1,
306-
'healthevent.generatedtimestamp.seconds': 1
307-
});
308-
{{- if .Values.mongodb.tls.enabled }}
309-
// Create X.509 users (TLS only)
310-
var userExists = db.getSiblingDB('\$external').getUser('$MONGODB_APPLICATION_USER_DN');
311-
if (userExists) {
312-
print('User already exists, skipping creation.');
313-
} else {
314-
print('Creating new X.509 user...');
315-
db.getSiblingDB('\$external').runCommand({
316-
createUser: '$MONGODB_APPLICATION_USER_DN',
317-
roles: [{ role: 'readWrite', db: '$MONGODB_DATABASE_NAME' }]
318-
});
319-
print('X.509 user created successfully.');
320-
}
321-
var dgxcopsUserExists = db.getSiblingDB('\$external').getUser('$MONGODB_DGXCOPS_USER_DN');
322-
if (dgxcopsUserExists) {
323-
print('Dgxcops user already exists, skipping creation.');
324-
} else {
325-
print('Creating new dgxcops X.509 user...');
326-
db.getSiblingDB('\$external').runCommand({
327-
createUser: '$MONGODB_DGXCOPS_USER_DN',
328-
roles: [{ role: 'read', db: '$MONGODB_DATABASE_NAME' }]
329-
});
330-
print('Dgxcops X.509 user created successfully.');
331-
}
332-
{{- else }}
333-
// Create SCRAM application user (non-TLS mode)
334-
var scramUser = db.getUser('$MONGODB_SCRAM_APP_USERNAME');
335-
if (scramUser) {
336-
print('SCRAM application user already exists, updating password...');
337-
db.changeUserPassword('$MONGODB_SCRAM_APP_USERNAME', '$MONGODB_SCRAM_APP_PASSWORD');
338-
print('SCRAM application user password updated.');
339-
} else {
340-
print('Creating SCRAM application user...');
341-
db.createUser({
342-
user: '$MONGODB_SCRAM_APP_USERNAME',
343-
pwd: '$MONGODB_SCRAM_APP_PASSWORD',
344-
roles: [{ role: 'readWrite', db: '$MONGODB_DATABASE_NAME' }]
345-
});
346-
print('SCRAM application user created successfully.');
347-
}
348-
{{- end }}"
271+
{{ include "mongodb-store.initEval" . | indent 18 }}
272+
"
349273
do
350274
echo "Waiting for mongodb to be ready...";
351275
sleep 5;

distros/kubernetes/nvsentinel/charts/mongodb-store/templates/pv.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
{{ if (eq .Values.mode "manual") }}
16+
{{- $storage := include "mongodb-store.persistenceSize" . }}
1617
{{- if .Values.usePerconaOperator }}
1718
{{- /* Percona PVs - one per replica */ -}}
1819
{{- $replicaCount := index .Values "psmdb-db" "replsets" "rs0" "size" | default 3 | int }}
@@ -27,7 +28,7 @@ metadata:
2728
type: local
2829
spec:
2930
capacity:
30-
storage: "8Gi"
31+
storage: {{ $storage | quote }}
3132
accessModes:
3233
- ReadWriteOnce
3334
persistentVolumeReclaimPolicy: Retain
@@ -48,7 +49,7 @@ metadata:
4849
type: local
4950
spec:
5051
capacity:
51-
storage: "8Gi"
52+
storage: {{ $storage | quote }}
5253
accessModes:
5354
- ReadWriteOnce
5455
persistentVolumeReclaimPolicy: Retain
@@ -59,4 +60,3 @@ spec:
5960
{{- end }}
6061
{{- end }}
6162
{{ end }}
62-

distros/kubernetes/nvsentinel/charts/mongodb-store/values.yaml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@
3131
useBitnami: true
3232
usePerconaOperator: false
3333

34+
# TTL expireAfterSeconds. Default 2592000 (30d); production often 604800 (7d).
35+
# Also used for external Mongo. Unset/null → 2592000 (int(nil) is 0, immediate expiry).
36+
# Job name is create-mongodb-database-<seconds>-<scriptHash> (-l app.kubernetes.io/name=create-mongodb-database).
37+
collectionExpirySeconds: 2592000
38+
39+
# PVC size. Default 8Gi is for development.
40+
# Bitnami: mongodb.persistence.size
41+
# Percona: psmdb-db.replsets.rs0.volumeSpec.pvc.resources.requests.storage
42+
# Existing Bound PVCs do not grow on helm upgrade (StatefulSet VCT is immutable).
43+
3444
# SCRAM application user (created when mongodb.tls.enabled is false).
3545
# Instead of X.509 cert-based users, the Job creates a SCRAM-SHA-256 user
3646
# with readWrite access to the NVSentinel database.
@@ -108,6 +118,7 @@ mongodb:
108118

109119
persistence:
110120
resourcePolicy: "keep"
121+
size: &persistenceSize "8Gi"
111122

112123
automountServiceAccountToken: true
113124

@@ -295,7 +306,7 @@ psmdb-db:
295306
pvc:
296307
resources:
297308
requests:
298-
storage: "8Gi"
309+
storage: *persistenceSize
299310
nodeSelector: {}
300311
tolerations: []
301312
podDisruptionBudget:

0 commit comments

Comments
 (0)