@intentius/chant-lexicon-helm 0.124.31 → 0.124.32

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 (111) hide show
  1. package/dist/archive-render.js +76 -0
  2. package/dist/codegen/docs-cli.js +3 -0
  3. package/dist/codegen/docs.js +113 -0
  4. package/dist/codegen/generate-cli.js +19 -0
  5. package/dist/codegen/generate.js +210 -0
  6. package/dist/codegen/naming.js +29 -0
  7. package/dist/codegen/package.js +44 -0
  8. package/dist/codegen/values-type.js +87 -0
  9. package/dist/commands.js +413 -0
  10. package/dist/components/builders.js +9 -0
  11. package/dist/components/capability-plugin.js +17 -0
  12. package/dist/components/helm-upgrade.js +109 -0
  13. package/dist/components/index.js +11 -0
  14. package/dist/composites/catalog.js +1119 -0
  15. package/dist/composites/helm-batch-job.js +148 -0
  16. package/dist/composites/helm-crd-lifecycle.js +145 -0
  17. package/dist/composites/helm-cron-job.js +130 -0
  18. package/dist/composites/helm-daemon-set.js +125 -0
  19. package/dist/composites/helm-external-secret.js +63 -0
  20. package/dist/composites/helm-library.js +24 -0
  21. package/dist/composites/helm-microservice.js +260 -0
  22. package/dist/composites/helm-monitored-service.js +188 -0
  23. package/dist/composites/helm-namespace-env.js +116 -0
  24. package/dist/composites/helm-secure-ingress.js +86 -0
  25. package/dist/composites/helm-stateful-service.js +160 -0
  26. package/dist/composites/helm-web-app.js +201 -0
  27. package/dist/composites/helm-worker.js +164 -0
  28. package/dist/composites/index.js +13 -0
  29. package/dist/config.js +161 -0
  30. package/dist/coverage.js +37 -0
  31. package/dist/deep-observe-hooks.js +19 -0
  32. package/dist/deep-observe.js +55 -0
  33. package/dist/describe-resources.js +119 -0
  34. package/dist/describe-stack-status.js +66 -0
  35. package/dist/detect.js +11 -0
  36. package/dist/generated/index.js +11 -0
  37. package/dist/helpers.js +84 -0
  38. package/dist/import/generator.js +292 -0
  39. package/dist/import/parser.js +141 -0
  40. package/dist/import/template-stripper.js +86 -0
  41. package/dist/index.js +55 -0
  42. package/dist/integrity.json +2 -2
  43. package/dist/intrinsics.js +482 -0
  44. package/dist/lint/audit-catalog.js +33 -0
  45. package/dist/lint/audit-lineage.js +53 -0
  46. package/dist/lint/post-synth/helm-helpers.js +60 -0
  47. package/dist/lint/post-synth/index.js +48 -0
  48. package/dist/lint/post-synth/whm005-no-empty-wrapper.js +47 -0
  49. package/dist/lint/post-synth/whm101.js +38 -0
  50. package/dist/lint/post-synth/whm102.js +26 -0
  51. package/dist/lint/post-synth/whm103.js +51 -0
  52. package/dist/lint/post-synth/whm104.js +29 -0
  53. package/dist/lint/post-synth/whm105.js +23 -0
  54. package/dist/lint/post-synth/whm201.js +29 -0
  55. package/dist/lint/post-synth/whm202.js +42 -0
  56. package/dist/lint/post-synth/whm203.js +32 -0
  57. package/dist/lint/post-synth/whm204.js +51 -0
  58. package/dist/lint/post-synth/whm301.js +31 -0
  59. package/dist/lint/post-synth/whm302.js +33 -0
  60. package/dist/lint/post-synth/whm401.js +52 -0
  61. package/dist/lint/post-synth/whm402.js +38 -0
  62. package/dist/lint/post-synth/whm403.js +38 -0
  63. package/dist/lint/post-synth/whm404.js +30 -0
  64. package/dist/lint/post-synth/whm405.js +47 -0
  65. package/dist/lint/post-synth/whm406.js +27 -0
  66. package/dist/lint/post-synth/whm407.js +72 -0
  67. package/dist/lint/post-synth/whm501.js +89 -0
  68. package/dist/lint/post-synth/whm502.js +85 -0
  69. package/dist/lint/post-synth/whm503.js +82 -0
  70. package/dist/lint/post-synth/whm504.js +47 -0
  71. package/dist/lint/rules/chart-metadata.js +53 -0
  72. package/dist/lint/rules/no-hardcoded-image.js +50 -0
  73. package/dist/lint/rules/values-no-helm-tpl.js +78 -0
  74. package/dist/lint/rules/values-no-secrets.js +65 -0
  75. package/dist/list-artifacts.js +134 -0
  76. package/dist/lsp/completions.d.ts.map +1 -1
  77. package/dist/lsp/completions.js +18 -0
  78. package/dist/lsp/hover.d.ts.map +1 -1
  79. package/dist/lsp/hover.js +40 -0
  80. package/dist/manifest.json +1 -1
  81. package/dist/op/activities/cluster-probe.js +116 -0
  82. package/dist/op/activities/helm.js +449 -0
  83. package/dist/op/activities/index.js +10 -0
  84. package/dist/op/builders.js +45 -0
  85. package/dist/package-cli.js +21 -0
  86. package/dist/pinnability/actions.js +207 -0
  87. package/dist/pinnability/classify.js +416 -0
  88. package/dist/pinnability/conditions.js +0 -0
  89. package/dist/pinnability/index.js +16 -0
  90. package/dist/pinnability/localize.js +518 -0
  91. package/dist/pinnability/render-stream.js +53 -0
  92. package/dist/pinnability/values.js +151 -0
  93. package/dist/plugin.js +458 -0
  94. package/dist/project-codegen.js +215 -0
  95. package/dist/release-observe.js +287 -0
  96. package/dist/render-diff.js +279 -0
  97. package/dist/render-digest.js +0 -0
  98. package/dist/render-records.js +29 -0
  99. package/dist/render-store.js +401 -0
  100. package/dist/render-wrapper.js +164 -0
  101. package/dist/render.js +394 -0
  102. package/dist/resources.js +109 -0
  103. package/dist/serializer.js +903 -0
  104. package/dist/validate-cli.js +17 -0
  105. package/dist/validate.js +30 -0
  106. package/dist/values-probe.js +504 -0
  107. package/dist/wrapper-chart.js +95 -0
  108. package/package.json +11 -11
  109. package/src/codegen/package.ts +2 -2
  110. package/src/lsp/completions.ts +2 -1
  111. package/src/lsp/hover.ts +2 -1
@@ -0,0 +1,148 @@
1
+ /**
2
+ * HelmBatchJob composite — Job + optional ServiceAccount + RBAC.
3
+ *
4
+ * One-shot batch job pattern with optional RBAC for jobs that need
5
+ * Kubernetes API access (e.g., data migrations, cluster operations).
6
+ */
7
+ import { Composite, mergeDefaults } from "@intentius/chant";
8
+ import { Chart, Values, Job, ServiceAccount, Role, RoleBinding } from "../resources.js";
9
+ import { values, include, printf, toYaml, With } from "../intrinsics.js";
10
+ export const HelmBatchJob = Composite((props) => {
11
+ const { name, imageRepository = "busybox", imageTag = "latest", backoffLimit = 6, completions = 1, parallelism = 1, restartPolicy = "OnFailure", serviceAccount = true, rbac = false, appVersion = "1.0.0", defaults: defs, } = props;
12
+ const chart = new Chart(mergeDefaults({
13
+ apiVersion: "v2",
14
+ name,
15
+ version: "0.1.0",
16
+ appVersion,
17
+ type: "application",
18
+ description: `A Helm chart for ${name} batch job`,
19
+ }, defs?.chart));
20
+ const valuesObj = {
21
+ image: {
22
+ repository: imageRepository,
23
+ tag: imageTag,
24
+ pullPolicy: "IfNotPresent",
25
+ },
26
+ job: {
27
+ backoffLimit,
28
+ completions,
29
+ parallelism,
30
+ },
31
+ restartPolicy,
32
+ command: [],
33
+ args: [],
34
+ resources: {},
35
+ };
36
+ if (props.ttlSecondsAfterFinished !== undefined) {
37
+ valuesObj.job.ttlSecondsAfterFinished = props.ttlSecondsAfterFinished;
38
+ }
39
+ if (props.podSecurityContext)
40
+ valuesObj.podSecurityContext = props.podSecurityContext;
41
+ if (props.securityContext)
42
+ valuesObj.securityContext = props.securityContext;
43
+ if (props.nodeSelector)
44
+ valuesObj.nodeSelector = props.nodeSelector;
45
+ if (props.tolerations)
46
+ valuesObj.tolerations = props.tolerations;
47
+ if (serviceAccount) {
48
+ valuesObj.serviceAccount = {
49
+ create: true,
50
+ name: "",
51
+ annotations: {},
52
+ };
53
+ }
54
+ if (rbac) {
55
+ valuesObj.rbac = {
56
+ create: true,
57
+ rules: [],
58
+ };
59
+ }
60
+ const valuesRes = new Values(mergeDefaults(valuesObj, defs?.values));
61
+ const containerSpec = {
62
+ name,
63
+ image: printf("%s:%s", values.image.repository, values.image.tag),
64
+ imagePullPolicy: values.image.pullPolicy,
65
+ command: values.command,
66
+ args: values.args,
67
+ resources: toYaml(values.resources),
68
+ };
69
+ if (props.securityContext)
70
+ containerSpec.securityContext = toYaml(values.securityContext);
71
+ const podSpec = {
72
+ restartPolicy: values.restartPolicy,
73
+ containers: [containerSpec],
74
+ };
75
+ if (props.podSecurityContext)
76
+ podSpec.securityContext = toYaml(values.podSecurityContext);
77
+ if (props.nodeSelector)
78
+ podSpec.nodeSelector = With(values.nodeSelector, toYaml(values.nodeSelector));
79
+ if (props.tolerations)
80
+ podSpec.tolerations = With(values.tolerations, toYaml(values.tolerations));
81
+ if (serviceAccount)
82
+ podSpec.serviceAccountName = include(`${name}.serviceAccountName`);
83
+ const jobSpec = {
84
+ backoffLimit: values.job.backoffLimit,
85
+ completions: values.job.completions,
86
+ parallelism: values.job.parallelism,
87
+ template: {
88
+ metadata: {
89
+ labels: include(`${name}.selectorLabels`),
90
+ },
91
+ spec: podSpec,
92
+ },
93
+ };
94
+ if (props.ttlSecondsAfterFinished !== undefined) {
95
+ jobSpec.ttlSecondsAfterFinished = values.job.ttlSecondsAfterFinished;
96
+ }
97
+ const job = new Job(mergeDefaults({
98
+ apiVersion: "batch/v1",
99
+ kind: "Job",
100
+ metadata: {
101
+ name: include(`${name}.fullname`),
102
+ labels: include(`${name}.labels`),
103
+ },
104
+ spec: jobSpec,
105
+ }, defs?.job));
106
+ const result = { chart, values: valuesRes, job };
107
+ if (serviceAccount) {
108
+ result.serviceAccount = new ServiceAccount(mergeDefaults({
109
+ apiVersion: "v1",
110
+ kind: "ServiceAccount",
111
+ metadata: {
112
+ name: include(`${name}.serviceAccountName`),
113
+ labels: include(`${name}.labels`),
114
+ annotations: toYaml(values.serviceAccount.annotations),
115
+ },
116
+ }, defs?.serviceAccount));
117
+ }
118
+ if (rbac) {
119
+ result.role = new Role(mergeDefaults({
120
+ apiVersion: "rbac.authorization.k8s.io/v1",
121
+ kind: "Role",
122
+ metadata: {
123
+ name: include(`${name}.fullname`),
124
+ labels: include(`${name}.labels`),
125
+ },
126
+ rules: toYaml(values.rbac.rules),
127
+ }, defs?.role));
128
+ result.roleBinding = new RoleBinding(mergeDefaults({
129
+ apiVersion: "rbac.authorization.k8s.io/v1",
130
+ kind: "RoleBinding",
131
+ metadata: {
132
+ name: include(`${name}.fullname`),
133
+ labels: include(`${name}.labels`),
134
+ },
135
+ roleRef: {
136
+ apiGroup: "rbac.authorization.k8s.io",
137
+ kind: "Role",
138
+ name: include(`${name}.fullname`),
139
+ },
140
+ subjects: [{
141
+ kind: "ServiceAccount",
142
+ name: include(`${name}.serviceAccountName`),
143
+ namespace: values.namespace ?? undefined,
144
+ }],
145
+ }, defs?.roleBinding));
146
+ }
147
+ return result;
148
+ }, "HelmBatchJob");
@@ -0,0 +1,145 @@
1
+ /**
2
+ * HelmCRDLifecycle composite — managed CRD lifecycle via Helm hooks.
3
+ *
4
+ * Produces a Job-based CRD installer that runs as a pre-install/pre-upgrade
5
+ * hook, solving the Helm limitation that CRDs in crds/ are never upgraded
6
+ * or deleted.
7
+ */
8
+ import { Composite, mergeDefaults } from "@intentius/chant";
9
+ import { Chart, Values, Job, ConfigMap, ServiceAccount, ClusterRole, ClusterRoleBinding } from "../resources.js";
10
+ import { values, include, printf } from "../intrinsics.js";
11
+ export const HelmCRDLifecycle = Composite((props) => {
12
+ const { name, crdContent, kubectlImage = "bitnami/kubectl", kubectlTag = "latest", serviceAccountName, defaults: defs, } = props;
13
+ const saName = serviceAccountName ?? `${name}-crd-installer`;
14
+ const chart = new Chart(mergeDefaults({
15
+ apiVersion: "v2",
16
+ name,
17
+ version: "0.1.0",
18
+ type: "application",
19
+ description: `CRD lifecycle management for ${name}`,
20
+ }, defs?.chart));
21
+ const valuesRes = new Values(mergeDefaults({
22
+ crdLifecycle: {
23
+ enabled: true,
24
+ kubectl: {
25
+ image: kubectlImage,
26
+ tag: kubectlTag,
27
+ },
28
+ serviceAccount: {
29
+ name: saName,
30
+ },
31
+ },
32
+ }, defs?.values));
33
+ const hookAnnotations = {
34
+ "helm.sh/hook": "pre-install,pre-upgrade",
35
+ "helm.sh/hook-weight": "-5",
36
+ "helm.sh/hook-delete-policy": "before-hook-creation",
37
+ };
38
+ const crdConfigMap = new ConfigMap(mergeDefaults({
39
+ apiVersion: "v1",
40
+ kind: "ConfigMap",
41
+ metadata: {
42
+ name: printf("%s-crd-content", include(`${name}.fullname`)),
43
+ labels: include(`${name}.labels`),
44
+ annotations: hookAnnotations,
45
+ },
46
+ data: {
47
+ "crds.yaml": crdContent,
48
+ },
49
+ }, defs?.crdConfigMap));
50
+ const serviceAccount = new ServiceAccount(mergeDefaults({
51
+ apiVersion: "v1",
52
+ kind: "ServiceAccount",
53
+ metadata: {
54
+ name: values.crdLifecycle.serviceAccount.name,
55
+ labels: include(`${name}.labels`),
56
+ annotations: hookAnnotations,
57
+ },
58
+ }, defs?.serviceAccount));
59
+ const clusterRole = new ClusterRole(mergeDefaults({
60
+ apiVersion: "rbac.authorization.k8s.io/v1",
61
+ kind: "ClusterRole",
62
+ metadata: {
63
+ name: printf("%s-crd-installer", include(`${name}.fullname`)),
64
+ labels: include(`${name}.labels`),
65
+ annotations: hookAnnotations,
66
+ },
67
+ rules: [{
68
+ apiGroups: ["apiextensions.k8s.io"],
69
+ resources: ["customresourcedefinitions"],
70
+ verbs: ["get", "list", "create", "update", "patch"],
71
+ }],
72
+ }, defs?.clusterRole));
73
+ const clusterRoleBinding = new ClusterRoleBinding(mergeDefaults({
74
+ apiVersion: "rbac.authorization.k8s.io/v1",
75
+ kind: "ClusterRoleBinding",
76
+ metadata: {
77
+ name: printf("%s-crd-installer", include(`${name}.fullname`)),
78
+ labels: include(`${name}.labels`),
79
+ annotations: hookAnnotations,
80
+ },
81
+ roleRef: {
82
+ apiGroup: "rbac.authorization.k8s.io",
83
+ kind: "ClusterRole",
84
+ name: printf("%s-crd-installer", include(`${name}.fullname`)),
85
+ },
86
+ subjects: [{
87
+ kind: "ServiceAccount",
88
+ name: values.crdLifecycle.serviceAccount.name,
89
+ namespace: "{{ .Release.Namespace }}",
90
+ }],
91
+ }, defs?.clusterRoleBinding));
92
+ const crdInstallJob = new Job(mergeDefaults({
93
+ apiVersion: "batch/v1",
94
+ kind: "Job",
95
+ metadata: {
96
+ name: printf("%s-crd-install", include(`${name}.fullname`)),
97
+ labels: include(`${name}.labels`),
98
+ annotations: hookAnnotations,
99
+ },
100
+ spec: {
101
+ template: {
102
+ metadata: {
103
+ labels: include(`${name}.selectorLabels`),
104
+ },
105
+ spec: {
106
+ serviceAccountName: values.crdLifecycle.serviceAccount.name,
107
+ restartPolicy: "Never",
108
+ securityContext: {
109
+ runAsNonRoot: true,
110
+ runAsUser: 1000,
111
+ },
112
+ containers: [{
113
+ name: "crd-installer",
114
+ image: printf("%s:%s", values.crdLifecycle.kubectl.image, values.crdLifecycle.kubectl.tag),
115
+ command: ["kubectl", "apply", "-f", "/crds/"],
116
+ securityContext: {
117
+ readOnlyRootFilesystem: true,
118
+ allowPrivilegeEscalation: false,
119
+ },
120
+ volumeMounts: [{
121
+ name: "crd-content",
122
+ mountPath: "/crds",
123
+ readOnly: true,
124
+ }],
125
+ }],
126
+ volumes: [{
127
+ name: "crd-content",
128
+ configMap: {
129
+ name: printf("%s-crd-content", include(`${name}.fullname`)),
130
+ },
131
+ }],
132
+ },
133
+ },
134
+ },
135
+ }, defs?.crdInstallJob));
136
+ return {
137
+ chart,
138
+ values: valuesRes,
139
+ crdInstallJob,
140
+ crdConfigMap,
141
+ serviceAccount,
142
+ clusterRole,
143
+ clusterRoleBinding,
144
+ };
145
+ }, "HelmCRDLifecycle");
@@ -0,0 +1,130 @@
1
+ /**
2
+ * HelmCronJob composite — CronJob chart.
3
+ *
4
+ * Produces a Helm chart for scheduled batch workloads.
5
+ */
6
+ import { Composite, mergeDefaults } from "@intentius/chant";
7
+ import { Chart, Values, CronJob, ServiceAccount } from "../resources.js";
8
+ import { values, include, printf, toYaml, With } from "../intrinsics.js";
9
+ export const HelmCronJob = Composite((props) => {
10
+ const { name, imageRepository = "busybox", imageTag = "latest", schedule = "0 * * * *", restartPolicy = "OnFailure", appVersion = "1.0.0", serviceAccount = false, defaults: defs, } = props;
11
+ const chart = new Chart(mergeDefaults({
12
+ apiVersion: "v2",
13
+ name,
14
+ version: "0.1.0",
15
+ appVersion,
16
+ type: "application",
17
+ description: `A Helm chart for ${name} (cron job)`,
18
+ }, defs?.chart));
19
+ const valuesObj = {
20
+ image: {
21
+ repository: imageRepository,
22
+ tag: imageTag,
23
+ pullPolicy: "IfNotPresent",
24
+ },
25
+ schedule,
26
+ restartPolicy,
27
+ command: [],
28
+ args: [],
29
+ resources: {},
30
+ };
31
+ if (props.podSecurityContext)
32
+ valuesObj.podSecurityContext = props.podSecurityContext;
33
+ if (props.securityContext)
34
+ valuesObj.securityContext = props.securityContext;
35
+ if (props.nodeSelector)
36
+ valuesObj.nodeSelector = props.nodeSelector;
37
+ if (props.tolerations)
38
+ valuesObj.tolerations = props.tolerations;
39
+ if (props.affinity)
40
+ valuesObj.affinity = props.affinity;
41
+ if (props.podAnnotations)
42
+ valuesObj.podAnnotations = props.podAnnotations;
43
+ if (props.concurrencyPolicy)
44
+ valuesObj.concurrencyPolicy = props.concurrencyPolicy;
45
+ if (props.successfulJobsHistoryLimit !== undefined)
46
+ valuesObj.successfulJobsHistoryLimit = props.successfulJobsHistoryLimit;
47
+ if (props.failedJobsHistoryLimit !== undefined)
48
+ valuesObj.failedJobsHistoryLimit = props.failedJobsHistoryLimit;
49
+ if (props.backoffLimit !== undefined)
50
+ valuesObj.backoffLimit = props.backoffLimit;
51
+ if (serviceAccount) {
52
+ valuesObj.serviceAccount = {
53
+ create: true,
54
+ name: "",
55
+ annotations: {},
56
+ };
57
+ }
58
+ const valuesRes = new Values(mergeDefaults(valuesObj, defs?.values));
59
+ const containerSpec = {
60
+ name,
61
+ image: printf("%s:%s", values.image.repository, values.image.tag),
62
+ imagePullPolicy: values.image.pullPolicy,
63
+ command: values.command,
64
+ args: values.args,
65
+ resources: toYaml(values.resources),
66
+ };
67
+ if (props.securityContext)
68
+ containerSpec.securityContext = toYaml(values.securityContext);
69
+ const podSpec = {
70
+ restartPolicy: values.restartPolicy,
71
+ containers: [containerSpec],
72
+ };
73
+ if (props.podSecurityContext)
74
+ podSpec.securityContext = toYaml(values.podSecurityContext);
75
+ if (props.nodeSelector)
76
+ podSpec.nodeSelector = With(values.nodeSelector, toYaml(values.nodeSelector));
77
+ if (props.tolerations)
78
+ podSpec.tolerations = With(values.tolerations, toYaml(values.tolerations));
79
+ if (props.affinity)
80
+ podSpec.affinity = With(values.affinity, toYaml(values.affinity));
81
+ if (serviceAccount)
82
+ podSpec.serviceAccountName = include(`${name}.serviceAccountName`);
83
+ const templateMetadata = {
84
+ labels: include(`${name}.selectorLabels`),
85
+ };
86
+ if (props.podAnnotations)
87
+ templateMetadata.annotations = toYaml(values.podAnnotations);
88
+ const jobSpec = {
89
+ template: {
90
+ metadata: templateMetadata,
91
+ spec: podSpec,
92
+ },
93
+ };
94
+ if (props.backoffLimit !== undefined)
95
+ jobSpec.backoffLimit = values.backoffLimit;
96
+ const cronJobSpec = {
97
+ schedule: values.schedule,
98
+ jobTemplate: {
99
+ spec: jobSpec,
100
+ },
101
+ };
102
+ if (props.concurrencyPolicy)
103
+ cronJobSpec.concurrencyPolicy = values.concurrencyPolicy;
104
+ if (props.successfulJobsHistoryLimit !== undefined)
105
+ cronJobSpec.successfulJobsHistoryLimit = values.successfulJobsHistoryLimit;
106
+ if (props.failedJobsHistoryLimit !== undefined)
107
+ cronJobSpec.failedJobsHistoryLimit = values.failedJobsHistoryLimit;
108
+ const cronJob = new CronJob(mergeDefaults({
109
+ apiVersion: "batch/v1",
110
+ kind: "CronJob",
111
+ metadata: {
112
+ name: include(`${name}.fullname`),
113
+ labels: include(`${name}.labels`),
114
+ },
115
+ spec: cronJobSpec,
116
+ }, defs?.cronJob));
117
+ const result = { chart, values: valuesRes, cronJob };
118
+ if (serviceAccount) {
119
+ result.serviceAccount = new ServiceAccount(mergeDefaults({
120
+ apiVersion: "v1",
121
+ kind: "ServiceAccount",
122
+ metadata: {
123
+ name: include(`${name}.serviceAccountName`),
124
+ labels: include(`${name}.labels`),
125
+ annotations: toYaml(values.serviceAccount.annotations),
126
+ },
127
+ }, defs?.serviceAccount));
128
+ }
129
+ return result;
130
+ }, "HelmCronJob");
@@ -0,0 +1,125 @@
1
+ /**
2
+ * HelmDaemonSet composite — DaemonSet + optional ServiceAccount.
3
+ *
4
+ * Common pattern for logging agents, monitoring sidecars, and node-level
5
+ * infrastructure that needs to run on every node.
6
+ */
7
+ import { Composite, mergeDefaults } from "@intentius/chant";
8
+ import { Chart, Values, DaemonSet, ServiceAccount } from "../resources.js";
9
+ import { values, include, printf, toYaml, With } from "../intrinsics.js";
10
+ export const HelmDaemonSet = Composite((props) => {
11
+ const { name, imageRepository = "fluent/fluent-bit", imageTag = "latest", port, hostPaths = [], serviceAccount = true, appVersion = "1.0.0", defaults: defs, } = props;
12
+ const chart = new Chart(mergeDefaults({
13
+ apiVersion: "v2",
14
+ name,
15
+ version: "0.1.0",
16
+ appVersion,
17
+ type: "application",
18
+ description: `A Helm chart for ${name} DaemonSet`,
19
+ }, defs?.chart));
20
+ const valuesObj = {
21
+ image: {
22
+ repository: imageRepository,
23
+ tag: imageTag,
24
+ pullPolicy: "IfNotPresent",
25
+ },
26
+ resources: {
27
+ limits: { cpu: "200m", memory: "256Mi" },
28
+ requests: { cpu: "100m", memory: "128Mi" },
29
+ },
30
+ nodeSelector: {},
31
+ tolerations: [],
32
+ updateStrategy: {
33
+ type: "RollingUpdate",
34
+ rollingUpdate: {
35
+ maxUnavailable: 1,
36
+ },
37
+ },
38
+ };
39
+ if (serviceAccount) {
40
+ valuesObj.serviceAccount = {
41
+ create: true,
42
+ name: "",
43
+ annotations: {},
44
+ };
45
+ }
46
+ const valuesRes = new Values(mergeDefaults(valuesObj, defs?.values));
47
+ const containerSpec = {
48
+ name,
49
+ image: printf("%s:%s", values.image.repository, values.image.tag),
50
+ imagePullPolicy: values.image.pullPolicy,
51
+ resources: toYaml(values.resources),
52
+ securityContext: {
53
+ runAsNonRoot: true,
54
+ readOnlyRootFilesystem: true,
55
+ allowPrivilegeEscalation: false,
56
+ },
57
+ };
58
+ if (port !== undefined) {
59
+ containerSpec.ports = [{ containerPort: port, name: "http" }];
60
+ }
61
+ if (hostPaths.length > 0) {
62
+ containerSpec.volumeMounts = hostPaths.map((hp) => ({
63
+ name: hp.name,
64
+ mountPath: hp.mountPath,
65
+ readOnly: hp.readOnly ?? true,
66
+ }));
67
+ }
68
+ const podSpec = {
69
+ containers: [containerSpec],
70
+ securityContext: {
71
+ runAsNonRoot: true,
72
+ },
73
+ nodeSelector: With(values.nodeSelector, toYaml(values.nodeSelector)),
74
+ tolerations: With(values.tolerations, toYaml(values.tolerations)),
75
+ };
76
+ if (serviceAccount) {
77
+ podSpec.serviceAccountName = include(`${name}.serviceAccountName`);
78
+ }
79
+ if (hostPaths.length > 0) {
80
+ podSpec.volumes = hostPaths.map((hp) => ({
81
+ name: hp.name,
82
+ hostPath: {
83
+ path: hp.hostPath,
84
+ type: "Directory",
85
+ },
86
+ }));
87
+ }
88
+ const daemonSet = new DaemonSet(mergeDefaults({
89
+ apiVersion: "apps/v1",
90
+ kind: "DaemonSet",
91
+ metadata: {
92
+ name: include(`${name}.fullname`),
93
+ labels: include(`${name}.labels`),
94
+ },
95
+ spec: {
96
+ selector: {
97
+ matchLabels: include(`${name}.selectorLabels`),
98
+ },
99
+ updateStrategy: toYaml(values.updateStrategy),
100
+ template: {
101
+ metadata: {
102
+ labels: include(`${name}.selectorLabels`),
103
+ },
104
+ spec: podSpec,
105
+ },
106
+ },
107
+ }, defs?.daemonSet));
108
+ const result = {
109
+ chart,
110
+ values: valuesRes,
111
+ daemonSet,
112
+ };
113
+ if (serviceAccount) {
114
+ result.serviceAccount = new ServiceAccount(mergeDefaults({
115
+ apiVersion: "v1",
116
+ kind: "ServiceAccount",
117
+ metadata: {
118
+ name: include(`${name}.serviceAccountName`),
119
+ labels: include(`${name}.labels`),
120
+ annotations: toYaml(values.serviceAccount.annotations),
121
+ },
122
+ }, defs?.serviceAccount));
123
+ }
124
+ return result;
125
+ }, "HelmDaemonSet");
@@ -0,0 +1,63 @@
1
+ /**
2
+ * HelmExternalSecret composite — ExternalSecret CR for secret management.
3
+ *
4
+ * Uses the external-secrets.io operator to sync secrets from external
5
+ * providers (AWS Secrets Manager, Vault, etc.) into Kubernetes Secrets.
6
+ *
7
+ * Thanks to the serializer's fallback GVK resolution, this composite
8
+ * returns a plain object with apiVersion/kind and the serializer handles
9
+ * it like any other K8s resource.
10
+ */
11
+ import { Composite, mergeDefaults } from "@intentius/chant";
12
+ import { Chart, Values, ExternalSecret } from "../resources.js";
13
+ import { values, include } from "../intrinsics.js";
14
+ export const HelmExternalSecret = Composite((props) => {
15
+ const { name, secretStoreName, secretStoreKind = "ClusterSecretStore", data, refreshInterval = "1h", defaults: defs, } = props;
16
+ const chart = new Chart(mergeDefaults({
17
+ apiVersion: "v2",
18
+ name,
19
+ version: "0.1.0",
20
+ type: "application",
21
+ description: `External secret management for ${name}`,
22
+ }, defs?.chart));
23
+ const secretDataEntries = Object.entries(data).map(([key, remotePath]) => ({
24
+ secretKey: key,
25
+ remoteRef: {
26
+ key: remotePath,
27
+ },
28
+ }));
29
+ const valuesRes = new Values(mergeDefaults({
30
+ externalSecret: {
31
+ refreshInterval,
32
+ secretStore: {
33
+ name: secretStoreName,
34
+ kind: secretStoreKind,
35
+ },
36
+ },
37
+ }, defs?.values));
38
+ const externalSecret = new ExternalSecret(mergeDefaults({
39
+ apiVersion: "external-secrets.io/v1beta1",
40
+ kind: "ExternalSecret",
41
+ metadata: {
42
+ name: include(`${name}.fullname`),
43
+ labels: include(`${name}.labels`),
44
+ },
45
+ spec: {
46
+ refreshInterval: values.externalSecret.refreshInterval,
47
+ secretStoreRef: {
48
+ name: values.externalSecret.secretStore.name,
49
+ kind: values.externalSecret.secretStore.kind,
50
+ },
51
+ target: {
52
+ name: include(`${name}.fullname`),
53
+ creationPolicy: "Owner",
54
+ },
55
+ data: secretDataEntries,
56
+ },
57
+ }, defs?.externalSecret));
58
+ return {
59
+ chart,
60
+ values: valuesRes,
61
+ externalSecret,
62
+ };
63
+ }, "HelmExternalSecret");
@@ -0,0 +1,24 @@
1
+ /**
2
+ * HelmLibrary composite — Library chart (type: library, no templates).
3
+ *
4
+ * Produces a Helm library chart with only Chart.yaml and _helpers.tpl.
5
+ */
6
+ import { Composite, mergeDefaults } from "@intentius/chant";
7
+ import { Chart, Values } from "../resources.js";
8
+ export const HelmLibrary = Composite((props) => {
9
+ const { name, version = "0.1.0", description = `A Helm library chart for ${name}`, dependencies = [], helpers = ["name", "fullname", "chart", "labels", "selectorLabels"], defaults: defs, } = props;
10
+ const chartProps = {
11
+ apiVersion: "v2",
12
+ name,
13
+ version,
14
+ type: "library",
15
+ description,
16
+ };
17
+ if (dependencies.length > 0) {
18
+ chartProps.dependencies = dependencies;
19
+ }
20
+ const chart = new Chart(mergeDefaults(chartProps, defs?.chart));
21
+ // Store helpers list in a Values resource so it's a Declarable member
22
+ const helpersRes = new Values(mergeDefaults({ helpers }, defs?.helpers));
23
+ return { chart, helpers: helpersRes };
24
+ }, "HelmLibrary");