@intentius/chant-lexicon-helm 0.0.18 → 0.0.24

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 (55) hide show
  1. package/dist/integrity.json +5 -5
  2. package/dist/manifest.json +1 -1
  3. package/dist/skills/chant-helm.md +447 -0
  4. package/package.json +21 -3
  5. package/src/codegen/docs.test.ts +14 -0
  6. package/src/codegen/generate.test.ts +71 -0
  7. package/src/codegen/package.test.ts +36 -0
  8. package/src/composites/composites.test.ts +116 -110
  9. package/src/composites/helm-batch-job.ts +33 -19
  10. package/src/composites/helm-crd-lifecycle.ts +37 -24
  11. package/src/composites/helm-cron-job.ts +25 -13
  12. package/src/composites/helm-daemon-set.ts +26 -14
  13. package/src/composites/helm-external-secret.ts +21 -12
  14. package/src/composites/helm-library.ts +21 -7
  15. package/src/composites/helm-microservice.ts +46 -29
  16. package/src/composites/helm-monitored-service.ts +75 -51
  17. package/src/composites/helm-namespace-env.ts +80 -52
  18. package/src/composites/helm-secure-ingress.ts +66 -50
  19. package/src/composites/helm-stateful-service.ts +29 -16
  20. package/src/composites/helm-web-app.ts +37 -22
  21. package/src/composites/helm-worker.ts +34 -20
  22. package/src/import/roundtrip.test.ts +144 -0
  23. package/src/lint/post-synth/whm101.test.ts +69 -0
  24. package/src/lint/post-synth/whm102.test.ts +57 -0
  25. package/src/lint/post-synth/whm103.test.ts +58 -0
  26. package/src/lint/post-synth/whm104.test.ts +57 -0
  27. package/src/lint/post-synth/whm105.test.ts +41 -0
  28. package/src/lint/post-synth/whm201.test.ts +59 -0
  29. package/src/lint/post-synth/whm202.test.ts +62 -0
  30. package/src/lint/post-synth/whm203.test.ts +58 -0
  31. package/src/lint/post-synth/whm204.test.ts +56 -0
  32. package/src/lint/post-synth/whm301.test.ts +49 -0
  33. package/src/lint/post-synth/whm302.test.ts +58 -0
  34. package/src/lint/post-synth/whm401.test.ts +59 -0
  35. package/src/lint/post-synth/whm402.test.ts +58 -0
  36. package/src/lint/post-synth/whm403.test.ts +50 -0
  37. package/src/lint/post-synth/whm404.test.ts +50 -0
  38. package/src/lint/post-synth/whm405.test.ts +60 -0
  39. package/src/lint/post-synth/whm406.test.ts +43 -0
  40. package/src/lint/post-synth/whm407.test.ts +60 -0
  41. package/src/lint/post-synth/whm501.test.ts +70 -0
  42. package/src/lint/post-synth/whm502.test.ts +72 -0
  43. package/src/lint/rules/chart-metadata.test.ts +45 -0
  44. package/src/lint/rules/no-hardcoded-image.test.ts +41 -0
  45. package/src/lint/rules/values-no-secrets.test.ts +48 -0
  46. package/src/plugin.test.ts +3 -3
  47. package/src/plugin.ts +190 -19
  48. package/src/resources.ts +29 -0
  49. package/src/skills/chant-helm.md +447 -0
  50. package/dist/skills/chant-helm-create-chart.md +0 -211
  51. package/src/skills/create-chart.md +0 -211
  52. /package/dist/skills/{chant-helm-chart-patterns.md → chant-helm-patterns.md} +0 -0
  53. /package/dist/skills/{chant-helm-chart-security-patterns.md → chant-helm-security.md} +0 -0
  54. /package/src/skills/{chart-patterns.md → chant-helm-patterns.md} +0 -0
  55. /package/src/skills/{chart-security-patterns.md → chant-helm-security.md} +0 -0
@@ -5,6 +5,8 @@
5
5
  * Kubernetes API access (e.g., data migrations, cluster operations).
6
6
  */
7
7
 
8
+ import { Composite, mergeDefaults } from "@intentius/chant";
9
+ import { Chart, Values, Job, ServiceAccount, Role, RoleBinding } from "../resources";
8
10
  import { values, include, printf, toYaml, If, With } from "../intrinsics";
9
11
 
10
12
  export interface HelmBatchJobProps {
@@ -38,18 +40,27 @@ export interface HelmBatchJobProps {
38
40
  tolerations?: Array<Record<string, unknown>>;
39
41
  /** Chart appVersion. */
40
42
  appVersion?: string;
43
+ /** Per-member defaults. */
44
+ defaults?: {
45
+ chart?: Partial<Record<string, unknown>>;
46
+ values?: Partial<Record<string, unknown>>;
47
+ job?: Partial<Record<string, unknown>>;
48
+ serviceAccount?: Partial<Record<string, unknown>>;
49
+ role?: Partial<Record<string, unknown>>;
50
+ roleBinding?: Partial<Record<string, unknown>>;
51
+ };
41
52
  }
42
53
 
43
54
  export interface HelmBatchJobResult {
44
- chart: Record<string, unknown>;
45
- values: Record<string, unknown>;
46
- job: Record<string, unknown>;
47
- serviceAccount?: Record<string, unknown>;
48
- role?: Record<string, unknown>;
49
- roleBinding?: Record<string, unknown>;
55
+ chart: InstanceType<typeof Chart>;
56
+ values: InstanceType<typeof Values>;
57
+ job: InstanceType<typeof Job>;
58
+ serviceAccount?: InstanceType<typeof ServiceAccount>;
59
+ role?: InstanceType<typeof Role>;
60
+ roleBinding?: InstanceType<typeof RoleBinding>;
50
61
  }
51
62
 
52
- export function HelmBatchJob(props: HelmBatchJobProps): HelmBatchJobResult {
63
+ export const HelmBatchJob = Composite<HelmBatchJobProps>((props) => {
53
64
  const {
54
65
  name,
55
66
  imageRepository = "busybox",
@@ -61,16 +72,17 @@ export function HelmBatchJob(props: HelmBatchJobProps): HelmBatchJobResult {
61
72
  serviceAccount = true,
62
73
  rbac = false,
63
74
  appVersion = "1.0.0",
75
+ defaults: defs,
64
76
  } = props;
65
77
 
66
- const chart = {
78
+ const chart = new Chart(mergeDefaults({
67
79
  apiVersion: "v2",
68
80
  name,
69
81
  version: "0.1.0",
70
82
  appVersion,
71
83
  type: "application",
72
84
  description: `A Helm chart for ${name} batch job`,
73
- };
85
+ }, defs?.chart));
74
86
 
75
87
  const valuesObj: Record<string, unknown> = {
76
88
  image: {
@@ -113,6 +125,8 @@ export function HelmBatchJob(props: HelmBatchJobProps): HelmBatchJobResult {
113
125
  };
114
126
  }
115
127
 
128
+ const valuesRes = new Values(mergeDefaults(valuesObj, defs?.values));
129
+
116
130
  const containerSpec: Record<string, unknown> = {
117
131
  name,
118
132
  image: printf("%s:%s", values.image.repository, values.image.tag),
@@ -150,7 +164,7 @@ export function HelmBatchJob(props: HelmBatchJobProps): HelmBatchJobResult {
150
164
  jobSpec.ttlSecondsAfterFinished = values.job.ttlSecondsAfterFinished;
151
165
  }
152
166
 
153
- const job = {
167
+ const job = new Job(mergeDefaults({
154
168
  apiVersion: "batch/v1",
155
169
  kind: "Job",
156
170
  metadata: {
@@ -158,12 +172,12 @@ export function HelmBatchJob(props: HelmBatchJobProps): HelmBatchJobResult {
158
172
  labels: include(`${name}.labels`),
159
173
  },
160
174
  spec: jobSpec,
161
- };
175
+ }, defs?.job));
162
176
 
163
- const result: HelmBatchJobResult = { chart, values: valuesObj, job };
177
+ const result: Record<string, any> = { chart, values: valuesRes, job };
164
178
 
165
179
  if (serviceAccount) {
166
- result.serviceAccount = {
180
+ result.serviceAccount = new ServiceAccount(mergeDefaults({
167
181
  apiVersion: "v1",
168
182
  kind: "ServiceAccount",
169
183
  metadata: {
@@ -171,11 +185,11 @@ export function HelmBatchJob(props: HelmBatchJobProps): HelmBatchJobResult {
171
185
  labels: include(`${name}.labels`),
172
186
  annotations: toYaml(values.serviceAccount.annotations),
173
187
  },
174
- };
188
+ }, defs?.serviceAccount));
175
189
  }
176
190
 
177
191
  if (rbac) {
178
- result.role = {
192
+ result.role = new Role(mergeDefaults({
179
193
  apiVersion: "rbac.authorization.k8s.io/v1",
180
194
  kind: "Role",
181
195
  metadata: {
@@ -183,9 +197,9 @@ export function HelmBatchJob(props: HelmBatchJobProps): HelmBatchJobResult {
183
197
  labels: include(`${name}.labels`),
184
198
  },
185
199
  rules: toYaml(values.rbac.rules),
186
- };
200
+ }, defs?.role));
187
201
 
188
- result.roleBinding = {
202
+ result.roleBinding = new RoleBinding(mergeDefaults({
189
203
  apiVersion: "rbac.authorization.k8s.io/v1",
190
204
  kind: "RoleBinding",
191
205
  metadata: {
@@ -202,8 +216,8 @@ export function HelmBatchJob(props: HelmBatchJobProps): HelmBatchJobResult {
202
216
  name: include(`${name}.serviceAccountName`),
203
217
  namespace: values.namespace ?? undefined,
204
218
  }],
205
- };
219
+ }, defs?.roleBinding));
206
220
  }
207
221
 
208
222
  return result;
209
- }
223
+ }, "HelmBatchJob");
@@ -6,6 +6,8 @@
6
6
  * or deleted.
7
7
  */
8
8
 
9
+ import { Composite, mergeDefaults } from "@intentius/chant";
10
+ import { Chart, Values, Job, ConfigMap, ServiceAccount, ClusterRole, ClusterRoleBinding } from "../resources";
9
11
  import { values, include, printf } from "../intrinsics";
10
12
 
11
13
  export interface HelmCRDLifecycleProps {
@@ -19,38 +21,49 @@ export interface HelmCRDLifecycleProps {
19
21
  kubectlTag?: string;
20
22
  /** ServiceAccount name for RBAC. */
21
23
  serviceAccountName?: string;
24
+ /** Per-member defaults. */
25
+ defaults?: {
26
+ chart?: Partial<Record<string, unknown>>;
27
+ values?: Partial<Record<string, unknown>>;
28
+ crdInstallJob?: Partial<Record<string, unknown>>;
29
+ crdConfigMap?: Partial<Record<string, unknown>>;
30
+ serviceAccount?: Partial<Record<string, unknown>>;
31
+ clusterRole?: Partial<Record<string, unknown>>;
32
+ clusterRoleBinding?: Partial<Record<string, unknown>>;
33
+ };
22
34
  }
23
35
 
24
36
  export interface HelmCRDLifecycleResult {
25
- chart: Record<string, unknown>;
26
- values: Record<string, unknown>;
27
- crdInstallJob: Record<string, unknown>;
28
- crdConfigMap: Record<string, unknown>;
29
- serviceAccount: Record<string, unknown>;
30
- clusterRole: Record<string, unknown>;
31
- clusterRoleBinding: Record<string, unknown>;
37
+ chart: InstanceType<typeof Chart>;
38
+ values: InstanceType<typeof Values>;
39
+ crdInstallJob: InstanceType<typeof Job>;
40
+ crdConfigMap: InstanceType<typeof ConfigMap>;
41
+ serviceAccount: InstanceType<typeof ServiceAccount>;
42
+ clusterRole: InstanceType<typeof ClusterRole>;
43
+ clusterRoleBinding: InstanceType<typeof ClusterRoleBinding>;
32
44
  }
33
45
 
34
- export function HelmCRDLifecycle(props: HelmCRDLifecycleProps): HelmCRDLifecycleResult {
46
+ export const HelmCRDLifecycle = Composite<HelmCRDLifecycleProps>((props) => {
35
47
  const {
36
48
  name,
37
49
  crdContent,
38
50
  kubectlImage = "bitnami/kubectl",
39
51
  kubectlTag = "latest",
40
52
  serviceAccountName,
53
+ defaults: defs,
41
54
  } = props;
42
55
 
43
56
  const saName = serviceAccountName ?? `${name}-crd-installer`;
44
57
 
45
- const chart = {
58
+ const chart = new Chart(mergeDefaults({
46
59
  apiVersion: "v2",
47
60
  name,
48
61
  version: "0.1.0",
49
62
  type: "application",
50
63
  description: `CRD lifecycle management for ${name}`,
51
- };
64
+ }, defs?.chart));
52
65
 
53
- const valuesObj = {
66
+ const valuesRes = new Values(mergeDefaults({
54
67
  crdLifecycle: {
55
68
  enabled: true,
56
69
  kubectl: {
@@ -61,7 +74,7 @@ export function HelmCRDLifecycle(props: HelmCRDLifecycleProps): HelmCRDLifecycle
61
74
  name: saName,
62
75
  },
63
76
  },
64
- };
77
+ } as Record<string, unknown>, defs?.values));
65
78
 
66
79
  const hookAnnotations = {
67
80
  "helm.sh/hook": "pre-install,pre-upgrade",
@@ -69,7 +82,7 @@ export function HelmCRDLifecycle(props: HelmCRDLifecycleProps): HelmCRDLifecycle
69
82
  "helm.sh/hook-delete-policy": "before-hook-creation",
70
83
  };
71
84
 
72
- const crdConfigMap = {
85
+ const crdConfigMap = new ConfigMap(mergeDefaults({
73
86
  apiVersion: "v1",
74
87
  kind: "ConfigMap",
75
88
  metadata: {
@@ -80,9 +93,9 @@ export function HelmCRDLifecycle(props: HelmCRDLifecycleProps): HelmCRDLifecycle
80
93
  data: {
81
94
  "crds.yaml": crdContent,
82
95
  },
83
- };
96
+ }, defs?.crdConfigMap));
84
97
 
85
- const serviceAccount = {
98
+ const serviceAccount = new ServiceAccount(mergeDefaults({
86
99
  apiVersion: "v1",
87
100
  kind: "ServiceAccount",
88
101
  metadata: {
@@ -90,9 +103,9 @@ export function HelmCRDLifecycle(props: HelmCRDLifecycleProps): HelmCRDLifecycle
90
103
  labels: include(`${name}.labels`),
91
104
  annotations: hookAnnotations,
92
105
  },
93
- };
106
+ }, defs?.serviceAccount));
94
107
 
95
- const clusterRole = {
108
+ const clusterRole = new ClusterRole(mergeDefaults({
96
109
  apiVersion: "rbac.authorization.k8s.io/v1",
97
110
  kind: "ClusterRole",
98
111
  metadata: {
@@ -105,9 +118,9 @@ export function HelmCRDLifecycle(props: HelmCRDLifecycleProps): HelmCRDLifecycle
105
118
  resources: ["customresourcedefinitions"],
106
119
  verbs: ["get", "list", "create", "update", "patch"],
107
120
  }],
108
- };
121
+ }, defs?.clusterRole));
109
122
 
110
- const clusterRoleBinding = {
123
+ const clusterRoleBinding = new ClusterRoleBinding(mergeDefaults({
111
124
  apiVersion: "rbac.authorization.k8s.io/v1",
112
125
  kind: "ClusterRoleBinding",
113
126
  metadata: {
@@ -125,9 +138,9 @@ export function HelmCRDLifecycle(props: HelmCRDLifecycleProps): HelmCRDLifecycle
125
138
  name: values.crdLifecycle.serviceAccount.name,
126
139
  namespace: "{{ .Release.Namespace }}",
127
140
  }],
128
- };
141
+ }, defs?.clusterRoleBinding));
129
142
 
130
- const crdInstallJob = {
143
+ const crdInstallJob = new Job(mergeDefaults({
131
144
  apiVersion: "batch/v1",
132
145
  kind: "Job",
133
146
  metadata: {
@@ -170,15 +183,15 @@ export function HelmCRDLifecycle(props: HelmCRDLifecycleProps): HelmCRDLifecycle
170
183
  },
171
184
  },
172
185
  },
173
- };
186
+ }, defs?.crdInstallJob));
174
187
 
175
188
  return {
176
189
  chart,
177
- values: valuesObj,
190
+ values: valuesRes,
178
191
  crdInstallJob,
179
192
  crdConfigMap,
180
193
  serviceAccount,
181
194
  clusterRole,
182
195
  clusterRoleBinding,
183
196
  };
184
- }
197
+ }, "HelmCRDLifecycle");
@@ -4,6 +4,8 @@
4
4
  * Produces a Helm chart for scheduled batch workloads.
5
5
  */
6
6
 
7
+ import { Composite, mergeDefaults } from "@intentius/chant";
8
+ import { Chart, Values, CronJob, ServiceAccount } from "../resources";
7
9
  import { values, include, printf, toYaml, With } from "../intrinsics";
8
10
 
9
11
  export interface HelmCronJobProps {
@@ -41,16 +43,23 @@ export interface HelmCronJobProps {
41
43
  backoffLimit?: number;
42
44
  /** Include ServiceAccount. Default: false. */
43
45
  serviceAccount?: boolean;
46
+ /** Per-member defaults. */
47
+ defaults?: {
48
+ chart?: Partial<Record<string, unknown>>;
49
+ values?: Partial<Record<string, unknown>>;
50
+ cronJob?: Partial<Record<string, unknown>>;
51
+ serviceAccount?: Partial<Record<string, unknown>>;
52
+ };
44
53
  }
45
54
 
46
55
  export interface HelmCronJobResult {
47
- chart: Record<string, unknown>;
48
- values: Record<string, unknown>;
49
- cronJob: Record<string, unknown>;
50
- serviceAccount?: Record<string, unknown>;
56
+ chart: InstanceType<typeof Chart>;
57
+ values: InstanceType<typeof Values>;
58
+ cronJob: InstanceType<typeof CronJob>;
59
+ serviceAccount?: InstanceType<typeof ServiceAccount>;
51
60
  }
52
61
 
53
- export function HelmCronJob(props: HelmCronJobProps): HelmCronJobResult {
62
+ export const HelmCronJob = Composite<HelmCronJobProps>((props) => {
54
63
  const {
55
64
  name,
56
65
  imageRepository = "busybox",
@@ -59,16 +68,17 @@ export function HelmCronJob(props: HelmCronJobProps): HelmCronJobResult {
59
68
  restartPolicy = "OnFailure",
60
69
  appVersion = "1.0.0",
61
70
  serviceAccount = false,
71
+ defaults: defs,
62
72
  } = props;
63
73
 
64
- const chart = {
74
+ const chart = new Chart(mergeDefaults({
65
75
  apiVersion: "v2",
66
76
  name,
67
77
  version: "0.1.0",
68
78
  appVersion,
69
79
  type: "application",
70
80
  description: `A Helm chart for ${name} (cron job)`,
71
- };
81
+ }, defs?.chart));
72
82
 
73
83
  const valuesObj: Record<string, unknown> = {
74
84
  image: {
@@ -102,6 +112,8 @@ export function HelmCronJob(props: HelmCronJobProps): HelmCronJobResult {
102
112
  };
103
113
  }
104
114
 
115
+ const valuesRes = new Values(mergeDefaults(valuesObj, defs?.values));
116
+
105
117
  const containerSpec: Record<string, unknown> = {
106
118
  name,
107
119
  image: printf("%s:%s", values.image.repository, values.image.tag),
@@ -149,7 +161,7 @@ export function HelmCronJob(props: HelmCronJobProps): HelmCronJobResult {
149
161
  if (props.successfulJobsHistoryLimit !== undefined) cronJobSpec.successfulJobsHistoryLimit = values.successfulJobsHistoryLimit;
150
162
  if (props.failedJobsHistoryLimit !== undefined) cronJobSpec.failedJobsHistoryLimit = values.failedJobsHistoryLimit;
151
163
 
152
- const cronJob = {
164
+ const cronJob = new CronJob(mergeDefaults({
153
165
  apiVersion: "batch/v1",
154
166
  kind: "CronJob",
155
167
  metadata: {
@@ -157,12 +169,12 @@ export function HelmCronJob(props: HelmCronJobProps): HelmCronJobResult {
157
169
  labels: include(`${name}.labels`),
158
170
  },
159
171
  spec: cronJobSpec,
160
- };
172
+ }, defs?.cronJob));
161
173
 
162
- const result: HelmCronJobResult = { chart, values: valuesObj, cronJob };
174
+ const result: Record<string, any> = { chart, values: valuesRes, cronJob };
163
175
 
164
176
  if (serviceAccount) {
165
- result.serviceAccount = {
177
+ result.serviceAccount = new ServiceAccount(mergeDefaults({
166
178
  apiVersion: "v1",
167
179
  kind: "ServiceAccount",
168
180
  metadata: {
@@ -170,8 +182,8 @@ export function HelmCronJob(props: HelmCronJobProps): HelmCronJobResult {
170
182
  labels: include(`${name}.labels`),
171
183
  annotations: toYaml(values.serviceAccount.annotations),
172
184
  },
173
- };
185
+ }, defs?.serviceAccount));
174
186
  }
175
187
 
176
188
  return result;
177
- }
189
+ }, "HelmCronJob");
@@ -5,6 +5,8 @@
5
5
  * infrastructure that needs to run on every node.
6
6
  */
7
7
 
8
+ import { Composite, mergeDefaults } from "@intentius/chant";
9
+ import { Chart, Values, DaemonSet, ServiceAccount } from "../resources";
8
10
  import { values, include, printf, toYaml, If, With } from "../intrinsics";
9
11
 
10
12
  export interface HelmDaemonSetProps {
@@ -22,16 +24,23 @@ export interface HelmDaemonSetProps {
22
24
  serviceAccount?: boolean;
23
25
  /** Chart appVersion. */
24
26
  appVersion?: string;
27
+ /** Per-member defaults. */
28
+ defaults?: {
29
+ chart?: Partial<Record<string, unknown>>;
30
+ values?: Partial<Record<string, unknown>>;
31
+ daemonSet?: Partial<Record<string, unknown>>;
32
+ serviceAccount?: Partial<Record<string, unknown>>;
33
+ };
25
34
  }
26
35
 
27
36
  export interface HelmDaemonSetResult {
28
- chart: Record<string, unknown>;
29
- values: Record<string, unknown>;
30
- daemonSet: Record<string, unknown>;
31
- serviceAccount?: Record<string, unknown>;
37
+ chart: InstanceType<typeof Chart>;
38
+ values: InstanceType<typeof Values>;
39
+ daemonSet: InstanceType<typeof DaemonSet>;
40
+ serviceAccount?: InstanceType<typeof ServiceAccount>;
32
41
  }
33
42
 
34
- export function HelmDaemonSet(props: HelmDaemonSetProps): HelmDaemonSetResult {
43
+ export const HelmDaemonSet = Composite<HelmDaemonSetProps>((props) => {
35
44
  const {
36
45
  name,
37
46
  imageRepository = "fluent/fluent-bit",
@@ -40,16 +49,17 @@ export function HelmDaemonSet(props: HelmDaemonSetProps): HelmDaemonSetResult {
40
49
  hostPaths = [],
41
50
  serviceAccount = true,
42
51
  appVersion = "1.0.0",
52
+ defaults: defs,
43
53
  } = props;
44
54
 
45
- const chart = {
55
+ const chart = new Chart(mergeDefaults({
46
56
  apiVersion: "v2",
47
57
  name,
48
58
  version: "0.1.0",
49
59
  appVersion,
50
60
  type: "application",
51
61
  description: `A Helm chart for ${name} DaemonSet`,
52
- };
62
+ }, defs?.chart));
53
63
 
54
64
  const valuesObj: Record<string, unknown> = {
55
65
  image: {
@@ -79,6 +89,8 @@ export function HelmDaemonSet(props: HelmDaemonSetProps): HelmDaemonSetResult {
79
89
  };
80
90
  }
81
91
 
92
+ const valuesRes = new Values(mergeDefaults(valuesObj, defs?.values));
93
+
82
94
  const containerSpec: Record<string, unknown> = {
83
95
  name,
84
96
  image: printf("%s:%s", values.image.repository, values.image.tag),
@@ -126,7 +138,7 @@ export function HelmDaemonSet(props: HelmDaemonSetProps): HelmDaemonSetResult {
126
138
  }));
127
139
  }
128
140
 
129
- const daemonSet = {
141
+ const daemonSet = new DaemonSet(mergeDefaults({
130
142
  apiVersion: "apps/v1",
131
143
  kind: "DaemonSet",
132
144
  metadata: {
@@ -145,16 +157,16 @@ export function HelmDaemonSet(props: HelmDaemonSetProps): HelmDaemonSetResult {
145
157
  spec: podSpec,
146
158
  },
147
159
  },
148
- };
160
+ }, defs?.daemonSet));
149
161
 
150
- const result: HelmDaemonSetResult = {
162
+ const result: Record<string, any> = {
151
163
  chart,
152
- values: valuesObj,
164
+ values: valuesRes,
153
165
  daemonSet,
154
166
  };
155
167
 
156
168
  if (serviceAccount) {
157
- result.serviceAccount = {
169
+ result.serviceAccount = new ServiceAccount(mergeDefaults({
158
170
  apiVersion: "v1",
159
171
  kind: "ServiceAccount",
160
172
  metadata: {
@@ -162,8 +174,8 @@ export function HelmDaemonSet(props: HelmDaemonSetProps): HelmDaemonSetResult {
162
174
  labels: include(`${name}.labels`),
163
175
  annotations: toYaml(values.serviceAccount.annotations),
164
176
  },
165
- };
177
+ }, defs?.serviceAccount));
166
178
  }
167
179
 
168
180
  return result;
169
- }
181
+ }, "HelmDaemonSet");
@@ -9,6 +9,8 @@
9
9
  * it like any other K8s resource.
10
10
  */
11
11
 
12
+ import { Composite, mergeDefaults } from "@intentius/chant";
13
+ import { Chart, Values, ExternalSecret } from "../resources";
12
14
  import { values, include } from "../intrinsics";
13
15
 
14
16
  export interface HelmExternalSecretProps {
@@ -22,30 +24,37 @@ export interface HelmExternalSecretProps {
22
24
  data: Record<string, string>;
23
25
  /** Refresh interval. Default: "1h". */
24
26
  refreshInterval?: string;
27
+ /** Per-member defaults. */
28
+ defaults?: {
29
+ chart?: Partial<Record<string, unknown>>;
30
+ values?: Partial<Record<string, unknown>>;
31
+ externalSecret?: Partial<Record<string, unknown>>;
32
+ };
25
33
  }
26
34
 
27
35
  export interface HelmExternalSecretResult {
28
- chart: Record<string, unknown>;
29
- values: Record<string, unknown>;
30
- externalSecret: Record<string, unknown>;
36
+ chart: InstanceType<typeof Chart>;
37
+ values: InstanceType<typeof Values>;
38
+ externalSecret: InstanceType<typeof ExternalSecret>;
31
39
  }
32
40
 
33
- export function HelmExternalSecret(props: HelmExternalSecretProps): HelmExternalSecretResult {
41
+ export const HelmExternalSecret = Composite<HelmExternalSecretProps>((props) => {
34
42
  const {
35
43
  name,
36
44
  secretStoreName,
37
45
  secretStoreKind = "ClusterSecretStore",
38
46
  data,
39
47
  refreshInterval = "1h",
48
+ defaults: defs,
40
49
  } = props;
41
50
 
42
- const chart = {
51
+ const chart = new Chart(mergeDefaults({
43
52
  apiVersion: "v2",
44
53
  name,
45
54
  version: "0.1.0",
46
55
  type: "application",
47
56
  description: `External secret management for ${name}`,
48
- };
57
+ }, defs?.chart));
49
58
 
50
59
  const secretDataEntries = Object.entries(data).map(([key, remotePath]) => ({
51
60
  secretKey: key,
@@ -54,7 +63,7 @@ export function HelmExternalSecret(props: HelmExternalSecretProps): HelmExternal
54
63
  },
55
64
  }));
56
65
 
57
- const valuesObj = {
66
+ const valuesRes = new Values(mergeDefaults({
58
67
  externalSecret: {
59
68
  refreshInterval,
60
69
  secretStore: {
@@ -62,9 +71,9 @@ export function HelmExternalSecret(props: HelmExternalSecretProps): HelmExternal
62
71
  kind: secretStoreKind,
63
72
  },
64
73
  },
65
- };
74
+ } as Record<string, unknown>, defs?.values));
66
75
 
67
- const externalSecret = {
76
+ const externalSecret = new ExternalSecret(mergeDefaults({
68
77
  apiVersion: "external-secrets.io/v1beta1",
69
78
  kind: "ExternalSecret",
70
79
  metadata: {
@@ -83,11 +92,11 @@ export function HelmExternalSecret(props: HelmExternalSecretProps): HelmExternal
83
92
  },
84
93
  data: secretDataEntries,
85
94
  },
86
- };
95
+ }, defs?.externalSecret));
87
96
 
88
97
  return {
89
98
  chart,
90
- values: valuesObj,
99
+ values: valuesRes,
91
100
  externalSecret,
92
101
  };
93
- }
102
+ }, "HelmExternalSecret");
@@ -4,6 +4,9 @@
4
4
  * Produces a Helm library chart with only Chart.yaml and _helpers.tpl.
5
5
  */
6
6
 
7
+ import { Composite, mergeDefaults } from "@intentius/chant";
8
+ import { Chart, Values } from "../resources";
9
+
7
10
  export interface HelmLibraryProps {
8
11
  /** Chart name. */
9
12
  name: string;
@@ -19,23 +22,29 @@ export interface HelmLibraryProps {
19
22
  }>;
20
23
  /** Helper template names to generate. */
21
24
  helpers?: string[];
25
+ /** Per-member defaults. */
26
+ defaults?: {
27
+ chart?: Partial<Record<string, unknown>>;
28
+ helpers?: Partial<Record<string, unknown>>;
29
+ };
22
30
  }
23
31
 
24
32
  export interface HelmLibraryResult {
25
- chart: Record<string, unknown>;
26
- helpers: string[];
33
+ chart: InstanceType<typeof Chart>;
34
+ helpers: InstanceType<typeof Values>;
27
35
  }
28
36
 
29
- export function HelmLibrary(props: HelmLibraryProps): HelmLibraryResult {
37
+ export const HelmLibrary = Composite<HelmLibraryProps>((props) => {
30
38
  const {
31
39
  name,
32
40
  version = "0.1.0",
33
41
  description = `A Helm library chart for ${name}`,
34
42
  dependencies = [],
35
43
  helpers = ["name", "fullname", "chart", "labels", "selectorLabels"],
44
+ defaults: defs,
36
45
  } = props;
37
46
 
38
- const chart: Record<string, unknown> = {
47
+ const chartProps: Record<string, unknown> = {
39
48
  apiVersion: "v2",
40
49
  name,
41
50
  version,
@@ -44,8 +53,13 @@ export function HelmLibrary(props: HelmLibraryProps): HelmLibraryResult {
44
53
  };
45
54
 
46
55
  if (dependencies.length > 0) {
47
- chart.dependencies = dependencies;
56
+ chartProps.dependencies = dependencies;
48
57
  }
49
58
 
50
- return { chart, helpers };
51
- }
59
+ const chart = new Chart(mergeDefaults(chartProps, defs?.chart));
60
+
61
+ // Store helpers list in a Values resource so it's a Declarable member
62
+ const helpersRes = new Values(mergeDefaults({ helpers }, defs?.helpers));
63
+
64
+ return { chart, helpers: helpersRes };
65
+ }, "HelmLibrary");