timonel 2.4.0 → 2.5.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.
- package/CHANGELOG.md +7 -0
- package/dist/cli.js +33 -38
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/resources/core/coreResources.d.ts +182 -0
- package/dist/lib/resources/core/coreResources.d.ts.map +1 -1
- package/dist/lib/resources/core/coreResources.js +267 -20
- package/dist/lib/resources/core/coreResources.js.map +1 -1
- package/dist/lib/rutter.d.ts +13 -0
- package/dist/lib/rutter.d.ts.map +1 -1
- package/dist/lib/rutter.js +45 -16
- package/dist/lib/rutter.js.map +1 -1
- package/dist/lib/utils/helmHelpers.d.ts +58 -0
- package/dist/lib/utils/helmHelpers.d.ts.map +1 -0
- package/dist/lib/utils/helmHelpers.js +155 -0
- package/dist/lib/utils/helmHelpers.js.map +1 -0
- package/dist/lib/utils/podTemplates.d.ts +192 -0
- package/dist/lib/utils/podTemplates.d.ts.map +1 -0
- package/dist/lib/utils/podTemplates.js +331 -0
- package/dist/lib/utils/podTemplates.js.map +1 -0
- package/dist/lib/utils/resourceNaming.d.ts +57 -0
- package/dist/lib/utils/resourceNaming.d.ts.map +1 -0
- package/dist/lib/utils/resourceNaming.js +82 -0
- package/dist/lib/utils/resourceNaming.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Pod template utilities for generating reusable Kubernetes pod specifications
|
|
3
|
+
* @since 2.5.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Creates a secure pod template with best practices
|
|
7
|
+
* @param spec - Pod template specification
|
|
8
|
+
* @param profile - Security profile to apply
|
|
9
|
+
* @returns Pod template object
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const template = createSecurePodTemplate({
|
|
14
|
+
* name: 'web-app',
|
|
15
|
+
* containers: [{
|
|
16
|
+
* name: 'app',
|
|
17
|
+
* image: 'nginx:1.27',
|
|
18
|
+
* port: 80
|
|
19
|
+
* }]
|
|
20
|
+
* }, 'restricted');
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @since 2.5.0
|
|
24
|
+
*/
|
|
25
|
+
export function createSecurePodTemplate(spec, profile = 'baseline') {
|
|
26
|
+
const securityContext = getSecurityContextForProfile(profile);
|
|
27
|
+
const containers = spec.containers.map((container) => applyContainerSecurity(container, profile));
|
|
28
|
+
const metadata = {
|
|
29
|
+
name: spec.name,
|
|
30
|
+
labels: {
|
|
31
|
+
'app.kubernetes.io/name': spec.name,
|
|
32
|
+
...(spec.labels || {}),
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
if (spec.annotations) {
|
|
36
|
+
metadata['annotations'] = spec.annotations;
|
|
37
|
+
}
|
|
38
|
+
const combinedSecurityContext = { ...securityContext };
|
|
39
|
+
if (spec.securityContext) {
|
|
40
|
+
Object.assign(combinedSecurityContext, spec.securityContext);
|
|
41
|
+
}
|
|
42
|
+
const podSpec = {
|
|
43
|
+
containers,
|
|
44
|
+
restartPolicy: spec.restartPolicy ?? 'Always',
|
|
45
|
+
securityContext: combinedSecurityContext,
|
|
46
|
+
};
|
|
47
|
+
if (spec.initContainers) {
|
|
48
|
+
podSpec['initContainers'] = spec.initContainers.map((container) => applyContainerSecurity(container, profile));
|
|
49
|
+
}
|
|
50
|
+
if (spec.volumes) {
|
|
51
|
+
podSpec['volumes'] = spec.volumes;
|
|
52
|
+
}
|
|
53
|
+
if (spec.serviceAccountName) {
|
|
54
|
+
podSpec['serviceAccountName'] = spec.serviceAccountName;
|
|
55
|
+
}
|
|
56
|
+
if (spec.nodeSelector) {
|
|
57
|
+
podSpec['nodeSelector'] = spec.nodeSelector;
|
|
58
|
+
}
|
|
59
|
+
if (spec.tolerations) {
|
|
60
|
+
podSpec['tolerations'] = spec.tolerations;
|
|
61
|
+
}
|
|
62
|
+
if (spec.affinity) {
|
|
63
|
+
podSpec['affinity'] = spec.affinity;
|
|
64
|
+
}
|
|
65
|
+
if (spec.dnsPolicy) {
|
|
66
|
+
podSpec['dnsPolicy'] = spec.dnsPolicy;
|
|
67
|
+
}
|
|
68
|
+
if (spec.hostNetwork) {
|
|
69
|
+
podSpec['hostNetwork'] = spec.hostNetwork;
|
|
70
|
+
}
|
|
71
|
+
if (spec.priorityClassName) {
|
|
72
|
+
podSpec['priorityClassName'] = spec.priorityClassName;
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
metadata,
|
|
76
|
+
spec: podSpec,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Creates a workload-optimized pod template
|
|
81
|
+
* @param spec - Pod template specification
|
|
82
|
+
* @param workloadType - Type of workload
|
|
83
|
+
* @returns Pod template object
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* const template = createWorkloadPodTemplate({
|
|
88
|
+
* name: 'api-server',
|
|
89
|
+
* containers: [{
|
|
90
|
+
* name: 'api',
|
|
91
|
+
* image: 'myapi:latest',
|
|
92
|
+
* port: 8080
|
|
93
|
+
* }]
|
|
94
|
+
* }, 'api');
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @since 2.5.0
|
|
98
|
+
*/
|
|
99
|
+
export function createWorkloadPodTemplate(spec, workloadType) {
|
|
100
|
+
const workloadConfig = getWorkloadConfiguration(workloadType);
|
|
101
|
+
const enhancedSpec = {
|
|
102
|
+
...spec,
|
|
103
|
+
labels: { ...(spec.labels || {}), ...(workloadConfig.labels || {}) },
|
|
104
|
+
};
|
|
105
|
+
if (workloadConfig.restartPolicy) {
|
|
106
|
+
enhancedSpec.restartPolicy = workloadConfig.restartPolicy;
|
|
107
|
+
}
|
|
108
|
+
return createSecurePodTemplate(enhancedSpec, 'baseline');
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Creates a multi-container pod template with sidecar pattern
|
|
112
|
+
* @param mainContainer - Main application container
|
|
113
|
+
* @param sidecars - Sidecar containers
|
|
114
|
+
* @param options - Additional pod options
|
|
115
|
+
* @returns Pod template object
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const template = createSidecarPodTemplate(
|
|
120
|
+
* { name: 'app', image: 'myapp:latest', port: 8080 },
|
|
121
|
+
* [{ name: 'proxy', image: 'envoy:latest', port: 9901 }],
|
|
122
|
+
* { name: 'app-with-proxy' }
|
|
123
|
+
* );
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @since 2.5.0
|
|
127
|
+
*/
|
|
128
|
+
export function createSidecarPodTemplate(mainContainer, sidecars, options) {
|
|
129
|
+
const spec = {
|
|
130
|
+
name: options.name || `${mainContainer.name}-pod`,
|
|
131
|
+
containers: [mainContainer, ...sidecars],
|
|
132
|
+
...options,
|
|
133
|
+
};
|
|
134
|
+
return createSecurePodTemplate(spec, 'baseline');
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Creates a pod template with health checks
|
|
138
|
+
* @param spec - Pod template specification
|
|
139
|
+
* @param healthConfig - Health check configuration
|
|
140
|
+
* @returns Pod template object
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* const template = createHealthyPodTemplate({
|
|
145
|
+
* name: 'web-app',
|
|
146
|
+
* containers: [{
|
|
147
|
+
* name: 'app',
|
|
148
|
+
* image: 'nginx:1.27',
|
|
149
|
+
* port: 80
|
|
150
|
+
* }]
|
|
151
|
+
* }, {
|
|
152
|
+
* httpPath: '/health',
|
|
153
|
+
* port: 80
|
|
154
|
+
* });
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* @since 2.5.0
|
|
158
|
+
*/
|
|
159
|
+
export function createHealthyPodTemplate(spec, healthConfig) {
|
|
160
|
+
const enhancedContainers = spec.containers.map((container) => ({
|
|
161
|
+
...container,
|
|
162
|
+
livenessProbe: createHttpProbe(healthConfig, 'liveness'),
|
|
163
|
+
readinessProbe: createHttpProbe(healthConfig, 'readiness'),
|
|
164
|
+
}));
|
|
165
|
+
return createSecurePodTemplate({ ...spec, containers: enhancedContainers }, 'baseline');
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Gets security context for the specified profile
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
171
|
+
function getSecurityContextForProfile(profile) {
|
|
172
|
+
switch (profile) {
|
|
173
|
+
case 'restricted':
|
|
174
|
+
return {
|
|
175
|
+
runAsNonRoot: true,
|
|
176
|
+
runAsUser: 65534,
|
|
177
|
+
runAsGroup: 65534,
|
|
178
|
+
fsGroup: 65534,
|
|
179
|
+
seccompProfile: { type: 'RuntimeDefault' },
|
|
180
|
+
};
|
|
181
|
+
case 'baseline':
|
|
182
|
+
return {
|
|
183
|
+
runAsNonRoot: true,
|
|
184
|
+
runAsUser: 1000,
|
|
185
|
+
runAsGroup: 1000,
|
|
186
|
+
fsGroup: 1000,
|
|
187
|
+
};
|
|
188
|
+
case 'privileged':
|
|
189
|
+
return {};
|
|
190
|
+
default:
|
|
191
|
+
return getSecurityContextForProfile('baseline');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Applies container security based on profile
|
|
196
|
+
* @private
|
|
197
|
+
*/
|
|
198
|
+
function applyContainerSecurity(container, profile) {
|
|
199
|
+
const baseContainer = {
|
|
200
|
+
name: container.name,
|
|
201
|
+
image: container.image,
|
|
202
|
+
};
|
|
203
|
+
if (container.port) {
|
|
204
|
+
baseContainer['ports'] = [{ containerPort: container.port }];
|
|
205
|
+
}
|
|
206
|
+
if (container.env) {
|
|
207
|
+
baseContainer['env'] = container.env;
|
|
208
|
+
}
|
|
209
|
+
if (container.resources) {
|
|
210
|
+
baseContainer['resources'] = container.resources;
|
|
211
|
+
}
|
|
212
|
+
if (container.volumeMounts) {
|
|
213
|
+
baseContainer['volumeMounts'] = container.volumeMounts;
|
|
214
|
+
}
|
|
215
|
+
if (container.command) {
|
|
216
|
+
baseContainer['command'] = container.command;
|
|
217
|
+
}
|
|
218
|
+
if (container.args) {
|
|
219
|
+
baseContainer['args'] = container.args;
|
|
220
|
+
}
|
|
221
|
+
if (container.livenessProbe) {
|
|
222
|
+
baseContainer['livenessProbe'] = container.livenessProbe;
|
|
223
|
+
}
|
|
224
|
+
if (container.readinessProbe) {
|
|
225
|
+
baseContainer['readinessProbe'] = container.readinessProbe;
|
|
226
|
+
}
|
|
227
|
+
if (container.startupProbe) {
|
|
228
|
+
baseContainer['startupProbe'] = container.startupProbe;
|
|
229
|
+
}
|
|
230
|
+
const securityContext = getContainerSecurityContext(profile);
|
|
231
|
+
const containerSecurityContext = { ...securityContext };
|
|
232
|
+
if (container.securityContext) {
|
|
233
|
+
Object.assign(containerSecurityContext, container.securityContext);
|
|
234
|
+
}
|
|
235
|
+
baseContainer['securityContext'] = containerSecurityContext;
|
|
236
|
+
return baseContainer;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Gets container security context for profile
|
|
240
|
+
* @private
|
|
241
|
+
*/
|
|
242
|
+
function getContainerSecurityContext(profile) {
|
|
243
|
+
switch (profile) {
|
|
244
|
+
case 'restricted':
|
|
245
|
+
return {
|
|
246
|
+
allowPrivilegeEscalation: false,
|
|
247
|
+
readOnlyRootFilesystem: true,
|
|
248
|
+
runAsNonRoot: true,
|
|
249
|
+
capabilities: { drop: ['ALL'] },
|
|
250
|
+
seccompProfile: { type: 'RuntimeDefault' },
|
|
251
|
+
};
|
|
252
|
+
case 'baseline':
|
|
253
|
+
return {
|
|
254
|
+
allowPrivilegeEscalation: false,
|
|
255
|
+
readOnlyRootFilesystem: false,
|
|
256
|
+
runAsNonRoot: true,
|
|
257
|
+
capabilities: { drop: ['ALL'] },
|
|
258
|
+
};
|
|
259
|
+
case 'privileged':
|
|
260
|
+
return {};
|
|
261
|
+
default:
|
|
262
|
+
return getContainerSecurityContext('baseline');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Gets workload-specific configuration
|
|
267
|
+
* @private
|
|
268
|
+
*/
|
|
269
|
+
function getWorkloadConfiguration(workloadType) {
|
|
270
|
+
switch (workloadType) {
|
|
271
|
+
case 'web':
|
|
272
|
+
return {
|
|
273
|
+
labels: { 'app.kubernetes.io/component': 'frontend' },
|
|
274
|
+
restartPolicy: 'Always',
|
|
275
|
+
};
|
|
276
|
+
case 'api':
|
|
277
|
+
return {
|
|
278
|
+
labels: { 'app.kubernetes.io/component': 'backend' },
|
|
279
|
+
restartPolicy: 'Always',
|
|
280
|
+
};
|
|
281
|
+
case 'worker':
|
|
282
|
+
return {
|
|
283
|
+
labels: { 'app.kubernetes.io/component': 'worker' },
|
|
284
|
+
restartPolicy: 'Always',
|
|
285
|
+
};
|
|
286
|
+
case 'database':
|
|
287
|
+
return {
|
|
288
|
+
labels: { 'app.kubernetes.io/component': 'database' },
|
|
289
|
+
restartPolicy: 'Always',
|
|
290
|
+
};
|
|
291
|
+
case 'cache':
|
|
292
|
+
return {
|
|
293
|
+
labels: { 'app.kubernetes.io/component': 'cache' },
|
|
294
|
+
restartPolicy: 'Always',
|
|
295
|
+
};
|
|
296
|
+
case 'batch':
|
|
297
|
+
return {
|
|
298
|
+
labels: { 'app.kubernetes.io/component': 'batch' },
|
|
299
|
+
restartPolicy: 'OnFailure',
|
|
300
|
+
};
|
|
301
|
+
default:
|
|
302
|
+
return {};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Creates HTTP probe configuration
|
|
307
|
+
* @private
|
|
308
|
+
*/
|
|
309
|
+
function createHttpProbe(config, type) {
|
|
310
|
+
const defaults = {
|
|
311
|
+
liveness: {
|
|
312
|
+
initialDelaySeconds: 30,
|
|
313
|
+
periodSeconds: 10,
|
|
314
|
+
timeoutSeconds: 5,
|
|
315
|
+
failureThreshold: 3,
|
|
316
|
+
},
|
|
317
|
+
readiness: { initialDelaySeconds: 5, periodSeconds: 5, timeoutSeconds: 3, failureThreshold: 3 },
|
|
318
|
+
};
|
|
319
|
+
const defaultConfig = type === 'liveness' ? defaults.liveness : defaults.readiness;
|
|
320
|
+
return {
|
|
321
|
+
httpGet: {
|
|
322
|
+
path: config.httpPath || '/health',
|
|
323
|
+
port: config.port || 8080,
|
|
324
|
+
},
|
|
325
|
+
initialDelaySeconds: config.initialDelaySeconds || defaultConfig.initialDelaySeconds,
|
|
326
|
+
periodSeconds: config.periodSeconds || defaultConfig.periodSeconds,
|
|
327
|
+
timeoutSeconds: config.timeoutSeconds || defaultConfig.timeoutSeconds,
|
|
328
|
+
failureThreshold: config.failureThreshold || defaultConfig.failureThreshold,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=podTemplates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"podTemplates.js","sourceRoot":"","sources":["../../../src/lib/utils/podTemplates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Resource naming utilities for Helm chart generation
|
|
3
|
+
* @since 2.5.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Kubernetes resource object interface
|
|
7
|
+
* @interface KubernetesResource
|
|
8
|
+
* @since 2.5.0
|
|
9
|
+
*/
|
|
10
|
+
export interface KubernetesResource {
|
|
11
|
+
/** Resource kind (e.g., Deployment, Service) */
|
|
12
|
+
kind?: string;
|
|
13
|
+
/** Resource metadata */
|
|
14
|
+
metadata?: {
|
|
15
|
+
/** Resource name */
|
|
16
|
+
name?: string;
|
|
17
|
+
/** Resource namespace */
|
|
18
|
+
namespace?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Naming strategy for manifest files
|
|
23
|
+
* @since 2.5.0
|
|
24
|
+
*/
|
|
25
|
+
export type NamingStrategy = 'descriptive' | 'numbered' | 'kind-only' | 'name-only';
|
|
26
|
+
/**
|
|
27
|
+
* Generates descriptive resource name from Kubernetes object
|
|
28
|
+
* @param resource - Kubernetes resource object
|
|
29
|
+
* @returns Descriptive name in format "kind-name"
|
|
30
|
+
* @since 2.5.0
|
|
31
|
+
*/
|
|
32
|
+
export declare function getResourceName(resource: unknown): string;
|
|
33
|
+
/**
|
|
34
|
+
* Generates manifest file name based on strategy
|
|
35
|
+
* @param resource - Kubernetes resource object
|
|
36
|
+
* @param strategy - Naming strategy to use
|
|
37
|
+
* @param index - Resource index for numbered strategy
|
|
38
|
+
* @param prefix - Optional prefix for file names
|
|
39
|
+
* @returns Generated file name without extension
|
|
40
|
+
* @since 2.5.0
|
|
41
|
+
*/
|
|
42
|
+
export declare function generateManifestName(resource: unknown, strategy?: NamingStrategy, index?: number, prefix?: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Sanitizes name for Kubernetes compatibility
|
|
45
|
+
* @param name - Raw name to sanitize
|
|
46
|
+
* @returns Kubernetes-compatible name
|
|
47
|
+
* @since 2.5.0
|
|
48
|
+
*/
|
|
49
|
+
export declare function sanitizeKubernetesName(name: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Validates Kubernetes resource name
|
|
52
|
+
* @param name - Name to validate
|
|
53
|
+
* @returns True if valid, false otherwise
|
|
54
|
+
* @since 2.5.0
|
|
55
|
+
*/
|
|
56
|
+
export declare function isValidKubernetesName(name: string): boolean;
|
|
57
|
+
//# sourceMappingURL=resourceNaming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resourceNaming.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/resourceNaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,QAAQ,CAAC,EAAE;QACT,oBAAoB;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,yBAAyB;QACzB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,UAAU,GACV,WAAW,GACX,WAAW,CAAC;AAEhB;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAoBzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EACjB,QAAQ,GAAE,cAA8B,EACxC,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAyBR;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAI3D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Resource naming utilities for Helm chart generation
|
|
3
|
+
* @since 2.5.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Generates descriptive resource name from Kubernetes object
|
|
7
|
+
* @param resource - Kubernetes resource object
|
|
8
|
+
* @returns Descriptive name in format "kind-name"
|
|
9
|
+
* @since 2.5.0
|
|
10
|
+
*/
|
|
11
|
+
export function getResourceName(resource) {
|
|
12
|
+
if (!resource || typeof resource !== 'object') {
|
|
13
|
+
return 'resource';
|
|
14
|
+
}
|
|
15
|
+
const k8sResource = resource;
|
|
16
|
+
if (k8sResource.kind && k8sResource.metadata?.name) {
|
|
17
|
+
return `${k8sResource.kind.toLowerCase()}-${k8sResource.metadata.name}`;
|
|
18
|
+
}
|
|
19
|
+
if (k8sResource.kind) {
|
|
20
|
+
return k8sResource.kind.toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
if (k8sResource.metadata?.name) {
|
|
23
|
+
return k8sResource.metadata.name;
|
|
24
|
+
}
|
|
25
|
+
return 'resource';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Generates manifest file name based on strategy
|
|
29
|
+
* @param resource - Kubernetes resource object
|
|
30
|
+
* @param strategy - Naming strategy to use
|
|
31
|
+
* @param index - Resource index for numbered strategy
|
|
32
|
+
* @param prefix - Optional prefix for file names
|
|
33
|
+
* @returns Generated file name without extension
|
|
34
|
+
* @since 2.5.0
|
|
35
|
+
*/
|
|
36
|
+
export function generateManifestName(resource, strategy = 'descriptive', index, prefix) {
|
|
37
|
+
const k8sResource = resource;
|
|
38
|
+
switch (strategy) {
|
|
39
|
+
case 'descriptive': {
|
|
40
|
+
return getResourceName(resource);
|
|
41
|
+
}
|
|
42
|
+
case 'numbered': {
|
|
43
|
+
const paddedIndex = String(index ?? 1).padStart(3, '0');
|
|
44
|
+
return prefix ? `${prefix}-${paddedIndex}` : `manifests-${paddedIndex}`;
|
|
45
|
+
}
|
|
46
|
+
case 'kind-only': {
|
|
47
|
+
return k8sResource.kind?.toLowerCase() ?? 'resource';
|
|
48
|
+
}
|
|
49
|
+
case 'name-only': {
|
|
50
|
+
return k8sResource.metadata?.name ?? 'resource';
|
|
51
|
+
}
|
|
52
|
+
default: {
|
|
53
|
+
return getResourceName(resource);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Sanitizes name for Kubernetes compatibility
|
|
59
|
+
* @param name - Raw name to sanitize
|
|
60
|
+
* @returns Kubernetes-compatible name
|
|
61
|
+
* @since 2.5.0
|
|
62
|
+
*/
|
|
63
|
+
export function sanitizeKubernetesName(name) {
|
|
64
|
+
return name
|
|
65
|
+
.toLowerCase()
|
|
66
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
67
|
+
.replace(/-+/g, '-')
|
|
68
|
+
.replace(/^-|-$/g, '')
|
|
69
|
+
.substring(0, 63);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Validates Kubernetes resource name
|
|
73
|
+
* @param name - Name to validate
|
|
74
|
+
* @returns True if valid, false otherwise
|
|
75
|
+
* @since 2.5.0
|
|
76
|
+
*/
|
|
77
|
+
export function isValidKubernetesName(name) {
|
|
78
|
+
// eslint-disable-next-line security/detect-unsafe-regex -- Safe: simple DNS-1123 validation
|
|
79
|
+
const regex = /^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/;
|
|
80
|
+
return regex.test(name) && name.length <= 63;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=resourceNaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resourceNaming.js","sourceRoot":"","sources":["../../../src/lib/utils/resourceNaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA6BH;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,QAAiB;IAC/C,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,WAAW,GAAG,QAA8B,CAAC;IAEnD,IAAI,WAAW,CAAC,IAAI,IAAI,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;QACnD,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC;QACrB,OAAO,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC;IAED,IAAI,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC/B,OAAO,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;IACnC,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAiB,EACjB,WAA2B,aAAa,EACxC,KAAc,EACd,MAAe;IAEf,MAAM,WAAW,GAAG,QAA8B,CAAC;IAEnD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;QAED,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACxD,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,aAAa,WAAW,EAAE,CAAC;QAC1E,CAAC;QAED,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,OAAO,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,UAAU,CAAC;QACvD,CAAC;QAED,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,OAAO,WAAW,CAAC,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC;QAClD,CAAC;QAED,OAAO,CAAC,CAAC,CAAC;YACR,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,4FAA4F;IAC5F,MAAM,KAAK,GAAG,iCAAiC,CAAC;IAChD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;AAC/C,CAAC"}
|