@bluedynamics/cdk8s-plone 0.1.9 → 0.1.11

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 (37) hide show
  1. package/.claude/claude.md +39 -0
  2. package/.claude/settings.local.json +31 -0
  3. package/.jsii +4 -4
  4. package/README.md +15 -2
  5. package/documentation/sources/how-to/deploy-classic-ui.md +322 -0
  6. package/documentation/sources/how-to/deploy-production-volto.md +319 -0
  7. package/documentation/sources/how-to/index.md +13 -0
  8. package/documentation/sources/reference/api/index.md +29 -0
  9. package/examples/classic-ui/.env.example +19 -0
  10. package/examples/classic-ui/README.md +343 -0
  11. package/examples/classic-ui/__snapshots__/main.test.ts.snap +1242 -0
  12. package/examples/classic-ui/cdk8s.yaml +6 -0
  13. package/examples/classic-ui/config/varnish.tpl.vcl +217 -0
  14. package/examples/classic-ui/ingress.ts +217 -0
  15. package/examples/classic-ui/jest.config.js +11 -0
  16. package/examples/classic-ui/main.test.ts +11 -0
  17. package/examples/classic-ui/main.ts +100 -0
  18. package/examples/classic-ui/package-lock.json +5719 -0
  19. package/examples/classic-ui/package.json +36 -0
  20. package/examples/classic-ui/postgres.bitnami.ts +49 -0
  21. package/examples/classic-ui/postgres.cloudnativepg.ts +63 -0
  22. package/examples/production-volto/.env.example +20 -0
  23. package/examples/production-volto/README.md +295 -0
  24. package/examples/production-volto/__snapshots__/main.test.ts.snap +1412 -0
  25. package/examples/production-volto/cdk8s.yaml +6 -0
  26. package/examples/production-volto/config/varnish.tpl.vcl +297 -0
  27. package/examples/production-volto/ingress.ts +229 -0
  28. package/examples/production-volto/jest.config.js +11 -0
  29. package/examples/production-volto/main.test.ts +11 -0
  30. package/examples/production-volto/main.ts +104 -0
  31. package/examples/production-volto/package-lock.json +5714 -0
  32. package/examples/production-volto/package.json +36 -0
  33. package/examples/production-volto/postgres.bitnami.ts +49 -0
  34. package/examples/production-volto/postgres.cloudnativepg.ts +63 -0
  35. package/lib/httpcache.js +1 -1
  36. package/lib/plone.js +1 -1
  37. package/package.json +3 -3
@@ -0,0 +1,1242 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Classic UI Example Synthesizes correctly 1`] = `
4
+ [
5
+ {
6
+ "apiVersion": "networking.k8s.io/v1",
7
+ "kind": "NetworkPolicy",
8
+ "metadata": {
9
+ "labels": {
10
+ "app.kubernetes.io/component": "primary",
11
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
12
+ "app.kubernetes.io/managed-by": "Helm",
13
+ "app.kubernetes.io/name": "postgresql",
14
+ "app.kubernetes.io/part-of": "plone",
15
+ "app.kubernetes.io/version": "18.1.0",
16
+ "helm.sh/chart": "postgresql-18.1.10",
17
+ },
18
+ "name": "test-chart-db-c80fdf3b-postgresql",
19
+ "namespace": "plone",
20
+ },
21
+ "spec": {
22
+ "egress": [
23
+ {},
24
+ ],
25
+ "ingress": [
26
+ {
27
+ "ports": [
28
+ {
29
+ "port": 5432,
30
+ },
31
+ ],
32
+ },
33
+ ],
34
+ "podSelector": {
35
+ "matchLabels": {
36
+ "app.kubernetes.io/component": "primary",
37
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
38
+ "app.kubernetes.io/name": "postgresql",
39
+ },
40
+ },
41
+ "policyTypes": [
42
+ "Ingress",
43
+ "Egress",
44
+ ],
45
+ },
46
+ },
47
+ {
48
+ "apiVersion": "policy/v1",
49
+ "kind": "PodDisruptionBudget",
50
+ "metadata": {
51
+ "labels": {
52
+ "app.kubernetes.io/component": "primary",
53
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
54
+ "app.kubernetes.io/managed-by": "Helm",
55
+ "app.kubernetes.io/name": "postgresql",
56
+ "app.kubernetes.io/part-of": "plone",
57
+ "app.kubernetes.io/version": "18.1.0",
58
+ "helm.sh/chart": "postgresql-18.1.10",
59
+ },
60
+ "name": "test-chart-db-c80fdf3b-postgresql",
61
+ "namespace": "plone",
62
+ },
63
+ "spec": {
64
+ "maxUnavailable": 1,
65
+ "selector": {
66
+ "matchLabels": {
67
+ "app.kubernetes.io/component": "primary",
68
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
69
+ "app.kubernetes.io/name": "postgresql",
70
+ },
71
+ },
72
+ },
73
+ },
74
+ {
75
+ "apiVersion": "v1",
76
+ "automountServiceAccountToken": false,
77
+ "kind": "ServiceAccount",
78
+ "metadata": {
79
+ "labels": {
80
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
81
+ "app.kubernetes.io/managed-by": "Helm",
82
+ "app.kubernetes.io/name": "postgresql",
83
+ "app.kubernetes.io/part-of": "plone",
84
+ "app.kubernetes.io/version": "18.1.0",
85
+ "helm.sh/chart": "postgresql-18.1.10",
86
+ },
87
+ "name": "test-chart-db-c80fdf3b-postgresql",
88
+ "namespace": "plone",
89
+ },
90
+ },
91
+ {
92
+ "apiVersion": "v1",
93
+ "data": {
94
+ "password": "YWRtaW5AcGxvbmU=",
95
+ "postgres-password": "cFRJd1JURjVoTA==",
96
+ },
97
+ "kind": "Secret",
98
+ "metadata": {
99
+ "labels": {
100
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
101
+ "app.kubernetes.io/managed-by": "Helm",
102
+ "app.kubernetes.io/name": "postgresql",
103
+ "app.kubernetes.io/part-of": "plone",
104
+ "app.kubernetes.io/version": "18.1.0",
105
+ "helm.sh/chart": "postgresql-18.1.10",
106
+ },
107
+ "name": "test-chart-db-c80fdf3b-postgresql",
108
+ "namespace": "plone",
109
+ },
110
+ "type": "Opaque",
111
+ },
112
+ {
113
+ "apiVersion": "v1",
114
+ "kind": "Service",
115
+ "metadata": {
116
+ "labels": {
117
+ "app.kubernetes.io/component": "primary",
118
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
119
+ "app.kubernetes.io/managed-by": "Helm",
120
+ "app.kubernetes.io/name": "postgresql",
121
+ "app.kubernetes.io/part-of": "plone",
122
+ "app.kubernetes.io/version": "18.1.0",
123
+ "helm.sh/chart": "postgresql-18.1.10",
124
+ },
125
+ "name": "test-chart-db-c80fdf3b-postgresql-hl",
126
+ "namespace": "plone",
127
+ },
128
+ "spec": {
129
+ "clusterIP": "None",
130
+ "ports": [
131
+ {
132
+ "name": "tcp-postgresql",
133
+ "port": 5432,
134
+ "targetPort": "tcp-postgresql",
135
+ },
136
+ ],
137
+ "publishNotReadyAddresses": true,
138
+ "selector": {
139
+ "app.kubernetes.io/component": "primary",
140
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
141
+ "app.kubernetes.io/name": "postgresql",
142
+ },
143
+ "type": "ClusterIP",
144
+ },
145
+ },
146
+ {
147
+ "apiVersion": "v1",
148
+ "kind": "Service",
149
+ "metadata": {
150
+ "labels": {
151
+ "app.kubernetes.io/component": "primary",
152
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
153
+ "app.kubernetes.io/managed-by": "Helm",
154
+ "app.kubernetes.io/name": "postgresql",
155
+ "app.kubernetes.io/part-of": "plone",
156
+ "app.kubernetes.io/version": "18.1.0",
157
+ "helm.sh/chart": "postgresql-18.1.10",
158
+ },
159
+ "name": "test-chart-db-c80fdf3b-postgresql",
160
+ "namespace": "plone",
161
+ },
162
+ "spec": {
163
+ "ports": [
164
+ {
165
+ "name": "tcp-postgresql",
166
+ "port": 5432,
167
+ "targetPort": "tcp-postgresql",
168
+ },
169
+ ],
170
+ "selector": {
171
+ "app.kubernetes.io/component": "primary",
172
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
173
+ "app.kubernetes.io/name": "postgresql",
174
+ },
175
+ "type": "ClusterIP",
176
+ },
177
+ },
178
+ {
179
+ "apiVersion": "apps/v1",
180
+ "kind": "StatefulSet",
181
+ "metadata": {
182
+ "labels": {
183
+ "app.kubernetes.io/component": "primary",
184
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
185
+ "app.kubernetes.io/managed-by": "Helm",
186
+ "app.kubernetes.io/name": "postgresql",
187
+ "app.kubernetes.io/part-of": "plone",
188
+ "app.kubernetes.io/version": "18.1.0",
189
+ "helm.sh/chart": "postgresql-18.1.10",
190
+ },
191
+ "name": "test-chart-db-c80fdf3b-postgresql",
192
+ "namespace": "plone",
193
+ },
194
+ "spec": {
195
+ "replicas": 1,
196
+ "selector": {
197
+ "matchLabels": {
198
+ "app.kubernetes.io/component": "primary",
199
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
200
+ "app.kubernetes.io/name": "postgresql",
201
+ },
202
+ },
203
+ "serviceName": "test-chart-db-c80fdf3b-postgresql-hl",
204
+ "template": {
205
+ "metadata": {
206
+ "labels": {
207
+ "app.kubernetes.io/component": "primary",
208
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
209
+ "app.kubernetes.io/managed-by": "Helm",
210
+ "app.kubernetes.io/name": "postgresql",
211
+ "app.kubernetes.io/part-of": "plone",
212
+ "app.kubernetes.io/version": "18.1.0",
213
+ "helm.sh/chart": "postgresql-18.1.10",
214
+ },
215
+ "name": "test-chart-db-c80fdf3b-postgresql",
216
+ },
217
+ "spec": {
218
+ "affinity": {
219
+ "podAntiAffinity": {
220
+ "preferredDuringSchedulingIgnoredDuringExecution": [
221
+ {
222
+ "podAffinityTerm": {
223
+ "labelSelector": {
224
+ "matchLabels": {
225
+ "app.kubernetes.io/component": "primary",
226
+ "app.kubernetes.io/instance": "test-chart-db-c80fdf3b",
227
+ "app.kubernetes.io/name": "postgresql",
228
+ },
229
+ },
230
+ "topologyKey": "kubernetes.io/hostname",
231
+ },
232
+ "weight": 1,
233
+ },
234
+ ],
235
+ },
236
+ },
237
+ "automountServiceAccountToken": false,
238
+ "containers": [
239
+ {
240
+ "env": [
241
+ {
242
+ "name": "BITNAMI_DEBUG",
243
+ "value": "false",
244
+ },
245
+ {
246
+ "name": "POSTGRESQL_PORT_NUMBER",
247
+ "value": "5432",
248
+ },
249
+ {
250
+ "name": "POSTGRESQL_VOLUME_DIR",
251
+ "value": "/bitnami/postgresql",
252
+ },
253
+ {
254
+ "name": "OPENSSL_FIPS",
255
+ "value": "yes",
256
+ },
257
+ {
258
+ "name": "PGDATA",
259
+ "value": "/bitnami/postgresql/data",
260
+ },
261
+ {
262
+ "name": "POSTGRES_USER",
263
+ "value": "plone",
264
+ },
265
+ {
266
+ "name": "POSTGRES_PASSWORD_FILE",
267
+ "value": "/opt/bitnami/postgresql/secrets/password",
268
+ },
269
+ {
270
+ "name": "POSTGRES_POSTGRES_PASSWORD_FILE",
271
+ "value": "/opt/bitnami/postgresql/secrets/postgres-password",
272
+ },
273
+ {
274
+ "name": "POSTGRES_DATABASE",
275
+ "value": "plone",
276
+ },
277
+ {
278
+ "name": "POSTGRESQL_ENABLE_LDAP",
279
+ "value": "no",
280
+ },
281
+ {
282
+ "name": "POSTGRESQL_ENABLE_TLS",
283
+ "value": "no",
284
+ },
285
+ {
286
+ "name": "POSTGRESQL_LOG_HOSTNAME",
287
+ "value": "false",
288
+ },
289
+ {
290
+ "name": "POSTGRESQL_LOG_CONNECTIONS",
291
+ "value": "false",
292
+ },
293
+ {
294
+ "name": "POSTGRESQL_LOG_DISCONNECTIONS",
295
+ "value": "false",
296
+ },
297
+ {
298
+ "name": "POSTGRESQL_PGAUDIT_LOG_CATALOG",
299
+ "value": "off",
300
+ },
301
+ {
302
+ "name": "POSTGRESQL_CLIENT_MIN_MESSAGES",
303
+ "value": "error",
304
+ },
305
+ {
306
+ "name": "POSTGRESQL_SHARED_PRELOAD_LIBRARIES",
307
+ "value": "pgaudit",
308
+ },
309
+ ],
310
+ "image": "registry-1.docker.io/bitnami/postgresql:latest",
311
+ "imagePullPolicy": "IfNotPresent",
312
+ "livenessProbe": {
313
+ "exec": {
314
+ "command": [
315
+ "/bin/sh",
316
+ "-c",
317
+ "exec pg_isready -U "plone" -d "dbname=plone" -h 127.0.0.1 -p 5432",
318
+ ],
319
+ },
320
+ "failureThreshold": 6,
321
+ "initialDelaySeconds": 30,
322
+ "periodSeconds": 10,
323
+ "successThreshold": 1,
324
+ "timeoutSeconds": 5,
325
+ },
326
+ "name": "postgresql",
327
+ "ports": [
328
+ {
329
+ "containerPort": 5432,
330
+ "name": "tcp-postgresql",
331
+ },
332
+ ],
333
+ "readinessProbe": {
334
+ "exec": {
335
+ "command": [
336
+ "/bin/sh",
337
+ "-c",
338
+ "-e",
339
+ "exec pg_isready -U "plone" -d "dbname=plone" -h 127.0.0.1 -p 5432
340
+ [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ]
341
+ ",
342
+ ],
343
+ },
344
+ "failureThreshold": 6,
345
+ "initialDelaySeconds": 5,
346
+ "periodSeconds": 10,
347
+ "successThreshold": 1,
348
+ "timeoutSeconds": 5,
349
+ },
350
+ "resources": {
351
+ "limits": {
352
+ "cpu": "150m",
353
+ "ephemeral-storage": "2Gi",
354
+ "memory": "192Mi",
355
+ },
356
+ "requests": {
357
+ "cpu": "100m",
358
+ "ephemeral-storage": "50Mi",
359
+ "memory": "128Mi",
360
+ },
361
+ },
362
+ "securityContext": {
363
+ "allowPrivilegeEscalation": false,
364
+ "capabilities": {
365
+ "drop": [
366
+ "ALL",
367
+ ],
368
+ },
369
+ "privileged": false,
370
+ "readOnlyRootFilesystem": true,
371
+ "runAsGroup": 1001,
372
+ "runAsNonRoot": true,
373
+ "runAsUser": 1001,
374
+ "seLinuxOptions": {},
375
+ "seccompProfile": {
376
+ "type": "RuntimeDefault",
377
+ },
378
+ },
379
+ "volumeMounts": [
380
+ {
381
+ "mountPath": "/tmp",
382
+ "name": "empty-dir",
383
+ "subPath": "tmp-dir",
384
+ },
385
+ {
386
+ "mountPath": "/opt/bitnami/postgresql/conf",
387
+ "name": "empty-dir",
388
+ "subPath": "app-conf-dir",
389
+ },
390
+ {
391
+ "mountPath": "/opt/bitnami/postgresql/tmp",
392
+ "name": "empty-dir",
393
+ "subPath": "app-tmp-dir",
394
+ },
395
+ {
396
+ "mountPath": "/opt/bitnami/postgresql/secrets/",
397
+ "name": "postgresql-password",
398
+ },
399
+ {
400
+ "mountPath": "/dev/shm",
401
+ "name": "dshm",
402
+ },
403
+ {
404
+ "mountPath": "/bitnami/postgresql",
405
+ "name": "data",
406
+ },
407
+ ],
408
+ },
409
+ ],
410
+ "hostIPC": false,
411
+ "hostNetwork": false,
412
+ "securityContext": {
413
+ "fsGroup": 1001,
414
+ "fsGroupChangePolicy": "Always",
415
+ "supplementalGroups": [],
416
+ "sysctls": [],
417
+ },
418
+ "serviceAccountName": "test-chart-db-c80fdf3b-postgresql",
419
+ "volumes": [
420
+ {
421
+ "emptyDir": {},
422
+ "name": "empty-dir",
423
+ },
424
+ {
425
+ "name": "postgresql-password",
426
+ "secret": {
427
+ "secretName": "test-chart-db-c80fdf3b-postgresql",
428
+ },
429
+ },
430
+ {
431
+ "emptyDir": {
432
+ "medium": "Memory",
433
+ },
434
+ "name": "dshm",
435
+ },
436
+ ],
437
+ },
438
+ },
439
+ "updateStrategy": {
440
+ "rollingUpdate": {},
441
+ "type": "RollingUpdate",
442
+ },
443
+ "volumeClaimTemplates": [
444
+ {
445
+ "apiVersion": "v1",
446
+ "kind": "PersistentVolumeClaim",
447
+ "metadata": {
448
+ "name": "data",
449
+ },
450
+ "spec": {
451
+ "accessModes": [
452
+ "ReadWriteOnce",
453
+ ],
454
+ "resources": {
455
+ "requests": {
456
+ "storage": "8Gi",
457
+ },
458
+ },
459
+ },
460
+ },
461
+ ],
462
+ },
463
+ },
464
+ {
465
+ "apiVersion": "apps/v1",
466
+ "kind": "Deployment",
467
+ "metadata": {
468
+ "labels": {
469
+ "app.kubernetes.io/component": "backend",
470
+ "app.kubernetes.io/name": "plone-backend-deployment",
471
+ },
472
+ "name": "test-chart-plone-backend-deployment-c8a3055e",
473
+ },
474
+ "spec": {
475
+ "replicas": 2,
476
+ "selector": {
477
+ "matchLabels": {
478
+ "app": "test-chart-plone-backend-c8848738",
479
+ },
480
+ },
481
+ "template": {
482
+ "metadata": {
483
+ "labels": {
484
+ "app": "test-chart-plone-backend-c8848738",
485
+ "app.kubernetes.io/component": "backend",
486
+ "app.kubernetes.io/managed-by": "cdk8s-plone",
487
+ "app.kubernetes.io/name": "plone-backend",
488
+ "app.kubernetes.io/part-of": "plone",
489
+ "app.kubernetes.io/version": "classic.version",
490
+ },
491
+ },
492
+ "spec": {
493
+ "containers": [
494
+ {
495
+ "env": [
496
+ {
497
+ "name": "SECRET_POSTGRESQL_USERNAME",
498
+ "value": "plone",
499
+ },
500
+ {
501
+ "name": "SECRET_POSTGRESQL_PASSWORD",
502
+ "valueFrom": {
503
+ "secretKeyRef": {
504
+ "key": "password",
505
+ "name": "test-chart-db-c80fdf3b-postgresql",
506
+ },
507
+ },
508
+ },
509
+ {
510
+ "name": "INSTANCE_db_storage",
511
+ "value": "relstorage",
512
+ },
513
+ {
514
+ "name": "INSTANCE_db_blob_mode",
515
+ "value": "cache",
516
+ },
517
+ {
518
+ "name": "INSTANCE_db_cache_size",
519
+ "value": "5000",
520
+ },
521
+ {
522
+ "name": "INSTANCE_db_cache_size_bytes",
523
+ "value": "1500MB",
524
+ },
525
+ {
526
+ "name": "INSTANCE_db_relstorage",
527
+ "value": "postgresql",
528
+ },
529
+ {
530
+ "name": "INSTANCE_db_relstorage_postgresql_dsn",
531
+ "value": "host='test-chart-db-c80fdf3b-postgresql' dbname='plone' user='$(SECRET_POSTGRESQL_USERNAME)' password='$(SECRET_POSTGRESQL_PASSWORD)'",
532
+ },
533
+ {
534
+ "name": "INSTANCE_db_relstorage_cache_local_mb",
535
+ "value": "800",
536
+ },
537
+ ],
538
+ "envFrom": [],
539
+ "image": "plone/plone-backend:6.1.3",
540
+ "imagePullPolicy": "IfNotPresent",
541
+ "name": "backend-container",
542
+ "readinessProbe": {
543
+ "failureThreshold": 3,
544
+ "httpGet": {
545
+ "path": "/",
546
+ "port": 8080,
547
+ },
548
+ "initialDelaySeconds": 10,
549
+ "periodSeconds": 10,
550
+ "successThreshold": 1,
551
+ "timeoutSeconds": 15,
552
+ },
553
+ "resources": {
554
+ "limits": {
555
+ "cpu": "500m",
556
+ "memory": "512Mi",
557
+ },
558
+ "requests": {
559
+ "cpu": "200m",
560
+ "memory": "256Mi",
561
+ },
562
+ },
563
+ },
564
+ ],
565
+ "imagePullSecrets": [],
566
+ },
567
+ },
568
+ },
569
+ },
570
+ {
571
+ "apiVersion": "policy/v1",
572
+ "kind": "PodDisruptionBudget",
573
+ "metadata": {
574
+ "labels": {
575
+ "app.kubernetes.io/managed-by": "cdk8s-plone",
576
+ "app.kubernetes.io/part-of": "plone",
577
+ },
578
+ "name": "test-chart-plone-backend-pdb-c8a5ffa9",
579
+ },
580
+ "spec": {
581
+ "minAvailable": 1,
582
+ "selector": {
583
+ "matchLabels": {
584
+ "app": "test-chart-plone-backend-c8848738",
585
+ },
586
+ },
587
+ },
588
+ },
589
+ {
590
+ "apiVersion": "v1",
591
+ "kind": "Service",
592
+ "metadata": {
593
+ "labels": {
594
+ "app.kubernetes.io/component": "service",
595
+ "app.kubernetes.io/managed-by": "cdk8s-plone",
596
+ "app.kubernetes.io/name": "plone-backend-service",
597
+ "app.kubernetes.io/part-of": "plone",
598
+ },
599
+ "name": "test-chart-plone-backend-service-c81ad65d",
600
+ },
601
+ "spec": {
602
+ "ports": [
603
+ {
604
+ "name": "backend-http",
605
+ "port": 8080,
606
+ "targetPort": 8080,
607
+ },
608
+ ],
609
+ "selector": {
610
+ "app": "test-chart-plone-backend-c8848738",
611
+ },
612
+ },
613
+ },
614
+ {
615
+ "apiVersion": "policy/v1",
616
+ "kind": "PodDisruptionBudget",
617
+ "metadata": {
618
+ "labels": {
619
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
620
+ "app.kubernetes.io/managed-by": "Helm",
621
+ "app.kubernetes.io/name": "kube-httpcache",
622
+ "app.kubernetes.io/version": "v0.9.1",
623
+ "helm.sh/chart": "kube-httpcache-0.9.1",
624
+ },
625
+ "name": "test-chart-httpcache-c89dd29d-kube-httpcache",
626
+ },
627
+ "spec": {
628
+ "maxUnavailable": 1,
629
+ "selector": {
630
+ "matchLabels": {
631
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
632
+ "app.kubernetes.io/name": "kube-httpcache",
633
+ },
634
+ },
635
+ },
636
+ },
637
+ {
638
+ "apiVersion": "v1",
639
+ "kind": "ServiceAccount",
640
+ "metadata": {
641
+ "labels": {
642
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
643
+ "app.kubernetes.io/managed-by": "Helm",
644
+ "app.kubernetes.io/name": "kube-httpcache",
645
+ "app.kubernetes.io/version": "v0.9.1",
646
+ "helm.sh/chart": "kube-httpcache-0.9.1",
647
+ },
648
+ "name": "test-chart-httpcache-c89dd29d-kube-httpcache",
649
+ },
650
+ },
651
+ {
652
+ "apiVersion": "v1",
653
+ "data": {
654
+ "secret": "YXBpdEw5TUdsZVFieHlrMjVkdWtjWlVCdkJVY1N0ZTQ=",
655
+ },
656
+ "kind": "Secret",
657
+ "metadata": {
658
+ "labels": {
659
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
660
+ "app.kubernetes.io/managed-by": "Helm",
661
+ "app.kubernetes.io/name": "kube-httpcache",
662
+ "app.kubernetes.io/version": "v0.9.1",
663
+ "helm.sh/chart": "kube-httpcache-0.9.1",
664
+ },
665
+ "name": "test-chart-httpcache-c89dd29d-kube-httpcache",
666
+ },
667
+ "type": "Opaque",
668
+ },
669
+ {
670
+ "apiVersion": "v1",
671
+ "data": {
672
+ "default.vcl.tmpl": "vcl 4.0;
673
+
674
+ import std;
675
+ import directors;
676
+
677
+ probe ploneBackendProbe {
678
+ .url = "/";
679
+ .timeout = 5s;
680
+ .interval = 15s;
681
+ .window = 10;
682
+ .threshold = 8;
683
+ }
684
+
685
+ backend ploneBackend {
686
+ .host = "{{ .Env.BACKEND_SERVICE_NAME }}";
687
+ .port = "{{ .Env.BACKEND_SERVICE_PORT }}";
688
+ .probe = ploneBackendProbe;
689
+ .connect_timeout = 0.5s;
690
+ .first_byte_timeout = 120s;
691
+ .between_bytes_timeout = 60s;
692
+ }
693
+
694
+ /* Only allow PURGE from kubernetes network */
695
+ acl purge {
696
+ "10.0.0.0/8";
697
+ }
698
+
699
+ sub detect_debug{
700
+ # Requests with X-Varnish-Debug will display additional
701
+ # information about requests
702
+ unset req.http.x-vcl-debug;
703
+ set req.http.x-vcl-debug = true;
704
+ }
705
+
706
+ sub detect_auth{
707
+ unset req.http.x-auth;
708
+ if (
709
+ (req.http.Cookie && (
710
+ req.http.Cookie ~ "__ac(_(name|password|persistent))?=" ||
711
+ req.http.Cookie ~ "_ZopeId" ||
712
+ req.http.Cookie ~ "auth_token")) ||
713
+ (req.http.Authenticate) ||
714
+ (req.http.Authorization)
715
+ ) {
716
+ set req.http.x-auth = true;
717
+ }
718
+ }
719
+
720
+ sub vcl_init {
721
+ new lbPloneBackend = directors.round_robin();
722
+ lbPloneBackend.add_backend(ploneBackend);
723
+ }
724
+
725
+ sub vcl_recv {
726
+ # Annotate request with x-vcl-debug
727
+ call detect_debug;
728
+
729
+ # Annotate request with x-auth indicating if request is authenticated or not
730
+ call detect_auth;
731
+
732
+ # Routing: All traffic goes to Plone backend for Classic UI
733
+ set req.backend_hint = lbPloneBackend.backend();
734
+
735
+ # short cut authenticated requests to pass
736
+ if (req.http.x-auth) {
737
+ return(pass);
738
+ }
739
+
740
+ # Sanitize cookies so they do not needlessly destroy cacheability for anonymous pages
741
+ if (req.http.Cookie) {
742
+ set req.http.Cookie = ";" + req.http.Cookie;
743
+ set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
744
+ set req.http.Cookie = regsuball(req.http.Cookie, ";(sticky|I18N_LANGUAGE|statusmessages|__ac|_ZopeId|__cp|beaker\\.session|authomatic|serverid|__rf|auth_token)=", "; \\1=");
745
+ set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
746
+ set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
747
+
748
+ if (req.http.Cookie == "") {
749
+ unset req.http.Cookie;
750
+ }
751
+ }
752
+
753
+ # Handle the different request types
754
+ if (req.method == "PURGE") {
755
+ if (!client.ip ~ purge) {
756
+ return (synth(405, "Not allowed."));
757
+ } else {
758
+ ban("req.url == " + req.url);
759
+ return (synth(200, "Purged."));
760
+ }
761
+
762
+ } elseif (req.method == "BAN") {
763
+ # Same ACL check as above:
764
+ if (!client.ip ~ purge) {
765
+ return (synth(405, "Not allowed."));
766
+ }
767
+ ban("req.http.host == " + req.http.host + "&& req.url == " + req.url);
768
+ # Throw a synthetic page so the
769
+ # request won't go to the backend.
770
+ return (synth(200, "Ban added"));
771
+
772
+ } elseif (req.method != "GET" &&
773
+ req.method != "HEAD" &&
774
+ req.method != "PUT" &&
775
+ req.method != "POST" &&
776
+ req.method != "PATCH" &&
777
+ req.method != "TRACE" &&
778
+ req.method != "OPTIONS" &&
779
+ req.method != "DELETE") {
780
+ /* Non-RFC2616 or CONNECT which is weird. */
781
+ return (pipe);
782
+ } elseif (req.method != "GET" &&
783
+ req.method != "HEAD" &&
784
+ req.method != "OPTIONS") {
785
+ /* POST, PUT, PATCH will pass, always */
786
+ return(pass);
787
+ }
788
+
789
+ return(hash);
790
+ }
791
+
792
+ sub vcl_pipe {
793
+ /* This is not necessary if you do not do any request rewriting. */
794
+ set req.http.connection = "close";
795
+ }
796
+
797
+ sub vcl_purge {
798
+ return (synth(200, "PURGE: " + req.url + " - " + req.hash));
799
+ }
800
+
801
+ sub vcl_synth {
802
+ if (resp.status == 301) {
803
+ set resp.http.location = resp.reason;
804
+ set resp.reason = "Moved";
805
+ return (deliver);
806
+ }
807
+ }
808
+
809
+ sub vcl_hit {
810
+ if (obj.ttl >= 0s) {
811
+ // A pure unadulterated hit, deliver it
812
+ return (deliver);
813
+ } elsif (obj.ttl + obj.grace > 0s) {
814
+ // Object is in grace, deliver it
815
+ // Automatically triggers a background fetch
816
+ return (deliver);
817
+ } else {
818
+ return (restart);
819
+ }
820
+ }
821
+
822
+
823
+ sub vcl_backend_response {
824
+ # Don't allow static files to set cookies.
825
+ # (?i) denotes case insensitive in PCRE (perl compatible regular expressions).
826
+ if (bereq.url ~ "(?i)\\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|png|gif|jpeg|jpg|ico|swf|css|js)(\\?.*)?$") {
827
+ unset beresp.http.set-cookie;
828
+ }
829
+ if (beresp.http.Set-Cookie) {
830
+ set beresp.http.x-varnish-action = "FETCH (pass - response sets cookie)";
831
+ set beresp.uncacheable = true;
832
+ set beresp.ttl = 120s;
833
+ return(deliver);
834
+ }
835
+ if (beresp.http.Cache-Control ~ "(private|no-cache|no-store)") {
836
+ set beresp.http.x-varnish-action = "FETCH (pass - cache control disallows)";
837
+ set beresp.uncacheable = true;
838
+ set beresp.ttl = 120s;
839
+ return(deliver);
840
+ }
841
+
842
+ if (beresp.http.Authorization) {
843
+ set beresp.http.x-varnish-action = "FETCH (pass - authorized and no public cache control)";
844
+ set beresp.uncacheable = true;
845
+ set beresp.ttl = 120s;
846
+ return(deliver);
847
+ }
848
+
849
+ if (!beresp.http.Cache-Control) {
850
+ set beresp.http.x-varnish-action = "FETCH (override - backend not setting cache control)";
851
+ set beresp.uncacheable = true;
852
+ set beresp.ttl = 120s;
853
+ return (deliver);
854
+ }
855
+
856
+ if (beresp.http.X-Anonymous && !beresp.http.Cache-Control) {
857
+ set beresp.http.x-varnish-action = "FETCH (override - anonymous backend not setting cache control)";
858
+ set beresp.ttl = 600s;
859
+ return (deliver);
860
+ }
861
+
862
+ set beresp.http.x-varnish-action = "FETCH (insert)";
863
+ return (deliver);
864
+ }
865
+
866
+ sub vcl_deliver {
867
+
868
+ if (req.http.x-vcl-debug) {
869
+ set resp.http.x-varnish-ttl = obj.ttl;
870
+ set resp.http.x-varnish-grace = obj.grace;
871
+ set resp.http.x-hits = obj.hits;
872
+ if (req.http.x-auth) {
873
+ set resp.http.x-auth = "Logged-in";
874
+ } else {
875
+ set resp.http.x-auth = "Anon";
876
+ }
877
+ if (obj.hits > 0) {
878
+ set resp.http.x-cache = "HIT";
879
+ } else {
880
+ set resp.http.x-cache = "MISS";
881
+ }
882
+ } else {
883
+ unset resp.http.x-varnish-action;
884
+ unset resp.http.x-cache-operation;
885
+ unset resp.http.x-cache-rule;
886
+ unset resp.http.x-powered-by;
887
+ }
888
+ }
889
+ ",
890
+ },
891
+ "kind": "ConfigMap",
892
+ "metadata": {
893
+ "name": "test-chart-httpcache-c89dd29d-kube-httpcache",
894
+ },
895
+ },
896
+ {
897
+ "apiVersion": "v1",
898
+ "kind": "Service",
899
+ "metadata": {
900
+ "labels": {
901
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
902
+ "app.kubernetes.io/managed-by": "Helm",
903
+ "app.kubernetes.io/name": "kube-httpcache",
904
+ "app.kubernetes.io/version": "v0.9.1",
905
+ "helm.sh/chart": "kube-httpcache-0.9.1",
906
+ },
907
+ "name": "test-chart-httpcache-c89dd29d-kube-httpcache",
908
+ },
909
+ "spec": {
910
+ "ports": [
911
+ {
912
+ "name": "http",
913
+ "port": 80,
914
+ "protocol": "TCP",
915
+ "targetPort": 8080,
916
+ },
917
+ {
918
+ "name": "signaller",
919
+ "port": 8090,
920
+ "targetPort": 8090,
921
+ },
922
+ {
923
+ "name": "metrics",
924
+ "port": 9131,
925
+ "targetPort": 9131,
926
+ },
927
+ ],
928
+ "selector": {
929
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
930
+ "app.kubernetes.io/name": "kube-httpcache",
931
+ },
932
+ "type": "ClusterIP",
933
+ },
934
+ },
935
+ {
936
+ "apiVersion": "apps/v1",
937
+ "kind": "StatefulSet",
938
+ "metadata": {
939
+ "labels": {
940
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
941
+ "app.kubernetes.io/managed-by": "Helm",
942
+ "app.kubernetes.io/name": "kube-httpcache",
943
+ "app.kubernetes.io/version": "v0.9.1",
944
+ "helm.sh/chart": "kube-httpcache-0.9.1",
945
+ },
946
+ "name": "test-chart-httpcache-c89dd29d-kube-httpcache",
947
+ },
948
+ "spec": {
949
+ "replicas": 2,
950
+ "selector": {
951
+ "matchLabels": {
952
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
953
+ "app.kubernetes.io/name": "kube-httpcache",
954
+ },
955
+ },
956
+ "serviceName": "test-chart-httpcache-c89dd29d-kube-httpcache",
957
+ "template": {
958
+ "metadata": {
959
+ "labels": {
960
+ "app.kubernetes.io/instance": "test-chart-httpcache-c89dd29d",
961
+ "app.kubernetes.io/name": "kube-httpcache",
962
+ },
963
+ },
964
+ "spec": {
965
+ "containers": [
966
+ {
967
+ "args": [
968
+ "-admin-addr=0.0.0.0",
969
+ "-admin-port=6083",
970
+ "-signaller-enable",
971
+ "-signaller-port=8090",
972
+ "-frontend-port=8080",
973
+ "-frontend-watch=false",
974
+ "-frontend-namespace=$(NAMESPACE)",
975
+ "-frontend-service=test-chart-httpcache-c89dd29d-kube-httpcache",
976
+ "-backend-watch=false",
977
+ "-backend-namespace=$(NAMESPACE)",
978
+ "-backend-service=backend-service",
979
+ "-varnish-secret-file=/etc/varnish/k8s-secret/secret",
980
+ "-varnish-vcl-template=/etc/varnish/tmpl/default.vcl.tmpl",
981
+ "-varnish-storage=malloc,128M",
982
+ "-varnish-vcl-template-poll",
983
+ ],
984
+ "env": [
985
+ {
986
+ "name": "NAMESPACE",
987
+ "valueFrom": {
988
+ "fieldRef": {
989
+ "fieldPath": "metadata.namespace",
990
+ },
991
+ },
992
+ },
993
+ {
994
+ "name": "BACKEND_SERVICE_NAME",
995
+ "value": "test-chart-plone-backend-service-c81ad65d",
996
+ },
997
+ {
998
+ "name": "BACKEND_SERVICE_PORT",
999
+ "value": "8080",
1000
+ },
1001
+ {
1002
+ "name": "BACKEND_SITE_ID",
1003
+ "value": "Plone",
1004
+ },
1005
+ {
1006
+ "name": "FRONTEND_SERVICE_NAME",
1007
+ },
1008
+ {
1009
+ "name": "FRONTEND_SERVICE_PORT",
1010
+ "value": "3000",
1011
+ },
1012
+ ],
1013
+ "image": "quay.io/mittwald/kube-httpcache:stable",
1014
+ "imagePullPolicy": "IfNotPresent",
1015
+ "name": "kube-httpcache",
1016
+ "resources": {
1017
+ "limits": {
1018
+ "cpu": "500m",
1019
+ "memory": "500Mi",
1020
+ },
1021
+ "requests": {
1022
+ "cpu": "100m",
1023
+ "memory": "100Mi",
1024
+ },
1025
+ },
1026
+ "securityContext": {},
1027
+ "volumeMounts": [
1028
+ {
1029
+ "mountPath": "/etc/varnish/tmpl",
1030
+ "name": "template",
1031
+ },
1032
+ {
1033
+ "mountPath": "/etc/varnish/k8s-secret",
1034
+ "name": "secret",
1035
+ },
1036
+ {
1037
+ "mountPath": "/var/lib/varnish",
1038
+ "name": "var",
1039
+ },
1040
+ ],
1041
+ },
1042
+ {
1043
+ "args": [
1044
+ "-no-exit",
1045
+ ],
1046
+ "command": [
1047
+ "/exporter/prometheus_varnish_exporter",
1048
+ ],
1049
+ "env": [
1050
+ {
1051
+ "name": "VSM_NOPID",
1052
+ "value": "1",
1053
+ },
1054
+ ],
1055
+ "image": "quay.io/mittwald/kube-httpcache:stable",
1056
+ "imagePullPolicy": "IfNotPresent",
1057
+ "name": "exporter",
1058
+ "ports": [
1059
+ {
1060
+ "containerPort": 9131,
1061
+ "name": "metrics",
1062
+ },
1063
+ ],
1064
+ "resources": {
1065
+ "limits": {
1066
+ "cpu": "100m",
1067
+ "memory": "100Mi",
1068
+ },
1069
+ "requests": {
1070
+ "cpu": "10m",
1071
+ "memory": "50Mi",
1072
+ },
1073
+ },
1074
+ "securityContext": {},
1075
+ "volumeMounts": [
1076
+ {
1077
+ "mountPath": "/var/lib/varnish",
1078
+ "name": "var",
1079
+ },
1080
+ ],
1081
+ },
1082
+ ],
1083
+ "nodeSelector": {
1084
+ "kubernetes.io/arch": "amd64",
1085
+ },
1086
+ "securityContext": {},
1087
+ "serviceAccountName": "test-chart-httpcache-c89dd29d-kube-httpcache",
1088
+ "volumes": [
1089
+ {
1090
+ "configMap": {
1091
+ "name": "test-chart-httpcache-c89dd29d-kube-httpcache",
1092
+ },
1093
+ "name": "template",
1094
+ },
1095
+ {
1096
+ "name": "secret",
1097
+ "secret": {
1098
+ "secretName": "test-chart-httpcache-c89dd29d-kube-httpcache",
1099
+ },
1100
+ },
1101
+ {
1102
+ "emptyDir": {},
1103
+ "name": "var",
1104
+ },
1105
+ ],
1106
+ },
1107
+ },
1108
+ },
1109
+ },
1110
+ {
1111
+ "apiVersion": "networking.k8s.io/v1",
1112
+ "kind": "Ingress",
1113
+ "metadata": {
1114
+ "annotations": {
1115
+ "cert-manager.io/cluster-issuer": "letsencrypt-prod",
1116
+ "kubernetes.io/ingress.class": "traefik",
1117
+ },
1118
+ "name": "test-chart-ingress-main-cached-c8b108e1",
1119
+ },
1120
+ "spec": {
1121
+ "ingressClassName": "traefik",
1122
+ "rules": [
1123
+ {
1124
+ "host": "plone-cached.example.com",
1125
+ "http": {
1126
+ "paths": [
1127
+ {
1128
+ "backend": {
1129
+ "service": {
1130
+ "name": "test-chart-httpcache-c89dd29d-kube-httpcache",
1131
+ "port": {
1132
+ "number": 80,
1133
+ },
1134
+ },
1135
+ },
1136
+ "path": "/",
1137
+ "pathType": "Prefix",
1138
+ },
1139
+ ],
1140
+ },
1141
+ },
1142
+ ],
1143
+ },
1144
+ },
1145
+ {
1146
+ "apiVersion": "traefik.io/v1alpha1",
1147
+ "kind": "Middleware",
1148
+ "metadata": {
1149
+ "name": "test-chart-ingress-main-uncached-addprefix-c820ef43",
1150
+ },
1151
+ "spec": {
1152
+ "addPrefix": {
1153
+ "prefix": "/VirtualHostBase/https/plone-uncached.example.com/Plone/VirtualHostRoot/",
1154
+ },
1155
+ },
1156
+ },
1157
+ {
1158
+ "apiVersion": "networking.k8s.io/v1",
1159
+ "kind": "Ingress",
1160
+ "metadata": {
1161
+ "annotations": {
1162
+ "cert-manager.io/cluster-issuer": "letsencrypt-prod",
1163
+ "kubernetes.io/ingress.class": "traefik",
1164
+ "traefik.ingress.kubernetes.io/router.middlewares": "plone-test-chart-ingress-main-uncached-addprefix-c820ef43@kubernetescrd",
1165
+ },
1166
+ "name": "test-chart-ingress-main-uncached-c85166a3",
1167
+ },
1168
+ "spec": {
1169
+ "ingressClassName": "traefik",
1170
+ "rules": [
1171
+ {
1172
+ "host": "plone-uncached.example.com",
1173
+ "http": {
1174
+ "paths": [
1175
+ {
1176
+ "backend": {
1177
+ "service": {
1178
+ "name": "test-chart-plone-backend-service-c81ad65d",
1179
+ "port": {
1180
+ "number": 8080,
1181
+ },
1182
+ },
1183
+ },
1184
+ "path": "/",
1185
+ "pathType": "Prefix",
1186
+ },
1187
+ ],
1188
+ },
1189
+ },
1190
+ ],
1191
+ },
1192
+ },
1193
+ {
1194
+ "apiVersion": "traefik.io/v1alpha1",
1195
+ "kind": "Middleware",
1196
+ "metadata": {
1197
+ "name": "test-chart-ingress-main-maintenance-addprefix-c8dc1efe",
1198
+ },
1199
+ "spec": {
1200
+ "addPrefix": {
1201
+ "prefix": "/VirtualHostBase/https/plone-maintenance.example.com/VirtualHostRoot/",
1202
+ },
1203
+ },
1204
+ },
1205
+ {
1206
+ "apiVersion": "networking.k8s.io/v1",
1207
+ "kind": "Ingress",
1208
+ "metadata": {
1209
+ "annotations": {
1210
+ "cert-manager.io/cluster-issuer": "letsencrypt-prod",
1211
+ "kubernetes.io/ingress.class": "traefik",
1212
+ "traefik.ingress.kubernetes.io/router.middlewares": "plone-test-chart-ingress-main-maintenance-addprefix-c8dc1efe@kubernetescrd",
1213
+ },
1214
+ "name": "test-chart-ingress-main-maintenance-c874242e",
1215
+ },
1216
+ "spec": {
1217
+ "ingressClassName": "traefik",
1218
+ "rules": [
1219
+ {
1220
+ "host": "plone-maintenance.example.com",
1221
+ "http": {
1222
+ "paths": [
1223
+ {
1224
+ "backend": {
1225
+ "service": {
1226
+ "name": "test-chart-plone-backend-service-c81ad65d",
1227
+ "port": {
1228
+ "number": 8080,
1229
+ },
1230
+ },
1231
+ },
1232
+ "path": "/",
1233
+ "pathType": "Prefix",
1234
+ },
1235
+ ],
1236
+ },
1237
+ },
1238
+ ],
1239
+ },
1240
+ },
1241
+ ]
1242
+ `;