Skip to content

Commit e3682df

Browse files
lucasrod16claude
andcommitted
Validate config.Kubernetes does not conflict with backends.kubernetes
Fail template rendering when config.Kubernetes.Enabled is false but backends.kubernetes.enabled is true, or when config.Kubernetes.Namespace differs from backends.kubernetes.namespace. These conflicts would produce an inconsistent gcfg where the chart enables the runner but the config disables it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7b22e7f commit e3682df

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

charts/rstudio-connect/templates/NOTES.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ Please consider removing this configuration value.
3838
{{- fail "\n\n`launcher.enabled` and `backends.kubernetes.enabled` cannot both be true"}}
3939
{{- end }}
4040

41+
{{- if .Values.backends.kubernetes.enabled }}
42+
{{- $configEnabled := dig "Kubernetes" "Enabled" "" .Values.config }}
43+
{{- if or (eq (printf "%v" $configEnabled) "false") (eq (printf "%v" $configEnabled) "0") }}
44+
{{- fail "\n\n`config.Kubernetes.Enabled` is set to false but `backends.kubernetes.enabled` is true. Remove `config.Kubernetes.Enabled` because the chart sets it automatically." }}
45+
{{- end }}
46+
{{- $configNs := dig "Kubernetes" "Namespace" "" .Values.config }}
47+
{{- $chartNs := default $.Release.Namespace .Values.backends.kubernetes.namespace }}
48+
{{- if and $configNs (ne $configNs $chartNs) }}
49+
{{- fail (printf "\n\n`config.Kubernetes.Namespace` (%s) conflicts with `backends.kubernetes.namespace` (%s). Remove `config.Kubernetes.Namespace` because the chart sets it automatically from `backends.kubernetes.namespace`." $configNs $chartNs) }}
50+
{{- end }}
51+
{{- end }}
52+
4153
{{- if and .Values.launcher.useTemplates .Values.launcher.enabled }}
4254
{{- range $k,$v := .Values.launcher.launcherKubernetesProfilesConf }}
4355
{{- if hasKey $v "job-json-overrides" }}
@@ -50,6 +62,10 @@ Please consider removing this configuration value.
5062
{{- fail "\n\nWhen launcher is enabled, persistent storage must be provided.\nThis is usually done via a PersistentVolumeClaim (PVC) with `sharedStorage.create=true`, although there are other options."}}
5163
{{- end }}
5264

65+
{{- if and .Values.backends.kubernetes.enabled (not .Values.sharedStorage.create) (not .Values.sharedStorage.mount) (not (dig "Kubernetes" "DataDirPVCName" "" .Values.config)) }}
66+
{{- fail "\n\nWhen backends.kubernetes is enabled, persistent storage must be provided.\nThis is usually done via a PersistentVolumeClaim (PVC) with `sharedStorage.create=true`, although there are other options."}}
67+
{{- end }}
68+
5369
{{- if .Values.launcher.contentInitContainer }}
5470
{{- fail "\n\n`launcher.contentInitContainer` values are now stored at `launcher.defaultInitContainer`" }}
5571
{{- end }}

charts/rstudio-connect/tests/kubernetes-values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ launcher:
44
backends:
55
kubernetes:
66
enabled: true
7+
8+
sharedStorage:
9+
create: true
10+
mount: true

charts/rstudio-connect/tests/kubernetes_test.yaml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ tests:
99
# Test validation: launcher.enabled and backends.kubernetes.enabled cannot both be true
1010
- it: should fail when both launcher.enabled and backends.kubernetes.enabled are true
1111
template: NOTES.txt
12+
values:
13+
- kubernetes-values.yaml
1214
set:
1315
launcher:
1416
enabled: true
@@ -19,6 +21,43 @@ tests:
1921
- failedTemplate:
2022
errorPattern: "launcher.enabled.*and.*backends.kubernetes.enabled.*cannot both be true"
2123

24+
- it: should fail when config.Kubernetes.Enabled conflicts with backends.kubernetes.enabled
25+
template: NOTES.txt
26+
set:
27+
launcher:
28+
enabled: false
29+
backends:
30+
kubernetes:
31+
enabled: true
32+
sharedStorage:
33+
create: true
34+
mount: true
35+
config:
36+
Kubernetes:
37+
Enabled: "false"
38+
asserts:
39+
- failedTemplate:
40+
errorPattern: "config.Kubernetes.Enabled.*is set to false.*backends.kubernetes.enabled.*is true"
41+
42+
- it: should fail when config.Kubernetes.Namespace conflicts with backends.kubernetes.namespace
43+
template: NOTES.txt
44+
set:
45+
launcher:
46+
enabled: false
47+
backends:
48+
kubernetes:
49+
enabled: true
50+
namespace: correct-ns
51+
sharedStorage:
52+
create: true
53+
mount: true
54+
config:
55+
Kubernetes:
56+
Namespace: wrong-ns
57+
asserts:
58+
- failedTemplate:
59+
errorPattern: "config.Kubernetes.Namespace.*conflicts with.*backends.kubernetes.namespace"
60+
2261
# Test backends.kubernetes.enabled creates configmap entries for job base
2362
- it: should create job.yaml in configmap when backends.kubernetes.enabled
2463
template: configmap.yaml
@@ -123,6 +162,8 @@ tests:
123162
# Test custom mount paths for job.yaml and service.yaml
124163
- it: should use custom DefaultResourceJobBase path for job.yaml mount
125164
template: deployment.yaml
165+
values:
166+
- kubernetes-values.yaml
126167
set:
127168
launcher:
128169
enabled: false
@@ -142,6 +183,8 @@ tests:
142183

143184
- it: should use custom DefaultResourceServiceBase path for service.yaml mount
144185
template: deployment.yaml
186+
values:
187+
- kubernetes-values.yaml
145188
set:
146189
launcher:
147190
enabled: false
@@ -166,6 +209,8 @@ tests:
166209
# Test default mount paths when config.Kubernetes is not set
167210
- it: should use default job.yaml mount path when config.Kubernetes is absent
168211
template: deployment.yaml
212+
values:
213+
- kubernetes-values.yaml
169214
set:
170215
launcher:
171216
enabled: false
@@ -184,6 +229,8 @@ tests:
184229

185230
- it: should fall back to default paths when DefaultResourceJobBase is empty string
186231
template: deployment.yaml
232+
values:
233+
- kubernetes-values.yaml
187234
set:
188235
launcher:
189236
enabled: false
@@ -203,6 +250,8 @@ tests:
203250

204251
- it: should write default path in gcfg when DefaultResourceJobBase is empty string
205252
template: configmap.yaml
253+
values:
254+
- kubernetes-values.yaml
206255
set:
207256
launcher:
208257
enabled: false
@@ -219,6 +268,8 @@ tests:
219268

220269
- it: should fall back to default paths when DefaultResourceServiceBase is empty string
221270
template: deployment.yaml
271+
values:
272+
- kubernetes-values.yaml
222273
set:
223274
launcher:
224275
enabled: false
@@ -242,6 +293,8 @@ tests:
242293

243294
- it: should write default path in gcfg when DefaultResourceServiceBase is empty string
244295
template: configmap.yaml
296+
values:
297+
- kubernetes-values.yaml
245298
set:
246299
launcher:
247300
enabled: false
@@ -263,6 +316,8 @@ tests:
263316
# Test RBAC resources are created when backends.kubernetes.enabled
264317
- it: should create RBAC resources when backends.kubernetes.enabled and rbac.create are true
265318
template: rbac.yaml
319+
values:
320+
- kubernetes-values.yaml
266321
set:
267322
launcher:
268323
enabled: false
@@ -292,6 +347,8 @@ tests:
292347
# Test kubernetes namespace configuration
293348
- it: should use custom namespace when backends.kubernetes.namespace is specified
294349
template: rbac.yaml
350+
values:
351+
- kubernetes-values.yaml
295352
set:
296353
launcher:
297354
enabled: false
@@ -311,6 +368,8 @@ tests:
311368
template: rbac.yaml
312369
release:
313370
namespace: test-namespace
371+
values:
372+
- kubernetes-values.yaml
314373
set:
315374
launcher:
316375
enabled: false
@@ -328,6 +387,8 @@ tests:
328387
# Test serviceAccount configuration with backends.kubernetes.enabled
329388
- it: should set serviceAccountName when backends.kubernetes.enabled and rbac.create are true
330389
template: deployment.yaml
390+
values:
391+
- kubernetes-values.yaml
331392
set:
332393
launcher:
333394
enabled: false
@@ -386,6 +447,8 @@ tests:
386447
# Test defaultInitContainer fields render on auto-generated init container
387448
- it: should apply imagePullPolicy, resources, and securityContext to init container
388449
template: configmap.yaml
450+
values:
451+
- kubernetes-values.yaml
389452
set:
390453
launcher:
391454
enabled: false
@@ -413,6 +476,8 @@ tests:
413476

414477
- it: should apply defaultInitContainer fields to user-provided connect-content-init
415478
template: configmap.yaml
479+
values:
480+
- kubernetes-values.yaml
416481
set:
417482
launcher:
418483
enabled: false
@@ -445,6 +510,8 @@ tests:
445510

446511
- it: should preserve user-provided init container fields over defaultInitContainer
447512
template: configmap.yaml
513+
values:
514+
- kubernetes-values.yaml
448515
set:
449516
launcher:
450517
enabled: false
@@ -487,6 +554,8 @@ tests:
487554
# Test kubernetes config section in rstudio-connect.gcfg
488555
- it: should configure Kubernetes.Enabled in gcfg when backends.kubernetes.enabled is true
489556
template: configmap.yaml
557+
values:
558+
- kubernetes-values.yaml
490559
set:
491560
launcher:
492561
enabled: false
@@ -517,6 +586,8 @@ tests:
517586
# Test with both launcher disabled and kubernetes enabled
518587
- it: should work correctly with launcher disabled and kubernetes enabled
519588
template: deployment.yaml
589+
values:
590+
- kubernetes-values.yaml
520591
set:
521592
launcher:
522593
enabled: false
@@ -535,6 +606,8 @@ tests:
535606
# Test serviceAccount is set correctly when backends.kubernetes.enabled
536607
- it: should generate default serviceAccountName when backends.kubernetes.enabled
537608
template: deployment.yaml
609+
values:
610+
- kubernetes-values.yaml
538611
set:
539612
launcher:
540613
enabled: false
@@ -553,6 +626,8 @@ tests:
553626
# Test that config includes Kubernetes section
554627
- it: should include Kubernetes config section when enabled
555628
template: configmap.yaml
629+
values:
630+
- kubernetes-values.yaml
556631
set:
557632
launcher:
558633
enabled: false
@@ -568,6 +643,8 @@ tests:
568643
# Test auto-generated job base contains init container
569644
- it: should auto-generate job.yaml with init container and correct image
570645
template: configmap.yaml
646+
values:
647+
- kubernetes-values.yaml
571648
set:
572649
launcher:
573650
enabled: false
@@ -590,6 +667,8 @@ tests:
590667

591668
- it: should ensure rsc-volume mount on user-provided connect-content-init
592669
template: configmap.yaml
670+
values:
671+
- kubernetes-values.yaml
593672
set:
594673
launcher:
595674
enabled: false
@@ -616,6 +695,8 @@ tests:
616695

617696
- it: should fail when connect-content has /opt/rstudio-connect mounted from a non-rsc-volume
618697
template: deployment.yaml
698+
values:
699+
- kubernetes-values.yaml
619700
set:
620701
launcher:
621702
enabled: false
@@ -637,6 +718,8 @@ tests:
637718

638719
- it: should fail when connect-content-init has /mnt/rstudio-connect-runtime/ mounted from a non-rsc-volume
639720
template: deployment.yaml
721+
values:
722+
- kubernetes-values.yaml
640723
set:
641724
launcher:
642725
enabled: false
@@ -658,6 +741,8 @@ tests:
658741

659742
- it: should not include init container when defaultInitContainer.enabled is false
660743
template: configmap.yaml
744+
values:
745+
- kubernetes-values.yaml
661746
set:
662747
launcher:
663748
enabled: false
@@ -677,6 +762,8 @@ tests:
677762
# Template order: ClusterRole(0), ClusterRoleBinding(1), SA(2), Role(3), RoleBinding(4)
678763
- it: should create ClusterRole with nodes/get when service type is NodePort
679764
template: rbac.yaml
765+
values:
766+
- kubernetes-values.yaml
680767
set:
681768
launcher:
682769
enabled: false
@@ -709,6 +796,8 @@ tests:
709796
# Template order: ClusterRole(0), ClusterRoleBinding(1), SA(2), Role(3), RoleBinding(4)
710797
- it: should create ClusterRole when rbac.clusterRoleCreate is true regardless of service type
711798
template: rbac.yaml
799+
values:
800+
- kubernetes-values.yaml
712801
set:
713802
launcher:
714803
enabled: false
@@ -730,6 +819,8 @@ tests:
730819
# Renders: Role(0), RoleBinding(1)
731820
- it: should not create ServiceAccount when rbac.serviceAccount.create is false
732821
template: rbac.yaml
822+
values:
823+
- kubernetes-values.yaml
733824
set:
734825
launcher:
735826
enabled: false
@@ -759,6 +850,8 @@ tests:
759850
# Test 4: rbac.create=false with direct runner enabled renders no RBAC docs
760851
- it: should not create any RBAC resources when rbac.create is false
761852
template: rbac.yaml
853+
values:
854+
- kubernetes-values.yaml
762855
set:
763856
launcher:
764857
enabled: false
@@ -848,6 +941,8 @@ tests:
848941
# Test 7: Init image tag precedence — explicit tag overrides tagPrefix+appVersion
849942
- it: should use explicit defaultInitContainer.tag when set
850943
template: configmap.yaml
944+
values:
945+
- kubernetes-values.yaml
851946
set:
852947
launcher:
853948
enabled: false
@@ -863,6 +958,8 @@ tests:
863958

864959
- it: should use tagPrefix plus appVersion when tag is not set
865960
template: configmap.yaml
961+
values:
962+
- kubernetes-values.yaml
866963
set:
867964
launcher:
868965
enabled: false
@@ -878,6 +975,8 @@ tests:
878975

879976
- it: should preserve user-provided sidecar and nodeSelector in job base
880977
template: configmap.yaml
978+
values:
979+
- kubernetes-values.yaml
881980
set:
882981
launcher:
883982
enabled: false

0 commit comments

Comments
 (0)