timonel 2.9.1 β 2.10.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 +42 -0
- package/README.md +159 -18
- package/SECURITY.md +53 -7
- package/dist/cli.js +81 -46
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -2
- package/dist/lib/helmChartWriter.js +9 -9
- package/dist/lib/rutter.js +19 -27
- package/dist/lib/templates/basic-chart.js +21 -0
- package/dist/lib/templates/flexible-subchart.d.ts +27 -0
- package/dist/lib/templates/flexible-subchart.js +107 -0
- package/dist/lib/templates/subchart.js +46 -48
- package/dist/lib/templates/umbrella-chart.d.ts +1 -0
- package/dist/lib/templates/umbrella-chart.js +130 -65
- package/dist/lib/types.d.ts +8 -1
- package/dist/lib/umbrellaRutter.js +4 -4
- package/dist/lib/utils/helmYamlSerializer.d.ts +8 -0
- package/dist/lib/utils/helmYamlSerializer.js +88 -0
- package/package.json +14 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,45 @@
|
|
|
1
|
+
# [2.10.0](https://github.com/KenkoGeek/timonel/compare/v2.9.2...v2.10.0) (2025-09-20)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- **ci:** and beside or ([2901953](https://github.com/KenkoGeek/timonel/commit/2901953363ff81c03ad95e57fbf61129bffe4138))
|
|
6
|
+
- **ci:** change CodeQL build-mode to 'none' for JavaScript/TypeScript ([017ec93](https://github.com/KenkoGeek/timonel/commit/017ec930940780fca9e6f93e02372067f899675f))
|
|
7
|
+
- **ci:** clean up workflows and fix CodeQL configuration ([4c3ac55](https://github.com/KenkoGeek/timonel/commit/4c3ac55e04210d77ad694aef1fab261482a7f5e9))
|
|
8
|
+
- **ci:** correct CodeQL workflow configuration ([25813d3](https://github.com/KenkoGeek/timonel/commit/25813d3b4ce649da5fa3b1cf29f825369c17b196))
|
|
9
|
+
- **ci:** correct CodeQL workflow name in release.yaml ([cb38608](https://github.com/KenkoGeek/timonel/commit/cb3860881b527f5016dcdc891f848c22ea464868))
|
|
10
|
+
- **ci:** correct job dependencies and summary references ([d37cc9c](https://github.com/KenkoGeek/timonel/commit/d37cc9ccf05407f28b85bd7eeb5710b2460b72ef))
|
|
11
|
+
- **ci:** ensure real release on main branch ([c06a5f7](https://github.com/KenkoGeek/timonel/commit/c06a5f7f9d0d45261c95e677f04382e0e20de58d))
|
|
12
|
+
- **ci:** lint errors ([08fbb64](https://github.com/KenkoGeek/timonel/commit/08fbb645b3661a2bc4e6bf33b309ab88cd707fef))
|
|
13
|
+
- **ci:** remove explicit pnpm version from CodeQL workflow ([25a8a6c](https://github.com/KenkoGeek/timonel/commit/25a8a6cd9556ae614bb84bfcc147aadb17850f48))
|
|
14
|
+
- **ci:** remove explicit pnpm version from workflows ([b517e1e](https://github.com/KenkoGeek/timonel/commit/b517e1eb35b3ab57673428c7d80fa25d427bf046))
|
|
15
|
+
- **ci:** reorder pnpm setup before Node.js in CodeQL workflow ([904579c](https://github.com/KenkoGeek/timonel/commit/904579ca507ef2cad5f11887e35431e6a15a59f5))
|
|
16
|
+
- **ci:** resolve pnpm version conflict in workflows ([a2ee153](https://github.com/KenkoGeek/timonel/commit/a2ee153934c5710e58f8e5bd85da6ea70e1c8959))
|
|
17
|
+
- **ci:** simple but effective release ([a6b2014](https://github.com/KenkoGeek/timonel/commit/a6b201476903cedf8e1d1dd7bbf36c2f02fa750b))
|
|
18
|
+
- **ci:** simple but effective release, security.md updated ([6911d21](https://github.com/KenkoGeek/timonel/commit/6911d2131971787d8afce1123ed4969e0ae8e077))
|
|
19
|
+
- **ci:** use exact pnpm version 10.15.0 in workflows ([2634e7d](https://github.com/KenkoGeek/timonel/commit/2634e7d30b58dcea182605a52a1e34daca0cf6bb))
|
|
20
|
+
- **core:** correct TypeScript errors and improve version handling ([3945d8b](https://github.com/KenkoGeek/timonel/commit/3945d8b6e3f84141579e0a08b48bdfd480e64168))
|
|
21
|
+
- **core:** resolve issue [#114](https://github.com/KenkoGeek/timonel/issues/114) - invalid Helm template generation ([eac0bdb](https://github.com/KenkoGeek/timonel/commit/eac0bdbbe4946e0dcf29346b956451f4d1f4a016))
|
|
22
|
+
- **docs:** apply prettier formatting to README.md ([0ad15aa](https://github.com/KenkoGeek/timonel/commit/0ad15aa8add475268b6b7c9af9bdcd3b6a82bb80))
|
|
23
|
+
- **release:** align required checks with ruleset configuration ([1b4d1dd](https://github.com/KenkoGeek/timonel/commit/1b4d1dd245974f80d3fb00096d48dbaaa79419f1))
|
|
24
|
+
- **release:** update required checks in release workflow ([1811247](https://github.com/KenkoGeek/timonel/commit/1811247fa1562885b8bd43909bd2127e23de225d))
|
|
25
|
+
- resolve issue [#114](https://github.com/KenkoGeek/timonel/issues/114) - Helm template generation bug and enhance documentation ([#116](https://github.com/KenkoGeek/timonel/issues/116)) ([92782f8](https://github.com/KenkoGeek/timonel/commit/92782f840571e036cc235d1b7739b00d8ac8d56c))
|
|
26
|
+
- **umbrella:** remove unused \_subchartInstance variables ([73b3a8a](https://github.com/KenkoGeek/timonel/commit/73b3a8a99b30ef4576f60331f66b30164bd8213e))
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
- **ci:** optimize GitHub workflows with enhanced performance and reliability ([09d0470](https://github.com/KenkoGeek/timonel/commit/09d04700b011e8dc4ae3875c4a46d835b88bb13d)), closes [#114](https://github.com/KenkoGeek/timonel/issues/114)
|
|
31
|
+
- **core:** enhance ChartProps for better flexibility ([385f966](https://github.com/KenkoGeek/timonel/commit/385f96607c27a1dd58ff8e4ceb60d8a56ece8422))
|
|
32
|
+
|
|
33
|
+
### Reverts
|
|
34
|
+
|
|
35
|
+
- **ci:** restore original release workflow ([f2f9b27](https://github.com/KenkoGeek/timonel/commit/f2f9b27e1950e8c9496f0faf6b874c0be5ad02e9))
|
|
36
|
+
|
|
37
|
+
## [2.9.2](https://github.com/KenkoGeek/timonel/compare/v2.9.1...v2.9.2) (2025-09-19)
|
|
38
|
+
|
|
39
|
+
### Bug Fixes
|
|
40
|
+
|
|
41
|
+
- **helm:** implement Helm-aware YAML serializer ([#112](https://github.com/KenkoGeek/timonel/issues/112)) ([daf4276](https://github.com/KenkoGeek/timonel/commit/daf427618eea73db832682f6b37287a9176bc31e))
|
|
42
|
+
|
|
1
43
|
## [2.9.1](https://github.com/KenkoGeek/timonel/compare/v2.9.0...v2.9.1) (2025-09-19)
|
|
2
44
|
|
|
3
45
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -10,39 +10,141 @@
|
|
|
10
10
|
[![TypeScript][ts-badge]][ts-url]
|
|
11
11
|
[![Maintained by KenkoGeek][maintained-badge]][maintained-url]
|
|
12
12
|
|
|
13
|
-
Timonel (Spanish for "helmsman") is a TypeScript library
|
|
14
|
-
using cdk8s. Define Kubernetes resources with classes and synthesize
|
|
15
|
-
`Chart.yaml`, `values.yaml`,
|
|
13
|
+
**Timonel** (Spanish for "helmsman") is a powerful TypeScript library that programmatically generates
|
|
14
|
+
Helm charts using cdk8s. Define Kubernetes resources with type-safe classes and synthesize complete
|
|
15
|
+
Helm charts with `Chart.yaml`, `values.yaml`, environment-specific values files, and `templates/`
|
|
16
|
+
directory.
|
|
17
|
+
|
|
18
|
+
> π **New in v2.9.2**: Enhanced umbrella chart support with flexible subchart templates, improved
|
|
19
|
+
> CLI version handling, and optimized GitHub workflows.
|
|
16
20
|
|
|
17
21
|
## β¨ Key Features
|
|
18
22
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
- **AWS**: EBS/EFS StorageClass, ALB Ingress, IRSA ServiceAccount
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
23
|
+
- **π Type-safe API** with strict TypeScript and cdk8s constructs
|
|
24
|
+
- **π§ Flexible resource creation** with built-in methods and `addManifest()` for custom resources
|
|
25
|
+
- **π Multi-environment support** with automatic values files generation
|
|
26
|
+
- **βοΈ Umbrella Charts** for managing multiple subcharts as a single unit
|
|
27
|
+
- **βοΈ Cloud integrations**:
|
|
28
|
+
- **AWS**: EBS/EFS StorageClass, ALB Ingress, IRSA ServiceAccount
|
|
29
|
+
- **Azure**: Azure Disk, Azure Files, AKS integrations
|
|
30
|
+
- **GCP**: GCE Persistent Disk, GKE integrations
|
|
31
|
+
- **π‘οΈ Security-first approach** with NetworkPolicies and best practices
|
|
32
|
+
- **β‘ Minimal CLI** (`tl`) for scaffolding and chart generation
|
|
33
|
+
- **π¦ Flexible subchart templates** supporting cdk8s, cdk8s-plus-33, and raw manifests
|
|
27
34
|
|
|
28
35
|
## π Quick Start
|
|
29
36
|
|
|
37
|
+
### Installation
|
|
38
|
+
|
|
30
39
|
```bash
|
|
31
40
|
# Install Timonel globally
|
|
32
41
|
npm install -g timonel
|
|
33
42
|
|
|
43
|
+
# Or use with pnpm
|
|
44
|
+
pnpm add -g timonel
|
|
45
|
+
|
|
46
|
+
# Verify installation
|
|
47
|
+
tl --version
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Basic Usage
|
|
51
|
+
|
|
52
|
+
```bash
|
|
34
53
|
# Create your first chart
|
|
35
54
|
tl init my-app
|
|
36
55
|
|
|
37
56
|
# Generate Helm chart
|
|
38
|
-
tl synth
|
|
57
|
+
tl synth my-app my-app-dist
|
|
39
58
|
|
|
40
59
|
# Use with Helm
|
|
41
|
-
helm install my-app
|
|
60
|
+
helm install my-app my-app-dist
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Umbrella Charts
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Create umbrella chart structure
|
|
67
|
+
tl umbrella init my-umbrella-app
|
|
68
|
+
|
|
69
|
+
# Add subcharts
|
|
70
|
+
tl umbrella add frontend
|
|
71
|
+
tl umbrella add backend
|
|
72
|
+
|
|
73
|
+
# Generate umbrella chart
|
|
74
|
+
tl umbrella synth
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## π‘ Examples
|
|
78
|
+
|
|
79
|
+
### Simple Web Application
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { Chart } from 'cdk8s';
|
|
83
|
+
import { Deployment, Service } from 'cdk8s-plus-33';
|
|
84
|
+
|
|
85
|
+
export class WebAppChart extends Chart {
|
|
86
|
+
constructor(scope: Chart, id: string) {
|
|
87
|
+
super(scope, id);
|
|
88
|
+
|
|
89
|
+
// Create deployment
|
|
90
|
+
new Deployment(this, 'web-deployment', {
|
|
91
|
+
containers: [
|
|
92
|
+
{
|
|
93
|
+
image: 'nginx:latest',
|
|
94
|
+
port: 80,
|
|
95
|
+
env: {
|
|
96
|
+
NGINX_PORT: '80',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Create service
|
|
103
|
+
new Service(this, 'web-service', {
|
|
104
|
+
selector: { app: 'web' },
|
|
105
|
+
ports: [{ port: 80, targetPort: 80 }],
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Umbrella Chart with Multiple Services
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { UmbrellaChartTemplate } from 'timonel';
|
|
115
|
+
|
|
116
|
+
const umbrellaConfig = {
|
|
117
|
+
name: 'my-umbrella-app',
|
|
118
|
+
version: '1.0.0',
|
|
119
|
+
subcharts: [
|
|
120
|
+
{
|
|
121
|
+
name: 'frontend',
|
|
122
|
+
version: '1.0.0',
|
|
123
|
+
chart: frontendChartFunction,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: 'backend',
|
|
127
|
+
version: '1.0.0',
|
|
128
|
+
chart: backendChartFunction,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export const umbrella = new UmbrellaChartTemplate(umbrellaConfig);
|
|
42
134
|
```
|
|
43
135
|
|
|
44
136
|
## π Documentation
|
|
45
137
|
|
|
138
|
+
- **[API Reference](https://github.com/KenkoGeek/timonel/wiki/API-Reference)** - Complete API
|
|
139
|
+
documentation
|
|
140
|
+
- **[CLI Reference](https://github.com/KenkoGeek/timonel/wiki/CLI-Reference)** - Command-line
|
|
141
|
+
interface guide
|
|
142
|
+
- **[Examples](https://github.com/KenkoGeek/timonel/wiki/Examples)** - Real-world usage examples
|
|
143
|
+
- **[Best Practices](https://github.com/KenkoGeek/timonel/wiki/Best-Practices)** - Recommended
|
|
144
|
+
patterns and practices
|
|
145
|
+
- **[Contributing](https://github.com/KenkoGeek/timonel/wiki/Contributing)** - Development setup
|
|
146
|
+
and guidelines
|
|
147
|
+
|
|
46
148
|
## π§ Troubleshooting
|
|
47
149
|
|
|
48
150
|
### CDK8s Module Not Found Error
|
|
@@ -59,13 +161,13 @@ If you get `Error: Cannot find module 'cdk8s'` when running `tl umbrella synth`:
|
|
|
59
161
|
"version": "1.0.0",
|
|
60
162
|
"type": "module",
|
|
61
163
|
"dependencies": {
|
|
62
|
-
"cdk8s": "^2.70.
|
|
63
|
-
"cdk8s-plus-33": "^2.3.
|
|
164
|
+
"cdk8s": "^2.70.15",
|
|
165
|
+
"cdk8s-plus-33": "^2.3.6",
|
|
64
166
|
"constructs": "^10.4.2",
|
|
65
|
-
"timonel": "^2.9.
|
|
167
|
+
"timonel": "^2.9.2"
|
|
66
168
|
},
|
|
67
169
|
"devDependencies": {
|
|
68
|
-
"@types/node": "^24.
|
|
170
|
+
"@types/node": "^24.5.2",
|
|
69
171
|
"typescript": "^5.9.2"
|
|
70
172
|
}
|
|
71
173
|
}
|
|
@@ -78,6 +180,45 @@ npm install
|
|
|
78
180
|
tl umbrella synth # Now it works!
|
|
79
181
|
```
|
|
80
182
|
|
|
183
|
+
### Version Display Issues
|
|
184
|
+
|
|
185
|
+
If the CLI shows an incorrect version:
|
|
186
|
+
|
|
187
|
+
**Problem**: The CLI might be using cached or hardcoded version information.
|
|
188
|
+
|
|
189
|
+
**Solution**: Rebuild the project:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# In the Timonel project directory
|
|
193
|
+
pnpm build
|
|
194
|
+
tl --version # Should show correct version
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### TypeScript Compilation Errors
|
|
198
|
+
|
|
199
|
+
If you encounter TypeScript errors when using umbrella charts:
|
|
200
|
+
|
|
201
|
+
**Problem**: Type mismatches in subchart configurations.
|
|
202
|
+
|
|
203
|
+
**Solution**: Ensure proper type casting for version and description fields:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// β
Correct
|
|
207
|
+
const subchart = {
|
|
208
|
+
name: 'my-service',
|
|
209
|
+
version: '1.0.0' as string,
|
|
210
|
+
description: 'My service' as string,
|
|
211
|
+
chart: myChartFunction,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// β Incorrect
|
|
215
|
+
const subchart = {
|
|
216
|
+
name: 'my-service',
|
|
217
|
+
version: someUnknownValue, // This will cause TypeScript errors
|
|
218
|
+
chart: myChartFunction,
|
|
219
|
+
};
|
|
220
|
+
```
|
|
221
|
+
|
|
81
222
|
## π€ Contributing
|
|
82
223
|
|
|
83
224
|
See our [Contributing Guide](https://github.com/KenkoGeek/timonel/wiki/Contributing) for development
|
|
@@ -104,6 +245,6 @@ MIT
|
|
|
104
245
|
[maintained-badge]: https://img.shields.io/badge/maintained%20by-KenkoGeek-6C78AF?style=flat
|
|
105
246
|
[maintained-url]: https://github.com/kenkogeek/
|
|
106
247
|
[ci-badge]: https://github.com/KenkoGeek/timonel/actions/workflows/test.yaml/badge.svg?branch=main
|
|
107
|
-
[ci-url]: https://github.com/KenkoGeek/timonel/actions/workflows/
|
|
248
|
+
[ci-url]: https://github.com/KenkoGeek/timonel/actions/workflows/test.yaml
|
|
108
249
|
[codeql-badge]: https://github.com/KenkoGeek/timonel/actions/workflows/codeql.yaml/badge.svg
|
|
109
250
|
[codeql-url]: https://github.com/KenkoGeek/timonel/actions/workflows/codeql.yaml
|
package/SECURITY.md
CHANGED
|
@@ -14,24 +14,40 @@
|
|
|
14
14
|
- Steps to reproduce
|
|
15
15
|
- Potential impact assessment
|
|
16
16
|
- Suggested mitigation (if any)
|
|
17
|
+
- Affected versions
|
|
17
18
|
|
|
18
19
|
**Response timeline:**
|
|
19
20
|
|
|
20
21
|
- Initial response: 48 hours
|
|
21
22
|
- Triage completion: 5 business days
|
|
22
23
|
- Status updates: Every 10 business days
|
|
24
|
+
- Fix timeline: Depends on severity (Critical: 72h, High: 1 week, Medium: 2 weeks)
|
|
25
|
+
|
|
26
|
+
**Severity levels:**
|
|
27
|
+
|
|
28
|
+
- **Critical**: Remote code execution, privilege escalation, data breach
|
|
29
|
+
- **High**: Authentication bypass, significant data exposure
|
|
30
|
+
- **Medium**: Information disclosure, denial of service
|
|
31
|
+
- **Low**: Minor information leakage, cosmetic issues
|
|
23
32
|
|
|
24
33
|
## Supported Versions
|
|
25
34
|
|
|
26
35
|
We provide security updates for the following versions:
|
|
27
36
|
|
|
28
|
-
| Version | Supported |
|
|
29
|
-
| ------- | -------------- |
|
|
30
|
-
| 2.4.0+ | β
Current |
|
|
31
|
-
| 2.3.x | β
Supported |
|
|
32
|
-
| 2.0-2.2 | β οΈ Limited | Critical
|
|
33
|
-
| 1.x.x | β End of life |
|
|
34
|
-
| < 1.0 | β End of life |
|
|
37
|
+
| Version | Supported | Security Updates | End of Life |
|
|
38
|
+
| ------- | -------------- | ---------------- | ----------- |
|
|
39
|
+
| 2.4.0+ | β
Current | Full support | TBD |
|
|
40
|
+
| 2.3.x | β
Supported | Full support | TBD |
|
|
41
|
+
| 2.0-2.2 | β οΈ Limited | Critical only | 2024-12-31 |
|
|
42
|
+
| 1.x.x | β End of life | None | 2024-06-30 |
|
|
43
|
+
| < 1.0 | β End of life | None | 2024-01-01 |
|
|
44
|
+
|
|
45
|
+
**Update policy:**
|
|
46
|
+
|
|
47
|
+
- **Current versions**: All security updates within 48 hours
|
|
48
|
+
- **Supported versions**: Critical updates within 1 week
|
|
49
|
+
- **Limited versions**: Critical updates only, within 2 weeks
|
|
50
|
+
- **End of life**: No updates provided
|
|
35
51
|
|
|
36
52
|
## Development Security
|
|
37
53
|
|
|
@@ -57,6 +73,10 @@ We provide security updates for the following versions:
|
|
|
57
73
|
- **Multi-layer scanning**: ESLint security plugin + CodeQL + pnpm audit
|
|
58
74
|
- **Branch protection**: Required status checks and reviews
|
|
59
75
|
- **Secrets management**: No hardcoded credentials
|
|
76
|
+
- **Native dependencies**: Uses `workflow_run` for secure pipeline dependencies
|
|
77
|
+
- **Environment protection**: Production releases require manual approval
|
|
78
|
+
- **Automated security**: Security scans run on every PR and push
|
|
79
|
+
- **Dependency provenance**: NPM_CONFIG_PROVENANCE enabled for package integrity
|
|
60
80
|
|
|
61
81
|
### Security Features
|
|
62
82
|
|
|
@@ -77,3 +97,29 @@ We provide security updates for the following versions:
|
|
|
77
97
|
- **Values files**: Avoid hardcoded secrets in values
|
|
78
98
|
- **Network policies**: Use provided NetworkPolicy helpers
|
|
79
99
|
- **RBAC**: Apply principle of least privilege in Kubernetes
|
|
100
|
+
|
|
101
|
+
## Security Best Practices
|
|
102
|
+
|
|
103
|
+
### For Developers
|
|
104
|
+
|
|
105
|
+
- **Keep dependencies updated**: Run `pnpm audit` regularly
|
|
106
|
+
- **Review PRs carefully**: Check for security implications
|
|
107
|
+
- **Use security tools**: Enable IDE security plugins
|
|
108
|
+
- **Follow secure coding**: Avoid dangerous patterns (eval, innerHTML, etc.)
|
|
109
|
+
- **Test security features**: Verify input validation and sanitization
|
|
110
|
+
|
|
111
|
+
### For Users
|
|
112
|
+
|
|
113
|
+
- **Update regularly**: Always use the latest stable version
|
|
114
|
+
- **Review configurations**: Check generated Helm charts before deployment
|
|
115
|
+
- **Use secrets management**: Never hardcode credentials
|
|
116
|
+
- **Monitor deployments**: Watch for unusual behavior
|
|
117
|
+
- **Apply patches**: Install security updates promptly
|
|
118
|
+
|
|
119
|
+
## Security Tools Integration
|
|
120
|
+
|
|
121
|
+
- **GitHub Dependabot**: Automated dependency updates
|
|
122
|
+
- **CodeQL**: Static analysis for security vulnerabilities
|
|
123
|
+
- **ESLint Security**: Runtime security checks
|
|
124
|
+
- **pnpm audit**: Dependency vulnerability scanning
|
|
125
|
+
- **Semantic Release**: Automated versioning with security considerations
|
package/dist/cli.js
CHANGED
|
@@ -8,46 +8,65 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
8
8
|
const __dirname = path.dirname(__filename);
|
|
9
9
|
const UMBRELLA_CONFIG_FILE = 'umbrella.config.json';
|
|
10
10
|
const UMBRELLA_FILE_NAME = 'umbrella.ts';
|
|
11
|
+
function getVersion() {
|
|
12
|
+
try {
|
|
13
|
+
const packagePath = path.join(__dirname, '..', 'package.json');
|
|
14
|
+
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
15
|
+
return packageJson.version || '0.1.0';
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return '0.1.0';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
11
21
|
function log(msg, silent = false) {
|
|
12
22
|
if (!silent) {
|
|
13
23
|
console.log(msg);
|
|
14
24
|
}
|
|
15
25
|
}
|
|
16
|
-
function
|
|
26
|
+
function logError(msg, silent = false) {
|
|
27
|
+
if (!silent) {
|
|
28
|
+
console.error(msg);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function usageAndExit(msg, silent = false) {
|
|
17
32
|
if (msg) {
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
33
|
+
logError(`Error: ${msg}`, silent);
|
|
34
|
+
}
|
|
35
|
+
if (!silent) {
|
|
36
|
+
console.log([
|
|
37
|
+
'Usage: tl <command> [options]',
|
|
38
|
+
'',
|
|
39
|
+
'Commands:',
|
|
40
|
+
' tl init <chart-name> Create new chart',
|
|
41
|
+
' tl synth [outDir] Generate Helm chart',
|
|
42
|
+
' tl validate Validate chart',
|
|
43
|
+
' tl deploy <release> [namespace] Deploy chart',
|
|
44
|
+
' tl templates List available templates',
|
|
45
|
+
' tl help Show this help message',
|
|
46
|
+
'',
|
|
47
|
+
'Umbrella Charts:',
|
|
48
|
+
' tl umbrella init <n> Create umbrella chart structure',
|
|
49
|
+
' tl umbrella add <subchart> Add subchart to umbrella',
|
|
50
|
+
' tl umbrella synth [outDir] Generate umbrella chart',
|
|
51
|
+
'',
|
|
52
|
+
'Flags:',
|
|
53
|
+
' --dry-run Show what would be done without executing',
|
|
54
|
+
' --silent Suppress output (useful for CI)',
|
|
55
|
+
' --env <environment> Use environment-specific values',
|
|
56
|
+
' --set <key=value> Override values (can be used multiple times)',
|
|
57
|
+
' --help, -h Show this help message',
|
|
58
|
+
' --version, -v Show version information',
|
|
59
|
+
'',
|
|
60
|
+
'Examples:',
|
|
61
|
+
' tl init my-app',
|
|
62
|
+
' tl synth my-app my-app/dist',
|
|
63
|
+
' tl validate my-app',
|
|
64
|
+
' tl deploy my-app my-release --env prod',
|
|
65
|
+
' tl synth --dry-run --silent',
|
|
66
|
+
' tl synth --set replicas=5 --set image.tag=v2.0.0',
|
|
67
|
+
' tl deploy my-app my-release --set service.port=8080',
|
|
68
|
+
].join('\n'));
|
|
69
|
+
}
|
|
51
70
|
process.exit(msg ? 1 : 0);
|
|
52
71
|
}
|
|
53
72
|
async function cmdInit(name, silent = false) {
|
|
@@ -165,14 +184,13 @@ async function cmdTemplates(flags) {
|
|
|
165
184
|
},
|
|
166
185
|
];
|
|
167
186
|
if (flags?.silent) {
|
|
168
|
-
console.log(JSON.stringify(templates));
|
|
187
|
+
console.log(JSON.stringify(templates, null, 2));
|
|
169
188
|
}
|
|
170
189
|
else {
|
|
171
190
|
console.log('Available templates:');
|
|
172
191
|
templates.forEach((t) => {
|
|
173
|
-
console.log(
|
|
174
|
-
console.log(`
|
|
175
|
-
console.log(` Usage: ${t.usage}`);
|
|
192
|
+
console.log(` ${t.name.padEnd(15)} - ${t.description}`);
|
|
193
|
+
console.log(` ${''.padEnd(15)} Usage: ${t.usage}`);
|
|
176
194
|
});
|
|
177
195
|
}
|
|
178
196
|
}
|
|
@@ -206,7 +224,7 @@ async function cmdUmbrellaInit(name, silent = false) {
|
|
|
206
224
|
fs.writeFileSync(umbrellaFile, generateUmbrellaChart(validName));
|
|
207
225
|
const config = {
|
|
208
226
|
name: validName,
|
|
209
|
-
version:
|
|
227
|
+
version: getVersion(),
|
|
210
228
|
description: `${validName} umbrella chart`,
|
|
211
229
|
subcharts: [],
|
|
212
230
|
};
|
|
@@ -307,7 +325,7 @@ async function cmdUmbrellaAdd(subchartPath, silent = false) {
|
|
|
307
325
|
fs.writeFileSync(chartFile, subchartContent);
|
|
308
326
|
config.subcharts.push({
|
|
309
327
|
name: subchartName,
|
|
310
|
-
version:
|
|
328
|
+
version: getVersion(),
|
|
311
329
|
path: `./charts/${validSubchartPath}/chart.ts`,
|
|
312
330
|
});
|
|
313
331
|
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
|
|
@@ -388,15 +406,17 @@ function parseFlags(args) {
|
|
|
388
406
|
}
|
|
389
407
|
case '--version':
|
|
390
408
|
case '-v':
|
|
391
|
-
|
|
409
|
+
if (!flags.silent) {
|
|
410
|
+
console.log(`Timonel v${getVersion()}`);
|
|
411
|
+
}
|
|
392
412
|
process.exit(0);
|
|
393
413
|
break;
|
|
394
414
|
case '--help':
|
|
395
415
|
case '-h':
|
|
396
|
-
usageAndExit();
|
|
416
|
+
usageAndExit(undefined, flags.silent);
|
|
397
417
|
break;
|
|
398
418
|
default:
|
|
399
|
-
usageAndExit(`Unknown flag: ${flag}
|
|
419
|
+
usageAndExit(`Unknown flag: ${flag}`, flags.silent);
|
|
400
420
|
}
|
|
401
421
|
}
|
|
402
422
|
return flags;
|
|
@@ -421,20 +441,35 @@ async function executeCommand(command, args, flags) {
|
|
|
421
441
|
case 'umbrella':
|
|
422
442
|
await cmdUmbrella(args[0], args.slice(1), flags);
|
|
423
443
|
break;
|
|
444
|
+
case 'help':
|
|
424
445
|
case undefined:
|
|
425
|
-
usageAndExit(
|
|
446
|
+
usageAndExit(undefined, flags.silent);
|
|
426
447
|
break;
|
|
427
448
|
default:
|
|
428
|
-
usageAndExit(`Unknown command: ${command}
|
|
449
|
+
usageAndExit(`Unknown command: ${command}`, flags.silent);
|
|
429
450
|
}
|
|
430
451
|
}
|
|
431
452
|
async function main() {
|
|
432
453
|
const args = process.argv.slice(2);
|
|
454
|
+
const isSilent = args.includes('--silent');
|
|
455
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
456
|
+
usageAndExit(undefined, isSilent);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
460
|
+
if (!isSilent) {
|
|
461
|
+
console.log(`Timonel v${getVersion()}`);
|
|
462
|
+
}
|
|
463
|
+
process.exit(0);
|
|
464
|
+
}
|
|
433
465
|
const command = args.shift();
|
|
434
466
|
const flags = parseFlags(args);
|
|
435
467
|
await executeCommand(command, args, flags);
|
|
436
468
|
}
|
|
437
469
|
main().catch((error) => {
|
|
438
|
-
|
|
470
|
+
const flags = parseFlags(process.argv.slice(2));
|
|
471
|
+
if (!flags.silent) {
|
|
472
|
+
console.error('Error:', error.message);
|
|
473
|
+
}
|
|
439
474
|
process.exit(1);
|
|
440
475
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,11 @@ export * from './lib/helmChartWriter.js';
|
|
|
3
3
|
export * from './lib/rutter.js';
|
|
4
4
|
export * from './lib/security.js';
|
|
5
5
|
export * from './lib/umbrella.js';
|
|
6
|
-
export { UmbrellaChartTemplate as UmbrellaChart } from './lib/templates/umbrella-chart.js';
|
|
7
|
-
export { Subchart } from './lib/templates/subchart.js';
|
|
8
6
|
export { BasicChart } from './lib/templates/basic-chart.js';
|
|
7
|
+
export { FlexibleSubchart, createFlexibleSubchart } from './lib/templates/flexible-subchart.js';
|
|
8
|
+
export { Subchart } from './lib/templates/subchart.js';
|
|
9
|
+
export { UmbrellaChartTemplate as UmbrellaChart } from './lib/templates/umbrella-chart.js';
|
|
10
|
+
export type { ChartProps, SubchartProps } from './lib/types.js';
|
|
9
11
|
export type { AWSALBIngressSpec, AWSEBSStorageClassSpec, AWSEFSStorageClassSpec, AWSIRSAServiceAccountSpec, } from './lib/resources/cloud/aws/awsResources.js';
|
|
10
12
|
export type { KarpenterDisruption, KarpenterDisruptionBudget, KarpenterEC2NodeClassSpec, KarpenterNodeClaimSpec, KarpenterNodePoolSpec, } from './lib/resources/cloud/aws/karpenterResources.js';
|
|
11
13
|
export { DEFAULT_TERMINATION_GRACE_PERIOD, isValidDisruptionBudget, isValidKubernetesDuration, KarpenterVersionUtils, } from './lib/resources/cloud/aws/karpenterResources.js';
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,9 @@ export * from './lib/helmChartWriter.js';
|
|
|
3
3
|
export * from './lib/rutter.js';
|
|
4
4
|
export * from './lib/security.js';
|
|
5
5
|
export * from './lib/umbrella.js';
|
|
6
|
-
export { UmbrellaChartTemplate as UmbrellaChart } from './lib/templates/umbrella-chart.js';
|
|
7
|
-
export { Subchart } from './lib/templates/subchart.js';
|
|
8
6
|
export { BasicChart } from './lib/templates/basic-chart.js';
|
|
7
|
+
export { FlexibleSubchart, createFlexibleSubchart } from './lib/templates/flexible-subchart.js';
|
|
8
|
+
export { Subchart } from './lib/templates/subchart.js';
|
|
9
|
+
export { UmbrellaChartTemplate as UmbrellaChart } from './lib/templates/umbrella-chart.js';
|
|
9
10
|
export { DEFAULT_TERMINATION_GRACE_PERIOD, isValidDisruptionBudget, isValidKubernetesDuration, KarpenterVersionUtils, } from './lib/resources/cloud/aws/karpenterResources.js';
|
|
10
11
|
export { AWS_HELPERS, createHelper, FILE_ACCESS_HELPERS, formatHelpers, generateHelpersTemplate, getDefaultHelpers, getHelpersByCategory, KUBERNETES_HELPERS, SPRIG_HELPERS, STANDARD_HELPERS, TEMPLATE_FUNCTION_HELPERS, } from './lib/utils/helmHelpers.js';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import YAML from 'yaml';
|
|
4
3
|
import { SecurityUtils } from './security.js';
|
|
4
|
+
import { dumpHelmAwareYaml } from './utils/helmYamlSerializer.js';
|
|
5
5
|
export class HelmChartWriter {
|
|
6
6
|
static write(opts) {
|
|
7
7
|
const { outDir, meta, defaultValues = {}, envValues = {}, assets, helpersTpl, notesTpl, valuesSchema, } = opts;
|
|
8
|
-
console.log(
|
|
8
|
+
console.log(`Writing chart: ${meta.name} v${meta.version} to ${outDir}`);
|
|
9
9
|
const validatedOutDir = SecurityUtils.validatePath(outDir, process.cwd());
|
|
10
10
|
this.createDirectories(validatedOutDir);
|
|
11
11
|
this.writeChartYaml(validatedOutDir, meta);
|
|
@@ -15,13 +15,13 @@ export class HelmChartWriter {
|
|
|
15
15
|
this.writeNotes(validatedOutDir, notesTpl);
|
|
16
16
|
this.writeSchema(validatedOutDir, valuesSchema);
|
|
17
17
|
this.writeHelmIgnore(validatedOutDir);
|
|
18
|
-
console.log(
|
|
18
|
+
console.log(`Chart written successfully to ${validatedOutDir}`);
|
|
19
19
|
}
|
|
20
20
|
static createDirectories(outDir) {
|
|
21
21
|
fs.mkdirSync(path.join(outDir, 'templates'), { recursive: true });
|
|
22
22
|
}
|
|
23
23
|
static writeChartYaml(outDir, meta) {
|
|
24
|
-
const chartYaml =
|
|
24
|
+
const chartYaml = dumpHelmAwareYaml({
|
|
25
25
|
apiVersion: 'v2',
|
|
26
26
|
name: meta.name,
|
|
27
27
|
version: meta.version,
|
|
@@ -39,10 +39,10 @@ export class HelmChartWriter {
|
|
|
39
39
|
fs.writeFileSync(path.join(outDir, 'Chart.yaml'), chartYaml);
|
|
40
40
|
}
|
|
41
41
|
static writeValuesFiles(outDir, defaultValues, envValues) {
|
|
42
|
-
fs.writeFileSync(path.join(outDir, 'values.yaml'),
|
|
42
|
+
fs.writeFileSync(path.join(outDir, 'values.yaml'), dumpHelmAwareYaml(defaultValues));
|
|
43
43
|
for (const [env, values] of Object.entries(envValues)) {
|
|
44
44
|
const sanitizedEnv = SecurityUtils.sanitizeEnvironmentName(env);
|
|
45
|
-
fs.writeFileSync(path.join(outDir, `values-${sanitizedEnv}.yaml`),
|
|
45
|
+
fs.writeFileSync(path.join(outDir, `values-${sanitizedEnv}.yaml`), dumpHelmAwareYaml(values));
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
static writeAssets(outDir, assets) {
|
|
@@ -111,7 +111,7 @@ function writeAssets(outDir, assets) {
|
|
|
111
111
|
for (const asset of assets) {
|
|
112
112
|
const sanitizedId = asset.id.replace(/[^a-zA-Z0-9-_]/g, '');
|
|
113
113
|
if (sanitizedId !== asset.id) {
|
|
114
|
-
console.error(
|
|
114
|
+
console.error(`Invalid asset ID detected: ${SecurityUtils.sanitizeLogMessage(asset.id)}`);
|
|
115
115
|
throw new Error(`Invalid asset ID: ${SecurityUtils.sanitizeLogMessage(asset.id)}`);
|
|
116
116
|
}
|
|
117
117
|
const targetDir = getTargetDirectory(asset.target);
|
|
@@ -124,7 +124,7 @@ function writeAssets(outDir, assets) {
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
catch (error) {
|
|
127
|
-
console.error(
|
|
127
|
+
console.error(`Failed to write asset ${asset.id}:`, error);
|
|
128
128
|
throw error;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
@@ -134,7 +134,7 @@ function getTargetDirectory(target) {
|
|
|
134
134
|
}
|
|
135
135
|
function writeSingleAssetFile(outDir, targetDir, assetId, yaml) {
|
|
136
136
|
if (assetId === 'ingress' && yaml.includes('number:')) {
|
|
137
|
-
console.log('
|
|
137
|
+
console.log('Writing ingress file with number fields');
|
|
138
138
|
const numberLines = yaml.split('\n').filter((line) => line.includes('number:'));
|
|
139
139
|
console.log('Number lines:', numberLines);
|
|
140
140
|
}
|