@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
@@ -5,6 +5,8 @@
5
5
  * Creates fine-grained ingress/egress policies for a single application.
6
6
  */
7
7
 
8
+ import type { ContainerSecurityContext } from "./security-context";
9
+
8
10
  export interface NetworkPolicyPeer {
9
11
  /** Pod selector for the peer. */
10
12
  podSelector?: Record<string, string>;
@@ -44,6 +46,8 @@ export interface NetworkIsolatedAppProps {
44
46
  namespace?: string;
45
47
  /** Environment variables for the container. */
46
48
  env?: Array<{ name: string; value: string }>;
49
+ /** Container security context (supports PSS restricted fields). */
50
+ securityContext?: ContainerSecurityContext;
47
51
  }
48
52
 
49
53
  export interface NetworkIsolatedAppResult {
@@ -88,6 +92,7 @@ export function NetworkIsolatedApp(props: NetworkIsolatedAppProps): NetworkIsola
88
92
  memoryRequest = "128Mi",
89
93
  namespace,
90
94
  env,
95
+ securityContext,
91
96
  } = props;
92
97
 
93
98
  const commonLabels: Record<string, string> = {
@@ -118,6 +123,7 @@ export function NetworkIsolatedApp(props: NetworkIsolatedAppProps): NetworkIsola
118
123
  requests: { cpu: cpuRequest, memory: memoryRequest },
119
124
  },
120
125
  ...(env && { env }),
126
+ ...(securityContext && { securityContext }),
121
127
  },
122
128
  ],
123
129
  },
@@ -5,6 +5,8 @@
5
5
  * security scanners) that need cluster-wide RBAC and tolerations.
6
6
  */
7
7
 
8
+ import type { ContainerSecurityContext } from "./security-context";
9
+
8
10
  export interface NodeAgentProps {
9
11
  /** Agent name — used in metadata and labels. */
10
12
  name: string;
@@ -43,6 +45,8 @@ export interface NodeAgentProps {
43
45
  memoryLimit?: string;
44
46
  /** Environment variables for the container. */
45
47
  env?: Array<{ name: string; value: string }>;
48
+ /** Container security context (supports PSS restricted fields). */
49
+ securityContext?: ContainerSecurityContext;
46
50
  }
47
51
 
48
52
  export interface NodeAgentResult {
@@ -87,6 +91,7 @@ export function NodeAgent(props: NodeAgentProps): NodeAgentResult {
87
91
  memoryLimit = "128Mi",
88
92
  labels: extraLabels = {},
89
93
  env,
94
+ securityContext,
90
95
  } = props;
91
96
 
92
97
  const saName = `${name}-sa`;
@@ -139,6 +144,7 @@ export function NodeAgent(props: NodeAgentProps): NodeAgentResult {
139
144
  },
140
145
  ...(env && { env }),
141
146
  ...(volumeMounts.length > 0 && { volumeMounts }),
147
+ ...(securityContext && { securityContext }),
142
148
  };
143
149
 
144
150
  const podSpec: Record<string, unknown> = {
@@ -0,0 +1,10 @@
1
+ /** Container-level security context — covers PSS restricted requirements. */
2
+ export interface ContainerSecurityContext {
3
+ runAsNonRoot?: boolean;
4
+ readOnlyRootFilesystem?: boolean;
5
+ runAsUser?: number;
6
+ runAsGroup?: number;
7
+ allowPrivilegeEscalation?: boolean;
8
+ capabilities?: { add?: string[]; drop?: string[] };
9
+ seccompProfile?: { type: string; localhostProfile?: string };
10
+ }
@@ -5,6 +5,8 @@
5
5
  * DB migration init). Supports shared volumes between containers.
6
6
  */
7
7
 
8
+ import type { ContainerSecurityContext } from "./security-context";
9
+
8
10
  export interface SidecarContainer {
9
11
  /** Sidecar container name. */
10
12
  name: string;
@@ -70,6 +72,8 @@ export interface SidecarAppProps {
70
72
  namespace?: string;
71
73
  /** Environment variables for the primary container. */
72
74
  env?: Array<{ name: string; value: string }>;
75
+ /** Container security context for the primary container (supports PSS restricted fields). */
76
+ securityContext?: ContainerSecurityContext;
73
77
  }
74
78
 
75
79
  export interface SidecarAppResult {
@@ -115,6 +119,7 @@ export function SidecarApp(props: SidecarAppProps): SidecarAppResult {
115
119
  memoryRequest = "128Mi",
116
120
  namespace,
117
121
  env,
122
+ securityContext,
118
123
  } = props;
119
124
 
120
125
  const commonLabels: Record<string, string> = {
@@ -133,6 +138,7 @@ export function SidecarApp(props: SidecarAppProps): SidecarAppResult {
133
138
  requests: { cpu: cpuRequest, memory: memoryRequest },
134
139
  },
135
140
  ...(env && { env }),
141
+ ...(securityContext && { securityContext }),
136
142
  };
137
143
 
138
144
  // Sidecar containers
@@ -5,6 +5,8 @@
5
5
  * like databases, caches, and message queues.
6
6
  */
7
7
 
8
+ import type { ContainerSecurityContext } from "./security-context";
9
+
8
10
  export interface StatefulAppProps {
9
11
  /** Application name — used in metadata and labels. */
10
12
  name: string;
@@ -29,13 +31,8 @@ export interface StatefulAppProps {
29
31
  command?: string[];
30
32
  args?: string[];
31
33
  }>;
32
- /** Pod security context. */
33
- securityContext?: {
34
- runAsNonRoot?: boolean;
35
- readOnlyRootFilesystem?: boolean;
36
- runAsUser?: number;
37
- runAsGroup?: number;
38
- };
34
+ /** Container security context (supports PSS restricted fields). */
35
+ securityContext?: ContainerSecurityContext;
39
36
  /** Termination grace period in seconds. */
40
37
  terminationGracePeriodSeconds?: number;
41
38
  /** Priority class name for pod scheduling. */
@@ -5,6 +5,8 @@
5
5
  * with common defaults (health probes, resource limits, labels).
6
6
  */
7
7
 
8
+ import type { ContainerSecurityContext } from "./security-context";
9
+
8
10
  export interface WebAppProps {
9
11
  /** Application name — used in metadata and labels. */
10
12
  name: string;
@@ -34,13 +36,8 @@ export interface WebAppProps {
34
36
  command?: string[];
35
37
  args?: string[];
36
38
  }>;
37
- /** Pod security context safe defaults when enabled. */
38
- securityContext?: {
39
- runAsNonRoot?: boolean;
40
- readOnlyRootFilesystem?: boolean;
41
- runAsUser?: number;
42
- runAsGroup?: number;
43
- };
39
+ /** Container security context (supports PSS restricted fields). */
40
+ securityContext?: ContainerSecurityContext;
44
41
  /** Termination grace period in seconds. */
45
42
  terminationGracePeriodSeconds?: number;
46
43
  /** Priority class name for pod scheduling. */
@@ -5,6 +5,8 @@
5
5
  * that need RBAC for secrets/configmaps and optional autoscaling, but no Service.
6
6
  */
7
7
 
8
+ import type { ContainerSecurityContext } from "./security-context";
9
+
8
10
  export interface WorkerPoolProps {
9
11
  /** Worker name — used in metadata and labels. */
10
12
  name: string;
@@ -32,13 +34,8 @@ export interface WorkerPoolProps {
32
34
  };
33
35
  /** PodDisruptionBudget minAvailable — if set, creates a PDB. */
34
36
  minAvailable?: number | string;
35
- /** Pod security context. */
36
- securityContext?: {
37
- runAsNonRoot?: boolean;
38
- readOnlyRootFilesystem?: boolean;
39
- runAsUser?: number;
40
- runAsGroup?: number;
41
- };
37
+ /** Container security context (supports PSS restricted fields). */
38
+ securityContext?: ContainerSecurityContext;
42
39
  /** Termination grace period in seconds. */
43
40
  terminationGracePeriodSeconds?: number;
44
41
  /** Priority class name for pod scheduling. */
@@ -0,0 +1,118 @@
1
+ /**
2
+ * WorkloadIdentityServiceAccount composite — ServiceAccount + Workload Identity annotation + optional RBAC.
3
+ *
4
+ * @aks Creates a ServiceAccount with the `azure.workload.identity/client-id`
5
+ * annotation and `azure.workload.identity/use: "true"` label for AKS Workload Identity.
6
+ */
7
+
8
+ export interface WorkloadIdentityServiceAccountProps {
9
+ /** ServiceAccount name — used in metadata and labels. */
10
+ name: string;
11
+ /** Azure AD application client ID for Workload Identity. */
12
+ clientId: string;
13
+ /** Optional RBAC rules — if provided, creates Role + RoleBinding. */
14
+ rbacRules?: Array<{
15
+ apiGroups: string[];
16
+ resources: string[];
17
+ verbs: string[];
18
+ }>;
19
+ /** Additional labels to apply to all resources. */
20
+ labels?: Record<string, string>;
21
+ /** Namespace for all resources. */
22
+ namespace?: string;
23
+ }
24
+
25
+ export interface WorkloadIdentityServiceAccountResult {
26
+ serviceAccount: Record<string, unknown>;
27
+ role?: Record<string, unknown>;
28
+ roleBinding?: Record<string, unknown>;
29
+ }
30
+
31
+ /**
32
+ * Create a WorkloadIdentityServiceAccount composite — returns prop objects for
33
+ * a ServiceAccount with AKS Workload Identity annotation, and optional Role + RoleBinding.
34
+ *
35
+ * @aks
36
+ * @example
37
+ * ```ts
38
+ * import { WorkloadIdentityServiceAccount } from "@intentius/chant-lexicon-k8s";
39
+ *
40
+ * const { serviceAccount, role, roleBinding } = WorkloadIdentityServiceAccount({
41
+ * name: "app-sa",
42
+ * clientId: "00000000-0000-0000-0000-000000000000",
43
+ * rbacRules: [
44
+ * { apiGroups: [""], resources: ["secrets"], verbs: ["get"] },
45
+ * ],
46
+ * });
47
+ * ```
48
+ */
49
+ export function WorkloadIdentityServiceAccount(props: WorkloadIdentityServiceAccountProps): WorkloadIdentityServiceAccountResult {
50
+ const {
51
+ name,
52
+ clientId,
53
+ rbacRules,
54
+ labels: extraLabels = {},
55
+ namespace,
56
+ } = props;
57
+
58
+ const roleName = `${name}-role`;
59
+ const bindingName = `${name}-binding`;
60
+
61
+ const commonLabels: Record<string, string> = {
62
+ "app.kubernetes.io/name": name,
63
+ "app.kubernetes.io/managed-by": "chant",
64
+ ...extraLabels,
65
+ };
66
+
67
+ const serviceAccountProps: Record<string, unknown> = {
68
+ metadata: {
69
+ name,
70
+ ...(namespace && { namespace }),
71
+ labels: {
72
+ ...commonLabels,
73
+ "app.kubernetes.io/component": "service-account",
74
+ "azure.workload.identity/use": "true",
75
+ },
76
+ annotations: {
77
+ "azure.workload.identity/client-id": clientId,
78
+ },
79
+ },
80
+ };
81
+
82
+ const result: WorkloadIdentityServiceAccountResult = {
83
+ serviceAccount: serviceAccountProps,
84
+ };
85
+
86
+ if (rbacRules && rbacRules.length > 0) {
87
+ result.role = {
88
+ metadata: {
89
+ name: roleName,
90
+ ...(namespace && { namespace }),
91
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
92
+ },
93
+ rules: rbacRules,
94
+ };
95
+
96
+ result.roleBinding = {
97
+ metadata: {
98
+ name: bindingName,
99
+ ...(namespace && { namespace }),
100
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
101
+ },
102
+ roleRef: {
103
+ apiGroup: "rbac.authorization.k8s.io",
104
+ kind: "Role",
105
+ name: roleName,
106
+ },
107
+ subjects: [
108
+ {
109
+ kind: "ServiceAccount",
110
+ name,
111
+ ...(namespace && { namespace }),
112
+ },
113
+ ],
114
+ };
115
+ }
116
+
117
+ return result;
118
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * WorkloadIdentityServiceAccount composite — ServiceAccount + GKE Workload Identity annotation + optional RBAC.
3
+ *
4
+ * @gke Creates a ServiceAccount with the `iam.gke.io/gcp-service-account`
5
+ * annotation for GKE Workload Identity Federation.
6
+ */
7
+
8
+ export interface WorkloadIdentityServiceAccountProps {
9
+ /** ServiceAccount name — used in metadata and labels. */
10
+ name: string;
11
+ /** GCP service account email for Workload Identity annotation. */
12
+ gcpServiceAccountEmail: string;
13
+ /** Optional RBAC rules — if provided, creates Role + RoleBinding. */
14
+ rbacRules?: Array<{
15
+ apiGroups: string[];
16
+ resources: string[];
17
+ verbs: string[];
18
+ }>;
19
+ /** Additional labels to apply to all resources. */
20
+ labels?: Record<string, string>;
21
+ /** Namespace for all resources. */
22
+ namespace?: string;
23
+ }
24
+
25
+ export interface WorkloadIdentityServiceAccountResult {
26
+ serviceAccount: Record<string, unknown>;
27
+ role?: Record<string, unknown>;
28
+ roleBinding?: Record<string, unknown>;
29
+ }
30
+
31
+ /**
32
+ * Create a WorkloadIdentityServiceAccount composite — returns prop objects for
33
+ * a ServiceAccount with GKE Workload Identity annotation, and optional Role + RoleBinding.
34
+ *
35
+ * @gke
36
+ * @example
37
+ * ```ts
38
+ * import { WorkloadIdentityServiceAccount } from "@intentius/chant-lexicon-k8s";
39
+ *
40
+ * const { serviceAccount, role, roleBinding } = WorkloadIdentityServiceAccount({
41
+ * name: "app-sa",
42
+ * gcpServiceAccountEmail: "sa@my-project.iam.gserviceaccount.com",
43
+ * rbacRules: [
44
+ * { apiGroups: [""], resources: ["secrets"], verbs: ["get"] },
45
+ * ],
46
+ * });
47
+ * ```
48
+ */
49
+ export function WorkloadIdentityServiceAccount(
50
+ props: WorkloadIdentityServiceAccountProps,
51
+ ): WorkloadIdentityServiceAccountResult {
52
+ const {
53
+ name,
54
+ gcpServiceAccountEmail,
55
+ rbacRules,
56
+ labels: extraLabels = {},
57
+ namespace,
58
+ } = props;
59
+
60
+ const roleName = `${name}-role`;
61
+ const bindingName = `${name}-binding`;
62
+
63
+ const commonLabels: Record<string, string> = {
64
+ "app.kubernetes.io/name": name,
65
+ "app.kubernetes.io/managed-by": "chant",
66
+ ...extraLabels,
67
+ };
68
+
69
+ const serviceAccountProps: Record<string, unknown> = {
70
+ metadata: {
71
+ name,
72
+ ...(namespace && { namespace }),
73
+ labels: { ...commonLabels, "app.kubernetes.io/component": "service-account" },
74
+ annotations: {
75
+ "iam.gke.io/gcp-service-account": gcpServiceAccountEmail,
76
+ },
77
+ },
78
+ };
79
+
80
+ const result: WorkloadIdentityServiceAccountResult = {
81
+ serviceAccount: serviceAccountProps,
82
+ };
83
+
84
+ if (rbacRules && rbacRules.length > 0) {
85
+ result.role = {
86
+ metadata: {
87
+ name: roleName,
88
+ ...(namespace && { namespace }),
89
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
90
+ },
91
+ rules: rbacRules,
92
+ };
93
+
94
+ result.roleBinding = {
95
+ metadata: {
96
+ name: bindingName,
97
+ ...(namespace && { namespace }),
98
+ labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
99
+ },
100
+ roleRef: {
101
+ apiGroup: "rbac.authorization.k8s.io",
102
+ kind: "Role",
103
+ name: roleName,
104
+ },
105
+ subjects: [
106
+ {
107
+ kind: "ServiceAccount",
108
+ name,
109
+ ...(namespace && { namespace }),
110
+ },
111
+ ],
112
+ };
113
+ }
114
+
115
+ return result;
116
+ }
package/src/index.ts CHANGED
@@ -20,7 +20,11 @@ export {
20
20
  WebApp, StatefulApp, CronWorkload, AutoscaledService, WorkerPool, NamespaceEnv, NodeAgent,
21
21
  BatchJob, SecureIngress, ConfiguredApp, SidecarApp, MonitoredService, NetworkIsolatedApp,
22
22
  IrsaServiceAccount, AlbIngress, EbsStorageClass, EfsStorageClass, FluentBitAgent, ExternalDnsAgent, AdotCollector,
23
- MetricsServer,
23
+ MetricsServer, WorkloadIdentityServiceAccount, GcePdStorageClass, FilestoreStorageClass, GkeGateway, ConfigConnectorContext,
24
+ GceIngress,
25
+ AgicIngress, AzureDiskStorageClass, AzureFileStorageClass, AzureMonitorCollector,
26
+ AksWorkloadIdentityServiceAccount,
27
+ GkeFluentBitAgent, GkeOtelCollector, GkeExternalDnsAgent, AksExternalDnsAgent,
24
28
  } from "./composites/index";
25
29
  export type {
26
30
  WebAppProps, WebAppResult, StatefulAppProps, StatefulAppResult, CronWorkloadProps, CronWorkloadResult,
@@ -34,6 +38,21 @@ export type {
34
38
  FluentBitAgentProps, FluentBitAgentResult, ExternalDnsAgentProps, ExternalDnsAgentResult,
35
39
  AdotCollectorProps, AdotCollectorResult,
36
40
  MetricsServerProps, MetricsServerResult,
41
+ WorkloadIdentityServiceAccountProps, WorkloadIdentityServiceAccountResult,
42
+ GcePdStorageClassProps, GcePdStorageClassResult,
43
+ FilestoreStorageClassProps, FilestoreStorageClassResult,
44
+ GkeGatewayProps, GkeGatewayResult,
45
+ ConfigConnectorContextProps, ConfigConnectorContextResult,
46
+ GceIngressProps, GceIngressResult,
47
+ AgicIngressProps, AgicIngressResult,
48
+ AzureDiskStorageClassProps, AzureDiskStorageClassResult,
49
+ AzureFileStorageClassProps, AzureFileStorageClassResult,
50
+ AzureMonitorCollectorProps, AzureMonitorCollectorResult,
51
+ AksWorkloadIdentityServiceAccountProps, AksWorkloadIdentityServiceAccountResult,
52
+ GkeFluentBitAgentProps, GkeFluentBitAgentResult,
53
+ GkeOtelCollectorProps, GkeOtelCollectorResult,
54
+ GkeExternalDnsAgentProps, GkeExternalDnsAgentResult,
55
+ AksExternalDnsAgentProps, AksExternalDnsAgentResult,
37
56
  } from "./composites/index";
38
57
 
39
58
  // RBAC verb constants