@intentius/chant-lexicon-k8s 0.0.14 → 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 (63) hide show
  1. package/dist/integrity.json +8 -4
  2. package/dist/manifest.json +1 -1
  3. package/dist/rules/latest-image-tag.ts +121 -0
  4. package/dist/rules/missing-resource-limits.ts +111 -0
  5. package/dist/rules/wk8204.ts +33 -1
  6. package/dist/rules/wk8304.ts +70 -0
  7. package/dist/rules/wk8305.ts +115 -0
  8. package/dist/rules/wk8306.ts +50 -0
  9. package/package.json +27 -24
  10. package/src/codegen/docs.ts +1 -1
  11. package/src/composites/adot-collector.ts +8 -2
  12. package/src/composites/agic-ingress.ts +148 -0
  13. package/src/composites/aks-external-dns-agent.ts +199 -0
  14. package/src/composites/alb-ingress.ts +2 -1
  15. package/src/composites/autoscaled-service.ts +25 -7
  16. package/src/composites/azure-disk-storage-class.ts +82 -0
  17. package/src/composites/azure-file-storage-class.ts +77 -0
  18. package/src/composites/azure-monitor-collector.ts +232 -0
  19. package/src/composites/batch-job.ts +36 -3
  20. package/src/composites/composites.test.ts +1060 -0
  21. package/src/composites/config-connector-context.ts +62 -0
  22. package/src/composites/configured-app.ts +6 -0
  23. package/src/composites/cron-workload.ts +6 -0
  24. package/src/composites/ebs-storage-class.ts +4 -4
  25. package/src/composites/external-dns-agent.ts +6 -0
  26. package/src/composites/filestore-storage-class.ts +79 -0
  27. package/src/composites/fluent-bit-agent.ts +5 -0
  28. package/src/composites/gce-ingress.ts +143 -0
  29. package/src/composites/gce-pd-storage-class.ts +85 -0
  30. package/src/composites/gke-external-dns-agent.ts +175 -0
  31. package/src/composites/gke-fluent-bit-agent.ts +219 -0
  32. package/src/composites/gke-gateway.ts +143 -0
  33. package/src/composites/gke-otel-collector.ts +229 -0
  34. package/src/composites/index.ts +31 -0
  35. package/src/composites/metrics-server.ts +1 -1
  36. package/src/composites/monitored-service.ts +6 -0
  37. package/src/composites/network-isolated-app.ts +6 -0
  38. package/src/composites/node-agent.ts +6 -0
  39. package/src/composites/security-context.ts +10 -0
  40. package/src/composites/sidecar-app.ts +6 -0
  41. package/src/composites/stateful-app.ts +4 -7
  42. package/src/composites/web-app.ts +4 -7
  43. package/src/composites/worker-pool.ts +4 -7
  44. package/src/composites/workload-identity-sa.ts +118 -0
  45. package/src/composites/workload-identity-service-account.ts +116 -0
  46. package/src/index.ts +20 -1
  47. package/src/lint/post-synth/post-synth.test.ts +362 -1
  48. package/src/lint/post-synth/wk8204.ts +33 -1
  49. package/src/lint/post-synth/wk8304.ts +70 -0
  50. package/src/lint/post-synth/wk8305.ts +115 -0
  51. package/src/lint/post-synth/wk8306.ts +50 -0
  52. package/src/lint/rules/latest-image-tag.ts +121 -0
  53. package/src/lint/rules/missing-resource-limits.ts +111 -0
  54. package/src/lint/rules/rules.test.ts +192 -0
  55. package/src/plugin.test.ts +2 -2
  56. package/src/plugin.ts +129 -209
  57. package/src/serializer.test.ts +120 -0
  58. package/src/serializer.ts +16 -4
  59. package/src/skills/chant-k8s-aks.md +146 -0
  60. package/src/skills/chant-k8s-gke.md +191 -0
  61. package/src/skills/kubernetes-patterns.md +183 -0
  62. package/src/skills/kubernetes-security.md +237 -0
  63. /package/{dist → src}/skills/chant-k8s-eks.md +0 -0
@@ -0,0 +1,219 @@
1
+ /**
2
+ * GkeFluentBitAgent composite — DaemonSet + RBAC + ConfigMap for Fluent Bit on GKE.
3
+ *
4
+ * @gke Like FluentBitAgent but targets Cloud Logging via the stackdriver
5
+ * output plugin and uses GKE Workload Identity instead of IRSA.
6
+ */
7
+
8
+ export interface GkeFluentBitAgentProps {
9
+ /** GKE cluster name — used as log stream prefix. */
10
+ clusterName: string;
11
+ /** GCP project ID. */
12
+ projectId: string;
13
+ /** GCP service account email for Workload Identity. */
14
+ gcpServiceAccountEmail?: string;
15
+ /** Agent name (default: "fluent-bit"). */
16
+ name?: string;
17
+ /** Fluent Bit image (default: "fluent/fluent-bit:latest"). */
18
+ image?: string;
19
+ /** Namespace (default: "gke-logging"). */
20
+ namespace?: string;
21
+ /** Additional labels. */
22
+ labels?: Record<string, string>;
23
+ /** CPU request (default: "50m"). */
24
+ cpuRequest?: string;
25
+ /** Memory request (default: "64Mi"). */
26
+ memoryRequest?: string;
27
+ /** CPU limit (default: "200m"). */
28
+ cpuLimit?: string;
29
+ /** Memory limit (default: "128Mi"). */
30
+ memoryLimit?: string;
31
+ }
32
+
33
+ export interface GkeFluentBitAgentResult {
34
+ daemonSet: Record<string, unknown>;
35
+ serviceAccount: Record<string, unknown>;
36
+ clusterRole: Record<string, unknown>;
37
+ clusterRoleBinding: Record<string, unknown>;
38
+ configMap: Record<string, unknown>;
39
+ }
40
+
41
+ /**
42
+ * Create a GkeFluentBitAgent composite — returns prop objects for
43
+ * a DaemonSet, ServiceAccount, ClusterRole, ClusterRoleBinding, and ConfigMap.
44
+ *
45
+ * @gke
46
+ * @example
47
+ * ```ts
48
+ * import { GkeFluentBitAgent } from "@intentius/chant-lexicon-k8s";
49
+ *
50
+ * const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = GkeFluentBitAgent({
51
+ * clusterName: "my-cluster",
52
+ * projectId: "my-project",
53
+ * gcpServiceAccountEmail: "fluent-bit@my-project.iam.gserviceaccount.com",
54
+ * });
55
+ * ```
56
+ */
57
+ export function GkeFluentBitAgent(props: GkeFluentBitAgentProps): GkeFluentBitAgentResult {
58
+ const {
59
+ clusterName,
60
+ projectId,
61
+ gcpServiceAccountEmail,
62
+ name = "fluent-bit",
63
+ image = "fluent/fluent-bit:latest",
64
+ namespace = "gke-logging",
65
+ labels: extraLabels = {},
66
+ cpuRequest = "50m",
67
+ memoryRequest = "64Mi",
68
+ cpuLimit = "200m",
69
+ memoryLimit = "128Mi",
70
+ } = props;
71
+
72
+ const saName = `${name}-sa`;
73
+ const clusterRoleName = `${name}-role`;
74
+ const bindingName = `${name}-binding`;
75
+ const configMapName = `${name}-config`;
76
+
77
+ const commonLabels: Record<string, string> = {
78
+ "app.kubernetes.io/name": name,
79
+ "app.kubernetes.io/managed-by": "chant",
80
+ ...extraLabels,
81
+ };
82
+
83
+ const fluentBitConfig = `[SERVICE]
84
+ Flush 5
85
+ Log_Level info
86
+ Daemon off
87
+ Parsers_File parsers.conf
88
+
89
+ [INPUT]
90
+ Name tail
91
+ Tag kube.*
92
+ Path /var/log/containers/*.log
93
+ Parser docker
94
+ DB /var/fluent-bit/state/flb_container.db
95
+ Mem_Buf_Limit 5MB
96
+ Skip_Long_Lines On
97
+ Refresh_Interval 10
98
+
99
+ [FILTER]
100
+ Name kubernetes
101
+ Match kube.*
102
+ Kube_URL https://kubernetes.default.svc:443
103
+ Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
104
+ Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
105
+ Merge_Log On
106
+ K8S-Logging.Parser On
107
+ K8S-Logging.Exclude Off
108
+
109
+ [OUTPUT]
110
+ Name stackdriver
111
+ Match *
112
+ google_service_credentials /var/run/secrets/kubernetes.io/serviceaccount/token
113
+ resource k8s_container
114
+ k8s_cluster_name ${clusterName}
115
+ k8s_cluster_location ${projectId}
116
+ `;
117
+
118
+ const container: Record<string, unknown> = {
119
+ name,
120
+ image,
121
+ resources: {
122
+ requests: { cpu: cpuRequest, memory: memoryRequest },
123
+ limits: { cpu: cpuLimit, memory: memoryLimit },
124
+ },
125
+ volumeMounts: [
126
+ { name: "varlog", mountPath: "/var/log", readOnly: true },
127
+ { name: "config", mountPath: `/etc/${name}`, readOnly: true },
128
+ { name: "state", mountPath: "/var/fluent-bit/state" },
129
+ ],
130
+ securityContext: {
131
+ runAsUser: 0,
132
+ readOnlyRootFilesystem: true,
133
+ allowPrivilegeEscalation: false,
134
+ },
135
+ };
136
+
137
+ const daemonSetProps: Record<string, unknown> = {
138
+ metadata: {
139
+ name,
140
+ namespace,
141
+ labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
142
+ },
143
+ spec: {
144
+ selector: { matchLabels: { "app.kubernetes.io/name": name } },
145
+ template: {
146
+ metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
147
+ spec: {
148
+ serviceAccountName: saName,
149
+ containers: [container],
150
+ volumes: [
151
+ { name: "varlog", hostPath: { path: "/var/log" } },
152
+ { name: "config", configMap: { name: configMapName } },
153
+ { name: "state", hostPath: { path: `/var/fluent-bit/state/${name}` } },
154
+ ],
155
+ tolerations: [{ operator: "Exists" }],
156
+ },
157
+ },
158
+ },
159
+ };
160
+
161
+ const serviceAccountProps: Record<string, unknown> = {
162
+ metadata: {
163
+ name: saName,
164
+ namespace,
165
+ labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
166
+ ...(gcpServiceAccountEmail
167
+ ? { annotations: { "iam.gke.io/gcp-service-account": gcpServiceAccountEmail } }
168
+ : {}),
169
+ },
170
+ };
171
+
172
+ const clusterRoleProps: Record<string, unknown> = {
173
+ metadata: {
174
+ name: clusterRoleName,
175
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
176
+ },
177
+ rules: [
178
+ { apiGroups: [""], resources: ["namespaces", "pods"], verbs: ["get", "list", "watch"] },
179
+ ],
180
+ };
181
+
182
+ const clusterRoleBindingProps: Record<string, unknown> = {
183
+ metadata: {
184
+ name: bindingName,
185
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
186
+ },
187
+ roleRef: {
188
+ apiGroup: "rbac.authorization.k8s.io",
189
+ kind: "ClusterRole",
190
+ name: clusterRoleName,
191
+ },
192
+ subjects: [
193
+ {
194
+ kind: "ServiceAccount",
195
+ name: saName,
196
+ namespace,
197
+ },
198
+ ],
199
+ };
200
+
201
+ const configMapProps: Record<string, unknown> = {
202
+ metadata: {
203
+ name: configMapName,
204
+ namespace,
205
+ labels: { ...commonLabels, "app.kubernetes.io/component": "config" },
206
+ },
207
+ data: {
208
+ "fluent-bit.conf": fluentBitConfig,
209
+ },
210
+ };
211
+
212
+ return {
213
+ daemonSet: daemonSetProps,
214
+ serviceAccount: serviceAccountProps,
215
+ clusterRole: clusterRoleProps,
216
+ clusterRoleBinding: clusterRoleBindingProps,
217
+ configMap: configMapProps,
218
+ };
219
+ }
@@ -0,0 +1,143 @@
1
+ /**
2
+ * GkeGateway composite — Gateway + HTTPRoute for GKE Gateway API.
3
+ *
4
+ * @gke Creates a Gateway with a GKE-specific `gatewayClassName` and
5
+ * HTTPRoute resources for traffic routing.
6
+ */
7
+
8
+ export interface GkeGatewayHost {
9
+ /** Hostname (e.g., "api.example.com"). */
10
+ hostname: string;
11
+ /** Path rules for this host. */
12
+ paths: Array<{
13
+ path: string;
14
+ serviceName: string;
15
+ servicePort: number;
16
+ }>;
17
+ }
18
+
19
+ export interface GkeGatewayProps {
20
+ /** Gateway name — used in metadata and labels. */
21
+ name: string;
22
+ /** GKE gateway class (default: "gke-l7-global-external-managed"). */
23
+ gatewayClassName?:
24
+ | "gke-l7-global-external-managed"
25
+ | "gke-l7-regional-external-managed"
26
+ | "gke-l7-rilb";
27
+ /** Host definitions with paths. */
28
+ hosts: GkeGatewayHost[];
29
+ /** Google-managed certificate name for TLS. */
30
+ certificateName?: string;
31
+ /** Additional labels to apply to all resources. */
32
+ labels?: Record<string, string>;
33
+ /** Namespace for all resources. */
34
+ namespace?: string;
35
+ }
36
+
37
+ export interface GkeGatewayResult {
38
+ gateway: Record<string, unknown>;
39
+ httpRoute: Record<string, unknown>;
40
+ }
41
+
42
+ /**
43
+ * Create a GkeGateway composite — returns prop objects for
44
+ * a Gateway and HTTPRoute with GKE-specific gateway class.
45
+ *
46
+ * @gke
47
+ * @example
48
+ * ```ts
49
+ * import { GkeGateway } from "@intentius/chant-lexicon-k8s";
50
+ *
51
+ * const { gateway, httpRoute } = GkeGateway({
52
+ * name: "api-gateway",
53
+ * hosts: [
54
+ * {
55
+ * hostname: "api.example.com",
56
+ * paths: [{ path: "/", serviceName: "api", servicePort: 80 }],
57
+ * },
58
+ * ],
59
+ * certificateName: "api-cert",
60
+ * });
61
+ * ```
62
+ */
63
+ export function GkeGateway(props: GkeGatewayProps): GkeGatewayResult {
64
+ const {
65
+ name,
66
+ gatewayClassName = "gke-l7-global-external-managed",
67
+ hosts,
68
+ certificateName,
69
+ labels: extraLabels = {},
70
+ namespace,
71
+ } = props;
72
+
73
+ const routeName = `${name}-route`;
74
+
75
+ const commonLabels: Record<string, string> = {
76
+ "app.kubernetes.io/name": name,
77
+ "app.kubernetes.io/managed-by": "chant",
78
+ ...extraLabels,
79
+ };
80
+
81
+ // Build Gateway listeners
82
+ const listeners: Array<Record<string, unknown>> = [];
83
+
84
+ if (certificateName) {
85
+ listeners.push({
86
+ name: "https",
87
+ protocol: "HTTPS",
88
+ port: 443,
89
+ tls: {
90
+ mode: "Terminate",
91
+ certificateRefs: [{ kind: "ManagedCertificate", name: certificateName }],
92
+ },
93
+ });
94
+ } else {
95
+ listeners.push({
96
+ name: "http",
97
+ protocol: "HTTP",
98
+ port: 80,
99
+ });
100
+ }
101
+
102
+ const gatewayProps: Record<string, unknown> = {
103
+ metadata: {
104
+ name,
105
+ ...(namespace && { namespace }),
106
+ labels: { ...commonLabels, "app.kubernetes.io/component": "gateway" },
107
+ },
108
+ spec: {
109
+ gatewayClassName,
110
+ listeners,
111
+ },
112
+ };
113
+
114
+ // Build HTTPRoute rules
115
+ const hostnames = hosts.map((h) => h.hostname);
116
+
117
+ const rules = hosts.flatMap((host) =>
118
+ host.paths.map((p) => ({
119
+ matches: [{ path: { type: "PathPrefix", value: p.path } }],
120
+ backendRefs: [
121
+ { name: p.serviceName, port: p.servicePort },
122
+ ],
123
+ })),
124
+ );
125
+
126
+ const httpRouteProps: Record<string, unknown> = {
127
+ metadata: {
128
+ name: routeName,
129
+ ...(namespace && { namespace }),
130
+ labels: { ...commonLabels, "app.kubernetes.io/component": "route" },
131
+ },
132
+ spec: {
133
+ parentRefs: [{ name }],
134
+ hostnames,
135
+ rules,
136
+ },
137
+ };
138
+
139
+ return {
140
+ gateway: gatewayProps,
141
+ httpRoute: httpRouteProps,
142
+ };
143
+ }
@@ -0,0 +1,229 @@
1
+ /**
2
+ * GkeOtelCollector composite — DaemonSet + RBAC + ConfigMap for OpenTelemetry on GKE.
3
+ *
4
+ * @gke Like AdotCollector but targets Cloud Trace + Cloud Monitoring via the
5
+ * googlecloud exporter and uses GKE Workload Identity instead of IRSA.
6
+ */
7
+
8
+ export interface GkeOtelCollectorProps {
9
+ /** GKE cluster name. */
10
+ clusterName: string;
11
+ /** GCP project ID. */
12
+ projectId: string;
13
+ /** GCP service account email for Workload Identity. */
14
+ gcpServiceAccountEmail?: string;
15
+ /** Agent name (default: "gke-otel-collector"). */
16
+ name?: string;
17
+ /** OTel Collector image (default: "otel/opentelemetry-collector-contrib:latest"). */
18
+ image?: string;
19
+ /** Namespace (default: "gke-monitoring"). */
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
+ }
32
+
33
+ export interface GkeOtelCollectorResult {
34
+ daemonSet: Record<string, unknown>;
35
+ serviceAccount: Record<string, unknown>;
36
+ clusterRole: Record<string, unknown>;
37
+ clusterRoleBinding: Record<string, unknown>;
38
+ configMap: Record<string, unknown>;
39
+ }
40
+
41
+ /**
42
+ * Create a GkeOtelCollector composite — returns prop objects for
43
+ * a DaemonSet, ServiceAccount, ClusterRole, ClusterRoleBinding, and ConfigMap.
44
+ *
45
+ * @gke
46
+ * @example
47
+ * ```ts
48
+ * import { GkeOtelCollector } from "@intentius/chant-lexicon-k8s";
49
+ *
50
+ * const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = GkeOtelCollector({
51
+ * clusterName: "my-cluster",
52
+ * projectId: "my-project",
53
+ * gcpServiceAccountEmail: "otel@my-project.iam.gserviceaccount.com",
54
+ * });
55
+ * ```
56
+ */
57
+ export function GkeOtelCollector(props: GkeOtelCollectorProps): GkeOtelCollectorResult {
58
+ const {
59
+ clusterName,
60
+ projectId,
61
+ gcpServiceAccountEmail,
62
+ name = "gke-otel-collector",
63
+ image = "otel/opentelemetry-collector-contrib:latest",
64
+ namespace = "gke-monitoring",
65
+ labels: extraLabels = {},
66
+ cpuRequest = "100m",
67
+ memoryRequest = "256Mi",
68
+ cpuLimit = "500m",
69
+ memoryLimit = "512Mi",
70
+ } = props;
71
+
72
+ const saName = `${name}-sa`;
73
+ const clusterRoleName = `${name}-role`;
74
+ const bindingName = `${name}-binding`;
75
+ const configMapName = `${name}-config`;
76
+
77
+ const commonLabels: Record<string, string> = {
78
+ "app.kubernetes.io/name": name,
79
+ "app.kubernetes.io/managed-by": "chant",
80
+ ...extraLabels,
81
+ };
82
+
83
+ const otelConfig = `receivers:
84
+ otlp:
85
+ protocols:
86
+ grpc:
87
+ endpoint: 0.0.0.0:4317
88
+ http:
89
+ endpoint: 0.0.0.0:4318
90
+
91
+ processors:
92
+ batch:
93
+ timeout: 30s
94
+ send_batch_size: 8192
95
+ resourcedetection:
96
+ detectors: [gcp]
97
+ timeout: 10s
98
+
99
+ exporters:
100
+ googlecloud:
101
+ project: ${projectId}
102
+ metric:
103
+ prefix: custom.googleapis.com/${clusterName}
104
+ trace:
105
+ attribute_mappings:
106
+ - key: service.name
107
+ replacement: g.co/r/service/name
108
+
109
+ service:
110
+ pipelines:
111
+ metrics:
112
+ receivers: [otlp]
113
+ processors: [batch, resourcedetection]
114
+ exporters: [googlecloud]
115
+ traces:
116
+ receivers: [otlp]
117
+ processors: [batch, resourcedetection]
118
+ exporters: [googlecloud]
119
+ `;
120
+
121
+ const container: Record<string, unknown> = {
122
+ name,
123
+ image,
124
+ args: ["--config=/etc/otel/config.yaml"],
125
+ ports: [
126
+ { containerPort: 4317, name: "otlp-grpc" },
127
+ { containerPort: 4318, name: "otlp-http" },
128
+ ],
129
+ resources: {
130
+ requests: { cpu: cpuRequest, memory: memoryRequest },
131
+ limits: { cpu: cpuLimit, memory: memoryLimit },
132
+ },
133
+ volumeMounts: [
134
+ { name: "config", mountPath: "/etc/otel", readOnly: true },
135
+ ],
136
+ securityContext: {
137
+ runAsNonRoot: true,
138
+ runAsUser: 10001,
139
+ readOnlyRootFilesystem: true,
140
+ allowPrivilegeEscalation: false,
141
+ },
142
+ };
143
+
144
+ const daemonSetProps: Record<string, unknown> = {
145
+ metadata: {
146
+ name,
147
+ namespace,
148
+ labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
149
+ },
150
+ spec: {
151
+ selector: { matchLabels: { "app.kubernetes.io/name": name } },
152
+ template: {
153
+ metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
154
+ spec: {
155
+ serviceAccountName: saName,
156
+ containers: [container],
157
+ volumes: [
158
+ { name: "config", configMap: { name: configMapName } },
159
+ ],
160
+ tolerations: [{ operator: "Exists" }],
161
+ },
162
+ },
163
+ },
164
+ };
165
+
166
+ const serviceAccountProps: Record<string, unknown> = {
167
+ metadata: {
168
+ name: saName,
169
+ namespace,
170
+ labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
171
+ ...(gcpServiceAccountEmail
172
+ ? { annotations: { "iam.gke.io/gcp-service-account": gcpServiceAccountEmail } }
173
+ : {}),
174
+ },
175
+ };
176
+
177
+ const clusterRoleProps: Record<string, unknown> = {
178
+ metadata: {
179
+ name: clusterRoleName,
180
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
181
+ },
182
+ rules: [
183
+ { apiGroups: [""], resources: ["pods", "nodes", "endpoints"], verbs: ["get", "list", "watch"] },
184
+ { apiGroups: ["apps"], resources: ["replicasets"], verbs: ["get", "list", "watch"] },
185
+ { apiGroups: ["batch"], resources: ["jobs"], verbs: ["get", "list", "watch"] },
186
+ { apiGroups: [""], resources: ["nodes/proxy"], verbs: ["get"] },
187
+ { apiGroups: [""], resources: ["nodes/stats", "configmaps", "events"], verbs: ["create", "get"] },
188
+ { apiGroups: [""], resources: ["configmaps"], verbs: ["get", "update", "create"], resourceNames: ["otel-container-insight-clusterleader"] },
189
+ ],
190
+ };
191
+
192
+ const clusterRoleBindingProps: Record<string, unknown> = {
193
+ metadata: {
194
+ name: bindingName,
195
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
196
+ },
197
+ roleRef: {
198
+ apiGroup: "rbac.authorization.k8s.io",
199
+ kind: "ClusterRole",
200
+ name: clusterRoleName,
201
+ },
202
+ subjects: [
203
+ {
204
+ kind: "ServiceAccount",
205
+ name: saName,
206
+ namespace,
207
+ },
208
+ ],
209
+ };
210
+
211
+ const configMapProps: Record<string, unknown> = {
212
+ metadata: {
213
+ name: configMapName,
214
+ namespace,
215
+ labels: { ...commonLabels, "app.kubernetes.io/component": "config" },
216
+ },
217
+ data: {
218
+ "config.yaml": otelConfig,
219
+ },
220
+ };
221
+
222
+ return {
223
+ daemonSet: daemonSetProps,
224
+ serviceAccount: serviceAccountProps,
225
+ clusterRole: clusterRoleProps,
226
+ clusterRoleBinding: clusterRoleBindingProps,
227
+ configMap: configMapProps,
228
+ };
229
+ }
@@ -1,3 +1,4 @@
1
+ export type { ContainerSecurityContext } from "./security-context";
1
2
  export { WebApp } from "./web-app";
2
3
  export type { WebAppProps, WebAppResult } from "./web-app";
3
4
  export { StatefulApp } from "./stateful-app";
@@ -40,3 +41,33 @@ export { AdotCollector } from "./adot-collector";
40
41
  export type { AdotCollectorProps, AdotCollectorResult } from "./adot-collector";
41
42
  export { MetricsServer } from "./metrics-server";
42
43
  export type { MetricsServerProps, MetricsServerResult } from "./metrics-server";
44
+ export { WorkloadIdentityServiceAccount } from "./workload-identity-service-account";
45
+ export type { WorkloadIdentityServiceAccountProps, WorkloadIdentityServiceAccountResult } from "./workload-identity-service-account";
46
+ export { GcePdStorageClass } from "./gce-pd-storage-class";
47
+ export type { GcePdStorageClassProps, GcePdStorageClassResult } from "./gce-pd-storage-class";
48
+ export { FilestoreStorageClass } from "./filestore-storage-class";
49
+ export type { FilestoreStorageClassProps, FilestoreStorageClassResult } from "./filestore-storage-class";
50
+ export { GkeGateway } from "./gke-gateway";
51
+ export type { GkeGatewayProps, GkeGatewayResult } from "./gke-gateway";
52
+ export { ConfigConnectorContext } from "./config-connector-context";
53
+ export type { ConfigConnectorContextProps, ConfigConnectorContextResult } from "./config-connector-context";
54
+ export { GceIngress } from "./gce-ingress";
55
+ export type { GceIngressProps, GceIngressResult } from "./gce-ingress";
56
+ export { AgicIngress } from "./agic-ingress";
57
+ export type { AgicIngressProps, AgicIngressResult } from "./agic-ingress";
58
+ export { AzureDiskStorageClass } from "./azure-disk-storage-class";
59
+ export type { AzureDiskStorageClassProps, AzureDiskStorageClassResult } from "./azure-disk-storage-class";
60
+ export { AzureFileStorageClass } from "./azure-file-storage-class";
61
+ export type { AzureFileStorageClassProps, AzureFileStorageClassResult } from "./azure-file-storage-class";
62
+ export { AzureMonitorCollector } from "./azure-monitor-collector";
63
+ export type { AzureMonitorCollectorProps, AzureMonitorCollectorResult } from "./azure-monitor-collector";
64
+ export { WorkloadIdentityServiceAccount as AksWorkloadIdentityServiceAccount } from "./workload-identity-sa";
65
+ export type { WorkloadIdentityServiceAccountProps as AksWorkloadIdentityServiceAccountProps, WorkloadIdentityServiceAccountResult as AksWorkloadIdentityServiceAccountResult } from "./workload-identity-sa";
66
+ export { GkeFluentBitAgent } from "./gke-fluent-bit-agent";
67
+ export type { GkeFluentBitAgentProps, GkeFluentBitAgentResult } from "./gke-fluent-bit-agent";
68
+ export { GkeOtelCollector } from "./gke-otel-collector";
69
+ export type { GkeOtelCollectorProps, GkeOtelCollectorResult } from "./gke-otel-collector";
70
+ export { GkeExternalDnsAgent } from "./gke-external-dns-agent";
71
+ export type { GkeExternalDnsAgentProps, GkeExternalDnsAgentResult } from "./gke-external-dns-agent";
72
+ export { AksExternalDnsAgent } from "./aks-external-dns-agent";
73
+ export type { AksExternalDnsAgentProps, AksExternalDnsAgentResult } from "./aks-external-dns-agent";
@@ -147,7 +147,7 @@ export function MetricsServer(props: MetricsServerProps): MetricsServerResult {
147
147
  labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
148
148
  },
149
149
  rules: [
150
- { apiGroups: [""], resources: ["pods", "nodes", "namespaces"], verbs: ["get", "list", "watch"] },
150
+ { apiGroups: [""], resources: ["pods", "nodes", "namespaces", "configmaps"], verbs: ["get", "list", "watch"] },
151
151
  { apiGroups: [""], resources: ["nodes/metrics", "nodes/stats"], verbs: ["get"] },
152
152
  ],
153
153
  };
@@ -6,6 +6,8 @@
6
6
  * as raw objects that can be serialized alongside native K8s resources.
7
7
  */
8
8
 
9
+ import type { ContainerSecurityContext } from "./security-context";
10
+
9
11
  export interface AlertRule {
10
12
  /** Alert name. */
11
13
  name: string;
@@ -50,6 +52,8 @@ export interface MonitoredServiceProps {
50
52
  namespace?: string;
51
53
  /** Environment variables for the container. */
52
54
  env?: Array<{ name: string; value: string }>;
55
+ /** Container security context (supports PSS restricted fields). */
56
+ securityContext?: ContainerSecurityContext;
53
57
  }
54
58
 
55
59
  export interface MonitoredServiceResult {
@@ -95,6 +99,7 @@ export function MonitoredService(props: MonitoredServiceProps): MonitoredService
95
99
  memoryRequest = "128Mi",
96
100
  namespace,
97
101
  env,
102
+ securityContext,
98
103
  } = props;
99
104
 
100
105
  const commonLabels: Record<string, string> = {
@@ -132,6 +137,7 @@ export function MonitoredService(props: MonitoredServiceProps): MonitoredService
132
137
  requests: { cpu: cpuRequest, memory: memoryRequest },
133
138
  },
134
139
  ...(env && { env }),
140
+ ...(securityContext && { securityContext }),
135
141
  },
136
142
  ],
137
143
  },