@intentius/chant-lexicon-k8s 0.0.13 → 0.0.15
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/dist/integrity.json +20 -15
- package/dist/manifest.json +1 -1
- package/dist/rules/wk8204.ts +33 -1
- package/dist/rules/wk8304.ts +70 -0
- package/dist/rules/wk8305.ts +115 -0
- package/dist/rules/wk8306.ts +50 -0
- 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 +27 -24
- package/src/codegen/docs.ts +5 -5
- package/src/composites/adot-collector.ts +245 -0
- package/src/composites/agic-ingress.ts +149 -0
- package/src/composites/alb-ingress.ts +152 -0
- package/src/composites/autoscaled-service.ts +51 -0
- package/src/composites/azure-disk-storage-class.ts +82 -0
- package/src/composites/azure-file-storage-class.ts +77 -0
- package/src/composites/azure-monitor-collector.ts +232 -0
- package/src/composites/batch-job.ts +221 -0
- package/src/composites/composites.test.ts +1584 -0
- package/src/composites/config-connector-context.ts +62 -0
- package/src/composites/configured-app.ts +224 -0
- package/src/composites/cron-workload.ts +6 -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 +174 -0
- package/src/composites/filestore-storage-class.ts +79 -0
- package/src/composites/fluent-bit-agent.ts +220 -0
- package/src/composites/gce-pd-storage-class.ts +85 -0
- package/src/composites/gke-gateway.ts +143 -0
- package/src/composites/index.ts +47 -0
- package/src/composites/irsa-service-account.ts +114 -0
- package/src/composites/metrics-server.ts +224 -0
- package/src/composites/monitored-service.ts +221 -0
- package/src/composites/network-isolated-app.ts +202 -0
- package/src/composites/node-agent.ts +6 -0
- package/src/composites/secure-ingress.ts +149 -0
- package/src/composites/security-context.ts +10 -0
- package/src/composites/sidecar-app.ts +207 -0
- package/src/composites/stateful-app.ts +67 -15
- package/src/composites/web-app.ts +104 -35
- package/src/composites/worker-pool.ts +38 -4
- package/src/composites/workload-identity-sa.ts +118 -0
- package/src/composites/workload-identity-service-account.ts +116 -0
- package/src/index.ts +24 -2
- package/src/lint/post-synth/post-synth.test.ts +362 -1
- package/src/lint/post-synth/wk8204.ts +33 -1
- package/src/lint/post-synth/wk8304.ts +70 -0
- package/src/lint/post-synth/wk8305.ts +115 -0
- package/src/lint/post-synth/wk8306.ts +50 -0
- package/src/plugin.test.ts +2 -2
- package/src/plugin.ts +556 -242
- package/src/serializer.test.ts +120 -0
- package/src/serializer.ts +16 -4
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FilestoreStorageClass composite — StorageClass for GCP Filestore CSI driver.
|
|
3
|
+
*
|
|
4
|
+
* @gke Creates a StorageClass with the `filestore.csi.storage.gke.io` provisioner.
|
|
5
|
+
* Filestore provides ReadWriteMany access mode (shared across pods/nodes).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface FilestoreStorageClassProps {
|
|
9
|
+
/** StorageClass name. */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Filestore tier (default: "standard"). */
|
|
12
|
+
tier?: "standard" | "premium" | "enterprise";
|
|
13
|
+
/** VPC network for the Filestore instance. */
|
|
14
|
+
network?: string;
|
|
15
|
+
/** Reclaim policy (default: "Delete"). */
|
|
16
|
+
reclaimPolicy?: string;
|
|
17
|
+
/** Volume binding mode (default: "WaitForFirstConsumer"). */
|
|
18
|
+
volumeBindingMode?: string;
|
|
19
|
+
/** Additional labels. */
|
|
20
|
+
labels?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface FilestoreStorageClassResult {
|
|
24
|
+
storageClass: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a FilestoreStorageClass composite — returns prop objects for
|
|
29
|
+
* a StorageClass with the GCP Filestore CSI provisioner.
|
|
30
|
+
*
|
|
31
|
+
* @gke
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { FilestoreStorageClass } from "@intentius/chant-lexicon-k8s";
|
|
35
|
+
*
|
|
36
|
+
* const { storageClass } = FilestoreStorageClass({
|
|
37
|
+
* name: "filestore-standard",
|
|
38
|
+
* tier: "standard",
|
|
39
|
+
* network: "default",
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function FilestoreStorageClass(props: FilestoreStorageClassProps): FilestoreStorageClassResult {
|
|
44
|
+
const {
|
|
45
|
+
name,
|
|
46
|
+
tier = "standard",
|
|
47
|
+
network,
|
|
48
|
+
reclaimPolicy = "Delete",
|
|
49
|
+
volumeBindingMode = "WaitForFirstConsumer",
|
|
50
|
+
labels: extraLabels = {},
|
|
51
|
+
} = props;
|
|
52
|
+
|
|
53
|
+
const commonLabels: Record<string, string> = {
|
|
54
|
+
"app.kubernetes.io/name": name,
|
|
55
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
56
|
+
...extraLabels,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const parameters: Record<string, string> = {
|
|
60
|
+
tier,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (network) {
|
|
64
|
+
parameters.network = network;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const storageClassProps: Record<string, unknown> = {
|
|
68
|
+
metadata: {
|
|
69
|
+
name,
|
|
70
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "storage" },
|
|
71
|
+
},
|
|
72
|
+
provisioner: "filestore.csi.storage.gke.io",
|
|
73
|
+
parameters,
|
|
74
|
+
reclaimPolicy,
|
|
75
|
+
volumeBindingMode,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return { storageClass: storageClassProps };
|
|
79
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FluentBitAgent composite — DaemonSet + RBAC + ConfigMap for Fluent Bit.
|
|
3
|
+
*
|
|
4
|
+
* @eks Thin wrapper around the NodeAgent pattern with Fluent Bit defaults
|
|
5
|
+
* (image, RBAC, CloudWatch output config).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface FluentBitAgentProps {
|
|
9
|
+
/** Agent name (default: "fluent-bit"). */
|
|
10
|
+
name?: string;
|
|
11
|
+
/** Fluent Bit image (default: "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable"). */
|
|
12
|
+
image?: string;
|
|
13
|
+
/** CloudWatch log group name. */
|
|
14
|
+
logGroup: string;
|
|
15
|
+
/** AWS region. */
|
|
16
|
+
region: string;
|
|
17
|
+
/** Cluster name — used as log stream prefix. */
|
|
18
|
+
clusterName: string;
|
|
19
|
+
/** Namespace (default: "amazon-cloudwatch"). */
|
|
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
|
+
/** IAM Role ARN for IRSA (adds eks.amazonaws.com/role-arn annotation to ServiceAccount). */
|
|
32
|
+
iamRoleArn?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface FluentBitAgentResult {
|
|
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 a FluentBitAgent composite — returns prop objects for
|
|
45
|
+
* a DaemonSet, ServiceAccount, ClusterRole, ClusterRoleBinding, and ConfigMap.
|
|
46
|
+
*
|
|
47
|
+
* @eks
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* import { FluentBitAgent } from "@intentius/chant-lexicon-k8s";
|
|
51
|
+
*
|
|
52
|
+
* const { daemonSet, serviceAccount, clusterRole, clusterRoleBinding, configMap } = FluentBitAgent({
|
|
53
|
+
* logGroup: "/aws/eks/my-cluster/containers",
|
|
54
|
+
* region: "us-east-1",
|
|
55
|
+
* clusterName: "my-cluster",
|
|
56
|
+
* });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function FluentBitAgent(props: FluentBitAgentProps): FluentBitAgentResult {
|
|
60
|
+
const {
|
|
61
|
+
name = "fluent-bit",
|
|
62
|
+
image = "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
|
|
63
|
+
logGroup,
|
|
64
|
+
region,
|
|
65
|
+
clusterName,
|
|
66
|
+
namespace = "amazon-cloudwatch",
|
|
67
|
+
labels: extraLabels = {},
|
|
68
|
+
cpuRequest = "50m",
|
|
69
|
+
memoryRequest = "64Mi",
|
|
70
|
+
cpuLimit = "200m",
|
|
71
|
+
memoryLimit = "128Mi",
|
|
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
|
+
const fluentBitConfig = `[SERVICE]
|
|
87
|
+
Flush 5
|
|
88
|
+
Log_Level info
|
|
89
|
+
Daemon off
|
|
90
|
+
Parsers_File parsers.conf
|
|
91
|
+
|
|
92
|
+
[INPUT]
|
|
93
|
+
Name tail
|
|
94
|
+
Tag kube.*
|
|
95
|
+
Path /var/log/containers/*.log
|
|
96
|
+
Parser docker
|
|
97
|
+
DB /var/fluent-bit/state/flb_container.db
|
|
98
|
+
Mem_Buf_Limit 5MB
|
|
99
|
+
Skip_Long_Lines On
|
|
100
|
+
Refresh_Interval 10
|
|
101
|
+
|
|
102
|
+
[FILTER]
|
|
103
|
+
Name kubernetes
|
|
104
|
+
Match kube.*
|
|
105
|
+
Kube_URL https://kubernetes.default.svc:443
|
|
106
|
+
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
107
|
+
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
|
|
108
|
+
Merge_Log On
|
|
109
|
+
K8S-Logging.Parser On
|
|
110
|
+
K8S-Logging.Exclude Off
|
|
111
|
+
|
|
112
|
+
[OUTPUT]
|
|
113
|
+
Name cloudwatch_logs
|
|
114
|
+
Match *
|
|
115
|
+
region ${region}
|
|
116
|
+
log_group_name ${logGroup}
|
|
117
|
+
log_stream_prefix ${clusterName}/
|
|
118
|
+
auto_create_group true
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
const container: Record<string, unknown> = {
|
|
122
|
+
name,
|
|
123
|
+
image,
|
|
124
|
+
resources: {
|
|
125
|
+
requests: { cpu: cpuRequest, memory: memoryRequest },
|
|
126
|
+
limits: { cpu: cpuLimit, memory: memoryLimit },
|
|
127
|
+
},
|
|
128
|
+
volumeMounts: [
|
|
129
|
+
{ name: "varlog", mountPath: "/var/log", readOnly: true },
|
|
130
|
+
{ name: "config", mountPath: `/etc/${name}`, readOnly: true },
|
|
131
|
+
{ name: "state", mountPath: "/var/fluent-bit/state" },
|
|
132
|
+
],
|
|
133
|
+
securityContext: {
|
|
134
|
+
runAsUser: 0,
|
|
135
|
+
readOnlyRootFilesystem: true,
|
|
136
|
+
allowPrivilegeEscalation: false,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const daemonSetProps: Record<string, unknown> = {
|
|
141
|
+
metadata: {
|
|
142
|
+
name,
|
|
143
|
+
namespace,
|
|
144
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
|
|
145
|
+
},
|
|
146
|
+
spec: {
|
|
147
|
+
selector: { matchLabels: { "app.kubernetes.io/name": name } },
|
|
148
|
+
template: {
|
|
149
|
+
metadata: { labels: { "app.kubernetes.io/name": name, ...extraLabels } },
|
|
150
|
+
spec: {
|
|
151
|
+
serviceAccountName: saName,
|
|
152
|
+
containers: [container],
|
|
153
|
+
volumes: [
|
|
154
|
+
{ name: "varlog", hostPath: { path: "/var/log" } },
|
|
155
|
+
{ name: "config", configMap: { name: configMapName } },
|
|
156
|
+
{ name: "state", hostPath: { path: `/var/fluent-bit/state/${name}` } },
|
|
157
|
+
],
|
|
158
|
+
tolerations: [{ operator: "Exists" }],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const serviceAccountProps: Record<string, unknown> = {
|
|
165
|
+
metadata: {
|
|
166
|
+
name: saName,
|
|
167
|
+
namespace,
|
|
168
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "agent" },
|
|
169
|
+
...(iamRoleArn ? { annotations: { "eks.amazonaws.com/role-arn": iamRoleArn } } : {}),
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const clusterRoleProps: Record<string, unknown> = {
|
|
174
|
+
metadata: {
|
|
175
|
+
name: clusterRoleName,
|
|
176
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
|
|
177
|
+
},
|
|
178
|
+
rules: [
|
|
179
|
+
{ apiGroups: [""], resources: ["namespaces", "pods"], verbs: ["get", "list", "watch"] },
|
|
180
|
+
],
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const clusterRoleBindingProps: Record<string, unknown> = {
|
|
184
|
+
metadata: {
|
|
185
|
+
name: bindingName,
|
|
186
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
|
|
187
|
+
},
|
|
188
|
+
roleRef: {
|
|
189
|
+
apiGroup: "rbac.authorization.k8s.io",
|
|
190
|
+
kind: "ClusterRole",
|
|
191
|
+
name: clusterRoleName,
|
|
192
|
+
},
|
|
193
|
+
subjects: [
|
|
194
|
+
{
|
|
195
|
+
kind: "ServiceAccount",
|
|
196
|
+
name: saName,
|
|
197
|
+
namespace,
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const configMapProps: Record<string, unknown> = {
|
|
203
|
+
metadata: {
|
|
204
|
+
name: configMapName,
|
|
205
|
+
namespace,
|
|
206
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "config" },
|
|
207
|
+
},
|
|
208
|
+
data: {
|
|
209
|
+
"fluent-bit.conf": fluentBitConfig,
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
daemonSet: daemonSetProps,
|
|
215
|
+
serviceAccount: serviceAccountProps,
|
|
216
|
+
clusterRole: clusterRoleProps,
|
|
217
|
+
clusterRoleBinding: clusterRoleBindingProps,
|
|
218
|
+
configMap: configMapProps,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GcePdStorageClass composite — StorageClass for GCE Persistent Disk CSI driver.
|
|
3
|
+
*
|
|
4
|
+
* @gke Creates a StorageClass with the `pd.csi.storage.gke.io` provisioner.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface GcePdStorageClassProps {
|
|
8
|
+
/** StorageClass name. */
|
|
9
|
+
name: string;
|
|
10
|
+
/** PD type (default: "pd-balanced"). */
|
|
11
|
+
type?: "pd-standard" | "pd-ssd" | "pd-balanced" | "pd-extreme";
|
|
12
|
+
/** Replication type (default: "none"). */
|
|
13
|
+
replicationType?: "none" | "regional-pd";
|
|
14
|
+
/** Filesystem type (default: "ext4"). */
|
|
15
|
+
fsType?: string;
|
|
16
|
+
/** Reclaim policy (default: "Delete"). */
|
|
17
|
+
reclaimPolicy?: string;
|
|
18
|
+
/** Volume binding mode (default: "WaitForFirstConsumer"). */
|
|
19
|
+
volumeBindingMode?: string;
|
|
20
|
+
/** Allow volume expansion (default: true). */
|
|
21
|
+
allowVolumeExpansion?: boolean;
|
|
22
|
+
/** Additional labels. */
|
|
23
|
+
labels?: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface GcePdStorageClassResult {
|
|
27
|
+
storageClass: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Create a GcePdStorageClass composite — returns prop objects for
|
|
32
|
+
* a StorageClass with the GCE Persistent Disk CSI provisioner.
|
|
33
|
+
*
|
|
34
|
+
* @gke
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { GcePdStorageClass } from "@intentius/chant-lexicon-k8s";
|
|
38
|
+
*
|
|
39
|
+
* const { storageClass } = GcePdStorageClass({
|
|
40
|
+
* name: "pd-ssd",
|
|
41
|
+
* type: "pd-ssd",
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function GcePdStorageClass(props: GcePdStorageClassProps): GcePdStorageClassResult {
|
|
46
|
+
const {
|
|
47
|
+
name,
|
|
48
|
+
type = "pd-balanced",
|
|
49
|
+
replicationType = "none",
|
|
50
|
+
fsType = "ext4",
|
|
51
|
+
reclaimPolicy = "Delete",
|
|
52
|
+
volumeBindingMode = "WaitForFirstConsumer",
|
|
53
|
+
allowVolumeExpansion = true,
|
|
54
|
+
labels: extraLabels = {},
|
|
55
|
+
} = props;
|
|
56
|
+
|
|
57
|
+
const commonLabels: Record<string, string> = {
|
|
58
|
+
"app.kubernetes.io/name": name,
|
|
59
|
+
"app.kubernetes.io/managed-by": "chant",
|
|
60
|
+
...extraLabels,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const parameters: Record<string, string> = {
|
|
64
|
+
type,
|
|
65
|
+
"csi.storage.k8s.io/fstype": fsType,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
if (replicationType !== "none") {
|
|
69
|
+
parameters["replication-type"] = replicationType;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const storageClassProps: Record<string, unknown> = {
|
|
73
|
+
metadata: {
|
|
74
|
+
name,
|
|
75
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "storage" },
|
|
76
|
+
},
|
|
77
|
+
provisioner: "pd.csi.storage.gke.io",
|
|
78
|
+
parameters,
|
|
79
|
+
reclaimPolicy,
|
|
80
|
+
volumeBindingMode,
|
|
81
|
+
allowVolumeExpansion,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
return { storageClass: storageClassProps };
|
|
85
|
+
}
|
|
@@ -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
|
+
}
|
package/src/composites/index.ts
CHANGED
|
@@ -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";
|
|
@@ -12,3 +13,49 @@ export { NamespaceEnv } from "./namespace-env";
|
|
|
12
13
|
export type { NamespaceEnvProps, NamespaceEnvResult } from "./namespace-env";
|
|
13
14
|
export { NodeAgent } from "./node-agent";
|
|
14
15
|
export type { NodeAgentProps, NodeAgentResult } from "./node-agent";
|
|
16
|
+
export { BatchJob } from "./batch-job";
|
|
17
|
+
export type { BatchJobProps, BatchJobResult } from "./batch-job";
|
|
18
|
+
export { SecureIngress } from "./secure-ingress";
|
|
19
|
+
export type { SecureIngressProps, SecureIngressResult } from "./secure-ingress";
|
|
20
|
+
export { ConfiguredApp } from "./configured-app";
|
|
21
|
+
export type { ConfiguredAppProps, ConfiguredAppResult } from "./configured-app";
|
|
22
|
+
export { SidecarApp } from "./sidecar-app";
|
|
23
|
+
export type { SidecarAppProps, SidecarAppResult } from "./sidecar-app";
|
|
24
|
+
export { MonitoredService } from "./monitored-service";
|
|
25
|
+
export type { MonitoredServiceProps, MonitoredServiceResult } from "./monitored-service";
|
|
26
|
+
export { NetworkIsolatedApp } from "./network-isolated-app";
|
|
27
|
+
export type { NetworkIsolatedAppProps, NetworkIsolatedAppResult } from "./network-isolated-app";
|
|
28
|
+
export { IrsaServiceAccount } from "./irsa-service-account";
|
|
29
|
+
export type { IrsaServiceAccountProps, IrsaServiceAccountResult } from "./irsa-service-account";
|
|
30
|
+
export { AlbIngress } from "./alb-ingress";
|
|
31
|
+
export type { AlbIngressProps, AlbIngressResult } from "./alb-ingress";
|
|
32
|
+
export { EbsStorageClass } from "./ebs-storage-class";
|
|
33
|
+
export type { EbsStorageClassProps, EbsStorageClassResult } from "./ebs-storage-class";
|
|
34
|
+
export { EfsStorageClass } from "./efs-storage-class";
|
|
35
|
+
export type { EfsStorageClassProps, EfsStorageClassResult } from "./efs-storage-class";
|
|
36
|
+
export { FluentBitAgent } from "./fluent-bit-agent";
|
|
37
|
+
export type { FluentBitAgentProps, FluentBitAgentResult } from "./fluent-bit-agent";
|
|
38
|
+
export { ExternalDnsAgent } from "./external-dns-agent";
|
|
39
|
+
export type { ExternalDnsAgentProps, ExternalDnsAgentResult } from "./external-dns-agent";
|
|
40
|
+
export { AdotCollector } from "./adot-collector";
|
|
41
|
+
export type { AdotCollectorProps, AdotCollectorResult } from "./adot-collector";
|
|
42
|
+
export { MetricsServer } from "./metrics-server";
|
|
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 { AgicIngress } from "./agic-ingress";
|
|
55
|
+
export type { AgicIngressProps, AgicIngressResult } from "./agic-ingress";
|
|
56
|
+
export { AzureDiskStorageClass } from "./azure-disk-storage-class";
|
|
57
|
+
export type { AzureDiskStorageClassProps, AzureDiskStorageClassResult } from "./azure-disk-storage-class";
|
|
58
|
+
export { AzureFileStorageClass } from "./azure-file-storage-class";
|
|
59
|
+
export type { AzureFileStorageClassProps, AzureFileStorageClassResult } from "./azure-file-storage-class";
|
|
60
|
+
export { AzureMonitorCollector } from "./azure-monitor-collector";
|
|
61
|
+
export type { AzureMonitorCollectorProps, AzureMonitorCollectorResult } from "./azure-monitor-collector";
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IrsaServiceAccount composite — ServiceAccount + IAM annotation + optional RBAC.
|
|
3
|
+
*
|
|
4
|
+
* @eks Creates a ServiceAccount with the `eks.amazonaws.com/role-arn`
|
|
5
|
+
* annotation for IAM Roles for Service Accounts (IRSA).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface IrsaServiceAccountProps {
|
|
9
|
+
/** ServiceAccount name — used in metadata and labels. */
|
|
10
|
+
name: string;
|
|
11
|
+
/** IAM Role ARN for IRSA annotation. */
|
|
12
|
+
iamRoleArn: 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 IrsaServiceAccountResult {
|
|
26
|
+
serviceAccount: Record<string, unknown>;
|
|
27
|
+
role?: Record<string, unknown>;
|
|
28
|
+
roleBinding?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create an IrsaServiceAccount composite — returns prop objects for
|
|
33
|
+
* a ServiceAccount with IRSA annotation, and optional Role + RoleBinding.
|
|
34
|
+
*
|
|
35
|
+
* @eks
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { IrsaServiceAccount } from "@intentius/chant-lexicon-k8s";
|
|
39
|
+
*
|
|
40
|
+
* const { serviceAccount, role, roleBinding } = IrsaServiceAccount({
|
|
41
|
+
* name: "app-sa",
|
|
42
|
+
* iamRoleArn: "arn:aws:iam::123456789012:role/my-app-role",
|
|
43
|
+
* rbacRules: [
|
|
44
|
+
* { apiGroups: [""], resources: ["secrets"], verbs: ["get"] },
|
|
45
|
+
* ],
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function IrsaServiceAccount(props: IrsaServiceAccountProps): IrsaServiceAccountResult {
|
|
50
|
+
const {
|
|
51
|
+
name,
|
|
52
|
+
iamRoleArn,
|
|
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: { ...commonLabels, "app.kubernetes.io/component": "service-account" },
|
|
72
|
+
annotations: {
|
|
73
|
+
"eks.amazonaws.com/role-arn": iamRoleArn,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const result: IrsaServiceAccountResult = {
|
|
79
|
+
serviceAccount: serviceAccountProps,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (rbacRules && rbacRules.length > 0) {
|
|
83
|
+
result.role = {
|
|
84
|
+
metadata: {
|
|
85
|
+
name: roleName,
|
|
86
|
+
...(namespace && { namespace }),
|
|
87
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
|
|
88
|
+
},
|
|
89
|
+
rules: rbacRules,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
result.roleBinding = {
|
|
93
|
+
metadata: {
|
|
94
|
+
name: bindingName,
|
|
95
|
+
...(namespace && { namespace }),
|
|
96
|
+
labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
|
|
97
|
+
},
|
|
98
|
+
roleRef: {
|
|
99
|
+
apiGroup: "rbac.authorization.k8s.io",
|
|
100
|
+
kind: "Role",
|
|
101
|
+
name: roleName,
|
|
102
|
+
},
|
|
103
|
+
subjects: [
|
|
104
|
+
{
|
|
105
|
+
kind: "ServiceAccount",
|
|
106
|
+
name,
|
|
107
|
+
...(namespace && { namespace }),
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return result;
|
|
114
|
+
}
|