timonel 2.3.0 → 2.5.0

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 (81) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +5 -1
  3. package/SECURITY.md +3 -3
  4. package/dist/cli.js +33 -38
  5. package/dist/cli.js.map +1 -1
  6. package/dist/index.d.ts +9 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +10 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/lib/{HelmChartWriter.d.ts → helmChartWriter.d.ts} +1 -1
  11. package/dist/lib/{HelmChartWriter.d.ts.map → helmChartWriter.d.ts.map} +1 -1
  12. package/dist/lib/{HelmChartWriter.js → helmChartWriter.js} +1 -1
  13. package/dist/lib/{HelmChartWriter.js.map → helmChartWriter.js.map} +1 -1
  14. package/dist/lib/resources/autoscaling/autoscalingResources.d.ts +26 -0
  15. package/dist/lib/resources/autoscaling/autoscalingResources.d.ts.map +1 -0
  16. package/dist/lib/resources/autoscaling/autoscalingResources.js +35 -0
  17. package/dist/lib/resources/autoscaling/autoscalingResources.js.map +1 -0
  18. package/dist/lib/resources/baseResourceProvider.d.ts +47 -0
  19. package/dist/lib/resources/baseResourceProvider.d.ts.map +1 -0
  20. package/dist/lib/resources/baseResourceProvider.js +83 -0
  21. package/dist/lib/resources/baseResourceProvider.js.map +1 -0
  22. package/dist/lib/resources/cloud/aws/awsResources.d.ts +165 -0
  23. package/dist/lib/resources/cloud/aws/awsResources.d.ts.map +1 -0
  24. package/dist/lib/resources/cloud/aws/awsResources.js +187 -0
  25. package/dist/lib/resources/cloud/aws/awsResources.js.map +1 -0
  26. package/dist/lib/resources/cloud/azure/azureResources.d.ts +169 -0
  27. package/dist/lib/resources/cloud/azure/azureResources.d.ts.map +1 -0
  28. package/dist/lib/resources/cloud/azure/azureResources.js +218 -0
  29. package/dist/lib/resources/cloud/azure/azureResources.js.map +1 -0
  30. package/dist/lib/resources/cloud/gcp/gcpResources.d.ts +133 -0
  31. package/dist/lib/resources/cloud/gcp/gcpResources.d.ts.map +1 -0
  32. package/dist/lib/resources/cloud/gcp/gcpResources.js +162 -0
  33. package/dist/lib/resources/cloud/gcp/gcpResources.js.map +1 -0
  34. package/dist/lib/resources/core/coreResources.d.ts +766 -0
  35. package/dist/lib/resources/core/coreResources.d.ts.map +1 -0
  36. package/dist/lib/resources/core/coreResources.js +1043 -0
  37. package/dist/lib/resources/core/coreResources.js.map +1 -0
  38. package/dist/lib/resources/core/storageResources.d.ts +133 -0
  39. package/dist/lib/resources/core/storageResources.d.ts.map +1 -0
  40. package/dist/lib/resources/core/storageResources.js +120 -0
  41. package/dist/lib/resources/core/storageResources.js.map +1 -0
  42. package/dist/lib/resources/validation/validationResources.d.ts +26 -0
  43. package/dist/lib/resources/validation/validationResources.d.ts.map +1 -0
  44. package/dist/lib/resources/validation/validationResources.js +33 -0
  45. package/dist/lib/resources/validation/validationResources.js.map +1 -0
  46. package/dist/lib/rutter.d.ts +567 -0
  47. package/dist/lib/rutter.d.ts.map +1 -0
  48. package/dist/lib/rutter.js +694 -0
  49. package/dist/lib/rutter.js.map +1 -0
  50. package/dist/lib/security.d.ts +21 -0
  51. package/dist/lib/security.d.ts.map +1 -1
  52. package/dist/lib/security.js +21 -0
  53. package/dist/lib/security.js.map +1 -1
  54. package/dist/lib/umbrella.d.ts +22 -2
  55. package/dist/lib/umbrella.d.ts.map +1 -1
  56. package/dist/lib/umbrella.js +21 -1
  57. package/dist/lib/umbrella.js.map +1 -1
  58. package/dist/lib/umbrellaRutter.d.ts +97 -0
  59. package/dist/lib/umbrellaRutter.d.ts.map +1 -0
  60. package/dist/lib/{UmbrellaRutter.js → umbrellaRutter.js} +44 -1
  61. package/dist/lib/umbrellaRutter.js.map +1 -0
  62. package/dist/lib/utils/helmHelpers.d.ts +58 -0
  63. package/dist/lib/utils/helmHelpers.d.ts.map +1 -0
  64. package/dist/lib/utils/helmHelpers.js +155 -0
  65. package/dist/lib/utils/helmHelpers.js.map +1 -0
  66. package/dist/lib/utils/podTemplates.d.ts +192 -0
  67. package/dist/lib/utils/podTemplates.d.ts.map +1 -0
  68. package/dist/lib/utils/podTemplates.js +331 -0
  69. package/dist/lib/utils/podTemplates.js.map +1 -0
  70. package/dist/lib/utils/resourceNaming.d.ts +57 -0
  71. package/dist/lib/utils/resourceNaming.d.ts.map +1 -0
  72. package/dist/lib/utils/resourceNaming.js +82 -0
  73. package/dist/lib/utils/resourceNaming.js.map +1 -0
  74. package/package.json +2 -1
  75. package/dist/lib/Rutter.d.ts +0 -2688
  76. package/dist/lib/Rutter.d.ts.map +0 -1
  77. package/dist/lib/Rutter.js +0 -2863
  78. package/dist/lib/Rutter.js.map +0 -1
  79. package/dist/lib/UmbrellaRutter.d.ts +0 -34
  80. package/dist/lib/UmbrellaRutter.d.ts.map +0 -1
  81. package/dist/lib/UmbrellaRutter.js.map +0 -1
@@ -0,0 +1,1043 @@
1
+ import { ApiObject } from 'cdk8s';
2
+ import { BaseResourceProvider } from '../baseResourceProvider.js';
3
+ import { include } from '../../helm.js';
4
+ /**
5
+ * Core Kubernetes resources provider
6
+ * Handles fundamental Kubernetes resources like Deployments, Services, ConfigMaps, etc.
7
+ *
8
+ * @since 2.4.0
9
+ */
10
+ export class CoreResources extends BaseResourceProvider {
11
+ /**
12
+ * Creates a Deployment resource
13
+ * @param spec - Deployment specification
14
+ * @returns Created Deployment ApiObject
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * coreResources.addDeployment({
19
+ * name: 'web-app',
20
+ * image: 'nginx:1.21',
21
+ * replicas: 3,
22
+ * containerPort: 80
23
+ * });
24
+ * ```
25
+ *
26
+ * @since 2.4.0
27
+ */
28
+ addDeployment(spec) {
29
+ const matchLabels = spec.matchLabels ?? {
30
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
31
+ };
32
+ const labels = {
33
+ ...matchLabels,
34
+ ...spec.labels,
35
+ };
36
+ const containers = [
37
+ {
38
+ name: spec.name,
39
+ image: spec.image,
40
+ ...(spec.containerPort ? { ports: [{ containerPort: spec.containerPort }] } : {}),
41
+ ...(spec.env ? { env: spec.env } : {}),
42
+ ...(spec.resources ? { resources: spec.resources } : {}),
43
+ ...(spec.volumeMounts ? { volumeMounts: spec.volumeMounts } : {}),
44
+ ...(spec.securityContext ? { securityContext: spec.securityContext } : {}),
45
+ },
46
+ ];
47
+ const deploymentSpec = {
48
+ replicas: spec.replicas ?? 1,
49
+ selector: { matchLabels },
50
+ template: {
51
+ metadata: { labels },
52
+ spec: {
53
+ containers,
54
+ ...(spec.volumes ? { volumes: spec.volumes } : {}),
55
+ ...(spec.serviceAccountName ? { serviceAccountName: spec.serviceAccountName } : {}),
56
+ ...(spec.securityContext ? { securityContext: spec.securityContext } : {}),
57
+ ...(spec.nodeSelector ? { nodeSelector: spec.nodeSelector } : {}),
58
+ ...(spec.tolerations ? { tolerations: spec.tolerations } : {}),
59
+ ...(spec.affinity ? { affinity: spec.affinity } : {}),
60
+ },
61
+ },
62
+ };
63
+ return new ApiObject(this.chart, spec.name, {
64
+ apiVersion: CoreResources.APPS_API_VERSION,
65
+ kind: 'Deployment',
66
+ metadata: {
67
+ name: spec.name,
68
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
69
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
70
+ ? { annotations: spec.annotations }
71
+ : {}),
72
+ },
73
+ spec: deploymentSpec,
74
+ });
75
+ }
76
+ /**
77
+ * Creates a Service resource
78
+ * @param spec - Service specification
79
+ * @returns Created Service ApiObject
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * coreResources.addService({
84
+ * name: 'web-service',
85
+ * port: 80,
86
+ * targetPort: 8080,
87
+ * type: 'ClusterIP'
88
+ * });
89
+ * ```
90
+ *
91
+ * @since 2.4.0
92
+ */
93
+ addService(spec) {
94
+ const selector = spec.selector ?? {
95
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
96
+ };
97
+ const ports = spec.ports ?? [
98
+ {
99
+ port: spec.port,
100
+ targetPort: spec.targetPort ?? spec.port,
101
+ ...(spec.protocol ? { protocol: spec.protocol } : {}),
102
+ ...(spec.name ? { name: spec.name } : {}),
103
+ },
104
+ ];
105
+ const serviceSpec = {
106
+ selector,
107
+ ports,
108
+ ...(spec.type ? { type: spec.type } : {}),
109
+ ...(spec.clusterIP ? { clusterIP: spec.clusterIP } : {}),
110
+ ...(spec.externalIPs ? { externalIPs: spec.externalIPs } : {}),
111
+ ...(spec.loadBalancerIP ? { loadBalancerIP: spec.loadBalancerIP } : {}),
112
+ ...(spec.sessionAffinity ? { sessionAffinity: spec.sessionAffinity } : {}),
113
+ };
114
+ return new ApiObject(this.chart, spec.name, {
115
+ apiVersion: CoreResources.CORE_API_VERSION,
116
+ kind: 'Service',
117
+ metadata: {
118
+ name: spec.name,
119
+ ...(spec.labels ? { labels: spec.labels } : {}),
120
+ ...(spec.annotations ? { annotations: spec.annotations } : {}),
121
+ },
122
+ spec: serviceSpec,
123
+ });
124
+ }
125
+ /**
126
+ * Creates a ConfigMap resource
127
+ * @param spec - ConfigMap specification
128
+ * @returns Created ConfigMap ApiObject
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * coreResources.addConfigMap({
133
+ * name: 'app-config',
134
+ * data: {
135
+ * 'config.yaml': 'key: value',
136
+ * 'app.properties': 'debug=true'
137
+ * }
138
+ * });
139
+ * ```
140
+ *
141
+ * @since 2.4.0
142
+ */
143
+ addConfigMap(spec) {
144
+ return new ApiObject(this.chart, spec.name, {
145
+ apiVersion: CoreResources.CORE_API_VERSION,
146
+ kind: 'ConfigMap',
147
+ metadata: {
148
+ name: spec.name,
149
+ ...(spec.labels ? { labels: spec.labels } : {}),
150
+ ...(spec.annotations ? { annotations: spec.annotations } : {}),
151
+ },
152
+ ...(spec.data ? { data: spec.data } : {}),
153
+ ...(spec.binaryData ? { binaryData: spec.binaryData } : {}),
154
+ });
155
+ }
156
+ /**
157
+ * Creates a Secret resource
158
+ * @param spec - Secret specification
159
+ * @returns Created Secret ApiObject
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * coreResources.addSecret({
164
+ * name: 'app-secrets',
165
+ * type: 'Opaque',
166
+ * data: {
167
+ * username: 'YWRtaW4=',
168
+ * password: 'MWYyZDFlMmU2N2Rm'
169
+ * }
170
+ * });
171
+ * ```
172
+ *
173
+ * @since 2.4.0
174
+ */
175
+ addSecret(spec) {
176
+ return new ApiObject(this.chart, spec.name, {
177
+ apiVersion: CoreResources.CORE_API_VERSION,
178
+ kind: 'Secret',
179
+ metadata: {
180
+ name: spec.name,
181
+ ...(spec.labels ? { labels: spec.labels } : {}),
182
+ ...(spec.annotations ? { annotations: spec.annotations } : {}),
183
+ },
184
+ type: spec.type ?? 'Opaque',
185
+ ...(spec.data ? { data: spec.data } : {}),
186
+ ...(spec.stringData ? { stringData: spec.stringData } : {}),
187
+ });
188
+ }
189
+ /**
190
+ * Creates a ServiceAccount resource
191
+ * @param spec - ServiceAccount specification
192
+ * @returns Created ServiceAccount ApiObject
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * coreResources.addServiceAccount({
197
+ * name: 'app-service-account',
198
+ * automountServiceAccountToken: false
199
+ * });
200
+ * ```
201
+ *
202
+ * @since 2.4.0
203
+ */
204
+ addServiceAccount(spec) {
205
+ return new ApiObject(this.chart, spec.name, {
206
+ apiVersion: CoreResources.CORE_API_VERSION,
207
+ kind: 'ServiceAccount',
208
+ metadata: {
209
+ name: spec.name,
210
+ ...(spec.labels ? { labels: spec.labels } : {}),
211
+ ...(spec.annotations ? { annotations: spec.annotations } : {}),
212
+ },
213
+ ...(spec.automountServiceAccountToken !== undefined
214
+ ? { automountServiceAccountToken: spec.automountServiceAccountToken }
215
+ : {}),
216
+ ...(spec.imagePullSecrets ? { imagePullSecrets: spec.imagePullSecrets } : {}),
217
+ ...(spec.secrets ? { secrets: spec.secrets } : {}),
218
+ });
219
+ }
220
+ /**
221
+ * Creates a DaemonSet resource
222
+ * @param spec - DaemonSet specification
223
+ * @returns Created DaemonSet ApiObject
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * coreResources.addDaemonSet({
228
+ * name: 'log-collector',
229
+ * image: 'fluentd:v1.14',
230
+ * containerPort: 24224,
231
+ * hostNetwork: true
232
+ * });
233
+ * ```
234
+ *
235
+ * @since 2.4.0
236
+ */
237
+ addDaemonSet(spec) {
238
+ const matchLabels = spec.matchLabels ?? {
239
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
240
+ };
241
+ const daemonSetSpec = this.buildDaemonSetSpec(spec, matchLabels);
242
+ const labels = {
243
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
244
+ ...(spec.labels || {}),
245
+ };
246
+ return new ApiObject(this.chart, spec.name, {
247
+ apiVersion: CoreResources.APPS_API_VERSION,
248
+ kind: 'DaemonSet',
249
+ metadata: {
250
+ name: spec.name,
251
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
252
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
253
+ ? { annotations: spec.annotations }
254
+ : {}),
255
+ },
256
+ spec: daemonSetSpec,
257
+ });
258
+ }
259
+ /**
260
+ * Builds DaemonSet specification object
261
+ * @private
262
+ */
263
+ buildDaemonSetSpec(spec, matchLabels) {
264
+ const containers = this.buildDaemonSetContainers(spec);
265
+ const podSpec = this.buildDaemonSetPodSpec(spec, containers);
266
+ return {
267
+ selector: { matchLabels },
268
+ template: {
269
+ metadata: {
270
+ labels: { ...matchLabels, ...(spec.labels || {}) },
271
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
272
+ ? { annotations: spec.annotations }
273
+ : {}),
274
+ },
275
+ spec: podSpec,
276
+ },
277
+ ...(spec.updateStrategy && { updateStrategy: spec.updateStrategy }),
278
+ };
279
+ }
280
+ /**
281
+ * Builds container specification for DaemonSet
282
+ * @private
283
+ */
284
+ buildDaemonSetContainers(spec) {
285
+ const container = {
286
+ name: spec.name,
287
+ image: spec.image,
288
+ };
289
+ if (spec.containerPort) {
290
+ container['ports'] = [{ containerPort: spec.containerPort }];
291
+ }
292
+ if (spec.env) {
293
+ container['env'] = spec.env;
294
+ }
295
+ if (spec.resources) {
296
+ container['resources'] = spec.resources;
297
+ }
298
+ if (spec.volumeMounts) {
299
+ container['volumeMounts'] = spec.volumeMounts;
300
+ }
301
+ if (spec.securityContext) {
302
+ container['securityContext'] = spec.securityContext;
303
+ }
304
+ return [container];
305
+ }
306
+ /**
307
+ * Builds pod specification for DaemonSet
308
+ * @private
309
+ */
310
+ buildDaemonSetPodSpec(spec, containers) {
311
+ const podSpec = {
312
+ containers,
313
+ };
314
+ if (spec.serviceAccountName) {
315
+ podSpec['serviceAccountName'] = spec.serviceAccountName;
316
+ }
317
+ if (spec.nodeSelector) {
318
+ podSpec['nodeSelector'] = spec.nodeSelector;
319
+ }
320
+ if (spec.tolerations) {
321
+ podSpec['tolerations'] = spec.tolerations;
322
+ }
323
+ if (spec.affinity) {
324
+ podSpec['affinity'] = spec.affinity;
325
+ }
326
+ if (spec.volumes) {
327
+ podSpec['volumes'] = spec.volumes;
328
+ }
329
+ if (spec.hostNetwork) {
330
+ podSpec['hostNetwork'] = spec.hostNetwork;
331
+ }
332
+ if (spec.hostPID) {
333
+ podSpec['hostPID'] = spec.hostPID;
334
+ }
335
+ if (spec.dnsPolicy) {
336
+ podSpec['dnsPolicy'] = spec.dnsPolicy;
337
+ }
338
+ if (spec.priorityClassName) {
339
+ podSpec['priorityClassName'] = spec.priorityClassName;
340
+ }
341
+ return podSpec;
342
+ }
343
+ /**
344
+ * Creates a StatefulSet resource
345
+ * @param spec - StatefulSet specification
346
+ * @returns Created StatefulSet ApiObject
347
+ *
348
+ * @example
349
+ * ```typescript
350
+ * coreResources.addStatefulSet({
351
+ * name: 'database',
352
+ * image: 'postgres:13',
353
+ * replicas: 3,
354
+ * containerPort: 5432,
355
+ * serviceName: 'database-headless'
356
+ * });
357
+ * ```
358
+ *
359
+ * @since 2.4.0
360
+ */
361
+ addStatefulSet(spec) {
362
+ const matchLabels = spec.matchLabels ?? {
363
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
364
+ };
365
+ const statefulSetSpec = this.buildStatefulSetSpec(spec, matchLabels);
366
+ const labels = {
367
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
368
+ ...(spec.labels || {}),
369
+ };
370
+ return new ApiObject(this.chart, spec.name, {
371
+ apiVersion: CoreResources.APPS_API_VERSION,
372
+ kind: 'StatefulSet',
373
+ metadata: {
374
+ name: spec.name,
375
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
376
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
377
+ ? { annotations: spec.annotations }
378
+ : {}),
379
+ },
380
+ spec: statefulSetSpec,
381
+ });
382
+ }
383
+ /**
384
+ * Builds StatefulSet specification object
385
+ * @private
386
+ */
387
+ buildStatefulSetSpec(spec, matchLabels) {
388
+ const containers = this.buildStatefulSetContainers(spec);
389
+ const podSpec = this.buildStatefulSetPodSpec(spec, containers);
390
+ const statefulSetSpec = {
391
+ replicas: spec.replicas ?? 1,
392
+ selector: { matchLabels },
393
+ serviceName: spec.serviceName,
394
+ template: {
395
+ metadata: {
396
+ labels: { ...matchLabels, ...(spec.labels || {}) },
397
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
398
+ ? { annotations: spec.annotations }
399
+ : {}),
400
+ },
401
+ spec: podSpec,
402
+ },
403
+ };
404
+ if (spec.volumeClaimTemplates) {
405
+ statefulSetSpec['volumeClaimTemplates'] = spec.volumeClaimTemplates;
406
+ }
407
+ if (spec.updateStrategy) {
408
+ statefulSetSpec['updateStrategy'] = spec.updateStrategy;
409
+ }
410
+ if (spec.podManagementPolicy) {
411
+ statefulSetSpec['podManagementPolicy'] = spec.podManagementPolicy;
412
+ }
413
+ if (spec.revisionHistoryLimit !== undefined) {
414
+ statefulSetSpec['revisionHistoryLimit'] = spec.revisionHistoryLimit;
415
+ }
416
+ return statefulSetSpec;
417
+ }
418
+ /**
419
+ * Builds container specification for StatefulSet
420
+ * @private
421
+ */
422
+ buildStatefulSetContainers(spec) {
423
+ const container = {
424
+ name: spec.name,
425
+ image: spec.image,
426
+ };
427
+ if (spec.containerPort) {
428
+ container['ports'] = [{ containerPort: spec.containerPort }];
429
+ }
430
+ if (spec.env) {
431
+ container['env'] = spec.env;
432
+ }
433
+ if (spec.resources) {
434
+ container['resources'] = spec.resources;
435
+ }
436
+ if (spec.volumeMounts) {
437
+ container['volumeMounts'] = spec.volumeMounts;
438
+ }
439
+ if (spec.securityContext) {
440
+ container['securityContext'] = spec.securityContext;
441
+ }
442
+ if (spec.livenessProbe) {
443
+ container['livenessProbe'] = spec.livenessProbe;
444
+ }
445
+ if (spec.readinessProbe) {
446
+ container['readinessProbe'] = spec.readinessProbe;
447
+ }
448
+ return [container];
449
+ }
450
+ /**
451
+ * Builds pod specification for StatefulSet
452
+ * @private
453
+ */
454
+ buildStatefulSetPodSpec(spec, containers) {
455
+ const podSpec = {
456
+ containers,
457
+ };
458
+ if (spec.serviceAccountName) {
459
+ podSpec['serviceAccountName'] = spec.serviceAccountName;
460
+ }
461
+ if (spec.nodeSelector) {
462
+ podSpec['nodeSelector'] = spec.nodeSelector;
463
+ }
464
+ if (spec.tolerations) {
465
+ podSpec['tolerations'] = spec.tolerations;
466
+ }
467
+ if (spec.affinity) {
468
+ podSpec['affinity'] = spec.affinity;
469
+ }
470
+ if (spec.volumes) {
471
+ podSpec['volumes'] = spec.volumes;
472
+ }
473
+ if (spec.initContainers) {
474
+ podSpec['initContainers'] = spec.initContainers;
475
+ }
476
+ if (spec.terminationGracePeriodSeconds !== undefined) {
477
+ podSpec['terminationGracePeriodSeconds'] = spec.terminationGracePeriodSeconds;
478
+ }
479
+ return podSpec;
480
+ }
481
+ /**
482
+ * Creates a Role resource for RBAC
483
+ * @param spec - Role specification
484
+ * @returns Created Role ApiObject
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * coreResources.addRole({
489
+ * name: 'pod-reader',
490
+ * rules: [
491
+ * {
492
+ * apiGroups: [''],
493
+ * resources: ['pods'],
494
+ * verbs: ['get', 'list', 'watch']
495
+ * }
496
+ * ]
497
+ * });
498
+ * ```
499
+ *
500
+ * @since 2.4.0
501
+ */
502
+ addRole(spec) {
503
+ const labels = {
504
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
505
+ ...(spec.labels || {}),
506
+ };
507
+ return new ApiObject(this.chart, spec.name, {
508
+ apiVersion: CoreResources.RBAC_API_VERSION,
509
+ kind: 'Role',
510
+ metadata: {
511
+ name: spec.name,
512
+ ...(spec.namespace && { namespace: spec.namespace }),
513
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
514
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
515
+ ? { annotations: spec.annotations }
516
+ : {}),
517
+ },
518
+ rules: spec.rules,
519
+ });
520
+ }
521
+ /**
522
+ * Creates a ClusterRole resource for cluster-wide RBAC
523
+ * @param spec - ClusterRole specification
524
+ * @returns Created ClusterRole ApiObject
525
+ *
526
+ * @example
527
+ * ```typescript
528
+ * coreResources.addClusterRole({
529
+ * name: 'cluster-admin',
530
+ * rules: [
531
+ * {
532
+ * apiGroups: ['*'],
533
+ * resources: ['*'],
534
+ * verbs: ['*']
535
+ * }
536
+ * ]
537
+ * });
538
+ * ```
539
+ *
540
+ * @since 2.4.0
541
+ */
542
+ addClusterRole(spec) {
543
+ const labels = {
544
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
545
+ ...(spec.labels || {}),
546
+ };
547
+ return new ApiObject(this.chart, spec.name, {
548
+ apiVersion: CoreResources.RBAC_API_VERSION,
549
+ kind: 'ClusterRole',
550
+ metadata: {
551
+ name: spec.name,
552
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
553
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
554
+ ? { annotations: spec.annotations }
555
+ : {}),
556
+ },
557
+ rules: spec.rules,
558
+ });
559
+ }
560
+ /**
561
+ * Creates a RoleBinding resource for RBAC
562
+ * @param spec - RoleBinding specification
563
+ * @returns Created RoleBinding ApiObject
564
+ *
565
+ * @example
566
+ * ```typescript
567
+ * coreResources.addRoleBinding({
568
+ * name: 'pod-reader-binding',
569
+ * roleRef: {
570
+ * kind: 'Role',
571
+ * name: 'pod-reader',
572
+ * apiGroup: 'rbac.authorization.k8s.io'
573
+ * },
574
+ * subjects: [
575
+ * {
576
+ * kind: 'ServiceAccount',
577
+ * name: 'my-service-account',
578
+ * namespace: 'default'
579
+ * }
580
+ * ]
581
+ * });
582
+ * ```
583
+ *
584
+ * @since 2.4.0
585
+ */
586
+ addRoleBinding(spec) {
587
+ const labels = {
588
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
589
+ ...(spec.labels || {}),
590
+ };
591
+ return new ApiObject(this.chart, spec.name, {
592
+ apiVersion: CoreResources.RBAC_API_VERSION,
593
+ kind: 'RoleBinding',
594
+ metadata: {
595
+ name: spec.name,
596
+ ...(spec.namespace && { namespace: spec.namespace }),
597
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
598
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
599
+ ? { annotations: spec.annotations }
600
+ : {}),
601
+ },
602
+ roleRef: spec.roleRef,
603
+ subjects: spec.subjects,
604
+ });
605
+ }
606
+ /**
607
+ * Creates a ClusterRoleBinding resource for cluster-wide RBAC
608
+ * @param spec - ClusterRoleBinding specification
609
+ * @returns Created ClusterRoleBinding ApiObject
610
+ *
611
+ * @example
612
+ * ```typescript
613
+ * coreResources.addClusterRoleBinding({
614
+ * name: 'cluster-admin-binding',
615
+ * roleRef: {
616
+ * kind: 'ClusterRole',
617
+ * name: 'cluster-admin',
618
+ * apiGroup: 'rbac.authorization.k8s.io'
619
+ * },
620
+ * subjects: [
621
+ * {
622
+ * kind: 'ServiceAccount',
623
+ * name: 'admin-user',
624
+ * namespace: 'kube-system'
625
+ * }
626
+ * ]
627
+ * });
628
+ * ```
629
+ *
630
+ * @since 2.4.0
631
+ */
632
+ addClusterRoleBinding(spec) {
633
+ const labels = {
634
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
635
+ ...(spec.labels || {}),
636
+ };
637
+ return new ApiObject(this.chart, spec.name, {
638
+ apiVersion: CoreResources.RBAC_API_VERSION,
639
+ kind: 'ClusterRoleBinding',
640
+ metadata: {
641
+ name: spec.name,
642
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
643
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
644
+ ? { annotations: spec.annotations }
645
+ : {}),
646
+ },
647
+ roleRef: spec.roleRef,
648
+ subjects: spec.subjects,
649
+ });
650
+ }
651
+ /**
652
+ * Creates a Job resource for batch workloads
653
+ * @param spec - Job specification
654
+ * @returns Created Job ApiObject
655
+ *
656
+ * @example
657
+ * ```typescript
658
+ * coreResources.addJob({
659
+ * name: 'data-processor',
660
+ * image: 'busybox:1.35',
661
+ * command: ['sh', '-c', 'echo "Processing data..." && sleep 30'],
662
+ * completions: 1,
663
+ * parallelism: 1
664
+ * });
665
+ * ```
666
+ *
667
+ * @since 2.4.0
668
+ */
669
+ addJob(spec) {
670
+ const matchLabels = spec.matchLabels ?? {
671
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
672
+ };
673
+ const jobSpec = this.buildJobSpec(spec, matchLabels);
674
+ const labels = {
675
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
676
+ ...(spec.labels || {}),
677
+ };
678
+ return new ApiObject(this.chart, spec.name, {
679
+ apiVersion: 'batch/v1',
680
+ kind: 'Job',
681
+ metadata: {
682
+ name: spec.name,
683
+ ...(labels && Object.keys(labels).length > 0 ? { labels } : {}),
684
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
685
+ ? { annotations: spec.annotations }
686
+ : {}),
687
+ },
688
+ spec: jobSpec,
689
+ });
690
+ }
691
+ /**
692
+ * Builds Job specification object
693
+ * @private
694
+ */
695
+ buildJobSpec(spec, matchLabels) {
696
+ const containers = this.buildJobContainers(spec);
697
+ const podSpec = this.buildJobPodSpec(spec, containers);
698
+ const jobSpec = {
699
+ template: {
700
+ metadata: {
701
+ labels: { ...matchLabels, ...(spec.labels || {}) },
702
+ ...(spec.annotations && Object.keys(spec.annotations).length > 0
703
+ ? { annotations: spec.annotations }
704
+ : {}),
705
+ },
706
+ spec: podSpec,
707
+ },
708
+ };
709
+ if (spec.completions !== undefined) {
710
+ jobSpec['completions'] = spec.completions;
711
+ }
712
+ if (spec.parallelism !== undefined) {
713
+ jobSpec['parallelism'] = spec.parallelism;
714
+ }
715
+ if (spec.backoffLimit !== undefined) {
716
+ jobSpec['backoffLimit'] = spec.backoffLimit;
717
+ }
718
+ if (spec.activeDeadlineSeconds !== undefined) {
719
+ jobSpec['activeDeadlineSeconds'] = spec.activeDeadlineSeconds;
720
+ }
721
+ if (spec.ttlSecondsAfterFinished !== undefined) {
722
+ jobSpec['ttlSecondsAfterFinished'] = spec.ttlSecondsAfterFinished;
723
+ }
724
+ if (spec.completionMode) {
725
+ jobSpec['completionMode'] = spec.completionMode;
726
+ }
727
+ if (spec.suspend !== undefined) {
728
+ jobSpec['suspend'] = spec.suspend;
729
+ }
730
+ return jobSpec;
731
+ }
732
+ /**
733
+ * Builds container specification for Job
734
+ * @private
735
+ */
736
+ buildJobContainers(spec) {
737
+ const containerSpec = {
738
+ name: spec.name,
739
+ image: spec.image,
740
+ };
741
+ if (spec.command)
742
+ containerSpec['command'] = spec.command;
743
+ if (spec.args)
744
+ containerSpec['args'] = spec.args;
745
+ if (spec.env)
746
+ containerSpec['env'] = spec.env;
747
+ if (spec.resources)
748
+ containerSpec['resources'] = spec.resources;
749
+ if (spec.volumeMounts)
750
+ containerSpec['volumeMounts'] = spec.volumeMounts;
751
+ if (spec.securityContext)
752
+ containerSpec['securityContext'] = spec.securityContext;
753
+ return this.buildGenericContainers(containerSpec);
754
+ }
755
+ /**
756
+ * Builds pod specification for Job
757
+ * @private
758
+ */
759
+ buildJobPodSpec(spec, containers) {
760
+ const podSpec = {
761
+ containers,
762
+ restartPolicy: spec.restartPolicy ?? 'Never',
763
+ };
764
+ if (spec.serviceAccountName) {
765
+ podSpec['serviceAccountName'] = spec.serviceAccountName;
766
+ }
767
+ if (spec.nodeSelector) {
768
+ podSpec['nodeSelector'] = spec.nodeSelector;
769
+ }
770
+ if (spec.tolerations) {
771
+ podSpec['tolerations'] = spec.tolerations;
772
+ }
773
+ if (spec.affinity) {
774
+ podSpec['affinity'] = spec.affinity;
775
+ }
776
+ if (spec.volumes) {
777
+ podSpec['volumes'] = spec.volumes;
778
+ }
779
+ if (spec.initContainers) {
780
+ podSpec['initContainers'] = spec.initContainers;
781
+ }
782
+ return podSpec;
783
+ }
784
+ /**
785
+ * Creates a ReplicaSet resource
786
+ * @param spec - ReplicaSet specification
787
+ * @returns Created ReplicaSet ApiObject
788
+ *
789
+ * @example
790
+ * ```typescript
791
+ * coreResources.addReplicaSet({
792
+ * name: 'web-replica',
793
+ * image: 'nginx:1.21',
794
+ * replicas: 3,
795
+ * containerPort: 80
796
+ * });
797
+ * ```
798
+ *
799
+ * @since 2.4.0
800
+ */
801
+ addReplicaSet(spec) {
802
+ const matchLabels = spec.matchLabels ?? {
803
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
804
+ };
805
+ const containers = [
806
+ {
807
+ name: spec.name,
808
+ image: spec.image,
809
+ ...(spec.containerPort ? { ports: [{ containerPort: spec.containerPort }] } : {}),
810
+ ...(spec.env ? { env: spec.env } : {}),
811
+ ...(spec.resources ? { resources: spec.resources } : {}),
812
+ ...(spec.volumeMounts ? { volumeMounts: spec.volumeMounts } : {}),
813
+ ...(spec.securityContext ? { securityContext: spec.securityContext } : {}),
814
+ },
815
+ ];
816
+ const replicaSetSpec = {
817
+ replicas: spec.replicas ?? 1,
818
+ selector: { matchLabels },
819
+ template: {
820
+ metadata: { labels: { ...matchLabels, ...spec.labels } },
821
+ spec: {
822
+ containers,
823
+ ...(spec.volumes ? { volumes: spec.volumes } : {}),
824
+ ...(spec.serviceAccountName ? { serviceAccountName: spec.serviceAccountName } : {}),
825
+ ...(spec.nodeSelector ? { nodeSelector: spec.nodeSelector } : {}),
826
+ ...(spec.tolerations ? { tolerations: spec.tolerations } : {}),
827
+ ...(spec.affinity ? { affinity: spec.affinity } : {}),
828
+ },
829
+ },
830
+ };
831
+ return new ApiObject(this.chart, spec.name, {
832
+ apiVersion: CoreResources.APPS_API_VERSION,
833
+ kind: 'ReplicaSet',
834
+ metadata: {
835
+ name: spec.name,
836
+ ...(spec.labels ? { labels: spec.labels } : {}),
837
+ ...(spec.annotations ? { annotations: spec.annotations } : {}),
838
+ },
839
+ spec: replicaSetSpec,
840
+ });
841
+ }
842
+ /**
843
+ * Creates a Pod resource
844
+ * @param spec - Pod specification
845
+ * @returns Created Pod ApiObject
846
+ *
847
+ * @example
848
+ * ```typescript
849
+ * coreResources.addPod({
850
+ * name: 'web-pod',
851
+ * image: 'nginx:1.21',
852
+ * containerPort: 80
853
+ * });
854
+ * ```
855
+ *
856
+ * @since 2.4.0
857
+ */
858
+ addPod(spec) {
859
+ const containers = [
860
+ {
861
+ name: spec.name,
862
+ image: spec.image,
863
+ ...(spec.containerPort ? { ports: [{ containerPort: spec.containerPort }] } : {}),
864
+ ...(spec.env ? { env: spec.env } : {}),
865
+ ...(spec.resources ? { resources: spec.resources } : {}),
866
+ ...(spec.volumeMounts ? { volumeMounts: spec.volumeMounts } : {}),
867
+ ...(spec.securityContext ? { securityContext: spec.securityContext } : {}),
868
+ },
869
+ ];
870
+ const podSpec = {
871
+ containers,
872
+ restartPolicy: spec.restartPolicy ?? 'Always',
873
+ ...(spec.volumes ? { volumes: spec.volumes } : {}),
874
+ ...(spec.serviceAccountName ? { serviceAccountName: spec.serviceAccountName } : {}),
875
+ ...(spec.nodeSelector ? { nodeSelector: spec.nodeSelector } : {}),
876
+ ...(spec.tolerations ? { tolerations: spec.tolerations } : {}),
877
+ ...(spec.affinity ? { affinity: spec.affinity } : {}),
878
+ ...(spec.initContainers ? { initContainers: spec.initContainers } : {}),
879
+ };
880
+ return new ApiObject(this.chart, spec.name, {
881
+ apiVersion: CoreResources.CORE_API_VERSION,
882
+ kind: 'Pod',
883
+ metadata: {
884
+ name: spec.name,
885
+ ...(spec.labels ? { labels: spec.labels } : {}),
886
+ ...(spec.annotations ? { annotations: spec.annotations } : {}),
887
+ },
888
+ spec: podSpec,
889
+ });
890
+ }
891
+ /**
892
+ * Creates a CronJob resource
893
+ * @param spec - CronJob specification
894
+ * @returns Created CronJob ApiObject
895
+ *
896
+ * @example
897
+ * ```typescript
898
+ * coreResources.addCronJob({
899
+ * name: 'backup-job',
900
+ * schedule: '0 2 * * *',
901
+ * image: 'backup:latest',
902
+ * command: ['sh', '-c', 'backup-script.sh']
903
+ * });
904
+ * ```
905
+ *
906
+ * @since 2.4.0
907
+ */
908
+ addCronJob(spec) {
909
+ const matchLabels = spec.matchLabels ?? {
910
+ [CoreResources.LABEL_NAME]: include(CoreResources.HELPER_NAME),
911
+ };
912
+ const cronJobSpec = this.buildCronJobSpec(spec, matchLabels);
913
+ return new ApiObject(this.chart, spec.name, {
914
+ apiVersion: 'batch/v1',
915
+ kind: 'CronJob',
916
+ metadata: {
917
+ name: spec.name,
918
+ ...(spec.labels ? { labels: spec.labels } : {}),
919
+ ...(spec.annotations ? { annotations: spec.annotations } : {}),
920
+ },
921
+ spec: cronJobSpec,
922
+ });
923
+ }
924
+ /**
925
+ * Builds CronJob specification object
926
+ * @private
927
+ */
928
+ buildCronJobSpec(spec, matchLabels) {
929
+ const containerSpec = {
930
+ name: spec.name,
931
+ image: spec.image,
932
+ };
933
+ if (spec.command)
934
+ containerSpec['command'] = spec.command;
935
+ if (spec.args)
936
+ containerSpec['args'] = spec.args;
937
+ if (spec.env)
938
+ containerSpec['env'] = spec.env;
939
+ if (spec.resources)
940
+ containerSpec['resources'] = spec.resources;
941
+ if (spec.volumeMounts)
942
+ containerSpec['volumeMounts'] = spec.volumeMounts;
943
+ if (spec.securityContext)
944
+ containerSpec['securityContext'] = spec.securityContext;
945
+ const containers = this.buildGenericContainers(containerSpec);
946
+ const podSpec = this.buildCronJobPodSpec(spec, containers);
947
+ const cronJobSpec = {
948
+ schedule: spec.schedule,
949
+ jobTemplate: {
950
+ spec: {
951
+ template: {
952
+ metadata: { labels: { ...matchLabels, ...spec.labels } },
953
+ spec: podSpec,
954
+ },
955
+ ...(spec.backoffLimit !== undefined ? { backoffLimit: spec.backoffLimit } : {}),
956
+ ...(spec.activeDeadlineSeconds !== undefined
957
+ ? { activeDeadlineSeconds: spec.activeDeadlineSeconds }
958
+ : {}),
959
+ },
960
+ },
961
+ };
962
+ if (spec.concurrencyPolicy) {
963
+ cronJobSpec['concurrencyPolicy'] = spec.concurrencyPolicy;
964
+ }
965
+ if (spec.suspend !== undefined) {
966
+ cronJobSpec['suspend'] = spec.suspend;
967
+ }
968
+ if (spec.successfulJobsHistoryLimit !== undefined) {
969
+ cronJobSpec['successfulJobsHistoryLimit'] = spec.successfulJobsHistoryLimit;
970
+ }
971
+ if (spec.failedJobsHistoryLimit !== undefined) {
972
+ cronJobSpec['failedJobsHistoryLimit'] = spec.failedJobsHistoryLimit;
973
+ }
974
+ if (spec.startingDeadlineSeconds !== undefined) {
975
+ cronJobSpec['startingDeadlineSeconds'] = spec.startingDeadlineSeconds;
976
+ }
977
+ return cronJobSpec;
978
+ }
979
+ /**
980
+ * Builds generic container specification
981
+ * @private
982
+ */
983
+ buildGenericContainers(spec) {
984
+ const container = {
985
+ name: spec['name'],
986
+ image: spec['image'],
987
+ };
988
+ if (spec['containerPort']) {
989
+ container['ports'] = [{ containerPort: spec['containerPort'] }];
990
+ }
991
+ if (spec['command']) {
992
+ container['command'] = spec['command'];
993
+ }
994
+ if (spec['args']) {
995
+ container['args'] = spec['args'];
996
+ }
997
+ if (spec['env']) {
998
+ container['env'] = spec['env'];
999
+ }
1000
+ if (spec['resources']) {
1001
+ container['resources'] = spec['resources'];
1002
+ }
1003
+ if (spec['volumeMounts']) {
1004
+ container['volumeMounts'] = spec['volumeMounts'];
1005
+ }
1006
+ if (spec['securityContext']) {
1007
+ container['securityContext'] = spec['securityContext'];
1008
+ }
1009
+ return [container];
1010
+ }
1011
+ /**
1012
+ * Builds pod specification for CronJob
1013
+ * @private
1014
+ */
1015
+ buildCronJobPodSpec(spec, containers) {
1016
+ const podSpec = {
1017
+ containers,
1018
+ restartPolicy: spec.restartPolicy ?? 'OnFailure',
1019
+ };
1020
+ if (spec.volumes) {
1021
+ podSpec['volumes'] = spec.volumes;
1022
+ }
1023
+ if (spec.serviceAccountName) {
1024
+ podSpec['serviceAccountName'] = spec.serviceAccountName;
1025
+ }
1026
+ if (spec.nodeSelector) {
1027
+ podSpec['nodeSelector'] = spec.nodeSelector;
1028
+ }
1029
+ if (spec.tolerations) {
1030
+ podSpec['tolerations'] = spec.tolerations;
1031
+ }
1032
+ if (spec.affinity) {
1033
+ podSpec['affinity'] = spec.affinity;
1034
+ }
1035
+ return podSpec;
1036
+ }
1037
+ }
1038
+ CoreResources.APPS_API_VERSION = 'apps/v1';
1039
+ CoreResources.CORE_API_VERSION = 'v1';
1040
+ CoreResources.RBAC_API_VERSION = 'rbac.authorization.k8s.io/v1';
1041
+ CoreResources.LABEL_NAME = 'app.kubernetes.io/name';
1042
+ CoreResources.HELPER_NAME = 'chart.name';
1043
+ //# sourceMappingURL=coreResources.js.map