vaulter 1.0.34 → 1.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -38
- package/action.yml +116 -0
- package/dist/action/formats.d.ts +57 -0
- package/dist/action/formats.d.ts.map +1 -0
- package/dist/action/formats.js +241 -0
- package/dist/action/formats.js.map +1 -0
- package/dist/action/index.cjs +101213 -0
- package/dist/action/index.d.ts +17 -0
- package/dist/action/index.d.ts.map +1 -0
- package/dist/action/index.js +216 -0
- package/dist/action/index.js.map +1 -0
- package/dist/action/inputs.d.ts +38 -0
- package/dist/action/inputs.d.ts.map +1 -0
- package/dist/action/inputs.js +109 -0
- package/dist/action/inputs.js.map +1 -0
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/lib/colors.d.ts +47 -1
- package/dist/cli/lib/colors.d.ts.map +1 -1
- package/dist/cli/lib/colors.js +124 -48
- package/dist/cli/lib/colors.js.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/mcp/resources.js +21 -5
- package/dist/mcp/resources.js.map +1 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -312,47 +312,164 @@ Vaulter separates **local development** from **deployment** configurations:
|
|
|
312
312
|
|
|
313
313
|
## CI/CD
|
|
314
314
|
|
|
315
|
-
### GitHub
|
|
315
|
+
### GitHub Action (Recommended)
|
|
316
316
|
|
|
317
|
-
Use
|
|
317
|
+
Use the official Vaulter GitHub Action for seamless CI/CD integration:
|
|
318
318
|
|
|
319
319
|
```yaml
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
320
|
+
- uses: forattini-dev/vaulter@v1
|
|
321
|
+
id: secrets
|
|
322
|
+
with:
|
|
323
|
+
backend: s3://my-bucket/secrets
|
|
324
|
+
project: my-app
|
|
325
|
+
environment: prd
|
|
326
|
+
outputs: env,k8s-secret
|
|
327
|
+
env:
|
|
328
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
329
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
330
|
+
VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
#### Output Formats
|
|
334
|
+
|
|
335
|
+
| Output | File | Use Case |
|
|
336
|
+
|:-------|:-----|:---------|
|
|
337
|
+
| `env` | `.env` | Docker, Node.js |
|
|
338
|
+
| `json` | `vaulter-vars.json` | Custom scripts |
|
|
339
|
+
| `k8s-secret` | `k8s-secret.yaml` | `kubectl apply` |
|
|
340
|
+
| `k8s-configmap` | `k8s-configmap.yaml` | `kubectl apply` |
|
|
341
|
+
| `helm-values` | `helm-values.yaml` | `helmfile`, `helm` |
|
|
342
|
+
| `tfvars` | `terraform.auto.tfvars` | `terraform`, `terragrunt` |
|
|
343
|
+
| `shell` | `vaulter-env.sh` | `source` in scripts |
|
|
344
|
+
|
|
345
|
+
#### Full Examples
|
|
346
|
+
|
|
347
|
+
**kubectl:**
|
|
348
|
+
```yaml
|
|
349
|
+
- uses: forattini-dev/vaulter@v1
|
|
350
|
+
with:
|
|
351
|
+
backend: ${{ secrets.VAULTER_BACKEND }}
|
|
352
|
+
project: my-app
|
|
353
|
+
environment: prd
|
|
354
|
+
outputs: k8s-secret,k8s-configmap
|
|
355
|
+
k8s-namespace: my-namespace
|
|
356
|
+
env:
|
|
357
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
358
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
359
|
+
VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
|
|
360
|
+
|
|
361
|
+
- run: |
|
|
362
|
+
kubectl apply -f k8s-secret.yaml
|
|
363
|
+
kubectl apply -f k8s-configmap.yaml
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**Helmfile:**
|
|
367
|
+
```yaml
|
|
368
|
+
- uses: forattini-dev/vaulter@v1
|
|
369
|
+
with:
|
|
370
|
+
backend: ${{ secrets.VAULTER_BACKEND }}
|
|
371
|
+
project: my-app
|
|
372
|
+
environment: prd
|
|
373
|
+
outputs: helm-values
|
|
374
|
+
helm-values-path: ./helm/secrets.yaml
|
|
375
|
+
env:
|
|
376
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
377
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
378
|
+
VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
|
|
379
|
+
|
|
380
|
+
- run: helmfile -e prd apply
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Terraform/Terragrunt:**
|
|
384
|
+
```yaml
|
|
385
|
+
- uses: forattini-dev/vaulter@v1
|
|
386
|
+
with:
|
|
387
|
+
backend: ${{ secrets.VAULTER_BACKEND }}
|
|
388
|
+
project: infra
|
|
389
|
+
environment: prd
|
|
390
|
+
outputs: tfvars
|
|
391
|
+
# .auto.tfvars is loaded automatically by Terraform!
|
|
392
|
+
tfvars-path: ./secrets.auto.tfvars
|
|
393
|
+
env:
|
|
394
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
395
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
396
|
+
VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
|
|
397
|
+
|
|
398
|
+
- run: terragrunt apply -auto-approve
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**Docker Build:**
|
|
402
|
+
```yaml
|
|
403
|
+
- uses: forattini-dev/vaulter@v1
|
|
404
|
+
with:
|
|
405
|
+
backend: ${{ secrets.VAULTER_BACKEND }}
|
|
406
|
+
project: my-app
|
|
407
|
+
environment: prd
|
|
408
|
+
outputs: env
|
|
409
|
+
env-path: .env.production
|
|
410
|
+
env:
|
|
411
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
412
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
413
|
+
VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
|
|
414
|
+
|
|
415
|
+
- run: docker build --secret id=env,src=.env.production -t app .
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
**Export to GITHUB_ENV:**
|
|
419
|
+
```yaml
|
|
420
|
+
- uses: forattini-dev/vaulter@v1
|
|
421
|
+
with:
|
|
422
|
+
backend: ${{ secrets.VAULTER_BACKEND }}
|
|
423
|
+
project: my-app
|
|
424
|
+
environment: prd
|
|
425
|
+
export-to-env: true # Makes vars available in subsequent steps
|
|
426
|
+
env:
|
|
427
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
428
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
429
|
+
VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
|
|
430
|
+
|
|
431
|
+
- run: echo "Database is $DATABASE_URL" # Available!
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
#### Action Inputs
|
|
435
|
+
|
|
436
|
+
| Input | Required | Default | Description |
|
|
437
|
+
|:------|:--------:|:--------|:------------|
|
|
438
|
+
| `backend` | ✓ | - | S3 connection string |
|
|
439
|
+
| `project` | ✓ | - | Project name |
|
|
440
|
+
| `environment` | ✓ | - | Environment (dev/stg/prd) |
|
|
441
|
+
| `service` | | - | Service (monorepo) |
|
|
442
|
+
| `outputs` | | `env` | Comma-separated outputs |
|
|
443
|
+
| `k8s-namespace` | | `default` | K8s namespace |
|
|
444
|
+
| `export-to-env` | | `false` | Export to GITHUB_ENV |
|
|
445
|
+
| `mask-values` | | `true` | Mask secrets in logs |
|
|
446
|
+
|
|
447
|
+
#### Action Outputs
|
|
448
|
+
|
|
449
|
+
| Output | Description |
|
|
450
|
+
|:-------|:------------|
|
|
451
|
+
| `env-file` | Path to .env file |
|
|
452
|
+
| `k8s-secret-file` | Path to K8s Secret YAML |
|
|
453
|
+
| `k8s-configmap-file` | Path to K8s ConfigMap YAML |
|
|
454
|
+
| `helm-values-file` | Path to Helm values file |
|
|
455
|
+
| `tfvars-file` | Path to .tfvars file |
|
|
456
|
+
| `vars-count` | Number of variables |
|
|
457
|
+
| `vars-json` | JSON array of variable names |
|
|
458
|
+
|
|
459
|
+
### CLI in CI/CD
|
|
460
|
+
|
|
461
|
+
You can also use the CLI directly:
|
|
462
|
+
|
|
463
|
+
```yaml
|
|
464
|
+
- name: Pull and build
|
|
465
|
+
env:
|
|
466
|
+
VAULTER_PASSPHRASE: ${{ secrets.VAULTER_PASSPHRASE }}
|
|
467
|
+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
468
|
+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
469
|
+
run: |
|
|
470
|
+
npx vaulter sync pull -e prd
|
|
471
|
+
npx vaulter run -e prd -- pnpm build
|
|
472
|
+
```
|
|
356
473
|
|
|
357
474
|
### Other Platforms
|
|
358
475
|
|
package/action.yml
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
name: 'Vaulter - Pull Secrets'
|
|
2
|
+
description: 'Pull environment variables from Vaulter backend and generate outputs for kubectl, helm, terraform, and more'
|
|
3
|
+
author: 'Forattini'
|
|
4
|
+
branding:
|
|
5
|
+
icon: 'lock'
|
|
6
|
+
color: 'purple'
|
|
7
|
+
|
|
8
|
+
inputs:
|
|
9
|
+
# ─── Connection ───
|
|
10
|
+
backend:
|
|
11
|
+
description: 'Connection string (s3://bucket, file://path, memory://). Can also use VAULTER_BACKEND env var.'
|
|
12
|
+
required: false
|
|
13
|
+
passphrase:
|
|
14
|
+
description: 'Encryption passphrase for symmetric mode. Can also use VAULTER_PASSPHRASE env var.'
|
|
15
|
+
required: false
|
|
16
|
+
|
|
17
|
+
# ─── Filters ───
|
|
18
|
+
project:
|
|
19
|
+
description: 'Project name'
|
|
20
|
+
required: true
|
|
21
|
+
environment:
|
|
22
|
+
description: 'Environment (dev/stg/prd or custom)'
|
|
23
|
+
required: true
|
|
24
|
+
service:
|
|
25
|
+
description: 'Service name for monorepo setups'
|
|
26
|
+
required: false
|
|
27
|
+
|
|
28
|
+
# ─── Outputs Selection ───
|
|
29
|
+
outputs:
|
|
30
|
+
description: 'Comma-separated list of outputs to generate: env,json,k8s-secret,k8s-configmap,helm-values,tfvars,shell'
|
|
31
|
+
default: 'env'
|
|
32
|
+
|
|
33
|
+
# ─── Output Paths ───
|
|
34
|
+
env-path:
|
|
35
|
+
description: 'Path for .env file output'
|
|
36
|
+
default: '.env'
|
|
37
|
+
json-path:
|
|
38
|
+
description: 'Path for JSON output'
|
|
39
|
+
default: 'vaulter-vars.json'
|
|
40
|
+
k8s-secret-path:
|
|
41
|
+
description: 'Path for Kubernetes Secret YAML'
|
|
42
|
+
default: 'k8s-secret.yaml'
|
|
43
|
+
k8s-configmap-path:
|
|
44
|
+
description: 'Path for Kubernetes ConfigMap YAML'
|
|
45
|
+
default: 'k8s-configmap.yaml'
|
|
46
|
+
helm-values-path:
|
|
47
|
+
description: 'Path for Helm values.yaml'
|
|
48
|
+
default: 'helm-values.yaml'
|
|
49
|
+
tfvars-path:
|
|
50
|
+
description: 'Path for Terraform .tfvars file'
|
|
51
|
+
default: 'terraform.auto.tfvars'
|
|
52
|
+
shell-path:
|
|
53
|
+
description: 'Path for shell export script'
|
|
54
|
+
default: 'vaulter-env.sh'
|
|
55
|
+
|
|
56
|
+
# ─── K8s Options ───
|
|
57
|
+
k8s-secret-name:
|
|
58
|
+
description: 'Name for Kubernetes Secret resource'
|
|
59
|
+
required: false
|
|
60
|
+
k8s-configmap-name:
|
|
61
|
+
description: 'Name for Kubernetes ConfigMap resource'
|
|
62
|
+
required: false
|
|
63
|
+
k8s-namespace:
|
|
64
|
+
description: 'Kubernetes namespace'
|
|
65
|
+
default: 'default'
|
|
66
|
+
|
|
67
|
+
# ─── Encryption Mode ───
|
|
68
|
+
encryption-mode:
|
|
69
|
+
description: 'Encryption mode: symmetric or asymmetric'
|
|
70
|
+
default: 'symmetric'
|
|
71
|
+
public-key:
|
|
72
|
+
description: 'Public key PEM content (asymmetric mode)'
|
|
73
|
+
required: false
|
|
74
|
+
private-key:
|
|
75
|
+
description: 'Private key PEM content (asymmetric mode)'
|
|
76
|
+
required: false
|
|
77
|
+
asymmetric-algorithm:
|
|
78
|
+
description: 'Algorithm for asymmetric mode: rsa-4096, rsa-2048, ec-p256, ec-p384'
|
|
79
|
+
default: 'rsa-4096'
|
|
80
|
+
|
|
81
|
+
# ─── Shared Vars ───
|
|
82
|
+
include-shared:
|
|
83
|
+
description: 'Include shared variables when service is specified'
|
|
84
|
+
default: 'true'
|
|
85
|
+
|
|
86
|
+
# ─── Export to GitHub Env ───
|
|
87
|
+
export-to-env:
|
|
88
|
+
description: 'Export variables to GITHUB_ENV for subsequent steps'
|
|
89
|
+
default: 'false'
|
|
90
|
+
mask-values:
|
|
91
|
+
description: 'Mask secret values in logs'
|
|
92
|
+
default: 'true'
|
|
93
|
+
|
|
94
|
+
outputs:
|
|
95
|
+
env-file:
|
|
96
|
+
description: 'Path to generated .env file'
|
|
97
|
+
json-file:
|
|
98
|
+
description: 'Path to generated JSON file'
|
|
99
|
+
k8s-secret-file:
|
|
100
|
+
description: 'Path to generated Kubernetes Secret YAML'
|
|
101
|
+
k8s-configmap-file:
|
|
102
|
+
description: 'Path to generated Kubernetes ConfigMap YAML'
|
|
103
|
+
helm-values-file:
|
|
104
|
+
description: 'Path to generated Helm values file'
|
|
105
|
+
tfvars-file:
|
|
106
|
+
description: 'Path to generated Terraform .tfvars file'
|
|
107
|
+
shell-file:
|
|
108
|
+
description: 'Path to generated shell export script'
|
|
109
|
+
vars-count:
|
|
110
|
+
description: 'Number of variables exported'
|
|
111
|
+
vars-json:
|
|
112
|
+
description: 'JSON string with all variable names (not values)'
|
|
113
|
+
|
|
114
|
+
runs:
|
|
115
|
+
using: 'node20'
|
|
116
|
+
main: 'dist/action/index.cjs'
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vaulter GitHub Action - Output Format Generators
|
|
3
|
+
*
|
|
4
|
+
* Generates output files in various formats for different IaC tools:
|
|
5
|
+
* - env: Standard .env file
|
|
6
|
+
* - json: JSON key-value pairs
|
|
7
|
+
* - k8s-secret: Kubernetes Secret YAML
|
|
8
|
+
* - k8s-configmap: Kubernetes ConfigMap YAML
|
|
9
|
+
* - helm-values: Helm values.yaml
|
|
10
|
+
* - tfvars: Terraform .tfvars
|
|
11
|
+
* - shell: Shell export script
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Generate .env file content
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateEnvFile(vars: Record<string, string>): string;
|
|
17
|
+
/**
|
|
18
|
+
* Generate JSON file content
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateJsonFile(vars: Record<string, string>): string;
|
|
21
|
+
/**
|
|
22
|
+
* Generate Kubernetes Secret YAML
|
|
23
|
+
*/
|
|
24
|
+
export declare function generateK8sSecret(vars: Record<string, string>, options: {
|
|
25
|
+
name: string;
|
|
26
|
+
namespace: string;
|
|
27
|
+
environment: string;
|
|
28
|
+
}): string;
|
|
29
|
+
/**
|
|
30
|
+
* Generate Kubernetes ConfigMap YAML
|
|
31
|
+
*/
|
|
32
|
+
export declare function generateK8sConfigMap(vars: Record<string, string>, options: {
|
|
33
|
+
name: string;
|
|
34
|
+
namespace: string;
|
|
35
|
+
environment: string;
|
|
36
|
+
}): string;
|
|
37
|
+
/**
|
|
38
|
+
* Generate Helm values.yaml
|
|
39
|
+
*/
|
|
40
|
+
export declare function generateHelmValues(vars: Record<string, string>, options: {
|
|
41
|
+
project: string;
|
|
42
|
+
environment: string;
|
|
43
|
+
service?: string;
|
|
44
|
+
}): string;
|
|
45
|
+
/**
|
|
46
|
+
* Generate Terraform .tfvars
|
|
47
|
+
*/
|
|
48
|
+
export declare function generateTfVars(vars: Record<string, string>, options: {
|
|
49
|
+
project: string;
|
|
50
|
+
environment: string;
|
|
51
|
+
service?: string;
|
|
52
|
+
}): string;
|
|
53
|
+
/**
|
|
54
|
+
* Generate shell export script
|
|
55
|
+
*/
|
|
56
|
+
export declare function generateShellExport(vars: Record<string, string>): string;
|
|
57
|
+
//# sourceMappingURL=formats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/action/formats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAyGH;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAYpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAErE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,GACA,MAAM,CAsBR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,GACA,MAAM,CAqBR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE;IACP,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GACA,MAAM,CA4BR;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE;IACP,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GACA,MAAM,CA6BR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAcxE"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vaulter GitHub Action - Output Format Generators
|
|
3
|
+
*
|
|
4
|
+
* Generates output files in various formats for different IaC tools:
|
|
5
|
+
* - env: Standard .env file
|
|
6
|
+
* - json: JSON key-value pairs
|
|
7
|
+
* - k8s-secret: Kubernetes Secret YAML
|
|
8
|
+
* - k8s-configmap: Kubernetes ConfigMap YAML
|
|
9
|
+
* - helm-values: Helm values.yaml
|
|
10
|
+
* - tfvars: Terraform .tfvars
|
|
11
|
+
* - shell: Shell export script
|
|
12
|
+
*/
|
|
13
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
14
|
+
// Utility Functions
|
|
15
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* Encode string to base64 (for K8s secrets)
|
|
18
|
+
*/
|
|
19
|
+
function base64Encode(str) {
|
|
20
|
+
return Buffer.from(str, 'utf-8').toString('base64');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Sanitize name for Kubernetes (lowercase, alphanumeric, dashes)
|
|
24
|
+
*/
|
|
25
|
+
function sanitizeK8sName(name) {
|
|
26
|
+
return name
|
|
27
|
+
.toLowerCase()
|
|
28
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
29
|
+
.replace(/--+/g, '-')
|
|
30
|
+
.replace(/^-|-$/g, '')
|
|
31
|
+
.slice(0, 63);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Escape value for .env file
|
|
35
|
+
*/
|
|
36
|
+
function escapeEnvValue(value) {
|
|
37
|
+
// If value contains special chars, wrap in quotes
|
|
38
|
+
if (value.includes(' ') ||
|
|
39
|
+
value.includes('"') ||
|
|
40
|
+
value.includes("'") ||
|
|
41
|
+
value.includes('#') ||
|
|
42
|
+
value.includes('\n') ||
|
|
43
|
+
value.includes('$') ||
|
|
44
|
+
value.startsWith(' ') ||
|
|
45
|
+
value.endsWith(' ')) {
|
|
46
|
+
// Use double quotes and escape internal quotes and backslashes
|
|
47
|
+
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`;
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Format value for YAML (with proper quoting)
|
|
53
|
+
*/
|
|
54
|
+
function formatYamlValue(value) {
|
|
55
|
+
const needsQuote = value === '' ||
|
|
56
|
+
value === 'true' ||
|
|
57
|
+
value === 'false' ||
|
|
58
|
+
value === 'null' ||
|
|
59
|
+
value === 'yes' ||
|
|
60
|
+
value === 'no' ||
|
|
61
|
+
value === 'on' ||
|
|
62
|
+
value === 'off' ||
|
|
63
|
+
!isNaN(Number(value)) ||
|
|
64
|
+
value.includes(':') ||
|
|
65
|
+
value.includes('#') ||
|
|
66
|
+
value.includes('\n') ||
|
|
67
|
+
value.includes('"') ||
|
|
68
|
+
value.includes("'") ||
|
|
69
|
+
value.startsWith(' ') ||
|
|
70
|
+
value.endsWith(' ') ||
|
|
71
|
+
value.startsWith('{') ||
|
|
72
|
+
value.startsWith('[') ||
|
|
73
|
+
value.startsWith('*') ||
|
|
74
|
+
value.startsWith('&');
|
|
75
|
+
if (needsQuote) {
|
|
76
|
+
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`;
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Format value for Terraform HCL
|
|
82
|
+
*/
|
|
83
|
+
function formatTfValue(value) {
|
|
84
|
+
const escaped = value
|
|
85
|
+
.replace(/\\/g, '\\\\')
|
|
86
|
+
.replace(/"/g, '\\"')
|
|
87
|
+
.replace(/\n/g, '\\n')
|
|
88
|
+
.replace(/\r/g, '\\r')
|
|
89
|
+
.replace(/\t/g, '\\t');
|
|
90
|
+
return `"${escaped}"`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Escape value for shell (single quotes)
|
|
94
|
+
*/
|
|
95
|
+
function escapeShellValue(value) {
|
|
96
|
+
// Use single quotes and escape internal single quotes
|
|
97
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
98
|
+
}
|
|
99
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
100
|
+
// Format Generators
|
|
101
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
102
|
+
/**
|
|
103
|
+
* Generate .env file content
|
|
104
|
+
*/
|
|
105
|
+
export function generateEnvFile(vars) {
|
|
106
|
+
const lines = [
|
|
107
|
+
'# Generated by Vaulter GitHub Action',
|
|
108
|
+
`# Generated at: ${new Date().toISOString()}`,
|
|
109
|
+
''
|
|
110
|
+
];
|
|
111
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
112
|
+
lines.push(`${key}=${escapeEnvValue(value)}`);
|
|
113
|
+
}
|
|
114
|
+
return lines.join('\n') + '\n';
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Generate JSON file content
|
|
118
|
+
*/
|
|
119
|
+
export function generateJsonFile(vars) {
|
|
120
|
+
return JSON.stringify(vars, null, 2) + '\n';
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Generate Kubernetes Secret YAML
|
|
124
|
+
*/
|
|
125
|
+
export function generateK8sSecret(vars, options) {
|
|
126
|
+
const lines = [
|
|
127
|
+
'# Generated by Vaulter GitHub Action',
|
|
128
|
+
`# Generated at: ${new Date().toISOString()}`,
|
|
129
|
+
'# Apply: kubectl apply -f <file>',
|
|
130
|
+
'apiVersion: v1',
|
|
131
|
+
'kind: Secret',
|
|
132
|
+
'metadata:',
|
|
133
|
+
` name: ${sanitizeK8sName(options.name)}`,
|
|
134
|
+
` namespace: ${sanitizeK8sName(options.namespace)}`,
|
|
135
|
+
' labels:',
|
|
136
|
+
' app.kubernetes.io/managed-by: vaulter',
|
|
137
|
+
` app.kubernetes.io/environment: ${options.environment}`,
|
|
138
|
+
'type: Opaque',
|
|
139
|
+
'data:'
|
|
140
|
+
];
|
|
141
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
142
|
+
lines.push(` ${key}: ${base64Encode(value)}`);
|
|
143
|
+
}
|
|
144
|
+
return lines.join('\n') + '\n';
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Generate Kubernetes ConfigMap YAML
|
|
148
|
+
*/
|
|
149
|
+
export function generateK8sConfigMap(vars, options) {
|
|
150
|
+
const lines = [
|
|
151
|
+
'# Generated by Vaulter GitHub Action',
|
|
152
|
+
`# Generated at: ${new Date().toISOString()}`,
|
|
153
|
+
'# Apply: kubectl apply -f <file>',
|
|
154
|
+
'apiVersion: v1',
|
|
155
|
+
'kind: ConfigMap',
|
|
156
|
+
'metadata:',
|
|
157
|
+
` name: ${sanitizeK8sName(options.name)}`,
|
|
158
|
+
` namespace: ${sanitizeK8sName(options.namespace)}`,
|
|
159
|
+
' labels:',
|
|
160
|
+
' app.kubernetes.io/managed-by: vaulter',
|
|
161
|
+
` app.kubernetes.io/environment: ${options.environment}`,
|
|
162
|
+
'data:'
|
|
163
|
+
];
|
|
164
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
165
|
+
lines.push(` ${key}: ${formatYamlValue(value)}`);
|
|
166
|
+
}
|
|
167
|
+
return lines.join('\n') + '\n';
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Generate Helm values.yaml
|
|
171
|
+
*/
|
|
172
|
+
export function generateHelmValues(vars, options) {
|
|
173
|
+
const lines = [
|
|
174
|
+
'# Generated by Vaulter GitHub Action',
|
|
175
|
+
`# Project: ${options.project}`,
|
|
176
|
+
`# Environment: ${options.environment}`,
|
|
177
|
+
options.service ? `# Service: ${options.service}` : null,
|
|
178
|
+
`# Generated at: ${new Date().toISOString()}`,
|
|
179
|
+
'# DO NOT EDIT - changes will be overwritten',
|
|
180
|
+
'',
|
|
181
|
+
'# All environment variables',
|
|
182
|
+
'env:'
|
|
183
|
+
].filter(Boolean);
|
|
184
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
185
|
+
lines.push(` ${key}: ${formatYamlValue(value)}`);
|
|
186
|
+
}
|
|
187
|
+
// Also provide as envFrom-compatible format
|
|
188
|
+
lines.push('');
|
|
189
|
+
lines.push('# As key-value pairs for envFrom');
|
|
190
|
+
lines.push('envVars:');
|
|
191
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
192
|
+
lines.push(` - name: ${key}`);
|
|
193
|
+
lines.push(` value: ${formatYamlValue(value)}`);
|
|
194
|
+
}
|
|
195
|
+
return lines.join('\n') + '\n';
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Generate Terraform .tfvars
|
|
199
|
+
*/
|
|
200
|
+
export function generateTfVars(vars, options) {
|
|
201
|
+
const lines = [
|
|
202
|
+
'# Generated by Vaulter GitHub Action',
|
|
203
|
+
`# Project: ${options.project}`,
|
|
204
|
+
`# Environment: ${options.environment}`,
|
|
205
|
+
options.service ? `# Service: ${options.service}` : null,
|
|
206
|
+
`# Generated at: ${new Date().toISOString()}`,
|
|
207
|
+
'# DO NOT EDIT - changes will be overwritten',
|
|
208
|
+
''
|
|
209
|
+
].filter(Boolean);
|
|
210
|
+
// Individual variables with lowercase names
|
|
211
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
212
|
+
const tfKey = key.toLowerCase();
|
|
213
|
+
lines.push(`${tfKey} = ${formatTfValue(value)}`);
|
|
214
|
+
}
|
|
215
|
+
// All vars as a map (useful for for_each)
|
|
216
|
+
lines.push('');
|
|
217
|
+
lines.push('# All environment variables as a map');
|
|
218
|
+
lines.push('env_vars = {');
|
|
219
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
220
|
+
lines.push(` "${key}" = ${formatTfValue(value)}`);
|
|
221
|
+
}
|
|
222
|
+
lines.push('}');
|
|
223
|
+
return lines.join('\n') + '\n';
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Generate shell export script
|
|
227
|
+
*/
|
|
228
|
+
export function generateShellExport(vars) {
|
|
229
|
+
const lines = [
|
|
230
|
+
'#!/bin/bash',
|
|
231
|
+
'# Generated by Vaulter GitHub Action',
|
|
232
|
+
`# Generated at: ${new Date().toISOString()}`,
|
|
233
|
+
'# Usage: source <file> or . <file>',
|
|
234
|
+
''
|
|
235
|
+
];
|
|
236
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
237
|
+
lines.push(`export ${key}=${escapeShellValue(value)}`);
|
|
238
|
+
}
|
|
239
|
+
return lines.join('\n') + '\n';
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=formats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/action/formats.ts"],"names":[],"mappings":"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"}
|