hereya-cli 0.9.1 → 0.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/README.md +65 -18
- package/dist/backend/common.d.ts +24 -4
- package/dist/backend/local.d.ts +3 -1
- package/dist/backend/local.js +112 -18
- package/dist/commands/remote/exec/index.js +10 -10
- package/dist/commands/workspace/env/set/index.d.ts +13 -0
- package/dist/commands/workspace/env/set/index.js +39 -0
- package/dist/commands/workspace/env/unset/index.d.ts +10 -0
- package/dist/commands/workspace/env/unset/index.js +33 -0
- package/dist/infrastructure/aws.d.ts +3 -1
- package/dist/infrastructure/aws.js +61 -16
- package/dist/infrastructure/common.d.ts +24 -0
- package/dist/infrastructure/local.d.ts +3 -1
- package/dist/infrastructure/local.js +10 -4
- package/oclif.manifest.json +155 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ $ npm install -g hereya-cli
|
|
|
20
20
|
$ hereya COMMAND
|
|
21
21
|
running command...
|
|
22
22
|
$ hereya (--version)
|
|
23
|
-
hereya-cli/0.
|
|
23
|
+
hereya-cli/0.10.0 linux-x64 node-v20.15.0
|
|
24
24
|
$ hereya --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ hereya COMMAND
|
|
@@ -45,6 +45,8 @@ USAGE
|
|
|
45
45
|
* [`hereya workspace create NAME`](#hereya-workspace-create-name)
|
|
46
46
|
* [`hereya workspace delete NAME`](#hereya-workspace-delete-name)
|
|
47
47
|
* [`hereya workspace env [NAME]`](#hereya-workspace-env-name)
|
|
48
|
+
* [`hereya workspace env set`](#hereya-workspace-env-set)
|
|
49
|
+
* [`hereya workspace env unset`](#hereya-workspace-env-unset)
|
|
48
50
|
* [`hereya workspace install PACKAGE`](#hereya-workspace-install-package)
|
|
49
51
|
* [`hereya workspace uninstall PACKAGE`](#hereya-workspace-uninstall-package)
|
|
50
52
|
|
|
@@ -71,7 +73,7 @@ EXAMPLES
|
|
|
71
73
|
$ hereya add cloudy/docker_postgres
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
_See code: [src/commands/add/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
76
|
+
_See code: [src/commands/add/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/add/index.ts)_
|
|
75
77
|
|
|
76
78
|
## `hereya bootstrap INFRASTRUCTURETYPE`
|
|
77
79
|
|
|
@@ -96,7 +98,7 @@ EXAMPLES
|
|
|
96
98
|
$ hereya bootstrap local
|
|
97
99
|
```
|
|
98
100
|
|
|
99
|
-
_See code: [src/commands/bootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
101
|
+
_See code: [src/commands/bootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/bootstrap/index.ts)_
|
|
100
102
|
|
|
101
103
|
## `hereya deploy`
|
|
102
104
|
|
|
@@ -117,7 +119,7 @@ EXAMPLES
|
|
|
117
119
|
$ hereya deploy
|
|
118
120
|
```
|
|
119
121
|
|
|
120
|
-
_See code: [src/commands/deploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
122
|
+
_See code: [src/commands/deploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/deploy/index.ts)_
|
|
121
123
|
|
|
122
124
|
## `hereya down`
|
|
123
125
|
|
|
@@ -139,7 +141,7 @@ EXAMPLES
|
|
|
139
141
|
$ hereya down
|
|
140
142
|
```
|
|
141
143
|
|
|
142
|
-
_See code: [src/commands/down/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
144
|
+
_See code: [src/commands/down/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/down/index.ts)_
|
|
143
145
|
|
|
144
146
|
## `hereya env [NAME]`
|
|
145
147
|
|
|
@@ -170,7 +172,7 @@ EXAMPLES
|
|
|
170
172
|
$ hereya env -w dev -l
|
|
171
173
|
```
|
|
172
174
|
|
|
173
|
-
_See code: [src/commands/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
175
|
+
_See code: [src/commands/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/env/index.ts)_
|
|
174
176
|
|
|
175
177
|
## `hereya help [COMMAND]`
|
|
176
178
|
|
|
@@ -216,7 +218,7 @@ EXAMPLES
|
|
|
216
218
|
$ hereya init myProject -w=defaultWorkspace --chdir=./myProject
|
|
217
219
|
```
|
|
218
220
|
|
|
219
|
-
_See code: [src/commands/init/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
221
|
+
_See code: [src/commands/init/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/init/index.ts)_
|
|
220
222
|
|
|
221
223
|
## `hereya remote exec [PKGPATH]`
|
|
222
224
|
|
|
@@ -240,7 +242,7 @@ EXAMPLES
|
|
|
240
242
|
$ hereya remote exec
|
|
241
243
|
```
|
|
242
244
|
|
|
243
|
-
_See code: [src/commands/remote/exec/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
245
|
+
_See code: [src/commands/remote/exec/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/remote/exec/index.ts)_
|
|
244
246
|
|
|
245
247
|
## `hereya remove PACKAGE`
|
|
246
248
|
|
|
@@ -263,7 +265,7 @@ EXAMPLES
|
|
|
263
265
|
$ hereya remove cloudy/docker_postgres
|
|
264
266
|
```
|
|
265
267
|
|
|
266
|
-
_See code: [src/commands/remove/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
268
|
+
_See code: [src/commands/remove/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/remove/index.ts)_
|
|
267
269
|
|
|
268
270
|
## `hereya run CMD`
|
|
269
271
|
|
|
@@ -289,7 +291,7 @@ EXAMPLES
|
|
|
289
291
|
$ hereya run -w uat -- node index.js
|
|
290
292
|
```
|
|
291
293
|
|
|
292
|
-
_See code: [src/commands/run/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
294
|
+
_See code: [src/commands/run/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/run/index.ts)_
|
|
293
295
|
|
|
294
296
|
## `hereya unbootstrap INFRASTRUCTURETYPE`
|
|
295
297
|
|
|
@@ -314,7 +316,7 @@ EXAMPLES
|
|
|
314
316
|
$ hereya unbootstrap local
|
|
315
317
|
```
|
|
316
318
|
|
|
317
|
-
_See code: [src/commands/unbootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
319
|
+
_See code: [src/commands/unbootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/unbootstrap/index.ts)_
|
|
318
320
|
|
|
319
321
|
## `hereya undeploy`
|
|
320
322
|
|
|
@@ -335,7 +337,7 @@ EXAMPLES
|
|
|
335
337
|
$ hereya undeploy
|
|
336
338
|
```
|
|
337
339
|
|
|
338
|
-
_See code: [src/commands/undeploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
340
|
+
_See code: [src/commands/undeploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/undeploy/index.ts)_
|
|
339
341
|
|
|
340
342
|
## `hereya up`
|
|
341
343
|
|
|
@@ -357,7 +359,7 @@ EXAMPLES
|
|
|
357
359
|
$ hereya up
|
|
358
360
|
```
|
|
359
361
|
|
|
360
|
-
_See code: [src/commands/up/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
362
|
+
_See code: [src/commands/up/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/up/index.ts)_
|
|
361
363
|
|
|
362
364
|
## `hereya workspace create NAME`
|
|
363
365
|
|
|
@@ -377,7 +379,7 @@ EXAMPLES
|
|
|
377
379
|
$ hereya workspace create dev
|
|
378
380
|
```
|
|
379
381
|
|
|
380
|
-
_See code: [src/commands/workspace/create/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
382
|
+
_See code: [src/commands/workspace/create/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/workspace/create/index.ts)_
|
|
381
383
|
|
|
382
384
|
## `hereya workspace delete NAME`
|
|
383
385
|
|
|
@@ -397,7 +399,7 @@ EXAMPLES
|
|
|
397
399
|
$ hereya workspace delete dev
|
|
398
400
|
```
|
|
399
401
|
|
|
400
|
-
_See code: [src/commands/workspace/delete/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
402
|
+
_See code: [src/commands/workspace/delete/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/workspace/delete/index.ts)_
|
|
401
403
|
|
|
402
404
|
## `hereya workspace env [NAME]`
|
|
403
405
|
|
|
@@ -423,7 +425,52 @@ EXAMPLES
|
|
|
423
425
|
$ hereya workspace env myEnv -w dev
|
|
424
426
|
```
|
|
425
427
|
|
|
426
|
-
_See code: [src/commands/workspace/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
428
|
+
_See code: [src/commands/workspace/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/workspace/env/index.ts)_
|
|
429
|
+
|
|
430
|
+
## `hereya workspace env set`
|
|
431
|
+
|
|
432
|
+
set an env var for a workspace
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
USAGE
|
|
436
|
+
$ hereya workspace env set -i <value> -n <value> -v <value> -w <value> [-s]
|
|
437
|
+
|
|
438
|
+
FLAGS
|
|
439
|
+
-i, --infra=<value> (required) the infrastructure to store the env var in
|
|
440
|
+
-n, --name=<value> (required) name of the env var to set
|
|
441
|
+
-s, --sensitive whether the env var is sensitive
|
|
442
|
+
-v, --value=<value> (required) value of the env var to set
|
|
443
|
+
-w, --workspace=<value> (required) name of the workspace to set an env var for
|
|
444
|
+
|
|
445
|
+
DESCRIPTION
|
|
446
|
+
set an env var for a workspace
|
|
447
|
+
|
|
448
|
+
EXAMPLES
|
|
449
|
+
$ hereya workspace env set -w my-workspace -n myVar -v my-value -i aws -s
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
_See code: [src/commands/workspace/env/set/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/workspace/env/set/index.ts)_
|
|
453
|
+
|
|
454
|
+
## `hereya workspace env unset`
|
|
455
|
+
|
|
456
|
+
unset an env var for a workspace
|
|
457
|
+
|
|
458
|
+
```
|
|
459
|
+
USAGE
|
|
460
|
+
$ hereya workspace env unset -n <value> -w <value>
|
|
461
|
+
|
|
462
|
+
FLAGS
|
|
463
|
+
-n, --name=<value> (required) name of the env var to unset
|
|
464
|
+
-w, --workspace=<value> (required) name of the workspace to unset an env var for
|
|
465
|
+
|
|
466
|
+
DESCRIPTION
|
|
467
|
+
unset an env var for a workspace
|
|
468
|
+
|
|
469
|
+
EXAMPLES
|
|
470
|
+
$ hereya workspace env unset -w my-workspace -n myVar
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
_See code: [src/commands/workspace/env/unset/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/workspace/env/unset/index.ts)_
|
|
427
474
|
|
|
428
475
|
## `hereya workspace install PACKAGE`
|
|
429
476
|
|
|
@@ -449,7 +496,7 @@ EXAMPLES
|
|
|
449
496
|
$ hereya workspace install hereya/aws-cognito
|
|
450
497
|
```
|
|
451
498
|
|
|
452
|
-
_See code: [src/commands/workspace/install/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
499
|
+
_See code: [src/commands/workspace/install/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/workspace/install/index.ts)_
|
|
453
500
|
|
|
454
501
|
## `hereya workspace uninstall PACKAGE`
|
|
455
502
|
|
|
@@ -475,5 +522,5 @@ EXAMPLES
|
|
|
475
522
|
$ hereya workspace uninstall hereya/aws-cognito
|
|
476
523
|
```
|
|
477
524
|
|
|
478
|
-
_See code: [src/commands/workspace/uninstall/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
525
|
+
_See code: [src/commands/workspace/uninstall/index.ts](https://github.com/hereya/hereya-cli/blob/v0.10.0/src/commands/workspace/uninstall/index.ts)_
|
|
479
526
|
<!-- commandsstop -->
|
package/dist/backend/common.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export interface Backend {
|
|
|
11
11
|
init(options: InitProjectInput): Promise<InitProjectOutput>;
|
|
12
12
|
removePackageFromWorkspace(input: RemovePackageFromWorkspaceInput): Promise<RemovePackageFromWorkspaceOutput>;
|
|
13
13
|
saveState(config: Omit<Config, 'workspace'>): Promise<void>;
|
|
14
|
+
setEnvVar(input: SetEnvVarInput): Promise<SetEnvVarOutput>;
|
|
15
|
+
unsetEnvVar(input: UnsetEnvVarInput): Promise<UnsetEnvVarOutput>;
|
|
14
16
|
}
|
|
15
17
|
export type AddPackageToWorkspaceInput = {
|
|
16
18
|
env: {
|
|
@@ -81,7 +83,9 @@ export type GetWorkspaceEnvOutput = {
|
|
|
81
83
|
reason: string;
|
|
82
84
|
success: false;
|
|
83
85
|
};
|
|
84
|
-
export type GetWorkspaceOutput =
|
|
86
|
+
export type GetWorkspaceOutput = {
|
|
87
|
+
found: false;
|
|
88
|
+
} | ({
|
|
85
89
|
found: true;
|
|
86
90
|
hasError: false;
|
|
87
91
|
workspace: {
|
|
@@ -103,9 +107,7 @@ export type GetWorkspaceOutput = ({
|
|
|
103
107
|
error: string;
|
|
104
108
|
found: true;
|
|
105
109
|
hasError: true;
|
|
106
|
-
})
|
|
107
|
-
found: false;
|
|
108
|
-
};
|
|
110
|
+
});
|
|
109
111
|
export type GetStateInput = {
|
|
110
112
|
project: string;
|
|
111
113
|
};
|
|
@@ -137,3 +139,21 @@ export type GetProvisioningIdOutput = {
|
|
|
137
139
|
reason: string;
|
|
138
140
|
success: false;
|
|
139
141
|
};
|
|
142
|
+
export type SetEnvVarInput = {
|
|
143
|
+
infra: InfrastructureType;
|
|
144
|
+
name: string;
|
|
145
|
+
sensitive?: boolean;
|
|
146
|
+
value: string;
|
|
147
|
+
workspace: string;
|
|
148
|
+
};
|
|
149
|
+
export type SetEnvVarOutput = {
|
|
150
|
+
reason: string;
|
|
151
|
+
success: false;
|
|
152
|
+
} | {
|
|
153
|
+
success: true;
|
|
154
|
+
};
|
|
155
|
+
export type UnsetEnvVarInput = {
|
|
156
|
+
name: string;
|
|
157
|
+
workspace: string;
|
|
158
|
+
};
|
|
159
|
+
export type UnsetEnvVarOutput = SetEnvVarOutput;
|
package/dist/backend/local.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Config } from '../lib/config/common.js';
|
|
2
|
-
import { AddPackageToWorkspaceInput, AddPackageToWorkspaceOutput, Backend, CreateWorkspaceInput, CreateWorkspaceOutput, DeleteWorkspaceInput, DeleteWorkspaceOutput, GetProvisioningIdInput, GetProvisioningIdOutput, GetStateInput, GetStateOutput, GetWorkspaceEnvInput, GetWorkspaceEnvOutput, GetWorkspaceOutput, InitProjectInput, InitProjectOutput, RemovePackageFromWorkspaceInput, RemovePackageFromWorkspaceOutput } from './common.js';
|
|
2
|
+
import { AddPackageToWorkspaceInput, AddPackageToWorkspaceOutput, Backend, CreateWorkspaceInput, CreateWorkspaceOutput, DeleteWorkspaceInput, DeleteWorkspaceOutput, GetProvisioningIdInput, GetProvisioningIdOutput, GetStateInput, GetStateOutput, GetWorkspaceEnvInput, GetWorkspaceEnvOutput, GetWorkspaceOutput, InitProjectInput, InitProjectOutput, RemovePackageFromWorkspaceInput, RemovePackageFromWorkspaceOutput, SetEnvVarInput, SetEnvVarOutput, UnsetEnvVarInput, UnsetEnvVarOutput } from './common.js';
|
|
3
3
|
export declare class LocalBackend implements Backend {
|
|
4
4
|
addPackageToWorkspace(input: AddPackageToWorkspaceInput): Promise<AddPackageToWorkspaceOutput>;
|
|
5
5
|
createWorkspace(input: CreateWorkspaceInput): Promise<CreateWorkspaceOutput>;
|
|
@@ -11,6 +11,8 @@ export declare class LocalBackend implements Backend {
|
|
|
11
11
|
init(options: InitProjectInput): Promise<InitProjectOutput>;
|
|
12
12
|
removePackageFromWorkspace(input: RemovePackageFromWorkspaceInput): Promise<RemovePackageFromWorkspaceOutput>;
|
|
13
13
|
saveState(config: Omit<Config, 'workspace'>): Promise<void>;
|
|
14
|
+
setEnvVar(input: SetEnvVarInput): Promise<SetEnvVarOutput>;
|
|
15
|
+
unsetEnvVar(input: UnsetEnvVarInput): Promise<UnsetEnvVarOutput>;
|
|
14
16
|
private getProjectStatePath;
|
|
15
17
|
private getWorkspacePath;
|
|
16
18
|
private saveWorkspace;
|
package/dist/backend/local.js
CHANGED
|
@@ -2,6 +2,7 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
+
import { getInfrastructure } from '../infrastructure/index.js';
|
|
5
6
|
import { resolveEnvValues } from '../lib/env-utils.js';
|
|
6
7
|
import { getAnyPath } from '../lib/filesystem.js';
|
|
7
8
|
import { load, save } from '../lib/yaml-utils.js';
|
|
@@ -9,10 +10,12 @@ const WorkspaceSchema = z.object({
|
|
|
9
10
|
env: z.record(z.string()).optional(),
|
|
10
11
|
id: z.string().min(2),
|
|
11
12
|
name: z.string().min(2),
|
|
12
|
-
packages: z
|
|
13
|
+
packages: z
|
|
14
|
+
.record(z.object({
|
|
13
15
|
parameters: z.record(z.any()).optional(),
|
|
14
16
|
version: z.string(),
|
|
15
|
-
}))
|
|
17
|
+
}))
|
|
18
|
+
.optional(),
|
|
16
19
|
});
|
|
17
20
|
export class LocalBackend {
|
|
18
21
|
async addPackageToWorkspace(input) {
|
|
@@ -37,8 +40,7 @@ export class LocalBackend {
|
|
|
37
40
|
version: '',
|
|
38
41
|
},
|
|
39
42
|
};
|
|
40
|
-
const newEnv = Object.fromEntries(Object.entries(input.env)
|
|
41
|
-
.map(([key, value]) => [key, `${input.infra}:${value}`]));
|
|
43
|
+
const newEnv = Object.fromEntries(Object.entries(input.env).map(([key, value]) => [key, `${input.infra}:${value}`]));
|
|
42
44
|
workspace.env = {
|
|
43
45
|
...workspace.env,
|
|
44
46
|
...newEnv,
|
|
@@ -60,14 +62,16 @@ export class LocalBackend {
|
|
|
60
62
|
async createWorkspace(input) {
|
|
61
63
|
const workspace$ = await this.getWorkspace(input.name);
|
|
62
64
|
if (workspace$.found) {
|
|
63
|
-
return workspace$.hasError
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
return workspace$.hasError
|
|
66
|
+
? {
|
|
67
|
+
reason: workspace$.error,
|
|
68
|
+
success: false,
|
|
69
|
+
}
|
|
70
|
+
: {
|
|
71
|
+
isNew: false,
|
|
72
|
+
success: true,
|
|
73
|
+
workspace: workspace$.workspace,
|
|
74
|
+
};
|
|
71
75
|
}
|
|
72
76
|
const workspace = {
|
|
73
77
|
id: input.name,
|
|
@@ -116,8 +120,11 @@ export class LocalBackend {
|
|
|
116
120
|
};
|
|
117
121
|
}
|
|
118
122
|
async getProvisioningId(input) {
|
|
119
|
-
const id = (
|
|
120
|
-
.
|
|
123
|
+
const id = (input.project || input.workspace
|
|
124
|
+
? [input.project, input.workspace, input.packageCanonicalName]
|
|
125
|
+
: [input.packageCanonicalName])
|
|
126
|
+
.filter(Boolean)
|
|
127
|
+
.join('')
|
|
121
128
|
.replaceAll(/[^\dA-Za-z]/g, '');
|
|
122
129
|
return {
|
|
123
130
|
id,
|
|
@@ -205,10 +212,8 @@ export class LocalBackend {
|
|
|
205
212
|
};
|
|
206
213
|
}
|
|
207
214
|
const { workspace } = workspace$;
|
|
208
|
-
workspace.packages = Object.fromEntries(Object.entries(workspace.packages ?? {})
|
|
209
|
-
|
|
210
|
-
workspace.env = Object.fromEntries(Object.entries(workspace.env ?? {})
|
|
211
|
-
.filter(([key]) => !(key in input.env)));
|
|
215
|
+
workspace.packages = Object.fromEntries(Object.entries(workspace.packages ?? {}).filter(([key]) => key !== input.package));
|
|
216
|
+
workspace.env = Object.fromEntries(Object.entries(workspace.env ?? {}).filter(([key]) => !(key in input.env)));
|
|
212
217
|
try {
|
|
213
218
|
await this.saveWorkspace(workspace, input.workspace);
|
|
214
219
|
return {
|
|
@@ -227,6 +232,95 @@ export class LocalBackend {
|
|
|
227
232
|
const projectStatePath = await this.getProjectStatePath(config.project);
|
|
228
233
|
await save(config, projectStatePath);
|
|
229
234
|
}
|
|
235
|
+
async setEnvVar(input) {
|
|
236
|
+
const workspace$ = await this.getWorkspace(input.workspace);
|
|
237
|
+
if (!workspace$.found) {
|
|
238
|
+
return {
|
|
239
|
+
reason: `Workspace ${input.workspace} not found`,
|
|
240
|
+
success: false,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
if (workspace$.hasError) {
|
|
244
|
+
return {
|
|
245
|
+
reason: workspace$.error,
|
|
246
|
+
success: false,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
const { workspace } = workspace$;
|
|
250
|
+
const infrastructure$ = getInfrastructure({ type: input.infra });
|
|
251
|
+
if (!infrastructure$.supported) {
|
|
252
|
+
return {
|
|
253
|
+
reason: `Infrastructure ${input.infra} not found`,
|
|
254
|
+
success: false,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const { infrastructure } = infrastructure$;
|
|
258
|
+
const setEnvVarOutput = await infrastructure.storeEnv({
|
|
259
|
+
name: input.name,
|
|
260
|
+
oldValue: workspace.env?.[input.name]?.split(':').slice(1).join(':'),
|
|
261
|
+
sensitive: input.sensitive,
|
|
262
|
+
value: input.value,
|
|
263
|
+
});
|
|
264
|
+
if (!setEnvVarOutput.success) {
|
|
265
|
+
return {
|
|
266
|
+
reason: setEnvVarOutput.reason,
|
|
267
|
+
success: false,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
workspace.env = {
|
|
271
|
+
...workspace.env,
|
|
272
|
+
[input.name]: `${input.infra}:${setEnvVarOutput.value}`,
|
|
273
|
+
};
|
|
274
|
+
await this.saveWorkspace(workspace, input.workspace);
|
|
275
|
+
return {
|
|
276
|
+
success: true,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
async unsetEnvVar(input) {
|
|
280
|
+
const workspace$ = await this.getWorkspace(input.workspace);
|
|
281
|
+
if (!workspace$.found) {
|
|
282
|
+
return {
|
|
283
|
+
reason: `Workspace ${input.workspace} not found`,
|
|
284
|
+
success: false,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
if (workspace$.hasError) {
|
|
288
|
+
return {
|
|
289
|
+
reason: workspace$.error,
|
|
290
|
+
success: false,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const { workspace } = workspace$;
|
|
294
|
+
const value = workspace.env?.[input.name];
|
|
295
|
+
if (!value) {
|
|
296
|
+
return {
|
|
297
|
+
success: true,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
const infra = value.split(':')[0];
|
|
301
|
+
const infrastructure$ = getInfrastructure({ type: infra });
|
|
302
|
+
if (!infrastructure$.supported) {
|
|
303
|
+
return {
|
|
304
|
+
reason: `Infrastructure ${infra} not found`,
|
|
305
|
+
success: false,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
const { infrastructure } = infrastructure$;
|
|
309
|
+
const unsetEnvVarOutput = await infrastructure.unstoreEnv({
|
|
310
|
+
value: value.split(':').slice(1).join(':'),
|
|
311
|
+
});
|
|
312
|
+
if (!unsetEnvVarOutput.success) {
|
|
313
|
+
return {
|
|
314
|
+
reason: unsetEnvVarOutput.reason,
|
|
315
|
+
success: false,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
workspace.env = Object.fromEntries(Object.entries(workspace.env ?? {}).filter(([key]) => key !== input.name));
|
|
319
|
+
await this.saveWorkspace(workspace, input.workspace);
|
|
320
|
+
return {
|
|
321
|
+
success: true,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
230
324
|
async getProjectStatePath(project) {
|
|
231
325
|
return getAnyPath(path.join(os.homedir(), '.hereya', 'state', 'projects', `${project}.yaml`), path.join(os.homedir(), '.hereya', 'state', 'projects', `${project}.yml`));
|
|
232
326
|
}
|
|
@@ -2,7 +2,7 @@ import { Args, Command, Flags } from '@oclif/core';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { getIac } from '../../../iac/index.js';
|
|
4
4
|
import { getInfrastructure } from '../../../infrastructure/index.js';
|
|
5
|
-
import {
|
|
5
|
+
import { tryBase64ToJSONString } from '../../../lib/object-utils.js';
|
|
6
6
|
import { save } from '../../../lib/yaml-utils.js';
|
|
7
7
|
export default class RemoteExec extends Command {
|
|
8
8
|
static args = {
|
|
@@ -12,9 +12,7 @@ export default class RemoteExec extends Command {
|
|
|
12
12
|
}),
|
|
13
13
|
};
|
|
14
14
|
static description = 'remotely provision or destroy a package';
|
|
15
|
-
static examples = [
|
|
16
|
-
'<%= config.bin %> <%= command.id %>',
|
|
17
|
-
];
|
|
15
|
+
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
18
16
|
static flags = {
|
|
19
17
|
output: Flags.string({
|
|
20
18
|
char: 'o',
|
|
@@ -30,14 +28,13 @@ export default class RemoteExec extends Command {
|
|
|
30
28
|
async run() {
|
|
31
29
|
const { args, flags } = await this.parse(RemoteExec);
|
|
32
30
|
const workspaceEnv = Object.fromEntries((process.env.HEREYA_WORKSPACE_ENV?.split(',') ?? [])
|
|
33
|
-
.filter(param => param.trim())
|
|
34
|
-
.map(param => param.split('='))
|
|
31
|
+
.filter((param) => param.trim())
|
|
32
|
+
.map((param) => param.split('='))
|
|
35
33
|
.map(([key, value]) => [key, tryBase64ToJSONString(value)]));
|
|
36
34
|
const parameters = Object.fromEntries((process.env.HEREYA_PARAMETERS?.split(',') ?? [])
|
|
37
|
-
.filter(param => param.trim())
|
|
38
|
-
.map(param => param.split('='))
|
|
35
|
+
.filter((param) => param.trim())
|
|
36
|
+
.map((param) => param.split('='))
|
|
39
37
|
.map(([key, value]) => [key, tryBase64ToJSONString(value)]));
|
|
40
|
-
parameters.hereyaProjectEnv = parameters.hereyaProjectEnv ? base64ToJSONString(parameters.hereyaProjectEnv) : '';
|
|
41
38
|
const id = process.env.HEREYA_ID;
|
|
42
39
|
const iacType = process.env.HEREYA_IAC_TYPE;
|
|
43
40
|
const destroy = process.env.HEREYA_DESTROY === 'true';
|
|
@@ -56,7 +53,10 @@ export default class RemoteExec extends Command {
|
|
|
56
53
|
`);
|
|
57
54
|
}
|
|
58
55
|
const input = {
|
|
59
|
-
env: workspaceEnv,
|
|
56
|
+
env: workspaceEnv,
|
|
57
|
+
id,
|
|
58
|
+
parameters,
|
|
59
|
+
pkgPath: args.pkgPath || process.cwd(),
|
|
60
60
|
};
|
|
61
61
|
if (deploy) {
|
|
62
62
|
input.parameters = {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class WorkspaceEnvSet extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
infra: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
7
|
+
name: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
sensitive: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
9
|
+
value: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
10
|
+
workspace: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { getBackend } from '../../../../backend/index.js';
|
|
3
|
+
export default class WorkspaceEnvSet extends Command {
|
|
4
|
+
static description = 'set an env var for a workspace';
|
|
5
|
+
static examples = ['<%= config.bin %> <%= command.id %> -w my-workspace -n myVar -v my-value -i aws -s'];
|
|
6
|
+
static flags = {
|
|
7
|
+
infra: Flags.string({ char: 'i', description: 'the infrastructure to store the env var in', required: true }),
|
|
8
|
+
name: Flags.string({ char: 'n', description: 'name of the env var to set', required: true }),
|
|
9
|
+
sensitive: Flags.boolean({ char: 's', description: 'whether the env var is sensitive' }),
|
|
10
|
+
value: Flags.string({ char: 'v', description: 'value of the env var to set', required: true }),
|
|
11
|
+
workspace: Flags.string({
|
|
12
|
+
char: 'w',
|
|
13
|
+
description: 'name of the workspace to set an env var for',
|
|
14
|
+
required: true,
|
|
15
|
+
}),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { flags } = await this.parse(WorkspaceEnvSet);
|
|
19
|
+
const backend = await getBackend();
|
|
20
|
+
const getWorkspaceOutput = await backend.getWorkspace(flags.workspace);
|
|
21
|
+
if (!getWorkspaceOutput.found) {
|
|
22
|
+
this.error(`Workspace ${flags.workspace} not found`);
|
|
23
|
+
}
|
|
24
|
+
if (getWorkspaceOutput.hasError) {
|
|
25
|
+
this.error(getWorkspaceOutput.error);
|
|
26
|
+
}
|
|
27
|
+
const setEnvVarOutput = await backend.setEnvVar({
|
|
28
|
+
infra: flags.infra,
|
|
29
|
+
name: flags.name,
|
|
30
|
+
sensitive: flags.sensitive,
|
|
31
|
+
value: flags.value,
|
|
32
|
+
workspace: flags.workspace,
|
|
33
|
+
});
|
|
34
|
+
if (!setEnvVarOutput.success) {
|
|
35
|
+
this.error(setEnvVarOutput.reason);
|
|
36
|
+
}
|
|
37
|
+
this.log(`Env var ${flags.name} set for workspace ${flags.workspace}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class WorkspaceEnvUnset extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
name: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
7
|
+
workspace: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { getBackend } from '../../../../backend/index.js';
|
|
3
|
+
export default class WorkspaceEnvUnset extends Command {
|
|
4
|
+
static description = 'unset an env var for a workspace';
|
|
5
|
+
static examples = ['<%= config.bin %> <%= command.id %> -w my-workspace -n myVar'];
|
|
6
|
+
static flags = {
|
|
7
|
+
name: Flags.string({ char: 'n', description: 'name of the env var to unset', required: true }),
|
|
8
|
+
workspace: Flags.string({
|
|
9
|
+
char: 'w',
|
|
10
|
+
description: 'name of the workspace to unset an env var for',
|
|
11
|
+
required: true,
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
async run() {
|
|
15
|
+
const { flags } = await this.parse(WorkspaceEnvUnset);
|
|
16
|
+
const backend = await getBackend();
|
|
17
|
+
const getWorkspaceOutput = await backend.getWorkspace(flags.workspace);
|
|
18
|
+
if (!getWorkspaceOutput.found) {
|
|
19
|
+
this.error(`Workspace ${flags.workspace} not found`);
|
|
20
|
+
}
|
|
21
|
+
if (getWorkspaceOutput.hasError) {
|
|
22
|
+
this.error(getWorkspaceOutput.error);
|
|
23
|
+
}
|
|
24
|
+
const unsetEnvVarOutput = await backend.unsetEnvVar({
|
|
25
|
+
name: flags.name,
|
|
26
|
+
workspace: flags.workspace,
|
|
27
|
+
});
|
|
28
|
+
if (!unsetEnvVarOutput.success) {
|
|
29
|
+
this.error(unsetEnvVarOutput.reason);
|
|
30
|
+
}
|
|
31
|
+
this.log(`Unset env var ${flags.name} for workspace ${flags.workspace}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BootstrapInput, DeployInput, DeployOutput, DestroyInput, DestroyOutput, Infrastructure, ProvisionInput, ProvisionOutput, ResolveEnvInput, ResolveEnvOutput, SaveEnvInput, SaveEnvOutput, UndeployInput, UndeployOutput } from './common.js';
|
|
1
|
+
import { BootstrapInput, DeployInput, DeployOutput, DestroyInput, DestroyOutput, Infrastructure, ProvisionInput, ProvisionOutput, ResolveEnvInput, ResolveEnvOutput, SaveEnvInput, SaveEnvOutput, StoreEnvInput, StoreEnvOutput, UndeployInput, UndeployOutput, UnstoreEnvInput, UnstoreEnvOutput } from './common.js';
|
|
2
2
|
export declare class AwsInfrastructure implements Infrastructure {
|
|
3
3
|
bootstrap(_: BootstrapInput): Promise<void>;
|
|
4
4
|
deploy(input: DeployInput): Promise<DeployOutput>;
|
|
@@ -6,8 +6,10 @@ export declare class AwsInfrastructure implements Infrastructure {
|
|
|
6
6
|
provision(input: ProvisionInput): Promise<ProvisionOutput>;
|
|
7
7
|
resolveEnv(input: ResolveEnvInput): Promise<ResolveEnvOutput>;
|
|
8
8
|
saveEnv(input: SaveEnvInput): Promise<SaveEnvOutput>;
|
|
9
|
+
storeEnv(input: StoreEnvInput): Promise<StoreEnvOutput>;
|
|
9
10
|
unbootstrap(_: BootstrapInput): Promise<void>;
|
|
10
11
|
undeploy(input: UndeployInput): Promise<UndeployOutput>;
|
|
12
|
+
unstoreEnv(input: UnstoreEnvInput): Promise<UnstoreEnvOutput>;
|
|
11
13
|
private getEnv;
|
|
12
14
|
private getFilesToUpload;
|
|
13
15
|
private removeEnv;
|
|
@@ -12,7 +12,7 @@ import { IacType } from '../iac/common.js';
|
|
|
12
12
|
import { fileExists, getAnyPath } from '../lib/filesystem.js';
|
|
13
13
|
import { objectToBase64 } from '../lib/object-utils.js';
|
|
14
14
|
import { runShell } from '../lib/shell.js';
|
|
15
|
-
import { InfrastructureType } from './common.js';
|
|
15
|
+
import { InfrastructureType, } from './common.js';
|
|
16
16
|
import { destroyPackage, provisionPackage } from './index.js';
|
|
17
17
|
export class AwsInfrastructure {
|
|
18
18
|
async bootstrap(_) {
|
|
@@ -33,7 +33,7 @@ export class AwsInfrastructure {
|
|
|
33
33
|
Name: key,
|
|
34
34
|
Overwrite: true,
|
|
35
35
|
Type: 'String',
|
|
36
|
-
Value: value
|
|
36
|
+
Value: value,
|
|
37
37
|
}));
|
|
38
38
|
}
|
|
39
39
|
async deploy(input) {
|
|
@@ -42,6 +42,7 @@ export class AwsInfrastructure {
|
|
|
42
42
|
let s3Client = new S3Client({});
|
|
43
43
|
let s3Key = '';
|
|
44
44
|
try {
|
|
45
|
+
;
|
|
45
46
|
({ files, s3Bucket, s3Client, s3Key } = await this.uploadProjectFiles(input));
|
|
46
47
|
input.parameters = {
|
|
47
48
|
...input.parameters,
|
|
@@ -50,7 +51,7 @@ export class AwsInfrastructure {
|
|
|
50
51
|
const output = await this.runCodeBuild({
|
|
51
52
|
...input,
|
|
52
53
|
deploy: true,
|
|
53
|
-
sourceS3Key: s3Key
|
|
54
|
+
sourceS3Key: s3Key,
|
|
54
55
|
});
|
|
55
56
|
if (!output.success) {
|
|
56
57
|
return output;
|
|
@@ -63,8 +64,8 @@ export class AwsInfrastructure {
|
|
|
63
64
|
await s3Client.send(new DeleteObjectsCommand({
|
|
64
65
|
Bucket: s3Bucket,
|
|
65
66
|
Delete: {
|
|
66
|
-
Objects: files.map(file => ({ Key: `${s3Key}/${file}` }))
|
|
67
|
-
}
|
|
67
|
+
Objects: files.map((file) => ({ Key: `${s3Key}/${file}` })),
|
|
68
|
+
},
|
|
68
69
|
}));
|
|
69
70
|
}
|
|
70
71
|
}
|
|
@@ -97,7 +98,7 @@ export class AwsInfrastructure {
|
|
|
97
98
|
}));
|
|
98
99
|
return {
|
|
99
100
|
isSecret: response.Parameter?.Type === 'SecureString',
|
|
100
|
-
value: response.Parameter?.Value ?? input.value
|
|
101
|
+
value: response.Parameter?.Value ?? input.value,
|
|
101
102
|
};
|
|
102
103
|
}
|
|
103
104
|
const secretManagerArnPattern = /^arn:aws:secretsmanager:[\da-z-]+:\d{12}:secret:[\w-]+/;
|
|
@@ -108,7 +109,7 @@ export class AwsInfrastructure {
|
|
|
108
109
|
}));
|
|
109
110
|
return {
|
|
110
111
|
isSecret: true,
|
|
111
|
-
value: response.SecretString ?? input.value
|
|
112
|
+
value: response.SecretString ?? input.value,
|
|
112
113
|
};
|
|
113
114
|
}
|
|
114
115
|
return { value: input.value };
|
|
@@ -127,7 +128,7 @@ export class AwsInfrastructure {
|
|
|
127
128
|
Name: key,
|
|
128
129
|
Overwrite: true,
|
|
129
130
|
Type: 'String',
|
|
130
|
-
Value: value
|
|
131
|
+
Value: value,
|
|
131
132
|
}));
|
|
132
133
|
return { success: true };
|
|
133
134
|
}
|
|
@@ -135,6 +136,27 @@ export class AwsInfrastructure {
|
|
|
135
136
|
return { reason: error.message, success: false };
|
|
136
137
|
}
|
|
137
138
|
}
|
|
139
|
+
async storeEnv(input) {
|
|
140
|
+
if (!input.sensitive) {
|
|
141
|
+
return { success: true, value: input.value };
|
|
142
|
+
}
|
|
143
|
+
const ssmClient = new SSMClient({});
|
|
144
|
+
const id = randomUUID();
|
|
145
|
+
const ssmParameterName = input.oldValue ?? `/hereya/${input.name}/${id}`;
|
|
146
|
+
await ssmClient.send(new PutParameterCommand({
|
|
147
|
+
Name: ssmParameterName,
|
|
148
|
+
Overwrite: true,
|
|
149
|
+
Type: 'SecureString',
|
|
150
|
+
Value: input.value,
|
|
151
|
+
}));
|
|
152
|
+
const parameter = await ssmClient.send(new GetParameterCommand({
|
|
153
|
+
Name: ssmParameterName,
|
|
154
|
+
}));
|
|
155
|
+
if (!parameter.Parameter?.ARN) {
|
|
156
|
+
throw new Error(`Could not store env var ${input.name} for AWS infrastructure`);
|
|
157
|
+
}
|
|
158
|
+
return { success: true, value: parameter.Parameter.ARN };
|
|
159
|
+
}
|
|
138
160
|
async unbootstrap(_) {
|
|
139
161
|
const ssmClient = new SSMClient({});
|
|
140
162
|
const key = '/hereya-bootstrap/config';
|
|
@@ -165,6 +187,7 @@ export class AwsInfrastructure {
|
|
|
165
187
|
console.log(`Could not get env for ${input.id}: ${error.message}. Continuing with undeployment...`);
|
|
166
188
|
}
|
|
167
189
|
try {
|
|
190
|
+
;
|
|
168
191
|
({ files, s3Bucket, s3Client, s3Key } = await this.uploadProjectFiles(input));
|
|
169
192
|
input.parameters = {
|
|
170
193
|
...input.parameters,
|
|
@@ -174,7 +197,7 @@ export class AwsInfrastructure {
|
|
|
174
197
|
...input,
|
|
175
198
|
deploy: true,
|
|
176
199
|
destroy: true,
|
|
177
|
-
sourceS3Key: s3Key
|
|
200
|
+
sourceS3Key: s3Key,
|
|
178
201
|
});
|
|
179
202
|
if (!output.success) {
|
|
180
203
|
return output;
|
|
@@ -186,12 +209,30 @@ export class AwsInfrastructure {
|
|
|
186
209
|
await s3Client.send(new DeleteObjectsCommand({
|
|
187
210
|
Bucket: s3Bucket,
|
|
188
211
|
Delete: {
|
|
189
|
-
Objects: files.map(file => ({ Key: `${s3Key}/${file}` }))
|
|
190
|
-
}
|
|
212
|
+
Objects: files.map((file) => ({ Key: `${s3Key}/${file}` })),
|
|
213
|
+
},
|
|
191
214
|
}));
|
|
192
215
|
}
|
|
193
216
|
}
|
|
194
217
|
}
|
|
218
|
+
async unstoreEnv(input) {
|
|
219
|
+
const parameterStoreArnPattern = /^arn:aws:ssm:[\da-z-]+:\d{12}:parameter\/[\w./-]+$/;
|
|
220
|
+
if (!parameterStoreArnPattern.test(input.value)) {
|
|
221
|
+
return { success: true };
|
|
222
|
+
}
|
|
223
|
+
const ssmClient = new SSMClient({});
|
|
224
|
+
const parameter = await ssmClient.send(new GetParameterCommand({
|
|
225
|
+
Name: input.value,
|
|
226
|
+
}));
|
|
227
|
+
const ssmParameterName = parameter.Parameter?.Name;
|
|
228
|
+
if (!ssmParameterName) {
|
|
229
|
+
return { success: true };
|
|
230
|
+
}
|
|
231
|
+
await ssmClient.send(new DeleteParameterCommand({
|
|
232
|
+
Name: ssmParameterName,
|
|
233
|
+
}));
|
|
234
|
+
return { success: true };
|
|
235
|
+
}
|
|
195
236
|
async getEnv(id) {
|
|
196
237
|
const ssmClient = new SSMClient({});
|
|
197
238
|
const ssmParameterName = `/hereya/${id}`;
|
|
@@ -202,7 +243,7 @@ export class AwsInfrastructure {
|
|
|
202
243
|
return JSON.parse(ssmParameter.Parameter?.Value ?? '{}');
|
|
203
244
|
}
|
|
204
245
|
catch (error) {
|
|
205
|
-
if (error.name ===
|
|
246
|
+
if (error.name === 'ParameterNotFound') {
|
|
206
247
|
console.debug(`Parameter "${ssmParameterName}" does not exist.`);
|
|
207
248
|
return {};
|
|
208
249
|
}
|
|
@@ -217,7 +258,7 @@ export class AwsInfrastructure {
|
|
|
217
258
|
ig.add(ignoreFileContent);
|
|
218
259
|
}
|
|
219
260
|
const files = glob.sync('**/*', { cwd: rootDir, nodir: true });
|
|
220
|
-
return files.filter(file => !ig.ignores(file));
|
|
261
|
+
return files.filter((file) => !ig.ignores(file));
|
|
221
262
|
}
|
|
222
263
|
async removeEnv(id) {
|
|
223
264
|
const ssmClient = new SSMClient({});
|
|
@@ -244,7 +285,9 @@ export class AwsInfrastructure {
|
|
|
244
285
|
}
|
|
245
286
|
const ssmClient = new SSMClient({});
|
|
246
287
|
const parameterName = `/hereya/package-parameters/${input.id}`;
|
|
247
|
-
const parameterValue = Object.entries(input.parameters ?? {})
|
|
288
|
+
const parameterValue = Object.entries(input.parameters ?? {})
|
|
289
|
+
.map(([key, value]) => `${key}=${typeof value === 'object' ? objectToBase64(value) : value}`)
|
|
290
|
+
.join(',');
|
|
248
291
|
if (parameterValue) {
|
|
249
292
|
await ssmClient.send(new PutParameterCommand({
|
|
250
293
|
Name: parameterName,
|
|
@@ -278,7 +321,9 @@ export class AwsInfrastructure {
|
|
|
278
321
|
{
|
|
279
322
|
name: 'HEREYA_WORKSPACE_ENV',
|
|
280
323
|
type: 'PLAINTEXT',
|
|
281
|
-
value: Object.entries(input.env ?? {})
|
|
324
|
+
value: Object.entries(input.env ?? {})
|
|
325
|
+
.map(([key, value]) => `${key}=${typeof value === 'object' ? objectToBase64(value) : value}`)
|
|
326
|
+
.join(','),
|
|
282
327
|
},
|
|
283
328
|
{
|
|
284
329
|
name: 'PKG_REPO_URL',
|
|
@@ -299,7 +344,7 @@ export class AwsInfrastructure {
|
|
|
299
344
|
name: 'HEREYA_PROJECT_S3_KEY',
|
|
300
345
|
type: 'PLAINTEXT',
|
|
301
346
|
value: input.deploy ? input.sourceS3Key : '',
|
|
302
|
-
}
|
|
347
|
+
},
|
|
303
348
|
],
|
|
304
349
|
projectName: codebuildProjectName,
|
|
305
350
|
}));
|
|
@@ -12,8 +12,10 @@ export interface Infrastructure {
|
|
|
12
12
|
provision(input: ProvisionInput): Promise<ProvisionOutput>;
|
|
13
13
|
resolveEnv(input: ResolveEnvInput): Promise<ResolveEnvOutput>;
|
|
14
14
|
saveEnv(input: SaveEnvInput): Promise<SaveEnvOutput>;
|
|
15
|
+
storeEnv(input: StoreEnvInput): Promise<StoreEnvOutput>;
|
|
15
16
|
unbootstrap(input: BootstrapInput): Promise<void>;
|
|
16
17
|
undeploy(input: UndeployInput): Promise<UndeployOutput>;
|
|
18
|
+
unstoreEnv(input: UnstoreEnvInput): Promise<UnstoreEnvOutput>;
|
|
17
19
|
}
|
|
18
20
|
export type BootstrapInput = {
|
|
19
21
|
force?: boolean;
|
|
@@ -70,3 +72,25 @@ export type SaveEnvOutput = {
|
|
|
70
72
|
} | {
|
|
71
73
|
success: true;
|
|
72
74
|
};
|
|
75
|
+
export type StoreEnvInput = {
|
|
76
|
+
name: string;
|
|
77
|
+
oldValue?: string;
|
|
78
|
+
sensitive?: boolean;
|
|
79
|
+
value: string;
|
|
80
|
+
};
|
|
81
|
+
export type StoreEnvOutput = {
|
|
82
|
+
reason: string;
|
|
83
|
+
success: false;
|
|
84
|
+
} | {
|
|
85
|
+
success: true;
|
|
86
|
+
value: string;
|
|
87
|
+
};
|
|
88
|
+
export type UnstoreEnvInput = {
|
|
89
|
+
value: string;
|
|
90
|
+
};
|
|
91
|
+
export type UnstoreEnvOutput = {
|
|
92
|
+
reason: string;
|
|
93
|
+
success: false;
|
|
94
|
+
} | {
|
|
95
|
+
success: true;
|
|
96
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DeployInput, DeployOutput, Infrastructure, ProvisionInput, ProvisionOutput, SaveEnvInput, SaveEnvOutput, UndeployInput, UndeployOutput } from './common.js';
|
|
1
|
+
import { DeployInput, DeployOutput, Infrastructure, ProvisionInput, ProvisionOutput, SaveEnvInput, SaveEnvOutput, StoreEnvInput, StoreEnvOutput, UndeployInput, UndeployOutput, UnstoreEnvInput, UnstoreEnvOutput } from './common.js';
|
|
2
2
|
export declare class LocalInfrastructure implements Infrastructure {
|
|
3
3
|
bootstrap(): Promise<void>;
|
|
4
4
|
deploy(input: DeployInput): Promise<DeployOutput>;
|
|
@@ -10,8 +10,10 @@ export declare class LocalInfrastructure implements Infrastructure {
|
|
|
10
10
|
value: string;
|
|
11
11
|
}>;
|
|
12
12
|
saveEnv(input: SaveEnvInput): Promise<SaveEnvOutput>;
|
|
13
|
+
storeEnv(input: StoreEnvInput): Promise<StoreEnvOutput>;
|
|
13
14
|
unbootstrap(): Promise<void>;
|
|
14
15
|
undeploy(input: UndeployInput): Promise<UndeployOutput>;
|
|
16
|
+
unstoreEnv(_: UnstoreEnvInput): Promise<UnstoreEnvOutput>;
|
|
15
17
|
private download;
|
|
16
18
|
private isNotEmpty;
|
|
17
19
|
}
|
|
@@ -11,7 +11,7 @@ export class LocalInfrastructure {
|
|
|
11
11
|
input.parameters = {
|
|
12
12
|
...input.parameters,
|
|
13
13
|
hereyaProjectEnv: JSON.stringify(input.projectEnv ?? {}),
|
|
14
|
-
hereyaProjectRootDir: input.projectRootDir
|
|
14
|
+
hereyaProjectRootDir: input.projectRootDir,
|
|
15
15
|
};
|
|
16
16
|
return this.provision(input);
|
|
17
17
|
}
|
|
@@ -28,7 +28,7 @@ export class LocalInfrastructure {
|
|
|
28
28
|
env: input.env ?? {},
|
|
29
29
|
id: input.id,
|
|
30
30
|
parameters: input.parameters,
|
|
31
|
-
pkgPath: downloadPath
|
|
31
|
+
pkgPath: downloadPath,
|
|
32
32
|
});
|
|
33
33
|
if (!output.success) {
|
|
34
34
|
return { reason: output.reason, success: false };
|
|
@@ -50,7 +50,7 @@ export class LocalInfrastructure {
|
|
|
50
50
|
env: input.env ?? {},
|
|
51
51
|
id: input.id,
|
|
52
52
|
parameters: input.parameters,
|
|
53
|
-
pkgPath: downloadPath
|
|
53
|
+
pkgPath: downloadPath,
|
|
54
54
|
});
|
|
55
55
|
if (!output.success) {
|
|
56
56
|
return { reason: output.reason, success: false };
|
|
@@ -64,6 +64,9 @@ export class LocalInfrastructure {
|
|
|
64
64
|
console.log(`Saving env to ${input.id}`);
|
|
65
65
|
return { success: true };
|
|
66
66
|
}
|
|
67
|
+
async storeEnv(input) {
|
|
68
|
+
return { success: true, value: input.value };
|
|
69
|
+
}
|
|
67
70
|
async unbootstrap() {
|
|
68
71
|
console.log('Unbootstrapping local infrastructure');
|
|
69
72
|
}
|
|
@@ -71,10 +74,13 @@ export class LocalInfrastructure {
|
|
|
71
74
|
input.parameters = {
|
|
72
75
|
...input.parameters,
|
|
73
76
|
hereyaProjectEnv: JSON.stringify(input.projectEnv ?? {}),
|
|
74
|
-
hereyaProjectRootDir: input.projectRootDir
|
|
77
|
+
hereyaProjectRootDir: input.projectRootDir,
|
|
75
78
|
};
|
|
76
79
|
return this.destroy(input);
|
|
77
80
|
}
|
|
81
|
+
async unstoreEnv(_) {
|
|
82
|
+
return { success: true };
|
|
83
|
+
}
|
|
78
84
|
async download(pkgUrl, destPath) {
|
|
79
85
|
if (await this.isNotEmpty(destPath)) {
|
|
80
86
|
console.log(`Package already downloaded at ${destPath}`);
|
package/oclif.manifest.json
CHANGED
|
@@ -48,45 +48,6 @@
|
|
|
48
48
|
"index.js"
|
|
49
49
|
]
|
|
50
50
|
},
|
|
51
|
-
"bootstrap": {
|
|
52
|
-
"aliases": [],
|
|
53
|
-
"args": {
|
|
54
|
-
"infrastructureType": {
|
|
55
|
-
"description": "infrastructure to bootstrap. Options are local, aws",
|
|
56
|
-
"name": "infrastructureType",
|
|
57
|
-
"required": true
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
"description": "Install necessary resources for hereya operations in an infrastructure.",
|
|
61
|
-
"examples": [
|
|
62
|
-
"<%= config.bin %> <%= command.id %> aws",
|
|
63
|
-
"<%= config.bin %> <%= command.id %> local"
|
|
64
|
-
],
|
|
65
|
-
"flags": {
|
|
66
|
-
"force": {
|
|
67
|
-
"char": "f",
|
|
68
|
-
"description": "redeploy hereya resources if already deployed",
|
|
69
|
-
"name": "force",
|
|
70
|
-
"allowNo": false,
|
|
71
|
-
"type": "boolean"
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
"hasDynamicHelp": false,
|
|
75
|
-
"hiddenAliases": [],
|
|
76
|
-
"id": "bootstrap",
|
|
77
|
-
"pluginAlias": "hereya-cli",
|
|
78
|
-
"pluginName": "hereya-cli",
|
|
79
|
-
"pluginType": "core",
|
|
80
|
-
"strict": true,
|
|
81
|
-
"enableJsonFlag": false,
|
|
82
|
-
"isESM": true,
|
|
83
|
-
"relativePath": [
|
|
84
|
-
"dist",
|
|
85
|
-
"commands",
|
|
86
|
-
"bootstrap",
|
|
87
|
-
"index.js"
|
|
88
|
-
]
|
|
89
|
-
},
|
|
90
51
|
"deploy": {
|
|
91
52
|
"aliases": [],
|
|
92
53
|
"args": {},
|
|
@@ -129,6 +90,45 @@
|
|
|
129
90
|
"index.js"
|
|
130
91
|
]
|
|
131
92
|
},
|
|
93
|
+
"bootstrap": {
|
|
94
|
+
"aliases": [],
|
|
95
|
+
"args": {
|
|
96
|
+
"infrastructureType": {
|
|
97
|
+
"description": "infrastructure to bootstrap. Options are local, aws",
|
|
98
|
+
"name": "infrastructureType",
|
|
99
|
+
"required": true
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"description": "Install necessary resources for hereya operations in an infrastructure.",
|
|
103
|
+
"examples": [
|
|
104
|
+
"<%= config.bin %> <%= command.id %> aws",
|
|
105
|
+
"<%= config.bin %> <%= command.id %> local"
|
|
106
|
+
],
|
|
107
|
+
"flags": {
|
|
108
|
+
"force": {
|
|
109
|
+
"char": "f",
|
|
110
|
+
"description": "redeploy hereya resources if already deployed",
|
|
111
|
+
"name": "force",
|
|
112
|
+
"allowNo": false,
|
|
113
|
+
"type": "boolean"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"hasDynamicHelp": false,
|
|
117
|
+
"hiddenAliases": [],
|
|
118
|
+
"id": "bootstrap",
|
|
119
|
+
"pluginAlias": "hereya-cli",
|
|
120
|
+
"pluginName": "hereya-cli",
|
|
121
|
+
"pluginType": "core",
|
|
122
|
+
"strict": true,
|
|
123
|
+
"enableJsonFlag": false,
|
|
124
|
+
"isESM": true,
|
|
125
|
+
"relativePath": [
|
|
126
|
+
"dist",
|
|
127
|
+
"commands",
|
|
128
|
+
"bootstrap",
|
|
129
|
+
"index.js"
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
132
|
"down": {
|
|
133
133
|
"aliases": [],
|
|
134
134
|
"args": {},
|
|
@@ -781,7 +781,122 @@
|
|
|
781
781
|
"uninstall",
|
|
782
782
|
"index.js"
|
|
783
783
|
]
|
|
784
|
+
},
|
|
785
|
+
"workspace:env:set": {
|
|
786
|
+
"aliases": [],
|
|
787
|
+
"args": {},
|
|
788
|
+
"description": "set an env var for a workspace",
|
|
789
|
+
"examples": [
|
|
790
|
+
"<%= config.bin %> <%= command.id %> -w my-workspace -n myVar -v my-value -i aws -s"
|
|
791
|
+
],
|
|
792
|
+
"flags": {
|
|
793
|
+
"infra": {
|
|
794
|
+
"char": "i",
|
|
795
|
+
"description": "the infrastructure to store the env var in",
|
|
796
|
+
"name": "infra",
|
|
797
|
+
"required": true,
|
|
798
|
+
"hasDynamicHelp": false,
|
|
799
|
+
"multiple": false,
|
|
800
|
+
"type": "option"
|
|
801
|
+
},
|
|
802
|
+
"name": {
|
|
803
|
+
"char": "n",
|
|
804
|
+
"description": "name of the env var to set",
|
|
805
|
+
"name": "name",
|
|
806
|
+
"required": true,
|
|
807
|
+
"hasDynamicHelp": false,
|
|
808
|
+
"multiple": false,
|
|
809
|
+
"type": "option"
|
|
810
|
+
},
|
|
811
|
+
"sensitive": {
|
|
812
|
+
"char": "s",
|
|
813
|
+
"description": "whether the env var is sensitive",
|
|
814
|
+
"name": "sensitive",
|
|
815
|
+
"allowNo": false,
|
|
816
|
+
"type": "boolean"
|
|
817
|
+
},
|
|
818
|
+
"value": {
|
|
819
|
+
"char": "v",
|
|
820
|
+
"description": "value of the env var to set",
|
|
821
|
+
"name": "value",
|
|
822
|
+
"required": true,
|
|
823
|
+
"hasDynamicHelp": false,
|
|
824
|
+
"multiple": false,
|
|
825
|
+
"type": "option"
|
|
826
|
+
},
|
|
827
|
+
"workspace": {
|
|
828
|
+
"char": "w",
|
|
829
|
+
"description": "name of the workspace to set an env var for",
|
|
830
|
+
"name": "workspace",
|
|
831
|
+
"required": true,
|
|
832
|
+
"hasDynamicHelp": false,
|
|
833
|
+
"multiple": false,
|
|
834
|
+
"type": "option"
|
|
835
|
+
}
|
|
836
|
+
},
|
|
837
|
+
"hasDynamicHelp": false,
|
|
838
|
+
"hiddenAliases": [],
|
|
839
|
+
"id": "workspace:env:set",
|
|
840
|
+
"pluginAlias": "hereya-cli",
|
|
841
|
+
"pluginName": "hereya-cli",
|
|
842
|
+
"pluginType": "core",
|
|
843
|
+
"strict": true,
|
|
844
|
+
"enableJsonFlag": false,
|
|
845
|
+
"isESM": true,
|
|
846
|
+
"relativePath": [
|
|
847
|
+
"dist",
|
|
848
|
+
"commands",
|
|
849
|
+
"workspace",
|
|
850
|
+
"env",
|
|
851
|
+
"set",
|
|
852
|
+
"index.js"
|
|
853
|
+
]
|
|
854
|
+
},
|
|
855
|
+
"workspace:env:unset": {
|
|
856
|
+
"aliases": [],
|
|
857
|
+
"args": {},
|
|
858
|
+
"description": "unset an env var for a workspace",
|
|
859
|
+
"examples": [
|
|
860
|
+
"<%= config.bin %> <%= command.id %> -w my-workspace -n myVar"
|
|
861
|
+
],
|
|
862
|
+
"flags": {
|
|
863
|
+
"name": {
|
|
864
|
+
"char": "n",
|
|
865
|
+
"description": "name of the env var to unset",
|
|
866
|
+
"name": "name",
|
|
867
|
+
"required": true,
|
|
868
|
+
"hasDynamicHelp": false,
|
|
869
|
+
"multiple": false,
|
|
870
|
+
"type": "option"
|
|
871
|
+
},
|
|
872
|
+
"workspace": {
|
|
873
|
+
"char": "w",
|
|
874
|
+
"description": "name of the workspace to unset an env var for",
|
|
875
|
+
"name": "workspace",
|
|
876
|
+
"required": true,
|
|
877
|
+
"hasDynamicHelp": false,
|
|
878
|
+
"multiple": false,
|
|
879
|
+
"type": "option"
|
|
880
|
+
}
|
|
881
|
+
},
|
|
882
|
+
"hasDynamicHelp": false,
|
|
883
|
+
"hiddenAliases": [],
|
|
884
|
+
"id": "workspace:env:unset",
|
|
885
|
+
"pluginAlias": "hereya-cli",
|
|
886
|
+
"pluginName": "hereya-cli",
|
|
887
|
+
"pluginType": "core",
|
|
888
|
+
"strict": true,
|
|
889
|
+
"enableJsonFlag": false,
|
|
890
|
+
"isESM": true,
|
|
891
|
+
"relativePath": [
|
|
892
|
+
"dist",
|
|
893
|
+
"commands",
|
|
894
|
+
"workspace",
|
|
895
|
+
"env",
|
|
896
|
+
"unset",
|
|
897
|
+
"index.js"
|
|
898
|
+
]
|
|
784
899
|
}
|
|
785
900
|
},
|
|
786
|
-
"version": "0.
|
|
901
|
+
"version": "0.10.0"
|
|
787
902
|
}
|