@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.
- package/README.md +24 -0
- package/dist/integrity.json +17 -15
- package/dist/manifest.json +1 -1
- package/dist/skills/chant-k8s-eks.md +156 -0
- package/dist/skills/chant-k8s-patterns.md +245 -0
- package/dist/skills/chant-k8s.md +36 -227
- package/package.json +2 -2
- package/src/codegen/docs.ts +4 -4
- package/src/composites/adot-collector.ts +239 -0
- package/src/composites/alb-ingress.ts +151 -0
- package/src/composites/autoscaled-service.ts +33 -0
- package/src/composites/batch-job.ts +188 -0
- package/src/composites/composites.test.ts +883 -0
- package/src/composites/configured-app.ts +218 -0
- package/src/composites/ebs-storage-class.ts +96 -0
- package/src/composites/efs-storage-class.ts +77 -0
- package/src/composites/external-dns-agent.ts +168 -0
- package/src/composites/fluent-bit-agent.ts +215 -0
- package/src/composites/index.ts +28 -0
- package/src/composites/irsa-service-account.ts +114 -0
- package/src/composites/metrics-server.ts +224 -0
- package/src/composites/monitored-service.ts +215 -0
- package/src/composites/network-isolated-app.ts +196 -0
- package/src/composites/secure-ingress.ts +149 -0
- package/src/composites/sidecar-app.ts +201 -0
- package/src/composites/stateful-app.ts +70 -15
- package/src/composites/web-app.ts +107 -35
- package/src/composites/worker-pool.ts +41 -4
- package/src/index.ts +19 -2
- package/src/plugin.ts +552 -241
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AlbIngress composite — Ingress with AWS Load Balancer Controller annotations.
|
|
3
|
+
*
|
|
4
|
+
* @eks Full `alb.ingress.kubernetes.io/*` annotation set including group name
|
|
5
|
+
* (shared ALB), SSL redirect, subnets, security groups.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface AlbIngressHost {
|
|
9
|
+
/** Hostname (e.g., "api.example.com"). */
|
|
10
|
+
hostname: string;
|
|
11
|
+
/** Path rules for this host. */
|
|
12
|
+
paths: Array<{
|
|
13
|
+
path: string;
|
|
14
|
+
pathType?: string;
|
|
15
|
+
serviceName: string;
|
|
16
|
+
servicePort: number;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface AlbIngressProps {
|
|
21
|
+
/** Ingress name — used in metadata and labels. */
|
|
22
|
+
name: string;
|
|
23
|
+
/** Host definitions with paths. */
|
|
24
|
+
hosts: AlbIngressHost[];
|
|
25
|
+
/** ALB scheme (default: "internet-facing"). */
|
|
26
|
+
scheme?: "internet-facing" | "internal";
|
|
27
|
+
/** Target type (default: "ip"). */
|
|
28
|
+
targetType?: "ip" | "instance";
|
|
29
|
+
/** ACM certificate ARN for TLS. */
|
|
30
|
+
certificateArn?: string;
|
|
31
|
+
/** WAF Web ACL ARN. */
|
|
32
|
+
wafAclArn?: string;
|
|
33
|
+
/** Health check path for target group. */
|
|
34
|
+
healthCheckPath?: string;
|
|
35
|
+
/** Ingress group name for shared ALB. */
|
|
36
|
+
groupName?: string;
|
|
37
|
+
/** Enable HTTP→HTTPS redirect (default: true when certificateArn set). */
|
|
38
|
+
sslRedirect?: boolean;
|
|
39
|
+
/** Additional annotations on the Ingress. */
|
|
40
|
+
annotations?: Record<string, string>;
|
|
41
|
+
/** Additional labels to apply to all resources. */
|
|
42
|
+
labels?: Record<string, string>;
|
|
43
|
+
/** Namespace for all resources. */
|
|
44
|
+
namespace?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface AlbIngressResult {
|
|
48
|
+
ingress: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Create an AlbIngress composite — returns prop objects for
|
|
53
|
+
* an Ingress with AWS ALB Controller annotations.
|
|
54
|
+
*
|
|
55
|
+
* @eks
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { AlbIngress } from "@intentius/chant-lexicon-k8s";
|
|
59
|
+
*
|
|
60
|
+
* const { ingress } = AlbIngress({
|
|
61
|
+
* name: "api-ingress",
|
|
62
|
+
* hosts: [
|
|
63
|
+
* {
|
|
64
|
+
* hostname: "api.example.com",
|
|
65
|
+
* paths: [{ path: "/", serviceName: "api", servicePort: 80 }],
|
|
66
|
+
* },
|
|
67
|
+
* ],
|
|
68
|
+
* scheme: "internet-facing",
|
|
69
|
+
* certificateArn: "arn:aws:acm:us-east-1:123456789012:certificate/abc-123",
|
|
70
|
+
* groupName: "shared-alb",
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export function AlbIngress(props: AlbIngressProps): AlbIngressResult {
|
|
75
|
+
const {
|
|
76
|
+
name,
|
|
77
|
+
hosts,
|
|
78
|
+
scheme = "internet-facing",
|
|
79
|
+
targetType = "ip",
|
|
80
|
+
certificateArn,
|
|
81
|
+
wafAclArn,
|
|
82
|
+
healthCheckPath,
|
|
83
|
+
groupName,
|
|
84
|
+
sslRedirect,
|
|
85
|
+
annotations: extraAnnotations = {},
|
|
86
|
+
labels: extraLabels = {},
|
|
87
|
+
namespace,
|
|
88
|
+
} = props;
|
|
89
|
+
|
|
90
|
+
const commonLabels: Record<string, string> = {
|
|
91
|
+
"app.kubernetes.io/name": name,
|
|
92
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
93
|
+
...extraLabels,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Build ALB annotations
|
|
97
|
+
const annotations: Record<string, string> = {
|
|
98
|
+
"alb.ingress.kubernetes.io/scheme": scheme,
|
|
99
|
+
"alb.ingress.kubernetes.io/target-type": targetType,
|
|
100
|
+
...extraAnnotations,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
if (certificateArn) {
|
|
104
|
+
annotations["alb.ingress.kubernetes.io/certificate-arn"] = certificateArn;
|
|
105
|
+
annotations["alb.ingress.kubernetes.io/listen-ports"] = '[{"HTTPS":443}]';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (sslRedirect ?? (certificateArn !== undefined)) {
|
|
109
|
+
annotations["alb.ingress.kubernetes.io/ssl-redirect"] = "443";
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (wafAclArn) {
|
|
113
|
+
annotations["alb.ingress.kubernetes.io/wafv2-acl-arn"] = wafAclArn;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (healthCheckPath) {
|
|
117
|
+
annotations["alb.ingress.kubernetes.io/healthcheck-path"] = healthCheckPath;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (groupName) {
|
|
121
|
+
annotations["alb.ingress.kubernetes.io/group.name"] = groupName;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const ingressRules = hosts.map((host) => ({
|
|
125
|
+
host: host.hostname,
|
|
126
|
+
http: {
|
|
127
|
+
paths: host.paths.map((p) => ({
|
|
128
|
+
path: p.path,
|
|
129
|
+
pathType: p.pathType ?? "Prefix",
|
|
130
|
+
backend: {
|
|
131
|
+
service: { name: p.serviceName, port: { number: p.servicePort } },
|
|
132
|
+
},
|
|
133
|
+
})),
|
|
134
|
+
},
|
|
135
|
+
}));
|
|
136
|
+
|
|
137
|
+
const ingressProps: Record<string, unknown> = {
|
|
138
|
+
metadata: {
|
|
139
|
+
name,
|
|
140
|
+
...(namespace && { namespace }),
|
|
141
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "ingress" },
|
|
142
|
+
annotations,
|
|
143
|
+
},
|
|
144
|
+
spec: {
|
|
145
|
+
ingressClassName: "alb",
|
|
146
|
+
rules: ingressRules,
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
return { ingress: ingressProps };
|
|
151
|
+
}
|
|
@@ -40,6 +40,24 @@ export interface AutoscaledServiceProps {
|
|
|
40
40
|
livenessPath?: string;
|
|
41
41
|
/** Readiness probe path (default: "/readyz"). */
|
|
42
42
|
readinessPath?: string;
|
|
43
|
+
/** Init containers (e.g., migrations, cert setup). */
|
|
44
|
+
initContainers?: Array<{
|
|
45
|
+
name: string;
|
|
46
|
+
image: string;
|
|
47
|
+
command?: string[];
|
|
48
|
+
args?: string[];
|
|
49
|
+
}>;
|
|
50
|
+
/** Pod security context. */
|
|
51
|
+
securityContext?: {
|
|
52
|
+
runAsNonRoot?: boolean;
|
|
53
|
+
readOnlyRootFilesystem?: boolean;
|
|
54
|
+
runAsUser?: number;
|
|
55
|
+
runAsGroup?: number;
|
|
56
|
+
};
|
|
57
|
+
/** Termination grace period in seconds. */
|
|
58
|
+
terminationGracePeriodSeconds?: number;
|
|
59
|
+
/** Priority class name for pod scheduling. */
|
|
60
|
+
priorityClassName?: string;
|
|
43
61
|
/** Additional labels to apply to all resources. */
|
|
44
62
|
labels?: Record<string, string>;
|
|
45
63
|
/** Namespace for all resources. */
|
|
@@ -89,6 +107,10 @@ export function AutoscaledService(props: AutoscaledServiceProps): AutoscaledServ
|
|
|
89
107
|
topologySpread = false,
|
|
90
108
|
livenessPath = "/healthz",
|
|
91
109
|
readinessPath = "/readyz",
|
|
110
|
+
initContainers,
|
|
111
|
+
securityContext,
|
|
112
|
+
terminationGracePeriodSeconds,
|
|
113
|
+
priorityClassName,
|
|
92
114
|
labels: extraLabels = {},
|
|
93
115
|
namespace,
|
|
94
116
|
env,
|
|
@@ -156,9 +178,20 @@ export function AutoscaledService(props: AutoscaledServiceProps): AutoscaledServ
|
|
|
156
178
|
periodSeconds: 5,
|
|
157
179
|
},
|
|
158
180
|
...(env && { env }),
|
|
181
|
+
...(securityContext && { securityContext }),
|
|
159
182
|
},
|
|
160
183
|
],
|
|
184
|
+
...(initContainers && {
|
|
185
|
+
initContainers: initContainers.map((ic) => ({
|
|
186
|
+
name: ic.name,
|
|
187
|
+
image: ic.image,
|
|
188
|
+
...(ic.command && { command: ic.command }),
|
|
189
|
+
...(ic.args && { args: ic.args }),
|
|
190
|
+
})),
|
|
191
|
+
}),
|
|
161
192
|
...(topologyConstraints && { topologySpreadConstraints: topologyConstraints }),
|
|
193
|
+
...(terminationGracePeriodSeconds !== undefined && { terminationGracePeriodSeconds }),
|
|
194
|
+
...(priorityClassName && { priorityClassName }),
|
|
162
195
|
},
|
|
163
196
|
},
|
|
164
197
|
},
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BatchJob composite — Job + optional RBAC (ServiceAccount + Role + RoleBinding).
|
|
3
|
+
*
|
|
4
|
+
* A higher-level construct for one-shot batch jobs (data migrations,
|
|
5
|
+
* seed tasks, backups). For scheduled workloads, use CronWorkload instead.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface BatchJobProps {
|
|
9
|
+
/** Job name — used in metadata and labels. */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Container image. */
|
|
12
|
+
image: string;
|
|
13
|
+
/** Command to run in the container. */
|
|
14
|
+
command?: string[];
|
|
15
|
+
/** Arguments to the command. */
|
|
16
|
+
args?: string[];
|
|
17
|
+
/** Number of retries before marking the job as failed (default: 6). */
|
|
18
|
+
backoffLimit?: number;
|
|
19
|
+
/** Seconds after completion before the job is eligible for GC. */
|
|
20
|
+
ttlSecondsAfterFinished?: number;
|
|
21
|
+
/** Number of completions required (default: 1). */
|
|
22
|
+
completions?: number;
|
|
23
|
+
/** Number of pods running in parallel (default: 1). */
|
|
24
|
+
parallelism?: number;
|
|
25
|
+
/** Restart policy (default: "OnFailure"). */
|
|
26
|
+
restartPolicy?: string;
|
|
27
|
+
/** RBAC rules for the service account. Omit for defaults; pass [] to skip RBAC entirely. */
|
|
28
|
+
rbacRules?: Array<{
|
|
29
|
+
apiGroups: string[];
|
|
30
|
+
resources: string[];
|
|
31
|
+
verbs: string[];
|
|
32
|
+
}>;
|
|
33
|
+
/** Additional labels to apply to all resources. */
|
|
34
|
+
labels?: Record<string, string>;
|
|
35
|
+
/** Namespace for all resources. */
|
|
36
|
+
namespace?: string;
|
|
37
|
+
/** CPU request (default: "100m"). */
|
|
38
|
+
cpuRequest?: string;
|
|
39
|
+
/** Memory request (default: "128Mi"). */
|
|
40
|
+
memoryRequest?: string;
|
|
41
|
+
/** CPU limit (default: "500m"). */
|
|
42
|
+
cpuLimit?: string;
|
|
43
|
+
/** Memory limit (default: "256Mi"). */
|
|
44
|
+
memoryLimit?: string;
|
|
45
|
+
/** Environment variables for the container. */
|
|
46
|
+
env?: Array<{ name: string; value: string }>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface BatchJobResult {
|
|
50
|
+
job: Record<string, unknown>;
|
|
51
|
+
serviceAccount?: Record<string, unknown>;
|
|
52
|
+
role?: Record<string, unknown>;
|
|
53
|
+
roleBinding?: Record<string, unknown>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Create a BatchJob composite — returns prop objects for
|
|
58
|
+
* a Job, and optional ServiceAccount, Role, and RoleBinding.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* import { BatchJob } from "@intentius/chant-lexicon-k8s";
|
|
63
|
+
*
|
|
64
|
+
* const { job, serviceAccount, role, roleBinding } = BatchJob({
|
|
65
|
+
* name: "db-migrate",
|
|
66
|
+
* image: "migrate:1.0",
|
|
67
|
+
* command: ["python", "manage.py", "migrate"],
|
|
68
|
+
* backoffLimit: 3,
|
|
69
|
+
* ttlSecondsAfterFinished: 3600,
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export function BatchJob(props: BatchJobProps): BatchJobResult {
|
|
74
|
+
const {
|
|
75
|
+
name,
|
|
76
|
+
image,
|
|
77
|
+
command,
|
|
78
|
+
args,
|
|
79
|
+
backoffLimit = 6,
|
|
80
|
+
ttlSecondsAfterFinished,
|
|
81
|
+
completions = 1,
|
|
82
|
+
parallelism = 1,
|
|
83
|
+
restartPolicy = "OnFailure",
|
|
84
|
+
rbacRules,
|
|
85
|
+
labels: extraLabels = {},
|
|
86
|
+
namespace,
|
|
87
|
+
cpuRequest = "100m",
|
|
88
|
+
memoryRequest = "128Mi",
|
|
89
|
+
cpuLimit = "500m",
|
|
90
|
+
memoryLimit = "256Mi",
|
|
91
|
+
env,
|
|
92
|
+
} = props;
|
|
93
|
+
|
|
94
|
+
const saName = `${name}-sa`;
|
|
95
|
+
const roleName = `${name}-role`;
|
|
96
|
+
const bindingName = `${name}-binding`;
|
|
97
|
+
|
|
98
|
+
const commonLabels: Record<string, string> = {
|
|
99
|
+
"app.kubernetes.io/name": name,
|
|
100
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
101
|
+
...extraLabels,
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// undefined → default RBAC rules; explicit [] → no RBAC resources
|
|
105
|
+
const createRbac = rbacRules === undefined || rbacRules.length > 0;
|
|
106
|
+
const effectiveRbacRules = rbacRules === undefined
|
|
107
|
+
? [{ apiGroups: [""], resources: ["pods"], verbs: ["get", "list"] }]
|
|
108
|
+
: rbacRules;
|
|
109
|
+
|
|
110
|
+
const container: Record<string, unknown> = {
|
|
111
|
+
name,
|
|
112
|
+
image,
|
|
113
|
+
...(command && { command }),
|
|
114
|
+
...(args && { args }),
|
|
115
|
+
resources: {
|
|
116
|
+
limits: { cpu: cpuLimit, memory: memoryLimit },
|
|
117
|
+
requests: { cpu: cpuRequest, memory: memoryRequest },
|
|
118
|
+
},
|
|
119
|
+
...(env && { env }),
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const jobProps: Record<string, unknown> = {
|
|
123
|
+
metadata: {
|
|
124
|
+
name,
|
|
125
|
+
...(namespace && { namespace }),
|
|
126
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "batch" },
|
|
127
|
+
},
|
|
128
|
+
spec: {
|
|
129
|
+
backoffLimit,
|
|
130
|
+
completions,
|
|
131
|
+
parallelism,
|
|
132
|
+
...(ttlSecondsAfterFinished !== undefined && { ttlSecondsAfterFinished }),
|
|
133
|
+
template: {
|
|
134
|
+
metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
|
|
135
|
+
spec: {
|
|
136
|
+
...(createRbac && { serviceAccountName: saName }),
|
|
137
|
+
restartPolicy,
|
|
138
|
+
containers: [container],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const result: BatchJobResult = {
|
|
145
|
+
job: jobProps,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
if (createRbac) {
|
|
149
|
+
result.serviceAccount = {
|
|
150
|
+
metadata: {
|
|
151
|
+
name: saName,
|
|
152
|
+
...(namespace && { namespace }),
|
|
153
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "batch" },
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
result.role = {
|
|
158
|
+
metadata: {
|
|
159
|
+
name: roleName,
|
|
160
|
+
...(namespace && { namespace }),
|
|
161
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
|
|
162
|
+
},
|
|
163
|
+
rules: effectiveRbacRules,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
result.roleBinding = {
|
|
167
|
+
metadata: {
|
|
168
|
+
name: bindingName,
|
|
169
|
+
...(namespace && { namespace }),
|
|
170
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
|
|
171
|
+
},
|
|
172
|
+
roleRef: {
|
|
173
|
+
apiGroup: "rbac.authorization.k8s.io",
|
|
174
|
+
kind: "Role",
|
|
175
|
+
name: roleName,
|
|
176
|
+
},
|
|
177
|
+
subjects: [
|
|
178
|
+
{
|
|
179
|
+
kind: "ServiceAccount",
|
|
180
|
+
name: saName,
|
|
181
|
+
...(namespace && { namespace }),
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return result;
|
|
188
|
+
}
|