@intentius/chant-lexicon-k8s 0.0.12 → 0.0.14

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.
@@ -126,20 +126,6 @@ kubectl port-forward pod/<pod-name> 8080:8080
126
126
  | CreateContainerError | Container config issue | `kubectl describe pod` → Events | Check volume mounts, configmap/secret refs, security context |
127
127
  | Init:CrashLoopBackOff | Init container failing | `kubectl logs -c <init-container>` | Fix init container command, check dependencies |
128
128
 
129
- ### Resource inspection
130
-
131
- ```bash
132
- # Get all resources in namespace
133
- kubectl get all -n <namespace>
134
-
135
- # YAML output for debugging
136
- kubectl get deployment/my-app -o yaml
137
-
138
- # Check resource usage
139
- kubectl top pods -l app.kubernetes.io/name=my-app
140
- kubectl top nodes
141
- ```
142
-
143
129
  ## Production safety
144
130
 
145
131
  ### Pre-apply validation
@@ -155,22 +141,6 @@ kubectl apply -f manifests.yaml --dry-run=server
155
141
  kubectl apply -f manifests.yaml --dry-run=client
156
142
  ```
157
143
 
158
- ### Rollback
159
-
160
- ```bash
161
- # Check rollout history
162
- kubectl rollout history deployment/my-app
163
-
164
- # Undo last rollout
165
- kubectl rollout undo deployment/my-app
166
-
167
- # Roll back to a specific revision
168
- kubectl rollout undo deployment/my-app --to-revision=2
169
-
170
- # Watch rollout progress
171
- kubectl rollout status deployment/my-app --timeout=300s
172
- ```
173
-
174
144
  ### Deployment strategies
175
145
 
176
146
  - **RollingUpdate** (default): Gradually replaces pods. Set `maxSurge` and `maxUnavailable`.
@@ -178,157 +148,42 @@ kubectl rollout status deployment/my-app --timeout=300s
178
148
  - **Canary**: Deploy a second Deployment with 1 replica + same selector labels. Route percentage via Ingress annotations or service mesh.
179
149
  - **Blue/Green**: Two full Deployments (blue/green), switch Service selector between them.
180
150
 
181
- ## Composites
182
-
183
- Composites are higher-level functions that produce multiple coordinated K8s resources from a single call. They return plain prop objects — not class instances — that you pass to generated constructors or serialize directly.
184
-
185
- ### WebApp — Deployment + Service + optional Ingress
186
-
187
- ```typescript
188
- import { WebApp } from "@intentius/chant-lexicon-k8s";
189
-
190
- const { deployment, service, ingress } = WebApp({
191
- name: "frontend",
192
- image: "frontend:1.0",
193
- port: 3000,
194
- replicas: 3,
195
- ingressHost: "frontend.example.com",
196
- ingressTlsSecret: "frontend-tls",
197
- });
198
- ```
199
-
200
- ### StatefulApp StatefulSet + headless Service + PVC
201
-
202
- ```typescript
203
- import { StatefulApp } from "@intentius/chant-lexicon-k8s";
204
-
205
- const { statefulSet, service } = StatefulApp({
206
- name: "postgres",
207
- image: "postgres:16",
208
- storageSize: "20Gi",
209
- env: [{ name: "POSTGRES_DB", value: "mydb" }],
210
- });
211
- ```
212
-
213
- ### CronWorkloadCronJob + ServiceAccount + Role + RoleBinding
214
-
215
- ```typescript
216
- import { CronWorkload } from "@intentius/chant-lexicon-k8s";
217
-
218
- const { cronJob, serviceAccount, role, roleBinding } = CronWorkload({
219
- name: "db-backup",
220
- image: "postgres:16",
221
- schedule: "0 2 * * *",
222
- command: ["pg_dump", "-h", "postgres", "mydb"],
223
- rbacRules: [{ apiGroups: [""], resources: ["secrets"], verbs: ["get"] }],
224
- });
225
- ```
226
-
227
- ### AutoscaledService — Deployment + Service + HPA + PDB
228
-
229
- Production HTTP service with autoscaling, health probes, and optional topology spreading.
230
-
231
- ```typescript
232
- import { AutoscaledService } from "@intentius/chant-lexicon-k8s";
233
-
234
- const { deployment, service, hpa, pdb } = AutoscaledService({
235
- name: "api",
236
- image: "api:2.0",
237
- port: 8080,
238
- maxReplicas: 10,
239
- minReplicas: 3,
240
- cpuRequest: "200m",
241
- memoryRequest: "256Mi",
242
- cpuLimit: "1",
243
- memoryLimit: "1Gi",
244
- // Probe paths — defaults: /healthz and /readyz
245
- livenessPath: "/healthz",
246
- readinessPath: "/readyz",
247
- // Zone-aware topology spreading (default: false)
248
- topologySpread: true,
249
- // Custom: topologySpread: { maxSkew: 2, topologyKey: "kubernetes.io/hostname" }
250
- });
251
- ```
252
-
253
- Key features:
254
- - **Probe paths**: `livenessPath` (default `/healthz`) and `readinessPath` (default `/readyz`) — override for apps that don't serve those routes
255
- - **Topology spread**: `topologySpread: true` adds zone-aware spreading (maxSkew=1, DoNotSchedule); pass an object for custom key/skew
256
- - **PDB minAvailable**: accepts number or string percentage (e.g., `"50%"`)
257
-
258
- ### WorkerPool — Deployment + RBAC + optional ConfigMap + optional HPA
259
-
260
- Background queue workers with optional RBAC and autoscaling.
261
-
262
- ```typescript
263
- import { WorkerPool } from "@intentius/chant-lexicon-k8s";
264
-
265
- const { deployment, serviceAccount, role, roleBinding, configMap, hpa } = WorkerPool({
266
- name: "email-worker",
267
- image: "worker:1.0",
268
- command: ["bundle", "exec", "sidekiq"],
269
- config: { REDIS_URL: "redis://redis:6379", QUEUE: "emails" },
270
- autoscaling: { minReplicas: 2, maxReplicas: 20, targetCPUPercent: 60 },
271
- });
272
- ```
273
-
274
- Key features:
275
- - **RBAC opt-out**: Pass `rbacRules: []` to skip ServiceAccount/Role/RoleBinding creation entirely. Omitting `rbacRules` (undefined) creates default rules for secrets/configmaps.
276
- - `serviceAccount`, `role`, `roleBinding` are optional in the result — check before use
277
-
278
- ### NamespaceEnv — Namespace + ResourceQuota + LimitRange + NetworkPolicy
279
-
280
- Multi-tenant namespace provisioning with resource guardrails and network isolation.
281
-
282
- ```typescript
283
- import { NamespaceEnv } from "@intentius/chant-lexicon-k8s";
284
-
285
- const { namespace, resourceQuota, limitRange, networkPolicy } = NamespaceEnv({
286
- name: "team-alpha",
287
- cpuQuota: "8",
288
- memoryQuota: "16Gi",
289
- maxPods: 50,
290
- defaultCpuRequest: "100m",
291
- defaultMemoryRequest: "128Mi",
292
- defaultCpuLimit: "500m",
293
- defaultMemoryLimit: "512Mi",
294
- defaultDenyIngress: true,
295
- defaultDenyEgress: true,
296
- });
297
- ```
298
-
299
- Key features:
300
- - **Quota-without-limits warning**: Setting ResourceQuota without LimitRange defaults emits a warning — pods without explicit resource requests will fail to schedule
301
- - **Network policies**: `defaultDenyIngress` (default true), `defaultDenyEgress` (default false) — can be combined or used individually
302
-
303
- ### NodeAgent — DaemonSet + ServiceAccount + ClusterRole + ClusterRoleBinding + optional ConfigMap
304
-
305
- Per-node agents (log collectors, security scanners, monitoring exporters).
306
-
307
- ```typescript
308
- import { NodeAgent } from "@intentius/chant-lexicon-k8s";
309
-
310
- const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = NodeAgent({
311
- name: "log-collector",
312
- image: "fluentd:v1.16",
313
- port: 24224,
314
- hostPaths: [
315
- { name: "varlog", hostPath: "/var/log", mountPath: "/var/log" },
316
- ],
317
- config: { "fluent.conf": "..." },
318
- rbacRules: [{ apiGroups: [""], resources: ["pods", "namespaces"], verbs: ["get", "list", "watch"] }],
319
- cpuRequest: "50m", // default: 50m
320
- memoryRequest: "64Mi", // default: 64Mi
321
- cpuLimit: "200m", // default: 200m
322
- memoryLimit: "128Mi", // default: 128Mi
323
- namespace: "monitoring",
324
- });
325
- ```
326
-
327
- Key features:
328
- - **Container resources**: Always set with sensible defaults (50m/64Mi requests, 200m/128Mi limits) — override per-agent
329
- - **Host paths**: Mounted read-only by default; set `readOnly: false` to enable writes
330
- - **Tolerations**: `tolerateAllTaints: true` (default) ensures agent runs on every node
331
- - Uses **ClusterRole/ClusterRoleBinding** (cluster-scoped) for node-level access
151
+ ## Choosing the Right Composite
152
+
153
+ Composites are higher-level functions that produce multiple coordinated K8s resources from a single call. They return plain prop objects — not class instances.
154
+
155
+ ### Decision Tree
156
+
157
+ | Need | Composite | Resources |
158
+ |------|-----------|-----------|
159
+ | Stateless web app | **WebApp** | Deployment + Service + optional Ingress + optional PDB |
160
+ | Stateful database/cache | **StatefulApp** | StatefulSet + headless Service + PVC + optional PDB |
161
+ | Production HTTP service with autoscaling | **AutoscaledService** | Deployment + Service + HPA + PDB |
162
+ | Background queue workers | **WorkerPool** | Deployment + RBAC + optional ConfigMap + optional HPA + optional PDB |
163
+ | Scheduled jobs | **CronWorkload** | CronJob + RBAC |
164
+ | One-shot batch jobs | **BatchJob** | Job + optional RBAC |
165
+ | App with ConfigMap/Secret mounts | **ConfiguredApp** | Deployment + Service + optional ConfigMap |
166
+ | Multi-container sidecar patterns | **SidecarApp** | Deployment + Service |
167
+ | App with Prometheus monitoring | **MonitoredService** | Deployment + Service + ServiceMonitor + optional PrometheusRule |
168
+ | App with fine-grained network policies | **NetworkIsolatedApp** | Deployment + Service + NetworkPolicy |
169
+ | Namespace with quotas and isolation | **NamespaceEnv** | Namespace + ResourceQuota + LimitRange + NetworkPolicy |
170
+ | Per-node agent (custom) | **NodeAgent** | DaemonSet + RBAC + optional ConfigMap |
171
+ | Multi-host TLS Ingress (cert-manager) | **SecureIngress** | Ingress + optional Certificate |
172
+ | EKS IRSA ServiceAccount | **IrsaServiceAccount** | ServiceAccount + optional RBAC |
173
+ | AWS ALB Ingress | **AlbIngress** | Ingress with ALB annotations |
174
+ | EBS StorageClass | **EbsStorageClass** | StorageClass (ebs.csi.aws.com) |
175
+ | EFS StorageClass | **EfsStorageClass** | StorageClass (efs.csi.aws.com) |
176
+ | Fluent Bit for CloudWatch | **FluentBitAgent** | DaemonSet + RBAC + ConfigMap |
177
+ | ExternalDNS for Route53 | **ExternalDnsAgent** | Deployment + IRSA SA + ClusterRole |
178
+ | ADOT for CloudWatch/X-Ray | **AdotCollector** | DaemonSet + RBAC + ConfigMap |
179
+
180
+ ### Hardening options (available on Deployment-based composites)
181
+
182
+ - `minAvailable` — creates a PodDisruptionBudget (WebApp, StatefulApp, WorkerPool; AutoscaledService always has one)
183
+ - `initContainers`run before main containers (WebApp, StatefulApp, AutoscaledService, ConfiguredApp, SidecarApp)
184
+ - `securityContext` — container security settings (WebApp, StatefulApp, AutoscaledService, WorkerPool)
185
+ - `terminationGracePeriodSeconds` — graceful shutdown (WebApp, StatefulApp, AutoscaledService, WorkerPool)
186
+ - `priorityClassName` pod scheduling priority (WebApp, StatefulApp, AutoscaledService, WorkerPool)
332
187
 
333
188
  ### Common patterns across all composites
334
189
 
@@ -337,49 +192,6 @@ Key features:
337
192
  - Pass `namespace: "prod"` to set namespace on all namespaced resources
338
193
  - Pass `env: [{ name: "KEY", value: "val" }]` for container environment variables
339
194
 
340
- ## Namespace management
341
-
342
- Use the **NamespaceEnv** composite (above) to manage namespaces declaratively. For manual kubectl management:
343
-
344
- ```bash
345
- # Create namespace
346
- kubectl create namespace my-project
347
-
348
- # Set default resource quotas
349
- kubectl apply -f - <<EOF
350
- apiVersion: v1
351
- kind: ResourceQuota
352
- metadata:
353
- name: default-quota
354
- namespace: my-project
355
- spec:
356
- hard:
357
- requests.cpu: "4"
358
- requests.memory: 8Gi
359
- limits.cpu: "8"
360
- limits.memory: 16Gi
361
- pods: "20"
362
- EOF
363
-
364
- # Set default container limits via LimitRange
365
- kubectl apply -f - <<EOF
366
- apiVersion: v1
367
- kind: LimitRange
368
- metadata:
369
- name: default-limits
370
- namespace: my-project
371
- spec:
372
- limits:
373
- - default:
374
- cpu: 500m
375
- memory: 256Mi
376
- defaultRequest:
377
- cpu: 100m
378
- memory: 128Mi
379
- type: Container
380
- EOF
381
- ```
382
-
383
195
  ## Troubleshooting reference table
384
196
 
385
197
  | Symptom | Likely cause | Resolution |
@@ -388,11 +200,8 @@ EOF
388
200
  | Pod stuck in Pending | PVC not bound | Check StorageClass exists, PV available |
389
201
  | Pod stuck in Pending | Node selector/affinity mismatch | Verify node labels match selectors |
390
202
  | Pod stuck in ContainerCreating | ConfigMap/Secret not found | Ensure referenced ConfigMaps/Secrets exist |
391
- | Pod stuck in ContainerCreating | Volume mount failure | Check PVC status, CSI driver health |
392
203
  | Service returns 503 | No ready endpoints | Check pod readiness probes, selector match |
393
- | Service returns 503 | Wrong port configuration | Verify targetPort matches containerPort |
394
204
  | Ingress returns 404 | Backend service not found | Check Ingress rules, service name/port |
395
- | Ingress returns 404 | Wrong path matching | Check pathType (Prefix vs Exact) |
396
205
  | HPA not scaling | Metrics server not installed | Install metrics-server |
397
206
  | HPA not scaling | Resource requests not set | Add CPU/memory requests to containers |
398
207
  | CronJob not running | Invalid cron expression | Validate cron syntax (5-field format) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-k8s",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "files": ["src/", "dist/"],
@@ -22,7 +22,7 @@
22
22
  "prepack": "bun run generate && bun run bundle && bun run validate"
23
23
  },
24
24
  "dependencies": {
25
- "@intentius/chant": "0.0.11"
25
+ "@intentius/chant": "0.0.13"
26
26
  },
27
27
  "devDependencies": {
28
28
  "typescript": "^5.9.3"
@@ -18,7 +18,7 @@ function serviceFromType(resourceType: string): string {
18
18
 
19
19
  const overview = `The **Kubernetes** lexicon provides typed constructors for Kubernetes resource
20
20
  manifests. It covers Deployments, Services, ConfigMaps, StatefulSets, Jobs,
21
- Ingress, RBAC, and 50+ additional resource and property types.
21
+ Ingress, RBAC, and 147 resources and 50 property types.
22
22
 
23
23
  New? Start with the [Getting Started](/chant/lexicons/k8s/getting-started/) guide.
24
24
 
@@ -64,7 +64,7 @@ export const service = new Service({
64
64
  });
65
65
  \`\`\`
66
66
 
67
- The lexicon provides **50+ resource types** (Deployment, Service, ConfigMap, StatefulSet, and more), **35+ property types** (Container, Probe, Volume, SecurityContext, etc.), and composites (WebApp, StatefulApp, CronWorkload, AutoscaledService, WorkerPool, NamespaceEnv, NodeAgent) for common patterns.
67
+ The lexicon provides **147 resource types** (Deployment, Service, ConfigMap, StatefulSet, and more), **50 property types** (Container, Probe, Volume, SecurityContext, etc.), and composites (WebApp, StatefulApp, CronWorkload, AutoscaledService, WorkerPool, NamespaceEnv, NodeAgent) for common patterns.
68
68
  `;
69
69
 
70
70
  const outputFormat = `The Kubernetes lexicon serializes resources into **multi-document YAML** with
@@ -76,7 +76,7 @@ structure: \`apiVersion\`, \`kind\`, \`metadata\`, and \`spec\`.
76
76
  Run \`chant build\` to produce Kubernetes manifests from your declarations:
77
77
 
78
78
  \`\`\`bash
79
- chant build
79
+ chant build src/ --output dist/manifests.yaml
80
80
  # Writes dist/manifests.yaml
81
81
  \`\`\`
82
82
 
@@ -134,7 +134,7 @@ export async function generateDocs(opts?: { verbose?: boolean }): Promise<void>
134
134
  overview,
135
135
  outputFormat,
136
136
  serviceFromType,
137
- suppressPages: ["pseudo-parameters"],
137
+ suppressPages: ["pseudo-parameters", "rules"],
138
138
  extraPages: [
139
139
  {
140
140
  slug: "getting-started",
@@ -0,0 +1,239 @@
1
+ /**
2
+ * AdotCollector composite — DaemonSet + RBAC + ConfigMap for AWS Distro for OpenTelemetry.
3
+ *
4
+ * @eks ADOT collector for CloudWatch and X-Ray. NodeAgent specialization
5
+ * with pre-configured pipelines for AWS observability.
6
+ */
7
+
8
+ export interface AdotCollectorProps {
9
+ /** AWS region. */
10
+ region: string;
11
+ /** EKS cluster name. */
12
+ clusterName: string;
13
+ /** Exporters to enable (default: ["cloudwatch", "xray"]). */
14
+ exporters?: ("cloudwatch" | "xray" | "prometheus")[];
15
+ /** Agent name (default: "adot-collector"). */
16
+ name?: string;
17
+ /** ADOT image (default: "public.ecr.aws/aws-observability/aws-otel-collector:latest"). */
18
+ image?: string;
19
+ /** Namespace (default: "amazon-metrics"). */
20
+ namespace?: string;
21
+ /** Additional labels. */
22
+ labels?: Record<string, string>;
23
+ /** CPU request (default: "100m"). */
24
+ cpuRequest?: string;
25
+ /** Memory request (default: "256Mi"). */
26
+ memoryRequest?: string;
27
+ /** CPU limit (default: "500m"). */
28
+ cpuLimit?: string;
29
+ /** Memory limit (default: "512Mi"). */
30
+ memoryLimit?: string;
31
+ /** IAM Role ARN for IRSA (adds eks.amazonaws.com/role-arn annotation to ServiceAccount). */
32
+ iamRoleArn?: string;
33
+ }
34
+
35
+ export interface AdotCollectorResult {
36
+ daemonSet: Record<string, unknown>;
37
+ serviceAccount: Record<string, unknown>;
38
+ clusterRole: Record<string, unknown>;
39
+ clusterRoleBinding: Record<string, unknown>;
40
+ configMap: Record<string, unknown>;
41
+ }
42
+
43
+ /**
44
+ * Create an AdotCollector composite — returns prop objects for
45
+ * a DaemonSet, ServiceAccount, ClusterRole, ClusterRoleBinding, and ConfigMap.
46
+ *
47
+ * @eks
48
+ * @example
49
+ * ```ts
50
+ * import { AdotCollector } from "@intentius/chant-lexicon-k8s";
51
+ *
52
+ * const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = AdotCollector({
53
+ * region: "us-east-1",
54
+ * clusterName: "my-cluster",
55
+ * exporters: ["cloudwatch", "xray"],
56
+ * });
57
+ * ```
58
+ */
59
+ export function AdotCollector(props: AdotCollectorProps): AdotCollectorResult {
60
+ const {
61
+ region,
62
+ clusterName,
63
+ exporters = ["cloudwatch", "xray"],
64
+ name = "adot-collector",
65
+ image = "public.ecr.aws/aws-observability/aws-otel-collector:latest",
66
+ namespace = "amazon-metrics",
67
+ labels: extraLabels = {},
68
+ cpuRequest = "100m",
69
+ memoryRequest = "256Mi",
70
+ cpuLimit = "500m",
71
+ memoryLimit = "512Mi",
72
+ iamRoleArn,
73
+ } = props;
74
+
75
+ const saName = `${name}-sa`;
76
+ const clusterRoleName = `${name}-role`;
77
+ const bindingName = `${name}-binding`;
78
+ const configMapName = `${name}-config`;
79
+
80
+ const commonLabels: Record<string, string> = {
81
+ "app.kubernetes.io/name": name,
82
+ "app.kubernetes.io/managed-by": "chant",
83
+ ...extraLabels,
84
+ };
85
+
86
+ // Build ADOT config YAML
87
+ const exporterConfigs: string[] = [];
88
+ const exporterNames: string[] = [];
89
+
90
+ if (exporters.includes("cloudwatch")) {
91
+ exporterConfigs.push(` awsemf:
92
+ region: ${region}
93
+ namespace: ContainerInsights
94
+ log_group_name: '/aws/containerinsights/${clusterName}/performance'
95
+ dimension_rollup_option: NoDimensionRollup`);
96
+ exporterNames.push("awsemf");
97
+ }
98
+
99
+ if (exporters.includes("xray")) {
100
+ exporterConfigs.push(` awsxray:
101
+ region: ${region}`);
102
+ exporterNames.push("awsxray");
103
+ }
104
+
105
+ if (exporters.includes("prometheus")) {
106
+ exporterConfigs.push(` prometheusremotewrite:
107
+ endpoint: http://prometheus:9090/api/v1/write`);
108
+ exporterNames.push("prometheusremotewrite");
109
+ }
110
+
111
+ const adotConfig = `receivers:
112
+ otlp:
113
+ protocols:
114
+ grpc:
115
+ endpoint: 0.0.0.0:4317
116
+ http:
117
+ endpoint: 0.0.0.0:4318
118
+
119
+ processors:
120
+ batch:
121
+ timeout: 30s
122
+ send_batch_size: 8192
123
+
124
+ exporters:
125
+ ${exporterConfigs.join("\n")}
126
+
127
+ service:
128
+ pipelines:
129
+ metrics:
130
+ receivers: [otlp]
131
+ processors: [batch]
132
+ exporters: [${exporterNames.join(", ")}]
133
+ traces:
134
+ receivers: [otlp]
135
+ processors: [batch]
136
+ exporters: [${exporterNames.filter((e) => e !== "awsemf").join(", ") || "awsxray"}]
137
+ `;
138
+
139
+ const container: Record<string, unknown> = {
140
+ name,
141
+ image,
142
+ command: ["--config=/etc/adot/config.yaml"],
143
+ ports: [
144
+ { containerPort: 4317, name: "otlp-grpc" },
145
+ { containerPort: 4318, name: "otlp-http" },
146
+ ],
147
+ resources: {
148
+ requests: { cpu: cpuRequest, memory: memoryRequest },
149
+ limits: { cpu: cpuLimit, memory: memoryLimit },
150
+ },
151
+ volumeMounts: [
152
+ { name: "config", mountPath: "/etc/adot", readOnly: true },
153
+ ],
154
+ };
155
+
156
+ const daemonSetProps: Record<string, unknown> = {
157
+ metadata: {
158
+ name,
159
+ namespace,
160
+ labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
161
+ },
162
+ spec: {
163
+ selector: { matchLabels: { "app.kubernetes.io/name": name } },
164
+ template: {
165
+ metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
166
+ spec: {
167
+ serviceAccountName: saName,
168
+ containers: [container],
169
+ volumes: [
170
+ { name: "config", configMap: { name: configMapName } },
171
+ ],
172
+ tolerations: [{ operator: "Exists" }],
173
+ },
174
+ },
175
+ },
176
+ };
177
+
178
+ const serviceAccountProps: Record<string, unknown> = {
179
+ metadata: {
180
+ name: saName,
181
+ namespace,
182
+ labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
183
+ ...(iamRoleArn ? { annotations: { "eks.amazonaws.com/role-arn": iamRoleArn } } : {}),
184
+ },
185
+ };
186
+
187
+ const clusterRoleProps: Record<string, unknown> = {
188
+ metadata: {
189
+ name: clusterRoleName,
190
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
191
+ },
192
+ rules: [
193
+ { apiGroups: [""], resources: ["pods", "nodes", "endpoints"], verbs: ["get", "list", "watch"] },
194
+ { apiGroups: ["apps"], resources: ["replicasets"], verbs: ["get", "list", "watch"] },
195
+ { apiGroups: ["batch"], resources: ["jobs"], verbs: ["get", "list", "watch"] },
196
+ { apiGroups: [""], resources: ["nodes/proxy"], verbs: ["get"] },
197
+ { apiGroups: [""], resources: ["nodes/stats", "configmaps", "events"], verbs: ["create", "get"] },
198
+ { apiGroups: [""], resources: ["configmaps"], verbs: ["get", "update", "create"], resourceNames: ["otel-container-insight-clusterleader"] },
199
+ ],
200
+ };
201
+
202
+ const clusterRoleBindingProps: Record<string, unknown> = {
203
+ metadata: {
204
+ name: bindingName,
205
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
206
+ },
207
+ roleRef: {
208
+ apiGroup: "rbac.authorization.k8s.io",
209
+ kind: "ClusterRole",
210
+ name: clusterRoleName,
211
+ },
212
+ subjects: [
213
+ {
214
+ kind: "ServiceAccount",
215
+ name: saName,
216
+ namespace,
217
+ },
218
+ ],
219
+ };
220
+
221
+ const configMapProps: Record<string, unknown> = {
222
+ metadata: {
223
+ name: configMapName,
224
+ namespace,
225
+ labels: { ...commonLabels, "app.kubernetes.io/component": "config" },
226
+ },
227
+ data: {
228
+ "config.yaml": adotConfig,
229
+ },
230
+ };
231
+
232
+ return {
233
+ daemonSet: daemonSetProps,
234
+ serviceAccount: serviceAccountProps,
235
+ clusterRole: clusterRoleProps,
236
+ clusterRoleBinding: clusterRoleBindingProps,
237
+ configMap: configMapProps,
238
+ };
239
+ }