@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,252 @@
1
+ /**
2
+ * HelmMonitoredService composite — Deployment + Service + ServiceMonitor + optional PrometheusRule.
3
+ *
4
+ * Full observability pattern for services monitored by Prometheus Operator.
5
+ * Uses fallback GVK for CRD resources (ServiceMonitor, PrometheusRule).
6
+ */
7
+
8
+ import { values, include, printf, toYaml, If, With, Capabilities } from "../intrinsics";
9
+
10
+ export interface HelmMonitoredServiceProps {
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
+ /** Application port. */
18
+ port?: number;
19
+ /** Metrics port. */
20
+ metricsPort?: number;
21
+ /** Metrics path. */
22
+ metricsPath?: string;
23
+ /** Scrape interval. */
24
+ scrapeInterval?: string;
25
+ /** Default replica count. */
26
+ replicas?: number;
27
+ /** Default service type. */
28
+ serviceType?: string;
29
+ /** Include ServiceAccount. Default: true. */
30
+ serviceAccount?: boolean;
31
+ /** Include PrometheusRule for alerting. Default: false. */
32
+ alertRules?: boolean;
33
+ /** Pod-level security context defaults. */
34
+ podSecurityContext?: Record<string, unknown>;
35
+ /** Container-level security context defaults. */
36
+ securityContext?: Record<string, unknown>;
37
+ /** Node selector defaults. */
38
+ nodeSelector?: Record<string, string>;
39
+ /** Tolerations defaults. */
40
+ tolerations?: Array<Record<string, unknown>>;
41
+ /** Affinity defaults. */
42
+ affinity?: Record<string, unknown>;
43
+ /** Chart appVersion. */
44
+ appVersion?: string;
45
+ }
46
+
47
+ export interface HelmMonitoredServiceResult {
48
+ chart: Record<string, unknown>;
49
+ values: Record<string, unknown>;
50
+ deployment: Record<string, unknown>;
51
+ service: Record<string, unknown>;
52
+ serviceAccount?: Record<string, unknown>;
53
+ serviceMonitor: Record<string, unknown>;
54
+ prometheusRule?: Record<string, unknown>;
55
+ }
56
+
57
+ export function HelmMonitoredService(props: HelmMonitoredServiceProps): HelmMonitoredServiceResult {
58
+ const {
59
+ name,
60
+ imageRepository = "nginx",
61
+ imageTag = "",
62
+ port = 8080,
63
+ metricsPort = 9090,
64
+ metricsPath = "/metrics",
65
+ scrapeInterval = "30s",
66
+ replicas = 2,
67
+ serviceType = "ClusterIP",
68
+ serviceAccount = true,
69
+ alertRules = false,
70
+ appVersion = "1.0.0",
71
+ } = props;
72
+
73
+ const chart = {
74
+ apiVersion: "v2",
75
+ name,
76
+ version: "0.1.0",
77
+ appVersion,
78
+ type: "application",
79
+ description: `A Helm chart for ${name} with monitoring`,
80
+ };
81
+
82
+ const valuesObj: Record<string, unknown> = {
83
+ replicaCount: replicas,
84
+ image: {
85
+ repository: imageRepository,
86
+ tag: imageTag,
87
+ pullPolicy: "IfNotPresent",
88
+ },
89
+ service: {
90
+ type: serviceType,
91
+ port,
92
+ },
93
+ resources: {},
94
+ monitoring: {
95
+ enabled: true,
96
+ metricsPort,
97
+ metricsPath,
98
+ scrapeInterval,
99
+ },
100
+ };
101
+
102
+ if (alertRules) {
103
+ valuesObj.alerting = {
104
+ enabled: false,
105
+ rules: [],
106
+ };
107
+ }
108
+
109
+ if (props.podSecurityContext) valuesObj.podSecurityContext = props.podSecurityContext;
110
+ if (props.securityContext) valuesObj.securityContext = props.securityContext;
111
+ if (props.nodeSelector) valuesObj.nodeSelector = props.nodeSelector;
112
+ if (props.tolerations) valuesObj.tolerations = props.tolerations;
113
+ if (props.affinity) valuesObj.affinity = props.affinity;
114
+
115
+ if (serviceAccount) {
116
+ valuesObj.serviceAccount = {
117
+ create: true,
118
+ name: "",
119
+ annotations: {},
120
+ };
121
+ }
122
+
123
+ const containerSpec: Record<string, unknown> = {
124
+ name,
125
+ image: printf("%s:%s", values.image.repository, values.image.tag),
126
+ imagePullPolicy: values.image.pullPolicy,
127
+ ports: [
128
+ { containerPort: values.service.port, name: "http" },
129
+ { containerPort: values.monitoring.metricsPort, name: "metrics" },
130
+ ],
131
+ resources: toYaml(values.resources),
132
+ };
133
+
134
+ if (props.securityContext) containerSpec.securityContext = toYaml(values.securityContext);
135
+
136
+ const podSpec: Record<string, unknown> = {
137
+ containers: [containerSpec],
138
+ };
139
+
140
+ if (props.podSecurityContext) podSpec.securityContext = toYaml(values.podSecurityContext);
141
+ if (props.nodeSelector) podSpec.nodeSelector = With(values.nodeSelector, toYaml(values.nodeSelector));
142
+ if (props.tolerations) podSpec.tolerations = With(values.tolerations, toYaml(values.tolerations));
143
+ if (props.affinity) podSpec.affinity = With(values.affinity, toYaml(values.affinity));
144
+ if (serviceAccount) podSpec.serviceAccountName = include(`${name}.serviceAccountName`);
145
+
146
+ const deployment = {
147
+ apiVersion: "apps/v1",
148
+ kind: "Deployment",
149
+ metadata: {
150
+ name: include(`${name}.fullname`),
151
+ labels: include(`${name}.labels`),
152
+ },
153
+ spec: {
154
+ replicas: values.replicaCount,
155
+ selector: {
156
+ matchLabels: include(`${name}.selectorLabels`),
157
+ },
158
+ template: {
159
+ metadata: {
160
+ labels: include(`${name}.selectorLabels`),
161
+ },
162
+ spec: podSpec,
163
+ },
164
+ },
165
+ };
166
+
167
+ const service = {
168
+ apiVersion: "v1",
169
+ kind: "Service",
170
+ metadata: {
171
+ name: include(`${name}.fullname`),
172
+ labels: include(`${name}.labels`),
173
+ },
174
+ spec: {
175
+ type: values.service.type,
176
+ ports: [
177
+ {
178
+ port: values.service.port,
179
+ targetPort: "http",
180
+ protocol: "TCP",
181
+ name: "http",
182
+ },
183
+ {
184
+ port: values.monitoring.metricsPort,
185
+ targetPort: "metrics",
186
+ protocol: "TCP",
187
+ name: "metrics",
188
+ },
189
+ ],
190
+ selector: include(`${name}.selectorLabels`),
191
+ },
192
+ };
193
+
194
+ // ServiceMonitor CRD (monitoring.coreos.com/v1) — gated on Capabilities check
195
+ const serviceMonitor = If(`and .Values.monitoring.enabled (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1")`, {
196
+ apiVersion: "monitoring.coreos.com/v1",
197
+ kind: "ServiceMonitor",
198
+ metadata: {
199
+ name: include(`${name}.fullname`),
200
+ labels: include(`${name}.labels`),
201
+ },
202
+ spec: {
203
+ selector: {
204
+ matchLabels: include(`${name}.selectorLabels`),
205
+ },
206
+ endpoints: [{
207
+ port: "metrics",
208
+ path: values.monitoring.metricsPath,
209
+ interval: values.monitoring.scrapeInterval,
210
+ }],
211
+ },
212
+ });
213
+
214
+ const result: HelmMonitoredServiceResult = {
215
+ chart,
216
+ values: valuesObj,
217
+ deployment,
218
+ service,
219
+ serviceMonitor: serviceMonitor as unknown as Record<string, unknown>,
220
+ };
221
+
222
+ if (serviceAccount) {
223
+ result.serviceAccount = {
224
+ apiVersion: "v1",
225
+ kind: "ServiceAccount",
226
+ metadata: {
227
+ name: include(`${name}.serviceAccountName`),
228
+ labels: include(`${name}.labels`),
229
+ annotations: toYaml(values.serviceAccount.annotations),
230
+ },
231
+ };
232
+ }
233
+
234
+ if (alertRules) {
235
+ result.prometheusRule = If(`and .Values.alerting.enabled (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1")`, {
236
+ apiVersion: "monitoring.coreos.com/v1",
237
+ kind: "PrometheusRule",
238
+ metadata: {
239
+ name: include(`${name}.fullname`),
240
+ labels: include(`${name}.labels`),
241
+ },
242
+ spec: {
243
+ groups: [{
244
+ name: printf("%s.rules", name),
245
+ rules: toYaml(values.alerting.rules),
246
+ }],
247
+ },
248
+ }) as unknown as Record<string, unknown>;
249
+ }
250
+
251
+ return result;
252
+ }
@@ -0,0 +1,154 @@
1
+ /**
2
+ * HelmNamespaceEnv composite — Namespace + ResourceQuota + LimitRange + NetworkPolicy.
3
+ *
4
+ * Environment namespace pattern with optional resource governance and
5
+ * network isolation.
6
+ */
7
+
8
+ import { values, include, toYaml, If } from "../intrinsics";
9
+
10
+ export interface HelmNamespaceEnvProps {
11
+ /** Chart and release name. */
12
+ name: string;
13
+ /** Include ResourceQuota. Default: true. */
14
+ resourceQuota?: boolean;
15
+ /** Include LimitRange. Default: true. */
16
+ limitRange?: boolean;
17
+ /** Include NetworkPolicy. Default: true. */
18
+ networkPolicy?: boolean;
19
+ /** Chart appVersion. */
20
+ appVersion?: string;
21
+ }
22
+
23
+ export interface HelmNamespaceEnvResult {
24
+ chart: Record<string, unknown>;
25
+ values: Record<string, unknown>;
26
+ namespace: Record<string, unknown>;
27
+ resourceQuota?: Record<string, unknown>;
28
+ limitRange?: Record<string, unknown>;
29
+ networkPolicy?: Record<string, unknown>;
30
+ }
31
+
32
+ export function HelmNamespaceEnv(props: HelmNamespaceEnvProps): HelmNamespaceEnvResult {
33
+ const {
34
+ name,
35
+ resourceQuota = true,
36
+ limitRange = true,
37
+ networkPolicy = true,
38
+ appVersion = "1.0.0",
39
+ } = props;
40
+
41
+ const chart = {
42
+ apiVersion: "v2",
43
+ name,
44
+ version: "0.1.0",
45
+ appVersion,
46
+ type: "application",
47
+ description: `A Helm chart for ${name} namespace environment`,
48
+ };
49
+
50
+ const valuesObj: Record<string, unknown> = {
51
+ namespace: {
52
+ labels: {},
53
+ annotations: {},
54
+ },
55
+ };
56
+
57
+ if (resourceQuota) {
58
+ valuesObj.resourceQuota = {
59
+ enabled: true,
60
+ hard: {
61
+ cpu: "10",
62
+ memory: "20Gi",
63
+ pods: "50",
64
+ },
65
+ };
66
+ }
67
+
68
+ if (limitRange) {
69
+ valuesObj.limitRange = {
70
+ enabled: true,
71
+ default: {
72
+ cpu: "500m",
73
+ memory: "256Mi",
74
+ },
75
+ defaultRequest: {
76
+ cpu: "100m",
77
+ memory: "128Mi",
78
+ },
79
+ };
80
+ }
81
+
82
+ if (networkPolicy) {
83
+ valuesObj.networkPolicy = {
84
+ enabled: true,
85
+ denyIngress: true,
86
+ denyEgress: false,
87
+ };
88
+ }
89
+
90
+ const ns = {
91
+ apiVersion: "v1",
92
+ kind: "Namespace",
93
+ metadata: {
94
+ name: include(`${name}.fullname`),
95
+ labels: toYaml(values.namespace.labels),
96
+ annotations: toYaml(values.namespace.annotations),
97
+ },
98
+ };
99
+
100
+ const result: HelmNamespaceEnvResult = {
101
+ chart,
102
+ values: valuesObj,
103
+ namespace: ns,
104
+ };
105
+
106
+ if (resourceQuota) {
107
+ result.resourceQuota = If(values.resourceQuota.enabled, {
108
+ apiVersion: "v1",
109
+ kind: "ResourceQuota",
110
+ metadata: {
111
+ name: include(`${name}.fullname`),
112
+ labels: include(`${name}.labels`),
113
+ },
114
+ spec: {
115
+ hard: toYaml(values.resourceQuota.hard),
116
+ },
117
+ }) as unknown as Record<string, unknown>;
118
+ }
119
+
120
+ if (limitRange) {
121
+ result.limitRange = If(values.limitRange.enabled, {
122
+ apiVersion: "v1",
123
+ kind: "LimitRange",
124
+ metadata: {
125
+ name: include(`${name}.fullname`),
126
+ labels: include(`${name}.labels`),
127
+ },
128
+ spec: {
129
+ limits: [{
130
+ type: "Container",
131
+ default: toYaml(values.limitRange.default),
132
+ defaultRequest: toYaml(values.limitRange.defaultRequest),
133
+ }],
134
+ },
135
+ }) as unknown as Record<string, unknown>;
136
+ }
137
+
138
+ if (networkPolicy) {
139
+ result.networkPolicy = If(values.networkPolicy.enabled, {
140
+ apiVersion: "networking.k8s.io/v1",
141
+ kind: "NetworkPolicy",
142
+ metadata: {
143
+ name: include(`${name}.fullname`),
144
+ labels: include(`${name}.labels`),
145
+ },
146
+ spec: {
147
+ podSelector: {},
148
+ policyTypes: ["Ingress", "Egress"],
149
+ },
150
+ }) as unknown as Record<string, unknown>;
151
+ }
152
+
153
+ return result;
154
+ }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * HelmSecureIngress composite — Ingress + optional cert-manager Certificate.
3
+ *
4
+ * TLS-enabled ingress pattern with optional cert-manager integration
5
+ * for automatic certificate provisioning.
6
+ */
7
+
8
+ import { values, include, toYaml, If, Range } from "../intrinsics";
9
+
10
+ export interface HelmSecureIngressProps {
11
+ /** Chart and release name. */
12
+ name: string;
13
+ /** Default ingress class name. */
14
+ ingressClassName?: string;
15
+ /** cert-manager ClusterIssuer name. */
16
+ clusterIssuer?: string;
17
+ /** Chart appVersion. */
18
+ appVersion?: string;
19
+ }
20
+
21
+ export interface HelmSecureIngressResult {
22
+ chart: Record<string, unknown>;
23
+ values: Record<string, unknown>;
24
+ ingress: Record<string, unknown>;
25
+ certificate?: Record<string, unknown>;
26
+ }
27
+
28
+ export function HelmSecureIngress(props: HelmSecureIngressProps): HelmSecureIngressResult {
29
+ const {
30
+ name,
31
+ ingressClassName = "",
32
+ clusterIssuer = "letsencrypt-prod",
33
+ appVersion = "1.0.0",
34
+ } = props;
35
+
36
+ const chart = {
37
+ apiVersion: "v2",
38
+ name,
39
+ version: "0.1.0",
40
+ appVersion,
41
+ type: "application",
42
+ description: `A Helm chart for ${name} secure ingress`,
43
+ };
44
+
45
+ const valuesObj: Record<string, unknown> = {
46
+ ingress: {
47
+ enabled: true,
48
+ className: ingressClassName,
49
+ annotations: {},
50
+ hosts: [
51
+ {
52
+ host: `${name}.example.com`,
53
+ paths: [{ path: "/", pathType: "Prefix" }],
54
+ },
55
+ ],
56
+ tls: {
57
+ enabled: true,
58
+ secretName: `${name}-tls`,
59
+ },
60
+ },
61
+ certManager: {
62
+ enabled: true,
63
+ clusterIssuer,
64
+ },
65
+ };
66
+
67
+ const ingress = If(values.ingress.enabled, {
68
+ apiVersion: "networking.k8s.io/v1",
69
+ kind: "Ingress",
70
+ metadata: {
71
+ name: include(`${name}.fullname`),
72
+ labels: include(`${name}.labels`),
73
+ annotations: toYaml(values.ingress.annotations),
74
+ },
75
+ spec: {
76
+ ingressClassName: values.ingress.className,
77
+ tls: [{
78
+ secretName: values.ingress.tls.secretName,
79
+ hosts: Range(values.ingress.hosts, values.ingress.hosts),
80
+ }],
81
+ rules: Range(values.ingress.hosts, {
82
+ host: values.ingress.hosts,
83
+ http: {
84
+ paths: values.ingress.hosts,
85
+ },
86
+ }),
87
+ },
88
+ });
89
+
90
+ // cert-manager Certificate CRD (cert-manager.io/v1)
91
+ const certificate = If(values.certManager.enabled, {
92
+ apiVersion: "cert-manager.io/v1",
93
+ kind: "Certificate",
94
+ metadata: {
95
+ name: include(`${name}.fullname`),
96
+ labels: include(`${name}.labels`),
97
+ },
98
+ spec: {
99
+ secretName: values.ingress.tls.secretName,
100
+ issuerRef: {
101
+ name: values.certManager.clusterIssuer,
102
+ kind: "ClusterIssuer",
103
+ },
104
+ dnsNames: values.ingress.hosts,
105
+ },
106
+ });
107
+
108
+ return {
109
+ chart,
110
+ values: valuesObj,
111
+ ingress: ingress as unknown as Record<string, unknown>,
112
+ certificate: certificate as unknown as Record<string, unknown>,
113
+ };
114
+ }