@adobe/aio-cli-plugin-app 14.0.1 → 14.1.1
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 +30 -30
- package/oclif.manifest.json +1 -1
- package/package.json +3 -3
- package/src/BaseCommand.js +2 -2
- package/src/commands/app/build.js +2 -0
- package/src/commands/app/config/get/log-forwarding/errors.js +5 -1
- package/src/commands/app/config/get/log-forwarding.js +4 -1
- package/src/commands/app/config/set/log-forwarding.js +1 -4
- package/src/commands/app/deploy.js +53 -21
- package/src/commands/app/pack.js +1 -1
- package/src/commands/app/undeploy.js +45 -11
- package/src/lib/app-helper.js +108 -33
- package/src/lib/audit-logger.js +135 -98
- package/src/lib/auth-helper.js +64 -30
- package/src/lib/run-dev.js +3 -1
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ DESCRIPTION
|
|
|
74
74
|
Create, run, test, and deploy Adobe I/O Apps
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
_See code: [src/commands/app/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
77
|
+
_See code: [src/commands/app/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/index.js)_
|
|
78
78
|
|
|
79
79
|
## `aio app add`
|
|
80
80
|
|
|
@@ -92,7 +92,7 @@ DESCRIPTION
|
|
|
92
92
|
Add a new component to an existing Adobe I/O App
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
_See code: [src/commands/app/add/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
95
|
+
_See code: [src/commands/app/add/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/add/index.js)_
|
|
96
96
|
|
|
97
97
|
## `aio app add action`
|
|
98
98
|
|
|
@@ -117,7 +117,7 @@ ALIASES
|
|
|
117
117
|
$ aio app add actions
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
_See code: [src/commands/app/add/action.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
120
|
+
_See code: [src/commands/app/add/action.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/add/action.js)_
|
|
121
121
|
|
|
122
122
|
## `aio app add ci`
|
|
123
123
|
|
|
@@ -135,7 +135,7 @@ DESCRIPTION
|
|
|
135
135
|
Add CI files
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
-
_See code: [src/commands/app/add/ci.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
138
|
+
_See code: [src/commands/app/add/ci.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/add/ci.js)_
|
|
139
139
|
|
|
140
140
|
## `aio app add event`
|
|
141
141
|
|
|
@@ -160,7 +160,7 @@ ALIASES
|
|
|
160
160
|
$ aio app add events
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
-
_See code: [src/commands/app/add/event.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
163
|
+
_See code: [src/commands/app/add/event.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/add/event.js)_
|
|
164
164
|
|
|
165
165
|
## `aio app add extension`
|
|
166
166
|
|
|
@@ -186,7 +186,7 @@ ALIASES
|
|
|
186
186
|
$ aio app add extensions
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
_See code: [src/commands/app/add/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
189
|
+
_See code: [src/commands/app/add/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/add/extension.js)_
|
|
190
190
|
|
|
191
191
|
## `aio app add service`
|
|
192
192
|
|
|
@@ -210,7 +210,7 @@ ALIASES
|
|
|
210
210
|
$ aio app add services
|
|
211
211
|
```
|
|
212
212
|
|
|
213
|
-
_See code: [src/commands/app/add/service.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
213
|
+
_See code: [src/commands/app/add/service.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/add/service.js)_
|
|
214
214
|
|
|
215
215
|
## `aio app add web-assets`
|
|
216
216
|
|
|
@@ -231,7 +231,7 @@ DESCRIPTION
|
|
|
231
231
|
Add web assets support
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
-
_See code: [src/commands/app/add/web-assets.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
234
|
+
_See code: [src/commands/app/add/web-assets.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/add/web-assets.js)_
|
|
235
235
|
|
|
236
236
|
## `aio app build`
|
|
237
237
|
|
|
@@ -261,7 +261,7 @@ DESCRIPTION
|
|
|
261
261
|
Use the --force-build flag to force a build even if one already exists.
|
|
262
262
|
```
|
|
263
263
|
|
|
264
|
-
_See code: [src/commands/app/build.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
264
|
+
_See code: [src/commands/app/build.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/build.js)_
|
|
265
265
|
|
|
266
266
|
## `aio app clean`
|
|
267
267
|
|
|
@@ -286,7 +286,7 @@ DESCRIPTION
|
|
|
286
286
|
Note that this will require a full rebuild on your next build command.
|
|
287
287
|
```
|
|
288
288
|
|
|
289
|
-
_See code: [src/commands/app/clean.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
289
|
+
_See code: [src/commands/app/clean.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/clean.js)_
|
|
290
290
|
|
|
291
291
|
## `aio app create [PATH]`
|
|
292
292
|
|
|
@@ -308,7 +308,7 @@ DESCRIPTION
|
|
|
308
308
|
Create a new Adobe I/O App with default parameters
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
-
_See code: [src/commands/app/create.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
311
|
+
_See code: [src/commands/app/create.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/create.js)_
|
|
312
312
|
|
|
313
313
|
## `aio app delete`
|
|
314
314
|
|
|
@@ -326,7 +326,7 @@ DESCRIPTION
|
|
|
326
326
|
Delete a component from an existing Adobe I/O App
|
|
327
327
|
```
|
|
328
328
|
|
|
329
|
-
_See code: [src/commands/app/delete/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
329
|
+
_See code: [src/commands/app/delete/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/delete/index.js)_
|
|
330
330
|
|
|
331
331
|
## `aio app delete action [ACTION-NAME]`
|
|
332
332
|
|
|
@@ -352,7 +352,7 @@ ALIASES
|
|
|
352
352
|
$ aio app delete actions
|
|
353
353
|
```
|
|
354
354
|
|
|
355
|
-
_See code: [src/commands/app/delete/action.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
355
|
+
_See code: [src/commands/app/delete/action.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/delete/action.js)_
|
|
356
356
|
|
|
357
357
|
## `aio app delete ci`
|
|
358
358
|
|
|
@@ -371,7 +371,7 @@ DESCRIPTION
|
|
|
371
371
|
Delete existing CI files
|
|
372
372
|
```
|
|
373
373
|
|
|
374
|
-
_See code: [src/commands/app/delete/ci.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
374
|
+
_See code: [src/commands/app/delete/ci.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/delete/ci.js)_
|
|
375
375
|
|
|
376
376
|
## `aio app delete extension`
|
|
377
377
|
|
|
@@ -397,7 +397,7 @@ ALIASES
|
|
|
397
397
|
$ aio app delete extensions
|
|
398
398
|
```
|
|
399
399
|
|
|
400
|
-
_See code: [src/commands/app/delete/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
400
|
+
_See code: [src/commands/app/delete/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/delete/extension.js)_
|
|
401
401
|
|
|
402
402
|
## `aio app delete service`
|
|
403
403
|
|
|
@@ -421,7 +421,7 @@ ALIASES
|
|
|
421
421
|
$ aio app delete services
|
|
422
422
|
```
|
|
423
423
|
|
|
424
|
-
_See code: [src/commands/app/delete/service.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
424
|
+
_See code: [src/commands/app/delete/service.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/delete/service.js)_
|
|
425
425
|
|
|
426
426
|
## `aio app delete web-assets`
|
|
427
427
|
|
|
@@ -440,7 +440,7 @@ DESCRIPTION
|
|
|
440
440
|
Delete existing web assets
|
|
441
441
|
```
|
|
442
442
|
|
|
443
|
-
_See code: [src/commands/app/delete/web-assets.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
443
|
+
_See code: [src/commands/app/delete/web-assets.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/delete/web-assets.js)_
|
|
444
444
|
|
|
445
445
|
## `aio app deploy`
|
|
446
446
|
|
|
@@ -486,7 +486,7 @@ DESCRIPTION
|
|
|
486
486
|
Use the --force-deploy flag to force deploy changes, regardless of production Workspace being published in Exchange.
|
|
487
487
|
```
|
|
488
488
|
|
|
489
|
-
_See code: [src/commands/app/deploy.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
489
|
+
_See code: [src/commands/app/deploy.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/deploy.js)_
|
|
490
490
|
|
|
491
491
|
## `aio app get-url [ACTION]`
|
|
492
492
|
|
|
@@ -508,7 +508,7 @@ DESCRIPTION
|
|
|
508
508
|
Get action URLs
|
|
509
509
|
```
|
|
510
510
|
|
|
511
|
-
_See code: [src/commands/app/get-url.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
511
|
+
_See code: [src/commands/app/get-url.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/get-url.js)_
|
|
512
512
|
|
|
513
513
|
## `aio app info`
|
|
514
514
|
|
|
@@ -530,7 +530,7 @@ DESCRIPTION
|
|
|
530
530
|
Display settings/configuration in use by an Adobe I/O App
|
|
531
531
|
```
|
|
532
532
|
|
|
533
|
-
_See code: [src/commands/app/info.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
533
|
+
_See code: [src/commands/app/info.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/info.js)_
|
|
534
534
|
|
|
535
535
|
## `aio app init [PATH]`
|
|
536
536
|
|
|
@@ -569,7 +569,7 @@ DESCRIPTION
|
|
|
569
569
|
Create a new Adobe I/O App
|
|
570
570
|
```
|
|
571
571
|
|
|
572
|
-
_See code: [src/commands/app/init.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
572
|
+
_See code: [src/commands/app/init.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/init.js)_
|
|
573
573
|
|
|
574
574
|
## `aio app install PATH`
|
|
575
575
|
|
|
@@ -592,7 +592,7 @@ DESCRIPTION
|
|
|
592
592
|
This command will support installing apps packaged by 'aio app pack'.
|
|
593
593
|
```
|
|
594
594
|
|
|
595
|
-
_See code: [src/commands/app/install.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
595
|
+
_See code: [src/commands/app/install.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/install.js)_
|
|
596
596
|
|
|
597
597
|
## `aio app list`
|
|
598
598
|
|
|
@@ -610,7 +610,7 @@ DESCRIPTION
|
|
|
610
610
|
List components for Adobe I/O App
|
|
611
611
|
```
|
|
612
612
|
|
|
613
|
-
_See code: [src/commands/app/list/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
613
|
+
_See code: [src/commands/app/list/index.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/list/index.js)_
|
|
614
614
|
|
|
615
615
|
## `aio app list extension`
|
|
616
616
|
|
|
@@ -635,7 +635,7 @@ ALIASES
|
|
|
635
635
|
$ aio app list extensions
|
|
636
636
|
```
|
|
637
637
|
|
|
638
|
-
_See code: [src/commands/app/list/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
638
|
+
_See code: [src/commands/app/list/extension.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/list/extension.js)_
|
|
639
639
|
|
|
640
640
|
## `aio app logs`
|
|
641
641
|
|
|
@@ -659,7 +659,7 @@ DESCRIPTION
|
|
|
659
659
|
Fetch logs for an Adobe I/O App
|
|
660
660
|
```
|
|
661
661
|
|
|
662
|
-
_See code: [src/commands/app/logs.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
662
|
+
_See code: [src/commands/app/logs.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/logs.js)_
|
|
663
663
|
|
|
664
664
|
## `aio app pack [PATH]`
|
|
665
665
|
|
|
@@ -681,7 +681,7 @@ DESCRIPTION
|
|
|
681
681
|
This command will support packaging apps for redistribution.
|
|
682
682
|
```
|
|
683
683
|
|
|
684
|
-
_See code: [src/commands/app/pack.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
684
|
+
_See code: [src/commands/app/pack.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/pack.js)_
|
|
685
685
|
|
|
686
686
|
## `aio app run`
|
|
687
687
|
|
|
@@ -703,7 +703,7 @@ DESCRIPTION
|
|
|
703
703
|
Run an Adobe I/O App
|
|
704
704
|
```
|
|
705
705
|
|
|
706
|
-
_See code: [src/commands/app/run.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
706
|
+
_See code: [src/commands/app/run.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/run.js)_
|
|
707
707
|
|
|
708
708
|
## `aio app test`
|
|
709
709
|
|
|
@@ -731,7 +731,7 @@ DESCRIPTION
|
|
|
731
731
|
If the extension has a hook called 'test' in its 'ext.config.yaml', the script specified will be run instead.
|
|
732
732
|
```
|
|
733
733
|
|
|
734
|
-
_See code: [src/commands/app/test.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
734
|
+
_See code: [src/commands/app/test.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/test.js)_
|
|
735
735
|
|
|
736
736
|
## `aio app undeploy`
|
|
737
737
|
|
|
@@ -756,7 +756,7 @@ DESCRIPTION
|
|
|
756
756
|
Undeploys an Adobe I/O App
|
|
757
757
|
```
|
|
758
758
|
|
|
759
|
-
_See code: [src/commands/app/undeploy.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
759
|
+
_See code: [src/commands/app/undeploy.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/undeploy.js)_
|
|
760
760
|
|
|
761
761
|
## `aio app use [CONFIG_FILE_PATH]`
|
|
762
762
|
|
|
@@ -803,5 +803,5 @@ DESCRIPTION
|
|
|
803
803
|
page in https://developer.adobe.com/console/
|
|
804
804
|
```
|
|
805
805
|
|
|
806
|
-
_See code: [src/commands/app/use.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.
|
|
806
|
+
_See code: [src/commands/app/use.js](https://github.com/adobe/aio-cli-plugin-app/blob/14.1.1/src/commands/app/use.js)_
|
|
807
807
|
<!-- commandsstop -->
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/aio-cli-plugin-app",
|
|
3
3
|
"description": "Create, Build and Deploy Adobe I/O Applications",
|
|
4
|
-
"version": "14.
|
|
4
|
+
"version": "14.1.1",
|
|
5
5
|
"author": "Adobe Inc.",
|
|
6
6
|
"bugs": "https://github.com/adobe/aio-cli-plugin-app/issues",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@adobe/aio-cli-lib-app-config": "^4.0.3",
|
|
9
|
-
"@adobe/aio-cli-lib-console": "^5",
|
|
9
|
+
"@adobe/aio-cli-lib-console": "^5.0.3",
|
|
10
10
|
"@adobe/aio-lib-core-config": "^5",
|
|
11
11
|
"@adobe/aio-lib-core-logging": "^3",
|
|
12
12
|
"@adobe/aio-lib-core-networking": "^5",
|
|
13
13
|
"@adobe/aio-lib-env": "^3",
|
|
14
14
|
"@adobe/aio-lib-ims": "^7",
|
|
15
|
-
"@adobe/aio-lib-runtime": "^7.1.
|
|
15
|
+
"@adobe/aio-lib-runtime": "^7.1.2",
|
|
16
16
|
"@adobe/aio-lib-templates": "^3",
|
|
17
17
|
"@adobe/aio-lib-web": "^7",
|
|
18
18
|
"@adobe/generator-aio-app": "^9",
|
package/src/BaseCommand.js
CHANGED
|
@@ -21,7 +21,7 @@ const STAGE_LAUNCH_PREFIX = 'https://experience-stage.adobe.com/?devMode=true#/c
|
|
|
21
21
|
const appConfig = require('@adobe/aio-cli-lib-app-config')
|
|
22
22
|
const inquirer = require('inquirer')
|
|
23
23
|
const { CONSOLE_API_KEYS, APPLICATION_CONFIG_KEY, EXTENSIONS_CONFIG_KEY } = require('./lib/defaults')
|
|
24
|
-
const {
|
|
24
|
+
const { getAccessToken } = require('./lib/auth-helper')
|
|
25
25
|
const LibConsoleCLI = require('@adobe/aio-cli-lib-console')
|
|
26
26
|
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app', { provider: 'debug' })
|
|
27
27
|
|
|
@@ -54,7 +54,7 @@ class BaseCommand extends Command {
|
|
|
54
54
|
async getLibConsoleCLI () {
|
|
55
55
|
if (!this.consoleCLI) {
|
|
56
56
|
// requires valid login
|
|
57
|
-
const { accessToken, env } = await
|
|
57
|
+
const { accessToken, env } = await getAccessToken()
|
|
58
58
|
// init console CLI sdk consoleCLI
|
|
59
59
|
this.consoleCLI = await LibConsoleCLI.init({ accessToken, env, apiKey: CONSOLE_API_KEYS[env] })
|
|
60
60
|
}
|
|
@@ -102,6 +102,8 @@ class Build extends BaseCommand {
|
|
|
102
102
|
if (flags['web-assets']) {
|
|
103
103
|
if (config.app.hasFrontend && (flags['force-build'] || !fs.existsSync(config.web.distProd))) {
|
|
104
104
|
if (config.app.hasBackend) {
|
|
105
|
+
// note: 3rd arg, _isLocalDev is not used in RuntimeLib
|
|
106
|
+
// there is no such thing as --local anymore
|
|
105
107
|
const urls = RuntimeLib.utils.getActionUrls(config, false, false, true)
|
|
106
108
|
await writeConfig(config.web.injectedConfig, urls)
|
|
107
109
|
}
|
|
@@ -12,6 +12,7 @@ governing permissions and limitations under the License.
|
|
|
12
12
|
const BaseCommand = require('../../../../../BaseCommand')
|
|
13
13
|
const rtLib = require('@adobe/aio-lib-runtime')
|
|
14
14
|
const ora = require('ora')
|
|
15
|
+
const { setRuntimeApiHostAndAuthHandler } = require('../../../../../lib/auth-helper')
|
|
15
16
|
|
|
16
17
|
class ErrorsCommand extends BaseCommand {
|
|
17
18
|
async run () {
|
|
@@ -30,7 +31,10 @@ class ErrorsCommand extends BaseCommand {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
async getLogForwarding () {
|
|
33
|
-
|
|
34
|
+
let aioConfig = (await this.getFullConfig()).aio
|
|
35
|
+
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
|
|
36
|
+
|
|
37
|
+
const runtimeConfig = aioConfig.runtime
|
|
34
38
|
rtLib.utils.checkOpenWhiskCredentials({ ow: runtimeConfig })
|
|
35
39
|
const rt = await rtLib.init({
|
|
36
40
|
...runtimeConfig,
|
|
@@ -11,10 +11,13 @@ governing permissions and limitations under the License.
|
|
|
11
11
|
|
|
12
12
|
const BaseCommand = require('../../../../BaseCommand')
|
|
13
13
|
const LogForwarding = require('../../../../lib/log-forwarding')
|
|
14
|
+
const { setRuntimeApiHostAndAuthHandler } = require('../../../../lib/auth-helper')
|
|
14
15
|
|
|
15
16
|
class LogForwardingCommand extends BaseCommand {
|
|
16
17
|
async run () {
|
|
17
|
-
|
|
18
|
+
let aioConfig = (await this.getFullConfig()).aio
|
|
19
|
+
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
|
|
20
|
+
const lf = await LogForwarding.init(aioConfig)
|
|
18
21
|
|
|
19
22
|
const localConfig = lf.getLocalConfig()
|
|
20
23
|
const serverConfig = await lf.getServerConfig()
|
|
@@ -17,10 +17,7 @@ const { setRuntimeApiHostAndAuthHandler } = require('../../../../lib/auth-helper
|
|
|
17
17
|
class LogForwardingCommand extends BaseCommand {
|
|
18
18
|
async run () {
|
|
19
19
|
let aioConfig = (await this.getFullConfig()).aio
|
|
20
|
-
|
|
21
|
-
if (process.env.IS_DEPLOY_SERVICE_ENABLED === 'true') {
|
|
22
|
-
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
|
|
23
|
-
}
|
|
20
|
+
aioConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
|
|
24
21
|
const lf = await LogForwarding.init(aioConfig)
|
|
25
22
|
|
|
26
23
|
const destination = await this.promptDestination(lf.getSupportedDestinations())
|
|
@@ -18,11 +18,15 @@ const BaseCommand = require('../../BaseCommand')
|
|
|
18
18
|
const BuildCommand = require('./build')
|
|
19
19
|
const webLib = require('@adobe/aio-lib-web')
|
|
20
20
|
const { Flags } = require('@oclif/core')
|
|
21
|
-
const {
|
|
21
|
+
const {
|
|
22
|
+
rewriteActionUrlInEntities, runInProcess,
|
|
23
|
+
buildExtensionPointPayloadWoMetadata, buildExcShellViewExtensionMetadata,
|
|
24
|
+
getFilesCountWithExtension
|
|
25
|
+
} = require('../../lib/app-helper')
|
|
22
26
|
const rtLib = require('@adobe/aio-lib-runtime')
|
|
23
27
|
const LogForwarding = require('../../lib/log-forwarding')
|
|
24
|
-
const {
|
|
25
|
-
const { setRuntimeApiHostAndAuthHandler } = require('../../lib/auth-helper')
|
|
28
|
+
const { sendAppAssetsDeployedAuditLog, sendAppDeployAuditLog } = require('../../lib/audit-logger')
|
|
29
|
+
const { setRuntimeApiHostAndAuthHandler, getAccessToken } = require('../../lib/auth-helper')
|
|
26
30
|
const logActions = require('../../lib/log-actions')
|
|
27
31
|
|
|
28
32
|
const PRE_DEPLOY_EVENT_REG = 'pre-deploy-event-reg'
|
|
@@ -53,15 +57,40 @@ class Deploy extends BuildCommand {
|
|
|
53
57
|
const spinner = ora()
|
|
54
58
|
|
|
55
59
|
try {
|
|
56
|
-
const aioConfig =
|
|
57
|
-
const cliDetails = await
|
|
60
|
+
const { aio: aioConfig, packagejson: packageJson } = await this.getFullConfig()
|
|
61
|
+
const cliDetails = await getAccessToken({ useCachedToken: flags.publish })
|
|
62
|
+
const appInfo = {
|
|
63
|
+
name: packageJson.name,
|
|
64
|
+
version: packageJson.version,
|
|
65
|
+
project: aioConfig?.project,
|
|
66
|
+
runtimeNamespace: aioConfig?.runtime?.namespace
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (cliDetails?.accessToken) {
|
|
70
|
+
try {
|
|
71
|
+
// send audit log at start (don't wait for deployment to finish)
|
|
72
|
+
await sendAppDeployAuditLog({
|
|
73
|
+
accessToken: cliDetails?.accessToken,
|
|
74
|
+
cliCommandFlags: flags,
|
|
75
|
+
appInfo,
|
|
76
|
+
env: cliDetails.env
|
|
77
|
+
})
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (flags.verbose) {
|
|
80
|
+
this.warn('Error: Audit Log Service Error: Failed to send audit log event for deployment.')
|
|
81
|
+
this.warn(error.message)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
58
85
|
|
|
59
86
|
// 1. update log forwarding configuration
|
|
60
87
|
// note: it is possible that .aio file does not exist, which means there is no local lg config
|
|
61
88
|
if (aioConfig?.project?.workspace && flags['log-forwarding-update'] && flags.actions) {
|
|
62
89
|
spinner.start('Updating log forwarding configuration')
|
|
63
90
|
try {
|
|
64
|
-
const
|
|
91
|
+
const lfConfig = setRuntimeApiHostAndAuthHandler(aioConfig)
|
|
92
|
+
|
|
93
|
+
const lf = await LogForwarding.init(lfConfig)
|
|
65
94
|
if (lf.isLocalConfigChanged()) {
|
|
66
95
|
const lfConfig = lf.getLocalConfigWithSecrets()
|
|
67
96
|
if (lfConfig.isDefined()) {
|
|
@@ -103,20 +132,22 @@ class Deploy extends BuildCommand {
|
|
|
103
132
|
const k = keys[i]
|
|
104
133
|
const v = setRuntimeApiHostAndAuthHandler(values[i])
|
|
105
134
|
|
|
106
|
-
await this.deploySingleConfig(k, v, flags, spinner)
|
|
107
|
-
if (v.app.hasFrontend && flags['web-assets']) {
|
|
135
|
+
await this.deploySingleConfig({ name: k, config: v, originalConfig: values[i], flags, spinner })
|
|
136
|
+
if (cliDetails?.accessToken && v.app.hasFrontend && flags['web-assets']) {
|
|
108
137
|
const opItems = getFilesCountWithExtension(v.web.distProd)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
138
|
+
try {
|
|
139
|
+
// only send logs in case of web-assets deployment
|
|
140
|
+
await sendAppAssetsDeployedAuditLog({
|
|
141
|
+
accessToken: cliDetails?.accessToken,
|
|
142
|
+
cliCommandFlags: flags,
|
|
143
|
+
opItems,
|
|
144
|
+
appInfo,
|
|
145
|
+
env: cliDetails.env
|
|
146
|
+
})
|
|
147
|
+
} catch (error) {
|
|
148
|
+
if (flags.verbose) {
|
|
149
|
+
this.warn('Error: Audit Log Service Error: Failed to send audit log event for deployment.')
|
|
150
|
+
this.warn(error.message)
|
|
120
151
|
}
|
|
121
152
|
}
|
|
122
153
|
}
|
|
@@ -140,7 +171,7 @@ class Deploy extends BuildCommand {
|
|
|
140
171
|
this.log(chalk.green(chalk.bold('Successful deployment 🏄')))
|
|
141
172
|
}
|
|
142
173
|
|
|
143
|
-
async deploySingleConfig (name, config, flags, spinner) {
|
|
174
|
+
async deploySingleConfig ({ name, config, originalConfig, flags, spinner }) {
|
|
144
175
|
const onProgress = !flags.verbose
|
|
145
176
|
? info => {
|
|
146
177
|
spinner.text = info
|
|
@@ -240,7 +271,8 @@ class Deploy extends BuildCommand {
|
|
|
240
271
|
|
|
241
272
|
// log deployed resources
|
|
242
273
|
if (deployedRuntimeEntities.actions && deployedRuntimeEntities.actions.length > 0) {
|
|
243
|
-
await
|
|
274
|
+
const entities = await rewriteActionUrlInEntities({ entities: deployedRuntimeEntities, config: originalConfig })
|
|
275
|
+
await logActions({ entities, log: (...rest) => this.log(chalk.bold(chalk.blue(...rest))) })
|
|
244
276
|
}
|
|
245
277
|
|
|
246
278
|
// TODO urls should depend on extension point, exc shell only for exc shell extension point - use a post-app-deploy hook ?
|
package/src/commands/app/pack.js
CHANGED
|
@@ -177,7 +177,7 @@ class Pack extends BaseCommand {
|
|
|
177
177
|
this.spinner.succeed('Got api-mesh config')
|
|
178
178
|
} catch (err) {
|
|
179
179
|
// Ignore error if no mesh found, otherwise throw
|
|
180
|
-
if (err?.message.includes('Error: Unable to get mesh config.
|
|
180
|
+
if (err?.message.includes('Error: Unable to get mesh config.')) {
|
|
181
181
|
aioLogger.debug('No api-mesh config found')
|
|
182
182
|
} else {
|
|
183
183
|
console.error(err)
|
|
@@ -17,10 +17,10 @@ const { Flags } = require('@oclif/core')
|
|
|
17
17
|
|
|
18
18
|
const BaseCommand = require('../../BaseCommand')
|
|
19
19
|
const webLib = require('@adobe/aio-lib-web')
|
|
20
|
-
const { runInProcess, buildExtensionPointPayloadWoMetadata
|
|
20
|
+
const { runInProcess, buildExtensionPointPayloadWoMetadata } = require('../../lib/app-helper')
|
|
21
21
|
const rtLib = require('@adobe/aio-lib-runtime')
|
|
22
|
-
const {
|
|
23
|
-
const { setRuntimeApiHostAndAuthHandler } = require('../../lib/auth-helper')
|
|
22
|
+
const { sendAppAssetsUndeployedAuditLog, sendAppUndeployAuditLog } = require('../../lib/audit-logger')
|
|
23
|
+
const { setRuntimeApiHostAndAuthHandler, getAccessToken } = require('../../lib/auth-helper')
|
|
24
24
|
|
|
25
25
|
class Undeploy extends BaseCommand {
|
|
26
26
|
async run () {
|
|
@@ -51,20 +51,47 @@ class Undeploy extends BaseCommand {
|
|
|
51
51
|
|
|
52
52
|
const spinner = ora()
|
|
53
53
|
try {
|
|
54
|
-
const aioConfig =
|
|
55
|
-
const cliDetails = await
|
|
54
|
+
const { aio: aioConfig, packagejson: packageJson } = await this.getFullConfig()
|
|
55
|
+
const cliDetails = await getAccessToken({ useCachedToken: flags.unpublish })
|
|
56
|
+
const appInfo = {
|
|
57
|
+
name: packageJson.name,
|
|
58
|
+
version: packageJson.version,
|
|
59
|
+
project: aioConfig?.project,
|
|
60
|
+
runtimeNamespace: aioConfig?.runtime?.namespace
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (cliDetails?.accessToken) {
|
|
64
|
+
try {
|
|
65
|
+
// send audit log at start (don't wait for deployment to finish)
|
|
66
|
+
await sendAppUndeployAuditLog({
|
|
67
|
+
accessToken: cliDetails?.accessToken,
|
|
68
|
+
cliCommandFlags: flags,
|
|
69
|
+
appInfo,
|
|
70
|
+
env: cliDetails.env
|
|
71
|
+
})
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if (flags.verbose) {
|
|
74
|
+
this.warn('Error: Audit Log Service Error: Failed to send audit log event for deployment.')
|
|
75
|
+
this.warn(error.message)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
56
79
|
|
|
57
80
|
for (let i = 0; i < keys.length; ++i) {
|
|
58
81
|
const k = keys[i]
|
|
59
82
|
// TODO: remove this check once the deploy service is enabled by default
|
|
60
|
-
const v =
|
|
83
|
+
const v = setRuntimeApiHostAndAuthHandler(values[i])
|
|
61
84
|
|
|
62
85
|
await this.undeployOneExt(k, v, flags, spinner)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (assetUndeployLogEvent && cliDetails?.accessToken) {
|
|
86
|
+
if (cliDetails?.accessToken) {
|
|
87
|
+
// send logs for case of web-assets undeployment
|
|
66
88
|
try {
|
|
67
|
-
await
|
|
89
|
+
await sendAppAssetsUndeployedAuditLog({
|
|
90
|
+
accessToken: cliDetails?.accessToken,
|
|
91
|
+
cliCommandFlags: flags,
|
|
92
|
+
appInfo,
|
|
93
|
+
env: cliDetails.env
|
|
94
|
+
})
|
|
68
95
|
} catch (error) {
|
|
69
96
|
this.warn('Warning: Audit Log Service Error: Failed to send audit log event for un-deployment.')
|
|
70
97
|
}
|
|
@@ -83,8 +110,15 @@ class Undeploy extends BaseCommand {
|
|
|
83
110
|
// delegate to top handler
|
|
84
111
|
throw error
|
|
85
112
|
}
|
|
113
|
+
|
|
114
|
+
const command = await this.config.findCommand('app:clean')
|
|
115
|
+
if (command) {
|
|
116
|
+
this.log('running app:clean command')
|
|
117
|
+
await this.config.runCommand('app:clean')
|
|
118
|
+
}
|
|
119
|
+
|
|
86
120
|
// final message
|
|
87
|
-
this.log(chalk.green(chalk.bold('Undeploy done
|
|
121
|
+
this.log(chalk.green(chalk.bold('Undeploy done!')))
|
|
88
122
|
}
|
|
89
123
|
|
|
90
124
|
async undeployOneExt (extName, config, flags, spinner) {
|
package/src/lib/app-helper.js
CHANGED
|
@@ -11,16 +11,13 @@ governing permissions and limitations under the License.
|
|
|
11
11
|
|
|
12
12
|
const execa = require('execa')
|
|
13
13
|
const fs = require('fs-extra')
|
|
14
|
-
const path = require('path')
|
|
14
|
+
const path = require('node:path')
|
|
15
15
|
const which = require('which')
|
|
16
16
|
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:lib-app-helper', { provider: 'debug' })
|
|
17
|
-
const { getToken, context } = require('@adobe/aio-lib-ims')
|
|
18
|
-
const { CLI } = require('@adobe/aio-lib-ims/src/context')
|
|
19
17
|
const chalk = require('chalk')
|
|
20
18
|
const aioConfig = require('@adobe/aio-lib-core-config')
|
|
21
19
|
const { AIO_CONFIG_WORKSPACE_SERVICES, AIO_CONFIG_ORG_SERVICES } = require('./defaults')
|
|
22
20
|
const { EOL } = require('os')
|
|
23
|
-
const { getCliEnv } = require('@adobe/aio-lib-env')
|
|
24
21
|
const yaml = require('js-yaml')
|
|
25
22
|
const RuntimeLib = require('@adobe/aio-lib-runtime')
|
|
26
23
|
|
|
@@ -179,33 +176,6 @@ function wrapError (err) {
|
|
|
179
176
|
return new Error(message)
|
|
180
177
|
}
|
|
181
178
|
|
|
182
|
-
/**
|
|
183
|
-
* getCliInfo
|
|
184
|
-
*
|
|
185
|
-
* @private
|
|
186
|
-
*
|
|
187
|
-
* @param {boolean} useForce - if true, user will be forced to login if not already logged in
|
|
188
|
-
* @returns {Promise<{accessToken: string, env: string}>} accessToken and env
|
|
189
|
-
*/
|
|
190
|
-
async function getCliInfo (useForce = true) {
|
|
191
|
-
const env = getCliEnv()
|
|
192
|
-
let accessToken
|
|
193
|
-
await context.setCli({ 'cli.bare-output': true }, false) // set this globally
|
|
194
|
-
if (useForce) {
|
|
195
|
-
aioLogger.debug('Retrieving CLI Token using force=true')
|
|
196
|
-
accessToken = await getToken(CLI)
|
|
197
|
-
} else {
|
|
198
|
-
aioLogger.debug('Retrieving CLI Token using force=false')
|
|
199
|
-
// in this case, the user might be logged in, but we don't want to force them
|
|
200
|
-
// we just check the config for the token ( we still use the cli context so we don't need to know
|
|
201
|
-
// the inner workings of ims-lib and where it stores access tokens)
|
|
202
|
-
// todo: this is a workaround, we should have a better way to check if the user is logged in (in ims-lib)
|
|
203
|
-
const contextConfig = await context.getCli()
|
|
204
|
-
accessToken = contextConfig?.access_token?.token
|
|
205
|
-
}
|
|
206
|
-
return { accessToken, env }
|
|
207
|
-
}
|
|
208
|
-
|
|
209
179
|
/**
|
|
210
180
|
* Joins url path parts
|
|
211
181
|
*
|
|
@@ -391,6 +361,8 @@ function buildExtensionPointPayloadWoMetadata (extConfigs) {
|
|
|
391
361
|
endpointsPayload[extPointName] = {}
|
|
392
362
|
let actionUrls = {}
|
|
393
363
|
if (extPointConfig.app.hasBackend) {
|
|
364
|
+
// note: 3rd arg, _isLocalDev is not used in RuntimeLib
|
|
365
|
+
// there is no such thing as --local anymore
|
|
394
366
|
actionUrls = RuntimeLib.utils.getActionUrls(extPointConfig, false, false)
|
|
395
367
|
}
|
|
396
368
|
Object.entries(extPointConfig.operations)
|
|
@@ -473,7 +445,110 @@ function getObjectValue (obj, key) {
|
|
|
473
445
|
return keys.filter(o => o.trim()).reduce((o, i) => o && getObjectProp(o, i), obj)
|
|
474
446
|
}
|
|
475
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Counts files by extension in a directory
|
|
450
|
+
*
|
|
451
|
+
* @param {string} directory Path to assets directory
|
|
452
|
+
* @returns {Array<string>} Array of formatted log messages
|
|
453
|
+
*/
|
|
454
|
+
function getFilesCountWithExtension (directory) {
|
|
455
|
+
const log = []
|
|
456
|
+
|
|
457
|
+
if (!fs.existsSync(directory)) {
|
|
458
|
+
throw new Error(`Error: Directory ${directory} does not exist.`)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const files = fs.readdirSync(directory, { recursive: true })
|
|
462
|
+
if (files.length === 0) {
|
|
463
|
+
throw new Error(`Error: No files found in directory ${directory}.`)
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const fileTypeCounts = {}
|
|
467
|
+
files.forEach(file => {
|
|
468
|
+
const ext = path.extname(file).toLowerCase() || 'no extension'
|
|
469
|
+
if (fileTypeCounts[ext]) {
|
|
470
|
+
fileTypeCounts[ext]++
|
|
471
|
+
} else {
|
|
472
|
+
fileTypeCounts[ext] = 1
|
|
473
|
+
}
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
Object.keys(fileTypeCounts).forEach(ext => {
|
|
477
|
+
const count = fileTypeCounts[ext]
|
|
478
|
+
let description
|
|
479
|
+
switch (ext) {
|
|
480
|
+
case '.js':
|
|
481
|
+
description = 'Javascript file(s)'
|
|
482
|
+
break
|
|
483
|
+
case '.css':
|
|
484
|
+
description = 'CSS file(s)'
|
|
485
|
+
break
|
|
486
|
+
case '.html':
|
|
487
|
+
description = 'HTML page(s)'
|
|
488
|
+
break
|
|
489
|
+
case '.png':
|
|
490
|
+
case '.jpg':
|
|
491
|
+
case '.jpeg':
|
|
492
|
+
case '.gif':
|
|
493
|
+
case '.svg':
|
|
494
|
+
case '.webp':
|
|
495
|
+
description = `${ext} image(s)`
|
|
496
|
+
break
|
|
497
|
+
case 'no extension':
|
|
498
|
+
description = 'file(s) without extension'
|
|
499
|
+
break
|
|
500
|
+
default:
|
|
501
|
+
description = `${ext} file(s)`
|
|
502
|
+
}
|
|
503
|
+
log.push(`${count} ${description}\n`)
|
|
504
|
+
})
|
|
505
|
+
|
|
506
|
+
return log
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Rewrites action URLs in deployed runtime entities using URLs from the manifest configuration.
|
|
511
|
+
*
|
|
512
|
+
* This function takes deployed runtime entities and updates the URL property of each action
|
|
513
|
+
* with the corresponding URL from the runtime manifest configuration. It creates a deep copy
|
|
514
|
+
* of the entities to avoid mutating the original object.
|
|
515
|
+
*
|
|
516
|
+
* @param {object} params - Parameters object
|
|
517
|
+
* @param {object} params.entities - The deployed runtime entities object
|
|
518
|
+
* @param {object} params.config - The application configuration object containing runtime manifest
|
|
519
|
+
* @returns {Promise<object>} A promise that resolves to a deep copy of the entities object with updated action URLs
|
|
520
|
+
* @example
|
|
521
|
+
* const entities = {
|
|
522
|
+
* actions: [
|
|
523
|
+
* { name: 'my-action', url: 'old-url' },
|
|
524
|
+
* { name: 'another-action', url: 'another-old-url' }
|
|
525
|
+
* ]
|
|
526
|
+
* }
|
|
527
|
+
* const config = {
|
|
528
|
+
* actions: { devRemote: false },
|
|
529
|
+
* // ... other config properties
|
|
530
|
+
* }
|
|
531
|
+
*
|
|
532
|
+
* const rewrittenEntities = await rewriteActionUrlInEntities({ entities, config })
|
|
533
|
+
* // rewrittenEntities.actions will have updated URLs from the manifest
|
|
534
|
+
*/
|
|
535
|
+
async function rewriteActionUrlInEntities ({ entities, config }) {
|
|
536
|
+
const actionUrlsFromManifest = RuntimeLib.utils.getActionUrls(config, config.actions.devRemote)
|
|
537
|
+
const rewrittenEntities = structuredClone(entities)
|
|
538
|
+
|
|
539
|
+
rewrittenEntities.actions = rewrittenEntities.actions?.map(action => {
|
|
540
|
+
const retAction = structuredClone(action)
|
|
541
|
+
const url = actionUrlsFromManifest[action.name]
|
|
542
|
+
if (url) {
|
|
543
|
+
retAction.url = url
|
|
544
|
+
}
|
|
545
|
+
return retAction
|
|
546
|
+
})
|
|
547
|
+
return rewrittenEntities
|
|
548
|
+
}
|
|
549
|
+
|
|
476
550
|
module.exports = {
|
|
551
|
+
rewriteActionUrlInEntities,
|
|
477
552
|
getObjectValue,
|
|
478
553
|
getObjectProp,
|
|
479
554
|
createWebExportFilter,
|
|
@@ -484,7 +559,6 @@ module.exports = {
|
|
|
484
559
|
runInProcess,
|
|
485
560
|
runPackageScript,
|
|
486
561
|
wrapError,
|
|
487
|
-
getCliInfo,
|
|
488
562
|
removeProtocolFromURL,
|
|
489
563
|
urlJoin,
|
|
490
564
|
checkFile,
|
|
@@ -496,5 +570,6 @@ module.exports = {
|
|
|
496
570
|
buildExtensionPointPayloadWoMetadata,
|
|
497
571
|
buildExcShellViewExtensionMetadata,
|
|
498
572
|
atLeastOne,
|
|
499
|
-
deleteUserConfig
|
|
573
|
+
deleteUserConfig,
|
|
574
|
+
getFilesCountWithExtension
|
|
500
575
|
}
|
package/src/lib/audit-logger.js
CHANGED
|
@@ -8,38 +8,74 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
8
8
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
9
9
|
governing permissions and limitations under the License.
|
|
10
10
|
*/
|
|
11
|
-
const fs = require('fs')
|
|
12
|
-
const path = require('path')
|
|
13
|
-
const chalk = require('chalk')
|
|
14
11
|
|
|
15
12
|
const OPERATIONS = {
|
|
16
13
|
AB_APP_DEPLOY: 'ab_app_deploy',
|
|
17
14
|
AB_APP_UNDEPLOY: 'ab_app_undeploy',
|
|
18
|
-
AB_APP_TEST: 'ab_app_test',
|
|
19
15
|
AB_APP_ASSETS_DEPLOYED: 'ab_app_assets_deployed',
|
|
20
16
|
AB_APP_ASSETS_UNDEPLOYED: 'ab_app_assets_undeployed'
|
|
21
17
|
}
|
|
22
18
|
|
|
19
|
+
const AUDIT_SERVICE_ENDPOINT_ROUTE = '/audit-log-api/event-post'
|
|
23
20
|
const AUDIT_SERVICE_ENDPOINTS = {
|
|
24
|
-
stage: 'https://
|
|
25
|
-
prod: 'https://
|
|
21
|
+
stage: 'https://deploy-service.stg.app-builder.corp.adp.adobe.io',
|
|
22
|
+
prod: 'https://deploy-service.app-builder.adp.adobe.io'
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
/**
|
|
29
|
-
*
|
|
30
|
-
* @
|
|
31
|
-
* @
|
|
32
|
-
* @
|
|
26
|
+
* @typedef {object} AppInfo
|
|
27
|
+
* @property {string} name - Application name
|
|
28
|
+
* @property {string} version - Application version
|
|
29
|
+
* @property {object} project - Project details containing org and workspace information
|
|
30
|
+
* @property {object} namespace - the runtime namespace
|
|
33
31
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @typedef {object} AuditLogParams
|
|
35
|
+
* @property {string} accessToken - Valid access token for authentication
|
|
36
|
+
* @property {object} cliCommandFlags - CLI command flags and options
|
|
37
|
+
* @property {AppInfo} appInfo - Application information including project details, name, and version
|
|
38
|
+
* @property {Array} [opItems] - List of deployed files (only for assets deployment)
|
|
39
|
+
* @property {string} [env='prod'] - Environment to use: 'stage' or 'prod'
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {object} PublishAuditLogParams
|
|
44
|
+
* @property {string} accessToken - Valid access token for authentication
|
|
45
|
+
* @property {object} logEvent - Audit log event details to be published
|
|
46
|
+
* @property {string} [env='prod'] - Environment to use: 'stage' or 'prod'
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {object} GetAuditLogEventParams
|
|
51
|
+
* @property {object} cliCommandFlags - CLI command flags and options
|
|
52
|
+
* @property {AppInfo} appInfo - Application information containing project details, name, version, and optional runtime namespace
|
|
53
|
+
* @property {string} operation - Operation type: 'ab_app_deploy', 'ab_app_undeploy', 'ab_app_assets_deployed', or 'ab_app_assets_undeployed'
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Publish audit log events to audit service
|
|
58
|
+
*
|
|
59
|
+
* @param {PublishAuditLogParams} params - Parameters object containing access token, log event, and environment
|
|
60
|
+
* @returns {Promise<void>} Promise that resolves when the audit log is sent successfully
|
|
61
|
+
* @throws {Error} If the audit log request fails
|
|
62
|
+
*/
|
|
63
|
+
async function publishAuditLogs ({ accessToken, logEvent, env = 'prod' }) {
|
|
64
|
+
let url = AUDIT_SERVICE_ENDPOINTS[env] ?? AUDIT_SERVICE_ENDPOINTS.prod
|
|
65
|
+
if (process.env.AIO_DEPLOY_SERVICE_URL) {
|
|
66
|
+
url = process.env.AIO_DEPLOY_SERVICE_URL
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// add the route to the endpoint
|
|
70
|
+
url += AUDIT_SERVICE_ENDPOINT_ROUTE
|
|
71
|
+
|
|
36
72
|
const payload = {
|
|
37
73
|
event: logEvent
|
|
38
74
|
}
|
|
39
75
|
const options = {
|
|
40
76
|
method: 'POST',
|
|
41
77
|
headers: {
|
|
42
|
-
Authorization:
|
|
78
|
+
Authorization: `Bearer ${accessToken}`,
|
|
43
79
|
'Content-type': 'application/json'
|
|
44
80
|
},
|
|
45
81
|
body: JSON.stringify(payload)
|
|
@@ -47,111 +83,112 @@ async function sendAuditLogs (accessToken, logEvent, env = 'prod') {
|
|
|
47
83
|
const response = await fetch(url, options)
|
|
48
84
|
if (response.status !== 200) {
|
|
49
85
|
const err = await response.text()
|
|
50
|
-
throw new Error(
|
|
86
|
+
throw new Error(`Failed to send audit log - ${response.status} ${err}`)
|
|
51
87
|
}
|
|
52
88
|
}
|
|
53
89
|
|
|
54
90
|
/**
|
|
91
|
+
* Creates an audit log event object
|
|
55
92
|
*
|
|
56
|
-
* @param {
|
|
57
|
-
* @
|
|
58
|
-
* @
|
|
59
|
-
* @returns {object} logEvent
|
|
93
|
+
* @param {GetAuditLogEventParams} params - Parameters object containing CLI flags, operation type, and app info
|
|
94
|
+
* @returns {object} Log event object containing audit log details
|
|
95
|
+
* @throws {Error} If project is missing, or if operation is invalid
|
|
60
96
|
*/
|
|
61
|
-
function getAuditLogEvent (
|
|
62
|
-
|
|
63
|
-
if (project && project.org && project.workspace) {
|
|
64
|
-
if (event === 'AB_APP_DEPLOY') {
|
|
65
|
-
logStrMsg = `Starting deployment for the App Builder application in workspace ${project.workspace.name}`
|
|
66
|
-
} else if (event === 'AB_APP_UNDEPLOY') {
|
|
67
|
-
logStrMsg = `Starting undeployment for the App Builder application in workspace ${project.workspace.name}`
|
|
68
|
-
} else if (event === 'AB_APP_ASSETS_UNDEPLOYED') {
|
|
69
|
-
logStrMsg = `All static assets for the App Builder application in workspace: ${project.workspace.name} were successfully undeployed from the CDN`
|
|
70
|
-
} else if (event === 'AB_APP_ASSETS_DEPLOYED') {
|
|
71
|
-
logStrMsg = `All static assets for the App Builder application in workspace: ${project.workspace.name} were successfully deployed to the CDN.\n Files deployed - `
|
|
72
|
-
}
|
|
97
|
+
function getAuditLogEvent ({ cliCommandFlags, operation, appInfo }) {
|
|
98
|
+
const { project, runtimeNamespace } = appInfo
|
|
73
99
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
100
|
+
if (!project) {
|
|
101
|
+
throw new Error('Project is required')
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!project.org) {
|
|
105
|
+
throw new Error('Project org is required')
|
|
106
|
+
}
|
|
107
|
+
if (!project.workspace) {
|
|
108
|
+
throw new Error('Project workspace is required')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!runtimeNamespace) {
|
|
112
|
+
throw new Error('Runtime namespace is required')
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!Object.values(OPERATIONS).find((op) => op === operation)) {
|
|
116
|
+
throw new Error(`Invalid operation: ${operation}`)
|
|
117
|
+
}
|
|
118
|
+
const orgId = project.org.id
|
|
119
|
+
|
|
120
|
+
const logEvent = {
|
|
121
|
+
orgId,
|
|
122
|
+
operation,
|
|
123
|
+
objectRef: appInfo.name,
|
|
124
|
+
objectRev: appInfo.version,
|
|
125
|
+
objectName: appInfo.name,
|
|
126
|
+
timestamp: new Date().valueOf(),
|
|
127
|
+
runtimeNamespace,
|
|
128
|
+
data: {
|
|
129
|
+
cliCommandFlags
|
|
85
130
|
}
|
|
86
131
|
}
|
|
87
132
|
return logEvent
|
|
88
133
|
}
|
|
89
134
|
|
|
90
135
|
/**
|
|
136
|
+
* Send audit log event for app deployment
|
|
91
137
|
*
|
|
92
|
-
* @param {
|
|
93
|
-
* @returns {
|
|
138
|
+
* @param {AuditLogParams} params - Parameters object containing access token, CLI flags, app info, and environment
|
|
139
|
+
* @returns {Promise<void>} Promise that resolves when the audit log is sent successfully
|
|
140
|
+
* @throws {Error} If the audit log request fails
|
|
94
141
|
*/
|
|
95
|
-
function
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.log(chalk.red(chalk.bold(`Error: Directory ${directory} does not exist.`)))
|
|
100
|
-
return log
|
|
101
|
-
}
|
|
142
|
+
async function sendAppDeployAuditLog ({ accessToken, cliCommandFlags, appInfo, env }) {
|
|
143
|
+
const logEvent = getAuditLogEvent({ cliCommandFlags, appInfo, operation: OPERATIONS.AB_APP_DEPLOY })
|
|
144
|
+
return publishAuditLogs({ accessToken, logEvent, env })
|
|
145
|
+
}
|
|
102
146
|
|
|
103
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Send audit log event for app undeployment
|
|
149
|
+
*
|
|
150
|
+
* @param {AuditLogParams} params - Parameters object containing access token, CLI flags, app info, and environment
|
|
151
|
+
* @returns {Promise<void>} Promise that resolves when the audit log is sent successfully
|
|
152
|
+
* @throws {Error} If the audit log request fails
|
|
153
|
+
*/
|
|
154
|
+
async function sendAppUndeployAuditLog ({ accessToken, cliCommandFlags, appInfo, env }) {
|
|
155
|
+
const logEvent = getAuditLogEvent({ cliCommandFlags, appInfo, operation: OPERATIONS.AB_APP_UNDEPLOY })
|
|
156
|
+
return publishAuditLogs({ accessToken, logEvent, env })
|
|
157
|
+
}
|
|
104
158
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Send audit log event for app assets deployment
|
|
161
|
+
*
|
|
162
|
+
* @param {AuditLogParams} params - Parameters object containing access token, CLI flags, app info, operation items, and environment
|
|
163
|
+
* @returns {Promise<void>} Promise that resolves when the audit log is sent successfully
|
|
164
|
+
* @throws {Error} If the audit log request fails
|
|
165
|
+
*/
|
|
166
|
+
async function sendAppAssetsDeployedAuditLog ({ accessToken, cliCommandFlags, appInfo, opItems, env }) {
|
|
167
|
+
const logEvent = getAuditLogEvent({ cliCommandFlags, appInfo, operation: OPERATIONS.AB_APP_ASSETS_DEPLOYED })
|
|
168
|
+
logEvent.data.opItems = opItems
|
|
169
|
+
return publishAuditLogs({ accessToken, logEvent, env })
|
|
170
|
+
}
|
|
109
171
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
Object.keys(fileTypeCounts).forEach(ext => {
|
|
121
|
-
const count = fileTypeCounts[ext]
|
|
122
|
-
let description
|
|
123
|
-
switch (ext) {
|
|
124
|
-
case '.js':
|
|
125
|
-
description = 'Javascript file(s)'
|
|
126
|
-
break
|
|
127
|
-
case '.css':
|
|
128
|
-
description = 'CSS file(s)'
|
|
129
|
-
break
|
|
130
|
-
case '.html':
|
|
131
|
-
description = 'HTML page(s)'
|
|
132
|
-
break
|
|
133
|
-
case '.png':
|
|
134
|
-
case '.jpg':
|
|
135
|
-
case '.jpeg':
|
|
136
|
-
case '.gif':
|
|
137
|
-
case '.svg':
|
|
138
|
-
case '.webp':
|
|
139
|
-
description = `${ext} image(s)`
|
|
140
|
-
break
|
|
141
|
-
case 'no extension':
|
|
142
|
-
description = 'file(s) without extension'
|
|
143
|
-
break
|
|
144
|
-
default:
|
|
145
|
-
description = `${ext} file(s)`
|
|
146
|
-
}
|
|
147
|
-
log.push(`${count} ${description}\n`)
|
|
148
|
-
})
|
|
149
|
-
return log
|
|
172
|
+
/**
|
|
173
|
+
* Send audit log event for app assets undeployment
|
|
174
|
+
*
|
|
175
|
+
* @param {AuditLogParams} params - Parameters object containing access token, CLI flags, app info, and environment
|
|
176
|
+
* @returns {Promise<void>} Promise that resolves when the audit log is sent successfully
|
|
177
|
+
* @throws {Error} If the audit log request fails
|
|
178
|
+
*/
|
|
179
|
+
async function sendAppAssetsUndeployedAuditLog ({ accessToken, cliCommandFlags, appInfo, env }) {
|
|
180
|
+
const logEvent = getAuditLogEvent({ cliCommandFlags, appInfo, operation: OPERATIONS.AB_APP_ASSETS_UNDEPLOYED })
|
|
181
|
+
return publishAuditLogs({ accessToken, logEvent, env })
|
|
150
182
|
}
|
|
151
183
|
|
|
152
184
|
module.exports = {
|
|
153
|
-
|
|
154
|
-
|
|
185
|
+
OPERATIONS,
|
|
186
|
+
AUDIT_SERVICE_ENDPOINT_ROUTE,
|
|
155
187
|
AUDIT_SERVICE_ENDPOINTS,
|
|
156
|
-
|
|
188
|
+
publishAuditLogs,
|
|
189
|
+
getAuditLogEvent,
|
|
190
|
+
sendAppDeployAuditLog,
|
|
191
|
+
sendAppUndeployAuditLog,
|
|
192
|
+
sendAppAssetsDeployedAuditLog,
|
|
193
|
+
sendAppAssetsUndeployedAuditLog
|
|
157
194
|
}
|
package/src/lib/auth-helper.js
CHANGED
|
@@ -12,7 +12,49 @@ governing permissions and limitations under the License.
|
|
|
12
12
|
const { getToken, context } = require('@adobe/aio-lib-ims')
|
|
13
13
|
const { CLI } = require('@adobe/aio-lib-ims/src/context')
|
|
14
14
|
const { getCliEnv } = require('@adobe/aio-lib-env')
|
|
15
|
-
const
|
|
15
|
+
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:auth-helper', { provider: 'debug' })
|
|
16
|
+
|
|
17
|
+
const DEPLOY_SERVICE_ENDPOINTS = {
|
|
18
|
+
stage: 'https://deploy-service.stg.app-builder.corp.adp.adobe.io',
|
|
19
|
+
prod: 'https://deploy-service.app-builder.adp.adobe.io'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Retrieves an access token for Adobe I/O CLI authentication.
|
|
24
|
+
* This function handles both CLI and custom contexts, setting up the appropriate
|
|
25
|
+
* authentication context and retrieving the corresponding access token.
|
|
26
|
+
*
|
|
27
|
+
* @async
|
|
28
|
+
* @function getAccessToken
|
|
29
|
+
* @param {object} [options] - Options for token retrieval
|
|
30
|
+
* @param {boolean} [options.useCachedToken=false] - Whether to use a cached token instead of requesting a new one
|
|
31
|
+
* @returns {Promise<{accessToken: string|null, env: string}>} An object containing:
|
|
32
|
+
* - accessToken: The retrieved access token for authentication, or null if token retrieval failed
|
|
33
|
+
* - env: The current CLI environment (e.g. 'prod', 'stage')
|
|
34
|
+
* @throws {Error} If token retrieval fails or context setup fails
|
|
35
|
+
*/
|
|
36
|
+
async function getAccessToken ({ useCachedToken = false } = {}) {
|
|
37
|
+
const env = getCliEnv()
|
|
38
|
+
aioLogger.debug(`Retrieving CLI Token using env=${env}`)
|
|
39
|
+
|
|
40
|
+
let contextName = CLI // default
|
|
41
|
+
const currentContext = await context.getCurrent() // potential override
|
|
42
|
+
if (currentContext && currentContext !== CLI) {
|
|
43
|
+
contextName = currentContext
|
|
44
|
+
} else {
|
|
45
|
+
await context.setCli({ 'cli.bare-output': true }, false) // set this globally
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let accessToken = null
|
|
49
|
+
if (useCachedToken) {
|
|
50
|
+
const contextConfig = await context.get(contextName)
|
|
51
|
+
accessToken = contextConfig?.access_token?.token
|
|
52
|
+
} else {
|
|
53
|
+
accessToken = await getToken(contextName)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return { accessToken, env }
|
|
57
|
+
}
|
|
16
58
|
|
|
17
59
|
/**
|
|
18
60
|
* For use with the openwhisk client js library to send a bearer token instead of basic
|
|
@@ -20,44 +62,36 @@ const defaultRuntimeUrl = 'https://adobeioruntime.net'
|
|
|
20
62
|
*/
|
|
21
63
|
const bearerAuthHandler = {
|
|
22
64
|
getAuthHeader: async () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const env = getCliEnv()
|
|
26
|
-
|
|
27
|
-
console.debug(`Retrieving CLI Token using env=${env}`)
|
|
28
|
-
const accessToken = await getToken(CLI)
|
|
65
|
+
const { accessToken } = await getAccessToken()
|
|
29
66
|
|
|
30
67
|
return `Bearer ${accessToken}`
|
|
31
68
|
}
|
|
32
69
|
}
|
|
33
70
|
|
|
34
|
-
const setRuntimeApiHostAndAuthHandler = (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (config && config.ow) {
|
|
54
|
-
config.ow.apihost = process.env.AIO_RUNTIME_APIHOST ?? defaultRuntimeUrl
|
|
55
|
-
}
|
|
71
|
+
const setRuntimeApiHostAndAuthHandler = (_config) => {
|
|
72
|
+
const env = getCliEnv()
|
|
73
|
+
let apiEndpoint = DEPLOY_SERVICE_ENDPOINTS[env] ?? DEPLOY_SERVICE_ENDPOINTS.prod
|
|
74
|
+
if (process.env.AIO_DEPLOY_SERVICE_URL) {
|
|
75
|
+
apiEndpoint = process.env.AIO_DEPLOY_SERVICE_URL
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const config = structuredClone(_config)
|
|
79
|
+
const aioConfig = (config && 'runtime' in config) ? config : null
|
|
80
|
+
if (aioConfig) {
|
|
81
|
+
aioConfig.runtime.apihost = `${apiEndpoint}/runtime`
|
|
82
|
+
aioConfig.runtime.auth_handler = bearerAuthHandler
|
|
83
|
+
return aioConfig
|
|
84
|
+
}
|
|
85
|
+
const owConfig = (config && 'ow' in config) ? config : null
|
|
86
|
+
if (owConfig) {
|
|
87
|
+
owConfig.ow.apihost = `${apiEndpoint}/runtime`
|
|
88
|
+
owConfig.ow.auth_handler = bearerAuthHandler
|
|
89
|
+
return owConfig
|
|
56
90
|
}
|
|
57
|
-
return config
|
|
58
91
|
}
|
|
59
92
|
|
|
60
93
|
module.exports = {
|
|
94
|
+
getAccessToken,
|
|
61
95
|
bearerAuthHandler,
|
|
62
96
|
setRuntimeApiHostAndAuthHandler
|
|
63
97
|
}
|
package/src/lib/run-dev.js
CHANGED
|
@@ -85,7 +85,9 @@ async function runDev (config, dataDir, options = {}, log = () => {}, inprocHook
|
|
|
85
85
|
// note the condition: we still write backend urls EVEN if skipActions is set
|
|
86
86
|
// the urls will always point to remotely deployed actions if skipActions is set
|
|
87
87
|
log('injecting backend urls into frontend config')
|
|
88
|
-
|
|
88
|
+
// note: 3rd arg, _isLocalDev is not used in RuntimeLib
|
|
89
|
+
// there is no such thing as --local anymore
|
|
90
|
+
urls = rtLibUtils.getActionUrls(devConfig, false, false, true)
|
|
89
91
|
}
|
|
90
92
|
utils.writeConfig(devConfig.web.injectedConfig, urls)
|
|
91
93
|
|