@intentius/chant-lexicon-k8s 0.0.22 → 0.1.0

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 (54) hide show
  1. package/dist/integrity.json +9 -4
  2. package/dist/manifest.json +1 -1
  3. package/dist/skills/chant-k8s-aks.md +146 -0
  4. package/{src/skills/kubernetes-patterns.md → dist/skills/chant-k8s-deployment-strategies.md} +1 -1
  5. package/dist/skills/chant-k8s-eks.md +156 -0
  6. package/dist/skills/chant-k8s-gke.md +246 -0
  7. package/{src/skills/kubernetes-security.md → dist/skills/chant-k8s-security.md} +1 -1
  8. package/dist/skills/chant-k8s.md +65 -2
  9. package/package.json +5 -4
  10. package/src/composites/adot-collector.ts +34 -22
  11. package/src/composites/agic-ingress.ts +14 -6
  12. package/src/composites/aks-external-dns-agent.ts +29 -18
  13. package/src/composites/alb-ingress.ts +14 -6
  14. package/src/composites/autoscaled-service.ts +25 -20
  15. package/src/composites/azure-disk-storage-class.ts +14 -6
  16. package/src/composites/azure-file-storage-class.ts +14 -6
  17. package/src/composites/azure-monitor-collector.ts +34 -22
  18. package/src/composites/batch-job.ts +25 -17
  19. package/src/composites/cockroachdb-cluster.ts +164 -58
  20. package/src/composites/composites.test.ts +371 -365
  21. package/src/composites/config-connector-context.ts +18 -11
  22. package/src/composites/configured-app.ts +21 -15
  23. package/src/composites/cron-workload.ts +25 -20
  24. package/src/composites/ebs-storage-class.ts +14 -6
  25. package/src/composites/efs-storage-class.ts +14 -6
  26. package/src/composites/external-dns-agent.ts +26 -20
  27. package/src/composites/filestore-storage-class.ts +14 -6
  28. package/src/composites/fluent-bit-agent.ts +30 -24
  29. package/src/composites/gce-ingress.ts +14 -6
  30. package/src/composites/gce-pd-storage-class.ts +14 -6
  31. package/src/composites/gke-external-dns-agent.ts +34 -21
  32. package/src/composites/gke-fluent-bit-agent.ts +34 -22
  33. package/src/composites/gke-gateway.ts +19 -12
  34. package/src/composites/gke-otel-collector.ts +34 -22
  35. package/src/composites/irsa-service-account.ts +22 -14
  36. package/src/composites/metrics-server.ts +41 -26
  37. package/src/composites/monitored-service.ts +26 -19
  38. package/src/composites/namespace-env.ts +26 -17
  39. package/src/composites/network-isolated-app.ts +21 -16
  40. package/src/composites/node-agent.ts +33 -22
  41. package/src/composites/secure-ingress.ts +19 -11
  42. package/src/composites/sidecar-app.ts +17 -12
  43. package/src/composites/stateful-app.ts +21 -12
  44. package/src/composites/web-app.ts +25 -21
  45. package/src/composites/worker-pool.ts +40 -26
  46. package/src/composites/workload-identity-sa.ts +22 -14
  47. package/src/composites/workload-identity-service-account.ts +22 -16
  48. package/src/plugin.ts +40 -614
  49. package/src/serializer.ts +7 -0
  50. package/src/skills/chant-k8s-deployment-strategies.md +183 -0
  51. package/src/skills/chant-k8s-gke.md +56 -1
  52. package/src/skills/chant-k8s-patterns.md +245 -0
  53. package/src/skills/chant-k8s-security.md +237 -0
  54. package/src/skills/chant-k8s.md +305 -0
@@ -5,6 +5,9 @@
5
5
  * Config Connector to manage GCP resources in a specific namespace.
6
6
  */
7
7
 
8
+ import { Composite, mergeDefaults } from "@intentius/chant";
9
+ import { Deployment } from "../generated";
10
+
8
11
  export interface ConfigConnectorContextProps {
9
12
  /** Context name (default: "configconnectorcontext.core.cnrm.cloud.google.com"). */
10
13
  name?: string;
@@ -12,12 +15,16 @@ export interface ConfigConnectorContextProps {
12
15
  googleServiceAccountEmail: string;
13
16
  /** Namespace for the context (default: "default"). */
14
17
  namespace?: string;
15
- /** Whether to sync status into spec (default: "absent"). */
16
- stateIntoSpec?: "absent" | "merge";
18
+ /** Whether to sync status into spec (default: "Absent"). */
19
+ stateIntoSpec?: "Absent" | "Merge";
20
+ /** Per-member defaults for fine-grained overrides. */
21
+ defaults?: {
22
+ context?: Partial<Record<string, unknown>>;
23
+ };
17
24
  }
18
25
 
19
26
  export interface ConfigConnectorContextResult {
20
- context: Record<string, unknown>;
27
+ context: InstanceType<typeof Deployment>; // CRD — use Deployment as proxy Declarable
21
28
  }
22
29
 
23
30
  /**
@@ -35,17 +42,17 @@ export interface ConfigConnectorContextResult {
35
42
  * });
36
43
  * ```
37
44
  */
38
- export function ConfigConnectorContext(
39
- props: ConfigConnectorContextProps,
40
- ): ConfigConnectorContextResult {
45
+ export const ConfigConnectorContext = Composite<ConfigConnectorContextProps>((props) => {
41
46
  const {
42
47
  name = "configconnectorcontext.core.cnrm.cloud.google.com",
43
48
  googleServiceAccountEmail,
44
49
  namespace = "default",
45
- stateIntoSpec = "absent",
50
+ stateIntoSpec = "Absent",
51
+ defaults: defs,
46
52
  } = props;
47
53
 
48
- const contextProps: Record<string, unknown> = {
54
+ // ConfigConnectorContext is a CRD — use Deployment constructor as a generic Declarable wrapper
55
+ const context = new Deployment(mergeDefaults({
49
56
  apiVersion: "core.cnrm.cloud.google.com/v1beta1",
50
57
  kind: "ConfigConnectorContext",
51
58
  metadata: {
@@ -56,7 +63,7 @@ export function ConfigConnectorContext(
56
63
  googleServiceAccount: googleServiceAccountEmail,
57
64
  stateIntoSpec,
58
65
  },
59
- };
66
+ }, defs?.context));
60
67
 
61
- return { context: contextProps };
62
- }
68
+ return { context };
69
+ }, "ConfigConnectorContext");
@@ -6,6 +6,8 @@
6
6
  * Volume.fromSecret(), and container.mount() patterns.
7
7
  */
8
8
 
9
+ import { Composite, mergeDefaults } from "@intentius/chant";
10
+ import { Deployment, Service, ConfigMap } from "../generated";
9
11
  import type { ContainerSecurityContext } from "./security-context";
10
12
 
11
13
  export interface ConfiguredAppProps {
@@ -53,12 +55,18 @@ export interface ConfiguredAppProps {
53
55
  env?: Array<{ name: string; value: string }>;
54
56
  /** Container security context (supports PSS restricted fields). */
55
57
  securityContext?: ContainerSecurityContext;
58
+ /** Per-member defaults for fine-grained overrides. */
59
+ defaults?: {
60
+ deployment?: Partial<Record<string, unknown>>;
61
+ service?: Partial<Record<string, unknown>>;
62
+ configMap?: Partial<Record<string, unknown>>;
63
+ };
56
64
  }
57
65
 
58
66
  export interface ConfiguredAppResult {
59
- deployment: Record<string, unknown>;
60
- service: Record<string, unknown>;
61
- configMap?: Record<string, unknown>;
67
+ deployment: InstanceType<typeof Deployment>;
68
+ service: InstanceType<typeof Service>;
69
+ configMap?: InstanceType<typeof ConfigMap>;
62
70
  }
63
71
 
64
72
  /**
@@ -81,7 +89,7 @@ export interface ConfiguredAppResult {
81
89
  * });
82
90
  * ```
83
91
  */
84
- export function ConfiguredApp(props: ConfiguredAppProps): ConfiguredAppResult {
92
+ export const ConfiguredApp = Composite<ConfiguredAppProps>((props) => {
85
93
  const {
86
94
  name,
87
95
  image,
@@ -101,6 +109,7 @@ export function ConfiguredApp(props: ConfiguredAppProps): ConfiguredAppResult {
101
109
  namespace,
102
110
  env,
103
111
  securityContext,
112
+ defaults: defs,
104
113
  } = props;
105
114
 
106
115
  const configMapName = `${name}-config`;
@@ -175,7 +184,7 @@ export function ConfiguredApp(props: ConfiguredAppProps): ConfiguredAppResult {
175
184
  }),
176
185
  };
177
186
 
178
- const deploymentProps: Record<string, unknown> = {
187
+ const deployment = new Deployment(mergeDefaults({
179
188
  metadata: {
180
189
  name,
181
190
  ...(namespace && { namespace }),
@@ -189,9 +198,9 @@ export function ConfiguredApp(props: ConfiguredAppProps): ConfiguredAppResult {
189
198
  spec: podSpec,
190
199
  },
191
200
  },
192
- };
201
+ }, defs?.deployment));
193
202
 
194
- const serviceProps: Record<string, unknown> = {
203
+ const service = new Service(mergeDefaults({
195
204
  metadata: {
196
205
  name,
197
206
  ...(namespace && { namespace }),
@@ -202,23 +211,20 @@ export function ConfiguredApp(props: ConfiguredAppProps): ConfiguredAppResult {
202
211
  ports: [{ port: 80, targetPort: port, protocol: "TCP", name: "http" }],
203
212
  type: "ClusterIP",
204
213
  },
205
- };
214
+ }, defs?.service));
206
215
 
207
- const result: ConfiguredAppResult = {
208
- deployment: deploymentProps,
209
- service: serviceProps,
210
- };
216
+ const result: Record<string, any> = { deployment, service };
211
217
 
212
218
  if (configData) {
213
- result.configMap = {
219
+ result.configMap = new ConfigMap(mergeDefaults({
214
220
  metadata: {
215
221
  name: configMapName,
216
222
  ...(namespace && { namespace }),
217
223
  labels: { ...commonLabels, "app.kubernetes.io/component": "config" },
218
224
  },
219
225
  data: configData,
220
- };
226
+ }, defs?.configMap));
221
227
  }
222
228
 
223
229
  return result;
224
- }
230
+ }, "ConfiguredApp");
@@ -5,6 +5,8 @@
5
5
  * proper RBAC permissions.
6
6
  */
7
7
 
8
+ import { Composite, mergeDefaults } from "@intentius/chant";
9
+ import { CronJob, ServiceAccount, Role, RoleBinding } from "../generated";
8
10
  import type { ContainerSecurityContext } from "./security-context";
9
11
 
10
12
  export interface CronWorkloadProps {
@@ -37,13 +39,20 @@ export interface CronWorkloadProps {
37
39
  env?: Array<{ name: string; value: string }>;
38
40
  /** Container security context (supports PSS restricted fields). */
39
41
  securityContext?: ContainerSecurityContext;
42
+ /** Per-member defaults for fine-grained overrides. */
43
+ defaults?: {
44
+ cronJob?: Partial<Record<string, unknown>>;
45
+ serviceAccount?: Partial<Record<string, unknown>>;
46
+ role?: Partial<Record<string, unknown>>;
47
+ roleBinding?: Partial<Record<string, unknown>>;
48
+ };
40
49
  }
41
50
 
42
51
  export interface CronWorkloadResult {
43
- cronJob: Record<string, unknown>;
44
- serviceAccount: Record<string, unknown>;
45
- role: Record<string, unknown>;
46
- roleBinding: Record<string, unknown>;
52
+ cronJob: InstanceType<typeof CronJob>;
53
+ serviceAccount: InstanceType<typeof ServiceAccount>;
54
+ role: InstanceType<typeof Role>;
55
+ roleBinding: InstanceType<typeof RoleBinding>;
47
56
  }
48
57
 
49
58
  /**
@@ -65,7 +74,7 @@ export interface CronWorkloadResult {
65
74
  * });
66
75
  * ```
67
76
  */
68
- export function CronWorkload(props: CronWorkloadProps): CronWorkloadResult {
77
+ export const CronWorkload = Composite<CronWorkloadProps>((props) => {
69
78
  const {
70
79
  name,
71
80
  image,
@@ -80,6 +89,7 @@ export function CronWorkload(props: CronWorkloadProps): CronWorkloadResult {
80
89
  namespace,
81
90
  env,
82
91
  securityContext,
92
+ defaults: defs,
83
93
  } = props;
84
94
 
85
95
  const saName = `${name}-sa`;
@@ -92,7 +102,7 @@ export function CronWorkload(props: CronWorkloadProps): CronWorkloadResult {
92
102
  ...extraLabels,
93
103
  };
94
104
 
95
- const cronJobProps: Record<string, unknown> = {
105
+ const cronJob = new CronJob(mergeDefaults({
96
106
  metadata: {
97
107
  name,
98
108
  ...(namespace && { namespace }),
@@ -123,17 +133,17 @@ export function CronWorkload(props: CronWorkloadProps): CronWorkloadResult {
123
133
  },
124
134
  },
125
135
  },
126
- };
136
+ }, defs?.cronJob));
127
137
 
128
- const serviceAccountProps: Record<string, unknown> = {
138
+ const serviceAccount = new ServiceAccount(mergeDefaults({
129
139
  metadata: {
130
140
  name: saName,
131
141
  ...(namespace && { namespace }),
132
142
  labels: { ...commonLabels, "app.kubernetes.io/component": "worker" },
133
143
  },
134
- };
144
+ }, defs?.serviceAccount));
135
145
 
136
- const roleProps: Record<string, unknown> = {
146
+ const role = new Role(mergeDefaults({
137
147
  metadata: {
138
148
  name: roleName,
139
149
  ...(namespace && { namespace }),
@@ -142,9 +152,9 @@ export function CronWorkload(props: CronWorkloadProps): CronWorkloadResult {
142
152
  rules: rbacRules.length > 0 ? rbacRules : [
143
153
  { apiGroups: [""], resources: ["pods"], verbs: ["get", "list"] },
144
154
  ],
145
- };
155
+ }, defs?.role));
146
156
 
147
- const roleBindingProps: Record<string, unknown> = {
157
+ const roleBinding = new RoleBinding(mergeDefaults({
148
158
  metadata: {
149
159
  name: bindingName,
150
160
  ...(namespace && { namespace }),
@@ -162,12 +172,7 @@ export function CronWorkload(props: CronWorkloadProps): CronWorkloadResult {
162
172
  ...(namespace && { namespace }),
163
173
  },
164
174
  ],
165
- };
175
+ }, defs?.roleBinding));
166
176
 
167
- return {
168
- cronJob: cronJobProps,
169
- serviceAccount: serviceAccountProps,
170
- role: roleProps,
171
- roleBinding: roleBindingProps,
172
- };
173
- }
177
+ return { cronJob, serviceAccount, role, roleBinding };
178
+ }, "CronWorkload");
@@ -4,6 +4,9 @@
4
4
  * @eks Creates a StorageClass with the `ebs.csi.aws.com` provisioner.
5
5
  */
6
6
 
7
+ import { Composite, mergeDefaults } from "@intentius/chant";
8
+ import { StorageClass } from "../generated";
9
+
7
10
  export interface EbsStorageClassProps {
8
11
  /** StorageClass name. */
9
12
  name: string;
@@ -27,10 +30,14 @@ export interface EbsStorageClassProps {
27
30
  allowVolumeExpansion?: boolean;
28
31
  /** Additional labels. */
29
32
  labels?: Record<string, string>;
33
+ /** Per-member defaults for fine-grained overrides. */
34
+ defaults?: {
35
+ storageClass?: Partial<Record<string, unknown>>;
36
+ };
30
37
  }
31
38
 
32
39
  export interface EbsStorageClassResult {
33
- storageClass: Record<string, unknown>;
40
+ storageClass: InstanceType<typeof StorageClass>;
34
41
  }
35
42
 
36
43
  /**
@@ -49,7 +56,7 @@ export interface EbsStorageClassResult {
49
56
  * });
50
57
  * ```
51
58
  */
52
- export function EbsStorageClass(props: EbsStorageClassProps): EbsStorageClassResult {
59
+ export const EbsStorageClass = Composite<EbsStorageClassProps>((props) => {
53
60
  const {
54
61
  name,
55
62
  type = "gp3",
@@ -62,6 +69,7 @@ export function EbsStorageClass(props: EbsStorageClassProps): EbsStorageClassRes
62
69
  volumeBindingMode = "WaitForFirstConsumer",
63
70
  allowVolumeExpansion = true,
64
71
  labels: extraLabels = {},
72
+ defaults: defs,
65
73
  } = props;
66
74
 
67
75
  const commonLabels: Record<string, string> = {
@@ -80,7 +88,7 @@ export function EbsStorageClass(props: EbsStorageClassProps): EbsStorageClassRes
80
88
  if (throughput !== undefined) parameters.throughput = String(throughput);
81
89
  if (kmsKeyId) parameters.kmsKeyId = kmsKeyId;
82
90
 
83
- const storageClassProps: Record<string, unknown> = {
91
+ const storageClass = new StorageClass(mergeDefaults({
84
92
  metadata: {
85
93
  name,
86
94
  labels: { ...commonLabels, "app.kubernetes.io/component": "storage" },
@@ -90,7 +98,7 @@ export function EbsStorageClass(props: EbsStorageClassProps): EbsStorageClassRes
90
98
  reclaimPolicy,
91
99
  volumeBindingMode,
92
100
  allowVolumeExpansion,
93
- };
101
+ }, defs?.storageClass));
94
102
 
95
- return { storageClass: storageClassProps };
96
- }
103
+ return { storageClass };
104
+ }, "EbsStorageClass");
@@ -5,6 +5,9 @@
5
5
  * EFS provides ReadWriteMany access mode (shared across pods/nodes).
6
6
  */
7
7
 
8
+ import { Composite, mergeDefaults } from "@intentius/chant";
9
+ import { StorageClass } from "../generated";
10
+
8
11
  export interface EfsStorageClassProps {
9
12
  /** StorageClass name. */
10
13
  name: string;
@@ -20,10 +23,14 @@ export interface EfsStorageClassProps {
20
23
  provisioningMode?: string;
21
24
  /** Additional labels. */
22
25
  labels?: Record<string, string>;
26
+ /** Per-member defaults for fine-grained overrides. */
27
+ defaults?: {
28
+ storageClass?: Partial<Record<string, unknown>>;
29
+ };
23
30
  }
24
31
 
25
32
  export interface EfsStorageClassResult {
26
- storageClass: Record<string, unknown>;
33
+ storageClass: InstanceType<typeof StorageClass>;
27
34
  }
28
35
 
29
36
  /**
@@ -41,7 +48,7 @@ export interface EfsStorageClassResult {
41
48
  * });
42
49
  * ```
43
50
  */
44
- export function EfsStorageClass(props: EfsStorageClassProps): EfsStorageClassResult {
51
+ export const EfsStorageClass = Composite<EfsStorageClassProps>((props) => {
45
52
  const {
46
53
  name,
47
54
  fileSystemId,
@@ -50,6 +57,7 @@ export function EfsStorageClass(props: EfsStorageClassProps): EfsStorageClassRes
50
57
  reclaimPolicy = "Delete",
51
58
  provisioningMode = "efs-ap",
52
59
  labels: extraLabels = {},
60
+ defaults: defs,
53
61
  } = props;
54
62
 
55
63
  const commonLabels: Record<string, string> = {
@@ -58,7 +66,7 @@ export function EfsStorageClass(props: EfsStorageClassProps): EfsStorageClassRes
58
66
  ...extraLabels,
59
67
  };
60
68
 
61
- const storageClassProps: Record<string, unknown> = {
69
+ const storageClass = new StorageClass(mergeDefaults({
62
70
  metadata: {
63
71
  name,
64
72
  labels: { ...commonLabels, "app.kubernetes.io/component": "storage" },
@@ -71,7 +79,7 @@ export function EfsStorageClass(props: EfsStorageClassProps): EfsStorageClassRes
71
79
  basePath,
72
80
  },
73
81
  reclaimPolicy,
74
- };
82
+ }, defs?.storageClass));
75
83
 
76
- return { storageClass: storageClassProps };
77
- }
84
+ return { storageClass };
85
+ }, "EfsStorageClass");
@@ -5,6 +5,9 @@
5
5
  * where Ingress/Service hostnames should automatically create DNS records.
6
6
  */
7
7
 
8
+ import { Composite, mergeDefaults } from "@intentius/chant";
9
+ import { Deployment, ServiceAccount, ClusterRole, ClusterRoleBinding } from "../generated";
10
+
8
11
  export interface ExternalDnsAgentProps {
9
12
  /** IAM Role ARN for IRSA (needs Route53 permissions). */
10
13
  iamRoleArn: string;
@@ -24,13 +27,20 @@ export interface ExternalDnsAgentProps {
24
27
  namespace?: string;
25
28
  /** Additional labels. */
26
29
  labels?: Record<string, string>;
30
+ /** Per-member defaults for fine-grained overrides. */
31
+ defaults?: {
32
+ deployment?: Partial<Record<string, unknown>>;
33
+ serviceAccount?: Partial<Record<string, unknown>>;
34
+ clusterRole?: Partial<Record<string, unknown>>;
35
+ clusterRoleBinding?: Partial<Record<string, unknown>>;
36
+ };
27
37
  }
28
38
 
29
39
  export interface ExternalDnsAgentResult {
30
- deployment: Record<string, unknown>;
31
- serviceAccount: Record<string, unknown>;
32
- clusterRole: Record<string, unknown>;
33
- clusterRoleBinding: Record<string, unknown>;
40
+ deployment: InstanceType<typeof Deployment>;
41
+ serviceAccount: InstanceType<typeof ServiceAccount>;
42
+ clusterRole: InstanceType<typeof ClusterRole>;
43
+ clusterRoleBinding: InstanceType<typeof ClusterRoleBinding>;
34
44
  }
35
45
 
36
46
  /**
@@ -49,7 +59,7 @@ export interface ExternalDnsAgentResult {
49
59
  * });
50
60
  * ```
51
61
  */
52
- export function ExternalDnsAgent(props: ExternalDnsAgentProps): ExternalDnsAgentResult {
62
+ export const ExternalDnsAgent = Composite<ExternalDnsAgentProps>((props) => {
53
63
  const {
54
64
  iamRoleArn,
55
65
  domainFilters,
@@ -60,6 +70,7 @@ export function ExternalDnsAgent(props: ExternalDnsAgentProps): ExternalDnsAgent
60
70
  image = "registry.k8s.io/external-dns/external-dns:v0.14.0",
61
71
  namespace = "kube-system",
62
72
  labels: extraLabels = {},
73
+ defaults: defs,
63
74
  } = props;
64
75
 
65
76
  const saName = `${name}-sa`;
@@ -88,7 +99,7 @@ export function ExternalDnsAgent(props: ExternalDnsAgentProps): ExternalDnsAgent
88
99
  args.push(`--txt-owner-id=${txtOwnerId}`);
89
100
  }
90
101
 
91
- const deploymentProps: Record<string, unknown> = {
102
+ const deployment = new Deployment(mergeDefaults({
92
103
  metadata: {
93
104
  name,
94
105
  namespace,
@@ -121,9 +132,9 @@ export function ExternalDnsAgent(props: ExternalDnsAgentProps): ExternalDnsAgent
121
132
  },
122
133
  },
123
134
  },
124
- };
135
+ }, defs?.deployment));
125
136
 
126
- const serviceAccountProps: Record<string, unknown> = {
137
+ const serviceAccount = new ServiceAccount(mergeDefaults({
127
138
  metadata: {
128
139
  name: saName,
129
140
  namespace,
@@ -132,9 +143,9 @@ export function ExternalDnsAgent(props: ExternalDnsAgentProps): ExternalDnsAgent
132
143
  "eks.amazonaws.com/role-arn": iamRoleArn,
133
144
  },
134
145
  },
135
- };
146
+ }, defs?.serviceAccount));
136
147
 
137
- const clusterRoleProps: Record<string, unknown> = {
148
+ const clusterRole = new ClusterRole(mergeDefaults({
138
149
  metadata: {
139
150
  name: clusterRoleName,
140
151
  labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
@@ -144,9 +155,9 @@ export function ExternalDnsAgent(props: ExternalDnsAgentProps): ExternalDnsAgent
144
155
  { apiGroups: ["extensions", "networking.k8s.io"], resources: ["ingresses"], verbs: ["get", "watch", "list"] },
145
156
  { apiGroups: [""], resources: ["nodes"], verbs: ["list", "watch"] },
146
157
  ],
147
- };
158
+ }, defs?.clusterRole));
148
159
 
149
- const clusterRoleBindingProps: Record<string, unknown> = {
160
+ const clusterRoleBinding = new ClusterRoleBinding(mergeDefaults({
150
161
  metadata: {
151
162
  name: bindingName,
152
163
  labels: { ...commonLabels, "app.kubernetes.io/component": "rbac" },
@@ -163,12 +174,7 @@ export function ExternalDnsAgent(props: ExternalDnsAgentProps): ExternalDnsAgent
163
174
  namespace,
164
175
  },
165
176
  ],
166
- };
177
+ }, defs?.clusterRoleBinding));
167
178
 
168
- return {
169
- deployment: deploymentProps,
170
- serviceAccount: serviceAccountProps,
171
- clusterRole: clusterRoleProps,
172
- clusterRoleBinding: clusterRoleBindingProps,
173
- };
174
- }
179
+ return { deployment, serviceAccount, clusterRole, clusterRoleBinding };
180
+ }, "ExternalDnsAgent");
@@ -5,6 +5,9 @@
5
5
  * Filestore provides ReadWriteMany access mode (shared across pods/nodes).
6
6
  */
7
7
 
8
+ import { Composite, mergeDefaults } from "@intentius/chant";
9
+ import { StorageClass } from "../generated";
10
+
8
11
  export interface FilestoreStorageClassProps {
9
12
  /** StorageClass name. */
10
13
  name: string;
@@ -18,10 +21,14 @@ export interface FilestoreStorageClassProps {
18
21
  volumeBindingMode?: string;
19
22
  /** Additional labels. */
20
23
  labels?: Record<string, string>;
24
+ /** Per-member defaults for fine-grained overrides. */
25
+ defaults?: {
26
+ storageClass?: Partial<Record<string, unknown>>;
27
+ };
21
28
  }
22
29
 
23
30
  export interface FilestoreStorageClassResult {
24
- storageClass: Record<string, unknown>;
31
+ storageClass: InstanceType<typeof StorageClass>;
25
32
  }
26
33
 
27
34
  /**
@@ -40,7 +47,7 @@ export interface FilestoreStorageClassResult {
40
47
  * });
41
48
  * ```
42
49
  */
43
- export function FilestoreStorageClass(props: FilestoreStorageClassProps): FilestoreStorageClassResult {
50
+ export const FilestoreStorageClass = Composite<FilestoreStorageClassProps>((props) => {
44
51
  const {
45
52
  name,
46
53
  tier = "standard",
@@ -48,6 +55,7 @@ export function FilestoreStorageClass(props: FilestoreStorageClassProps): Filest
48
55
  reclaimPolicy = "Delete",
49
56
  volumeBindingMode = "WaitForFirstConsumer",
50
57
  labels: extraLabels = {},
58
+ defaults: defs,
51
59
  } = props;
52
60
 
53
61
  const commonLabels: Record<string, string> = {
@@ -64,7 +72,7 @@ export function FilestoreStorageClass(props: FilestoreStorageClassProps): Filest
64
72
  parameters.network = network;
65
73
  }
66
74
 
67
- const storageClassProps: Record<string, unknown> = {
75
+ const storageClass = new StorageClass(mergeDefaults({
68
76
  metadata: {
69
77
  name,
70
78
  labels: { ...commonLabels, "app.kubernetes.io/component": "storage" },
@@ -73,7 +81,7 @@ export function FilestoreStorageClass(props: FilestoreStorageClassProps): Filest
73
81
  parameters,
74
82
  reclaimPolicy,
75
83
  volumeBindingMode,
76
- };
84
+ }, defs?.storageClass));
77
85
 
78
- return { storageClass: storageClassProps };
79
- }
86
+ return { storageClass };
87
+ }, "FilestoreStorageClass");