@intentius/chant-lexicon-helm 0.0.16

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 (110) hide show
  1. package/README.md +22 -0
  2. package/dist/integrity.json +36 -0
  3. package/dist/manifest.json +37 -0
  4. package/dist/meta.json +208 -0
  5. package/dist/rules/chart-metadata.ts +64 -0
  6. package/dist/rules/helm-helpers.ts +64 -0
  7. package/dist/rules/no-hardcoded-image.ts +62 -0
  8. package/dist/rules/values-no-secrets.ts +82 -0
  9. package/dist/rules/whm101.ts +46 -0
  10. package/dist/rules/whm102.ts +33 -0
  11. package/dist/rules/whm103.ts +59 -0
  12. package/dist/rules/whm104.ts +35 -0
  13. package/dist/rules/whm105.ts +30 -0
  14. package/dist/rules/whm201.ts +36 -0
  15. package/dist/rules/whm202.ts +50 -0
  16. package/dist/rules/whm203.ts +39 -0
  17. package/dist/rules/whm204.ts +60 -0
  18. package/dist/rules/whm301.ts +41 -0
  19. package/dist/rules/whm302.ts +40 -0
  20. package/dist/rules/whm401.ts +57 -0
  21. package/dist/rules/whm402.ts +45 -0
  22. package/dist/rules/whm403.ts +45 -0
  23. package/dist/rules/whm404.ts +36 -0
  24. package/dist/rules/whm405.ts +53 -0
  25. package/dist/rules/whm406.ts +34 -0
  26. package/dist/rules/whm407.ts +83 -0
  27. package/dist/rules/whm501.ts +103 -0
  28. package/dist/rules/whm502.ts +94 -0
  29. package/dist/skills/chant-helm-chart-patterns.md +229 -0
  30. package/dist/skills/chant-helm-chart-security-patterns.md +192 -0
  31. package/dist/skills/chant-helm-create-chart.md +211 -0
  32. package/dist/types/index.d.ts +132 -0
  33. package/package.json +34 -0
  34. package/src/codegen/docs-cli.ts +4 -0
  35. package/src/codegen/docs.ts +483 -0
  36. package/src/codegen/generate-cli.ts +28 -0
  37. package/src/codegen/generate.ts +249 -0
  38. package/src/codegen/naming.ts +38 -0
  39. package/src/codegen/package.ts +64 -0
  40. package/src/composites/composites.test.ts +1050 -0
  41. package/src/composites/helm-batch-job.ts +209 -0
  42. package/src/composites/helm-crd-lifecycle.ts +184 -0
  43. package/src/composites/helm-cron-job.ts +177 -0
  44. package/src/composites/helm-daemon-set.ts +169 -0
  45. package/src/composites/helm-external-secret.ts +93 -0
  46. package/src/composites/helm-library.ts +51 -0
  47. package/src/composites/helm-microservice.ts +331 -0
  48. package/src/composites/helm-monitored-service.ts +252 -0
  49. package/src/composites/helm-namespace-env.ts +154 -0
  50. package/src/composites/helm-secure-ingress.ts +114 -0
  51. package/src/composites/helm-stateful-service.ts +213 -0
  52. package/src/composites/helm-web-app.ts +264 -0
  53. package/src/composites/helm-worker.ts +207 -0
  54. package/src/composites/index.ts +38 -0
  55. package/src/coverage.test.ts +21 -0
  56. package/src/coverage.ts +50 -0
  57. package/src/generated/index.d.ts +132 -0
  58. package/src/generated/index.ts +13 -0
  59. package/src/generated/lexicon-helm.json +208 -0
  60. package/src/helpers.test.ts +51 -0
  61. package/src/helpers.ts +100 -0
  62. package/src/import/generator.ts +285 -0
  63. package/src/import/import.test.ts +224 -0
  64. package/src/import/parser.ts +160 -0
  65. package/src/import/template-stripper.ts +123 -0
  66. package/src/index.ts +108 -0
  67. package/src/intrinsics.test.ts +380 -0
  68. package/src/intrinsics.ts +484 -0
  69. package/src/lint/post-synth/helm-helpers.ts +64 -0
  70. package/src/lint/post-synth/post-synth.test.ts +504 -0
  71. package/src/lint/post-synth/whm101.ts +46 -0
  72. package/src/lint/post-synth/whm102.ts +33 -0
  73. package/src/lint/post-synth/whm103.ts +59 -0
  74. package/src/lint/post-synth/whm104.ts +35 -0
  75. package/src/lint/post-synth/whm105.ts +30 -0
  76. package/src/lint/post-synth/whm201.ts +36 -0
  77. package/src/lint/post-synth/whm202.ts +50 -0
  78. package/src/lint/post-synth/whm203.ts +39 -0
  79. package/src/lint/post-synth/whm204.ts +60 -0
  80. package/src/lint/post-synth/whm301.ts +41 -0
  81. package/src/lint/post-synth/whm302.ts +40 -0
  82. package/src/lint/post-synth/whm401.ts +57 -0
  83. package/src/lint/post-synth/whm402.ts +45 -0
  84. package/src/lint/post-synth/whm403.ts +45 -0
  85. package/src/lint/post-synth/whm404.ts +36 -0
  86. package/src/lint/post-synth/whm405.ts +53 -0
  87. package/src/lint/post-synth/whm406.ts +34 -0
  88. package/src/lint/post-synth/whm407.ts +83 -0
  89. package/src/lint/post-synth/whm501.ts +103 -0
  90. package/src/lint/post-synth/whm502.ts +94 -0
  91. package/src/lint/rules/chart-metadata.ts +64 -0
  92. package/src/lint/rules/lint-rules.test.ts +97 -0
  93. package/src/lint/rules/no-hardcoded-image.ts +62 -0
  94. package/src/lint/rules/values-no-secrets.ts +82 -0
  95. package/src/lsp/completions.test.ts +72 -0
  96. package/src/lsp/completions.ts +20 -0
  97. package/src/lsp/hover.test.ts +46 -0
  98. package/src/lsp/hover.ts +46 -0
  99. package/src/package-cli.ts +28 -0
  100. package/src/plugin.test.ts +71 -0
  101. package/src/plugin.ts +206 -0
  102. package/src/resources.ts +77 -0
  103. package/src/serializer.test.ts +930 -0
  104. package/src/serializer.ts +835 -0
  105. package/src/skills/chart-patterns.md +229 -0
  106. package/src/skills/chart-security-patterns.md +192 -0
  107. package/src/skills/create-chart.md +211 -0
  108. package/src/validate-cli.ts +21 -0
  109. package/src/validate.test.ts +37 -0
  110. package/src/validate.ts +36 -0
@@ -0,0 +1,169 @@
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
+
8
+ import { values, include, printf, toYaml, If, With } from "../intrinsics";
9
+
10
+ export interface HelmDaemonSetProps {
11
+ /** Chart and release name. */
12
+ name: string;
13
+ /** Default container image repository. */
14
+ imageRepository?: string;
15
+ /** Default container image tag. */
16
+ imageTag?: string;
17
+ /** Container port (omitted if undefined). */
18
+ port?: number;
19
+ /** Host path volume mounts. */
20
+ hostPaths?: Array<{ name: string; hostPath: string; mountPath: string }>;
21
+ /** Include ServiceAccount. Default: true. */
22
+ serviceAccount?: boolean;
23
+ /** Chart appVersion. */
24
+ appVersion?: string;
25
+ }
26
+
27
+ export interface HelmDaemonSetResult {
28
+ chart: Record<string, unknown>;
29
+ values: Record<string, unknown>;
30
+ daemonSet: Record<string, unknown>;
31
+ serviceAccount?: Record<string, unknown>;
32
+ }
33
+
34
+ export function HelmDaemonSet(props: HelmDaemonSetProps): HelmDaemonSetResult {
35
+ const {
36
+ name,
37
+ imageRepository = "fluent/fluent-bit",
38
+ imageTag = "latest",
39
+ port,
40
+ hostPaths = [],
41
+ serviceAccount = true,
42
+ appVersion = "1.0.0",
43
+ } = props;
44
+
45
+ const chart = {
46
+ apiVersion: "v2",
47
+ name,
48
+ version: "0.1.0",
49
+ appVersion,
50
+ type: "application",
51
+ description: `A Helm chart for ${name} DaemonSet`,
52
+ };
53
+
54
+ const valuesObj: Record<string, unknown> = {
55
+ image: {
56
+ repository: imageRepository,
57
+ tag: imageTag,
58
+ pullPolicy: "IfNotPresent",
59
+ },
60
+ resources: {
61
+ limits: { cpu: "200m", memory: "256Mi" },
62
+ requests: { cpu: "100m", memory: "128Mi" },
63
+ },
64
+ nodeSelector: {},
65
+ tolerations: [],
66
+ updateStrategy: {
67
+ type: "RollingUpdate",
68
+ rollingUpdate: {
69
+ maxUnavailable: 1,
70
+ },
71
+ },
72
+ };
73
+
74
+ if (serviceAccount) {
75
+ valuesObj.serviceAccount = {
76
+ create: true,
77
+ name: "",
78
+ annotations: {},
79
+ };
80
+ }
81
+
82
+ const containerSpec: Record<string, unknown> = {
83
+ name,
84
+ image: printf("%s:%s", values.image.repository, values.image.tag),
85
+ imagePullPolicy: values.image.pullPolicy,
86
+ resources: toYaml(values.resources),
87
+ securityContext: {
88
+ runAsNonRoot: true,
89
+ readOnlyRootFilesystem: true,
90
+ allowPrivilegeEscalation: false,
91
+ },
92
+ };
93
+
94
+ if (port !== undefined) {
95
+ containerSpec.ports = [{ containerPort: port, name: "http" }];
96
+ }
97
+
98
+ if (hostPaths.length > 0) {
99
+ containerSpec.volumeMounts = hostPaths.map((hp) => ({
100
+ name: hp.name,
101
+ mountPath: hp.mountPath,
102
+ readOnly: true,
103
+ }));
104
+ }
105
+
106
+ const podSpec: Record<string, unknown> = {
107
+ containers: [containerSpec],
108
+ securityContext: {
109
+ runAsNonRoot: true,
110
+ },
111
+ nodeSelector: With(values.nodeSelector, toYaml(values.nodeSelector)),
112
+ tolerations: With(values.tolerations, toYaml(values.tolerations)),
113
+ };
114
+
115
+ if (serviceAccount) {
116
+ podSpec.serviceAccountName = include(`${name}.serviceAccountName`);
117
+ }
118
+
119
+ if (hostPaths.length > 0) {
120
+ podSpec.volumes = hostPaths.map((hp) => ({
121
+ name: hp.name,
122
+ hostPath: {
123
+ path: hp.hostPath,
124
+ type: "Directory",
125
+ },
126
+ }));
127
+ }
128
+
129
+ const daemonSet = {
130
+ apiVersion: "apps/v1",
131
+ kind: "DaemonSet",
132
+ metadata: {
133
+ name: include(`${name}.fullname`),
134
+ labels: include(`${name}.labels`),
135
+ },
136
+ spec: {
137
+ selector: {
138
+ matchLabels: include(`${name}.selectorLabels`),
139
+ },
140
+ updateStrategy: toYaml(values.updateStrategy),
141
+ template: {
142
+ metadata: {
143
+ labels: include(`${name}.selectorLabels`),
144
+ },
145
+ spec: podSpec,
146
+ },
147
+ },
148
+ };
149
+
150
+ const result: HelmDaemonSetResult = {
151
+ chart,
152
+ values: valuesObj,
153
+ daemonSet,
154
+ };
155
+
156
+ if (serviceAccount) {
157
+ result.serviceAccount = {
158
+ apiVersion: "v1",
159
+ kind: "ServiceAccount",
160
+ metadata: {
161
+ name: include(`${name}.serviceAccountName`),
162
+ labels: include(`${name}.labels`),
163
+ annotations: toYaml(values.serviceAccount.annotations),
164
+ },
165
+ };
166
+ }
167
+
168
+ return result;
169
+ }
@@ -0,0 +1,93 @@
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
+
12
+ import { values, include } from "../intrinsics";
13
+
14
+ export interface HelmExternalSecretProps {
15
+ /** Chart and release name. */
16
+ name: string;
17
+ /** Name of the SecretStore or ClusterSecretStore to reference. */
18
+ secretStoreName: string;
19
+ /** Kind of secret store. Default: "ClusterSecretStore". */
20
+ secretStoreKind?: "SecretStore" | "ClusterSecretStore";
21
+ /** Map of { envVarName: "remote/path" } for secret data. */
22
+ data: Record<string, string>;
23
+ /** Refresh interval. Default: "1h". */
24
+ refreshInterval?: string;
25
+ }
26
+
27
+ export interface HelmExternalSecretResult {
28
+ chart: Record<string, unknown>;
29
+ values: Record<string, unknown>;
30
+ externalSecret: Record<string, unknown>;
31
+ }
32
+
33
+ export function HelmExternalSecret(props: HelmExternalSecretProps): HelmExternalSecretResult {
34
+ const {
35
+ name,
36
+ secretStoreName,
37
+ secretStoreKind = "ClusterSecretStore",
38
+ data,
39
+ refreshInterval = "1h",
40
+ } = props;
41
+
42
+ const chart = {
43
+ apiVersion: "v2",
44
+ name,
45
+ version: "0.1.0",
46
+ type: "application",
47
+ description: `External secret management for ${name}`,
48
+ };
49
+
50
+ const secretDataEntries = Object.entries(data).map(([key, remotePath]) => ({
51
+ secretKey: key,
52
+ remoteRef: {
53
+ key: remotePath,
54
+ },
55
+ }));
56
+
57
+ const valuesObj = {
58
+ externalSecret: {
59
+ refreshInterval,
60
+ secretStore: {
61
+ name: secretStoreName,
62
+ kind: secretStoreKind,
63
+ },
64
+ },
65
+ };
66
+
67
+ const externalSecret = {
68
+ apiVersion: "external-secrets.io/v1beta1",
69
+ kind: "ExternalSecret",
70
+ metadata: {
71
+ name: include(`${name}.fullname`),
72
+ labels: include(`${name}.labels`),
73
+ },
74
+ spec: {
75
+ refreshInterval: values.externalSecret.refreshInterval,
76
+ secretStoreRef: {
77
+ name: values.externalSecret.secretStore.name,
78
+ kind: values.externalSecret.secretStore.kind,
79
+ },
80
+ target: {
81
+ name: include(`${name}.fullname`),
82
+ creationPolicy: "Owner",
83
+ },
84
+ data: secretDataEntries,
85
+ },
86
+ };
87
+
88
+ return {
89
+ chart,
90
+ values: valuesObj,
91
+ externalSecret,
92
+ };
93
+ }
@@ -0,0 +1,51 @@
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
+
7
+ export interface HelmLibraryProps {
8
+ /** Chart name. */
9
+ name: string;
10
+ /** Chart version. */
11
+ version?: string;
12
+ /** Chart description. */
13
+ description?: string;
14
+ /** Chart dependencies. */
15
+ dependencies?: Array<{
16
+ name: string;
17
+ version: string;
18
+ repository: string;
19
+ }>;
20
+ /** Helper template names to generate. */
21
+ helpers?: string[];
22
+ }
23
+
24
+ export interface HelmLibraryResult {
25
+ chart: Record<string, unknown>;
26
+ helpers: string[];
27
+ }
28
+
29
+ export function HelmLibrary(props: HelmLibraryProps): HelmLibraryResult {
30
+ const {
31
+ name,
32
+ version = "0.1.0",
33
+ description = `A Helm library chart for ${name}`,
34
+ dependencies = [],
35
+ helpers = ["name", "fullname", "chart", "labels", "selectorLabels"],
36
+ } = props;
37
+
38
+ const chart: Record<string, unknown> = {
39
+ apiVersion: "v2",
40
+ name,
41
+ version,
42
+ type: "library",
43
+ description,
44
+ };
45
+
46
+ if (dependencies.length > 0) {
47
+ chart.dependencies = dependencies;
48
+ }
49
+
50
+ return { chart, helpers };
51
+ }
@@ -0,0 +1,331 @@
1
+ /**
2
+ * HelmMicroservice composite — Deployment + Service + Ingress + HPA + PDB + ServiceAccount + ConfigMap.
3
+ *
4
+ * Full microservice pattern with all common production resources.
5
+ */
6
+
7
+ import { values, include, printf, toYaml, If, With } from "../intrinsics";
8
+
9
+ export interface HelmMicroserviceProps {
10
+ /** Chart and release name. */
11
+ name: string;
12
+ /** Default container image repository. */
13
+ imageRepository?: string;
14
+ /** Default container image tag. */
15
+ imageTag?: string;
16
+ /** Default service port. */
17
+ port?: number;
18
+ /** Default replica count. */
19
+ replicas?: number;
20
+ /** Default service type. */
21
+ serviceType?: string;
22
+ /** Include Ingress (conditional). */
23
+ ingress?: boolean;
24
+ /** Include HPA (conditional). */
25
+ autoscaling?: boolean;
26
+ /** Include PDB. */
27
+ pdb?: boolean;
28
+ /** Include ConfigMap. */
29
+ configMap?: boolean;
30
+ /** Chart appVersion. */
31
+ appVersion?: string;
32
+ /** Pod-level security context defaults. */
33
+ podSecurityContext?: Record<string, unknown>;
34
+ /** Container-level security context defaults. */
35
+ securityContext?: Record<string, unknown>;
36
+ /** Node selector defaults. */
37
+ nodeSelector?: Record<string, string>;
38
+ /** Tolerations defaults. */
39
+ tolerations?: Array<Record<string, unknown>>;
40
+ /** Affinity defaults. */
41
+ affinity?: Record<string, unknown>;
42
+ /** Pod annotations defaults. */
43
+ podAnnotations?: Record<string, string>;
44
+ /** Deployment strategy defaults. */
45
+ strategy?: Record<string, unknown>;
46
+ }
47
+
48
+ export interface HelmMicroserviceResult {
49
+ chart: Record<string, unknown>;
50
+ values: Record<string, unknown>;
51
+ deployment: Record<string, unknown>;
52
+ service: Record<string, unknown>;
53
+ serviceAccount: Record<string, unknown>;
54
+ configMap?: Record<string, unknown>;
55
+ ingress?: Record<string, unknown>;
56
+ hpa?: Record<string, unknown>;
57
+ pdb?: Record<string, unknown>;
58
+ }
59
+
60
+ export function HelmMicroservice(props: HelmMicroserviceProps): HelmMicroserviceResult {
61
+ const {
62
+ name,
63
+ imageRepository = "nginx",
64
+ imageTag = "",
65
+ port = 8080,
66
+ replicas = 2,
67
+ serviceType = "ClusterIP",
68
+ ingress = true,
69
+ autoscaling = true,
70
+ pdb = true,
71
+ configMap = true,
72
+ appVersion = "1.0.0",
73
+ } = props;
74
+
75
+ const chart = {
76
+ apiVersion: "v2",
77
+ name,
78
+ version: "0.1.0",
79
+ appVersion,
80
+ type: "application",
81
+ description: `A Helm chart for ${name} microservice`,
82
+ };
83
+
84
+ const valuesObj: Record<string, unknown> = {
85
+ replicaCount: replicas,
86
+ image: {
87
+ repository: imageRepository,
88
+ tag: imageTag,
89
+ pullPolicy: "IfNotPresent",
90
+ },
91
+ service: {
92
+ type: serviceType,
93
+ port,
94
+ },
95
+ serviceAccount: {
96
+ create: true,
97
+ name: "",
98
+ annotations: {},
99
+ },
100
+ resources: {
101
+ limits: { cpu: "500m", memory: "256Mi" },
102
+ requests: { cpu: "100m", memory: "128Mi" },
103
+ },
104
+ livenessProbe: {
105
+ httpGet: { path: "/healthz", port: "http" },
106
+ initialDelaySeconds: 15,
107
+ periodSeconds: 20,
108
+ },
109
+ readinessProbe: {
110
+ httpGet: { path: "/readyz", port: "http" },
111
+ initialDelaySeconds: 5,
112
+ periodSeconds: 10,
113
+ },
114
+ };
115
+
116
+ if (props.podSecurityContext) valuesObj.podSecurityContext = props.podSecurityContext;
117
+ if (props.securityContext) valuesObj.securityContext = props.securityContext;
118
+ if (props.nodeSelector) valuesObj.nodeSelector = props.nodeSelector;
119
+ if (props.tolerations) valuesObj.tolerations = props.tolerations;
120
+ if (props.affinity) valuesObj.affinity = props.affinity;
121
+ if (props.podAnnotations) valuesObj.podAnnotations = props.podAnnotations;
122
+ if (props.strategy) valuesObj.strategy = props.strategy;
123
+
124
+ if (configMap) {
125
+ valuesObj.config = {};
126
+ }
127
+
128
+ if (ingress) {
129
+ valuesObj.ingress = {
130
+ enabled: false,
131
+ className: "",
132
+ annotations: {},
133
+ hosts: [{ host: `${name}.local`, paths: [{ path: "/", pathType: "Prefix" }] }],
134
+ tls: [],
135
+ };
136
+ }
137
+
138
+ if (autoscaling) {
139
+ valuesObj.autoscaling = {
140
+ enabled: false,
141
+ minReplicas: replicas,
142
+ maxReplicas: 10,
143
+ targetCPUUtilizationPercentage: 80,
144
+ targetMemoryUtilizationPercentage: 80,
145
+ };
146
+ }
147
+
148
+ if (pdb) {
149
+ valuesObj.podDisruptionBudget = {
150
+ enabled: true,
151
+ minAvailable: 1,
152
+ };
153
+ }
154
+
155
+ const containerSpec: Record<string, unknown> = {
156
+ name,
157
+ image: printf("%s:%s", values.image.repository, values.image.tag),
158
+ imagePullPolicy: values.image.pullPolicy,
159
+ ports: [{ containerPort: values.service.port, name: "http" }],
160
+ resources: toYaml(values.resources),
161
+ livenessProbe: toYaml(values.livenessProbe),
162
+ readinessProbe: toYaml(values.readinessProbe),
163
+ };
164
+
165
+ if (props.securityContext) containerSpec.securityContext = toYaml(values.securityContext);
166
+
167
+ const podSpec: Record<string, unknown> = {
168
+ serviceAccountName: include(`${name}.serviceAccountName`),
169
+ containers: [containerSpec],
170
+ };
171
+
172
+ if (props.podSecurityContext) podSpec.securityContext = toYaml(values.podSecurityContext);
173
+ if (props.nodeSelector) podSpec.nodeSelector = With(values.nodeSelector, toYaml(values.nodeSelector));
174
+ if (props.tolerations) podSpec.tolerations = With(values.tolerations, toYaml(values.tolerations));
175
+ if (props.affinity) podSpec.affinity = With(values.affinity, toYaml(values.affinity));
176
+
177
+ const templateMetadata: Record<string, unknown> = {
178
+ labels: include(`${name}.selectorLabels`),
179
+ };
180
+ if (props.podAnnotations) templateMetadata.annotations = toYaml(values.podAnnotations);
181
+
182
+ const deploymentSpec: Record<string, unknown> = {
183
+ replicas: values.replicaCount,
184
+ selector: {
185
+ matchLabels: include(`${name}.selectorLabels`),
186
+ },
187
+ template: {
188
+ metadata: templateMetadata,
189
+ spec: podSpec,
190
+ },
191
+ };
192
+
193
+ if (props.strategy) deploymentSpec.strategy = toYaml(values.strategy);
194
+
195
+ const deployment = {
196
+ apiVersion: "apps/v1",
197
+ kind: "Deployment",
198
+ metadata: {
199
+ name: include(`${name}.fullname`),
200
+ labels: include(`${name}.labels`),
201
+ },
202
+ spec: deploymentSpec,
203
+ };
204
+
205
+ const service = {
206
+ apiVersion: "v1",
207
+ kind: "Service",
208
+ metadata: {
209
+ name: include(`${name}.fullname`),
210
+ labels: include(`${name}.labels`),
211
+ },
212
+ spec: {
213
+ type: values.service.type,
214
+ ports: [{
215
+ port: values.service.port,
216
+ targetPort: "http",
217
+ protocol: "TCP",
218
+ name: "http",
219
+ }],
220
+ selector: include(`${name}.selectorLabels`),
221
+ },
222
+ };
223
+
224
+ const serviceAccount = {
225
+ apiVersion: "v1",
226
+ kind: "ServiceAccount",
227
+ metadata: {
228
+ name: include(`${name}.serviceAccountName`),
229
+ labels: include(`${name}.labels`),
230
+ annotations: toYaml(values.serviceAccount.annotations),
231
+ },
232
+ };
233
+
234
+ const result: HelmMicroserviceResult = {
235
+ chart,
236
+ values: valuesObj,
237
+ deployment,
238
+ service,
239
+ serviceAccount,
240
+ };
241
+
242
+ if (configMap) {
243
+ result.configMap = {
244
+ apiVersion: "v1",
245
+ kind: "ConfigMap",
246
+ metadata: {
247
+ name: include(`${name}.fullname`),
248
+ labels: include(`${name}.labels`),
249
+ },
250
+ data: values.config,
251
+ };
252
+ }
253
+
254
+ if (ingress) {
255
+ result.ingress = {
256
+ apiVersion: "networking.k8s.io/v1",
257
+ kind: "Ingress",
258
+ metadata: {
259
+ name: include(`${name}.fullname`),
260
+ labels: include(`${name}.labels`),
261
+ annotations: toYaml(values.ingress.annotations),
262
+ },
263
+ spec: {
264
+ ingressClassName: values.ingress.className,
265
+ rules: values.ingress.hosts,
266
+ tls: values.ingress.tls,
267
+ },
268
+ };
269
+ }
270
+
271
+ if (autoscaling) {
272
+ result.hpa = {
273
+ apiVersion: "autoscaling/v2",
274
+ kind: "HorizontalPodAutoscaler",
275
+ metadata: {
276
+ name: include(`${name}.fullname`),
277
+ labels: include(`${name}.labels`),
278
+ },
279
+ spec: {
280
+ scaleTargetRef: {
281
+ apiVersion: "apps/v1",
282
+ kind: "Deployment",
283
+ name: include(`${name}.fullname`),
284
+ },
285
+ minReplicas: values.autoscaling.minReplicas,
286
+ maxReplicas: values.autoscaling.maxReplicas,
287
+ metrics: [
288
+ {
289
+ type: "Resource",
290
+ resource: {
291
+ name: "cpu",
292
+ target: {
293
+ type: "Utilization",
294
+ averageUtilization: values.autoscaling.targetCPUUtilizationPercentage,
295
+ },
296
+ },
297
+ },
298
+ {
299
+ type: "Resource",
300
+ resource: {
301
+ name: "memory",
302
+ target: {
303
+ type: "Utilization",
304
+ averageUtilization: values.autoscaling.targetMemoryUtilizationPercentage,
305
+ },
306
+ },
307
+ },
308
+ ],
309
+ },
310
+ };
311
+ }
312
+
313
+ if (pdb) {
314
+ result.pdb = {
315
+ apiVersion: "policy/v1",
316
+ kind: "PodDisruptionBudget",
317
+ metadata: {
318
+ name: include(`${name}.fullname`),
319
+ labels: include(`${name}.labels`),
320
+ },
321
+ spec: {
322
+ minAvailable: values.podDisruptionBudget.minAvailable,
323
+ selector: {
324
+ matchLabels: include(`${name}.selectorLabels`),
325
+ },
326
+ },
327
+ };
328
+ }
329
+
330
+ return result;
331
+ }