kourou 0.21.1 → 0.24.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 CHANGED
@@ -26,7 +26,7 @@ $ npm install -g kourou
26
26
  $ kourou COMMAND
27
27
  running command...
28
28
  $ kourou (-v|--version|version)
29
- kourou/0.21.1 linux-x64 node-v16.13.2
29
+ kourou/0.24.0 darwin-x64 node-v14.18.2
30
30
  $ kourou --help [COMMAND]
31
31
  USAGE
32
32
  $ kourou COMMAND
@@ -129,6 +129,7 @@ All other arguments and options will be passed as-is to the `sdk:query` method.
129
129
  * [`kourou api-key:create USER`](#kourou-api-keycreate-user)
130
130
  * [`kourou api-key:delete USER ID`](#kourou-api-keydelete-user-id)
131
131
  * [`kourou api-key:search USER`](#kourou-api-keysearch-user)
132
+ * [`kourou app:debug-proxy`](#kourou-appdebug-proxy)
132
133
  * [`kourou app:scaffold DESTINATION`](#kourou-appscaffold-destination)
133
134
  * [`kourou app:start-services`](#kourou-appstart-services)
134
135
  * [`kourou autocomplete [SHELL]`](#kourou-autocomplete-shell)
@@ -155,9 +156,10 @@ All other arguments and options will be passed as-is to the `sdk:query` method.
155
156
  * [`kourou instance:list`](#kourou-instancelist)
156
157
  * [`kourou instance:logs`](#kourou-instancelogs)
157
158
  * [`kourou instance:spawn`](#kourou-instancespawn)
158
- * [`kourou paas:init USERNAME NAMESPACE`](#kourou-paasinit-username-namespace)
159
+ * [`kourou paas:deploy ENVIRONMENT APPLICATIONID IMAGE`](#kourou-paasdeploy-environment-applicationid-image)
160
+ * [`kourou paas:init PROJECT`](#kourou-paasinit-project)
159
161
  * [`kourou paas:login`](#kourou-paaslogin)
160
- * [`kourou paas:publish PROJECT IMAGE`](#kourou-paaspublish-project-image)
162
+ * [`kourou paas:logs ENVIRONMENT APPLICATION`](#kourou-paaslogs-environment-application)
161
163
  * [`kourou profile:export`](#kourou-profileexport)
162
164
  * [`kourou profile:import PATH`](#kourou-profileimport-path)
163
165
  * [`kourou realtime:subscribe INDEX COLLECTION [FILTERS]`](#kourou-realtimesubscribe-index-collection-filters)
@@ -196,6 +198,7 @@ OPTIONS
196
198
  --port=port [default: 7512] Kuzzle server port
197
199
  --protocol=protocol [default: ws] Kuzzle protocol (http or ws)
198
200
  --ssl Use SSL to connect to Kuzzle
201
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
199
202
  --username=username [default: anonymous] Kuzzle username (local strategy)
200
203
 
201
204
  EXAMPLE
@@ -227,6 +230,7 @@ OPTIONS
227
230
  --port=port [default: 7512] Kuzzle server port
228
231
  --protocol=protocol [default: ws] Kuzzle protocol (http or ws)
229
232
  --ssl Use SSL to connect to Kuzzle
233
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
230
234
  --username=username [default: anonymous] Kuzzle username (local strategy)
231
235
  ```
232
236
 
@@ -253,6 +257,7 @@ OPTIONS
253
257
  --port=port [default: 7512] Kuzzle server port
254
258
  --protocol=protocol [default: ws] Kuzzle protocol (http or ws)
255
259
  --ssl Use SSL to connect to Kuzzle
260
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
256
261
  --username=username [default: anonymous] Kuzzle username (local strategy)
257
262
 
258
263
  EXAMPLE
@@ -282,11 +287,50 @@ OPTIONS
282
287
  --port=port [default: 7512] Kuzzle server port
283
288
  --protocol=protocol [default: ws] Kuzzle protocol (http or ws)
284
289
  --ssl Use SSL to connect to Kuzzle
290
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
285
291
  --username=username [default: anonymous] Kuzzle username (local strategy)
286
292
  ```
287
293
 
288
294
  _See code: [src/commands/api-key/search.ts](src/commands/api-key/search.ts)_
289
295
 
296
+ ## `kourou app:debug-proxy`
297
+
298
+ Create a Proxy Server that allows Chrome to debug Kuzzle remotely using the DebugController
299
+
300
+ ```
301
+ USAGE
302
+ $ kourou app:debug-proxy
303
+
304
+ OPTIONS
305
+ --api-key=api-key Kuzzle user api-key
306
+ --as=as Impersonate a user
307
+ --forwardPort=forwardPort [default: 9222] Port of the forwarding server
308
+ --help show CLI help
309
+ --host=host [default: localhost] Kuzzle server host
310
+ --keepAuth Keep the user authenticated
311
+
312
+ --noAutoEnableDebugger True if Kourou should not enable and disable the Debugger automatically before and after
313
+ usage
314
+
315
+ --password=password Kuzzle user password
316
+
317
+ --port=port [default: 7512] Kuzzle server port
318
+
319
+ --protocol=protocol [default: ws] Kuzzle protocol (http or ws)
320
+
321
+ --showDebuggerEvents Verbose mode to display events sent to the Chrome Debugger
322
+
323
+ --showDebuggerPayloads Verbose mode to display payloads sent by and to the Chrome Debugger
324
+
325
+ --ssl Use SSL to connect to Kuzzle
326
+
327
+ --ttl=ttl [default: 1h] Kuzzle login TTL
328
+
329
+ --username=username [default: anonymous] Kuzzle username (local strategy)
330
+ ```
331
+
332
+ _See code: [src/commands/app/debug-proxy.ts](src/commands/app/debug-proxy.ts)_
333
+
290
334
  ## `kourou app:scaffold DESTINATION`
291
335
 
292
336
  Scaffolds a new Kuzzle application
@@ -341,7 +385,7 @@ EXAMPLES
341
385
  $ kourou autocomplete --refresh-cache
342
386
  ```
343
387
 
344
- _See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.2.0/src/commands/autocomplete/index.ts)_
388
+ _See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.3.0/src/commands/autocomplete/index.ts)_
345
389
 
346
390
  ## `kourou collection:create INDEX COLLECTION [BODY]`
347
391
 
@@ -365,6 +409,7 @@ OPTIONS
365
409
  --port=port [default: 7512] Kuzzle server port
366
410
  --protocol=protocol [default: ws] Kuzzle protocol (http or ws)
367
411
  --ssl Use SSL to connect to Kuzzle
412
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
368
413
  --username=username [default: anonymous] Kuzzle username (local strategy)
369
414
  ```
370
415
 
@@ -437,6 +482,9 @@ OPTIONS
437
482
  --ssl
438
483
  Use SSL to connect to Kuzzle
439
484
 
485
+ --ttl=ttl
486
+ [default: 90] Kuzzle login TTL (in seconds)
487
+
440
488
  --username=username
441
489
  [default: anonymous] Kuzzle username (local strategy)
442
490
 
@@ -471,6 +519,7 @@ OPTIONS
471
519
  --port=port [default: 7512] Kuzzle server port
472
520
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
473
521
  --ssl Use SSL to connect to Kuzzle
522
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
474
523
  --username=username [default: anonymous] Kuzzle username (local strategy)
475
524
  ```
476
525
 
@@ -526,6 +575,7 @@ OPTIONS
526
575
  --size=size Optional page size
527
576
  --sort=sort [default: {}] Sort in JS or JSON format.
528
577
  --ssl Use SSL to connect to Kuzzle
578
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
529
579
  --username=username [default: anonymous] Kuzzle username (local strategy)
530
580
 
531
581
  EXAMPLES
@@ -602,9 +652,12 @@ USAGE
602
652
  OPTIONS
603
653
  --batch-size=batch-size [default: 1000] How many documents to move in batch per operation
604
654
  --dest=dest (required) Destination Elasticsearch server URL
655
+ --dry-run Print witch collections will be migrated
605
656
  --help show CLI help
606
657
  --no-interactive Skip confirmation interactive prompts (perfect for scripting)
658
+ --pattern=pattern Pattern to match indices to migrate
607
659
  --reset Reset destination Elasticsearch server
660
+ --scroll=scroll [default: 30s] Scroll duration for Elasticsearch scrolling
608
661
  --src=src (required) Source Elasticsearch server URL
609
662
 
610
663
  EXAMPLES
@@ -777,6 +830,7 @@ OPTIONS
777
830
  --preserve-anonymous Preserve anonymous rights
778
831
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
779
832
  --ssl Use SSL to connect to Kuzzle
833
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
780
834
  --username=username [default: anonymous] Kuzzle username (local strategy)
781
835
  ```
782
836
 
@@ -817,6 +871,8 @@ OPTIONS
817
871
 
818
872
  --ssl Use SSL to connect to Kuzzle
819
873
 
874
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
875
+
820
876
  --username=username [default: anonymous] Kuzzle username (local strategy)
821
877
 
822
878
  EXAMPLES
@@ -849,6 +905,7 @@ OPTIONS
849
905
  --port=port [default: 7512] Kuzzle server port
850
906
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
851
907
  --ssl Use SSL to connect to Kuzzle
908
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
852
909
  --username=username [default: anonymous] Kuzzle username (local strategy)
853
910
 
854
911
  EXAMPLES
@@ -915,17 +972,37 @@ OPTIONS
915
972
 
916
973
  _See code: [src/commands/instance/spawn.ts](src/commands/instance/spawn.ts)_
917
974
 
918
- ## `kourou paas:init USERNAME NAMESPACE`
975
+ ## `kourou paas:deploy ENVIRONMENT APPLICATIONID IMAGE`
919
976
 
920
- Initialize a PaaS namespace in current directory
977
+ Deploy a new version of the application in the PaaS
921
978
 
922
979
  ```
923
980
  USAGE
924
- $ kourou paas:init USERNAME NAMESPACE
981
+ $ kourou paas:deploy ENVIRONMENT APPLICATIONID IMAGE
925
982
 
926
983
  ARGUMENTS
927
- USERNAME Username
928
- NAMESPACE Namespace
984
+ ENVIRONMENT Project environment name
985
+ APPLICATIONID Application Identifier
986
+ IMAGE Image name and hash as myimage:mytag
987
+
988
+ OPTIONS
989
+ --help show CLI help
990
+ --project=project Current PaaS project
991
+ --token=token Authentication token
992
+ ```
993
+
994
+ _See code: [src/commands/paas/deploy.ts](src/commands/paas/deploy.ts)_
995
+
996
+ ## `kourou paas:init PROJECT`
997
+
998
+ Initialize a PaaS project in current directory
999
+
1000
+ ```
1001
+ USAGE
1002
+ $ kourou paas:init PROJECT
1003
+
1004
+ ARGUMENTS
1005
+ PROJECT Kuzzle PaaS project name
929
1006
 
930
1007
  OPTIONS
931
1008
  --help show CLI help
@@ -935,39 +1012,38 @@ _See code: [src/commands/paas/init.ts](src/commands/paas/init.ts)_
935
1012
 
936
1013
  ## `kourou paas:login`
937
1014
 
938
- Login for a PaaS namespace
1015
+ Login for a PaaS project
939
1016
 
940
1017
  ```
941
1018
  USAGE
942
1019
  $ kourou paas:login
943
1020
 
944
1021
  OPTIONS
945
- --help show CLI help
946
- --namespace=namespace Current PaaS namespace
947
- --username=username PaaS username
1022
+ --help show CLI help
1023
+ --project=project Current PaaS project
1024
+ --username=username PaaS username
948
1025
  ```
949
1026
 
950
1027
  _See code: [src/commands/paas/login.ts](src/commands/paas/login.ts)_
951
1028
 
952
- ## `kourou paas:publish PROJECT IMAGE`
1029
+ ## `kourou paas:logs ENVIRONMENT APPLICATION`
953
1030
 
954
- Deploy a new version of the application in the PaaS
1031
+ Show logs of the targeted application
955
1032
 
956
1033
  ```
957
1034
  USAGE
958
- $ kourou paas:publish PROJECT IMAGE
1035
+ $ kourou paas:logs ENVIRONMENT APPLICATION
959
1036
 
960
1037
  ARGUMENTS
961
- PROJECT Project name
962
- IMAGE Image name and hash
1038
+ ENVIRONMENT Kuzzle PaaS environment
1039
+ APPLICATION Kuzzle PaaS application
963
1040
 
964
1041
  OPTIONS
965
- --help show CLI help
966
- --namespace=namespace Current PaaS namespace
967
- --token=token Authentication token
1042
+ --help show CLI help
1043
+ --project=project Current PaaS project
968
1044
  ```
969
1045
 
970
- _See code: [src/commands/paas/publish.ts](src/commands/paas/publish.ts)_
1046
+ _See code: [src/commands/paas/logs.ts](src/commands/paas/logs.ts)_
971
1047
 
972
1048
  ## `kourou profile:export`
973
1049
 
@@ -987,6 +1063,7 @@ OPTIONS
987
1063
  --port=port [default: 7512] Kuzzle server port
988
1064
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
989
1065
  --ssl Use SSL to connect to Kuzzle
1066
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
990
1067
  --username=username [default: anonymous] Kuzzle username (local strategy)
991
1068
  ```
992
1069
 
@@ -1012,6 +1089,7 @@ OPTIONS
1012
1089
  --port=port [default: 7512] Kuzzle server port
1013
1090
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
1014
1091
  --ssl Use SSL to connect to Kuzzle
1092
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1015
1093
  --username=username [default: anonymous] Kuzzle username (local strategy)
1016
1094
  ```
1017
1095
 
@@ -1053,6 +1131,8 @@ OPTIONS
1053
1131
 
1054
1132
  --ssl Use SSL to connect to Kuzzle
1055
1133
 
1134
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1135
+
1056
1136
  --username=username [default: anonymous] Kuzzle username (local strategy)
1057
1137
 
1058
1138
  --users=users [default: all] Subscribe to users entering or leaving the room (all, in, out, none)
@@ -1092,6 +1172,7 @@ OPTIONS
1092
1172
  --remove Remove matching keys
1093
1173
  --size=size [default: 100] Page size
1094
1174
  --ssl Use SSL to connect to Kuzzle
1175
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1095
1176
  --username=username [default: anonymous] Kuzzle username (local strategy)
1096
1177
 
1097
1178
  EXAMPLES
@@ -1119,6 +1200,7 @@ OPTIONS
1119
1200
  --port=port [default: 7512] Kuzzle server port
1120
1201
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
1121
1202
  --ssl Use SSL to connect to Kuzzle
1203
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1122
1204
  --username=username [default: anonymous] Kuzzle username (local strategy)
1123
1205
  ```
1124
1206
 
@@ -1145,6 +1227,7 @@ OPTIONS
1145
1227
  --preserve-anonymous Preserve anonymous rights
1146
1228
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
1147
1229
  --ssl Use SSL to connect to Kuzzle
1230
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1148
1231
  --username=username [default: anonymous] Kuzzle username (local strategy)
1149
1232
  ```
1150
1233
 
@@ -1174,6 +1257,7 @@ OPTIONS
1174
1257
  --print-raw Print only the script result to stdout
1175
1258
  --protocol=protocol [default: ws] Kuzzle protocol (http or ws)
1176
1259
  --ssl Use SSL to connect to Kuzzle
1260
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1177
1261
  --username=username [default: anonymous] Kuzzle username (local strategy)
1178
1262
 
1179
1263
  DESCRIPTION
@@ -1247,6 +1331,8 @@ OPTIONS
1247
1331
 
1248
1332
  --ssl Use SSL to connect to Kuzzle
1249
1333
 
1334
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1335
+
1250
1336
  --username=username [default: anonymous] Kuzzle username (local strategy)
1251
1337
 
1252
1338
  DESCRIPTION
@@ -1329,6 +1415,7 @@ OPTIONS
1329
1415
  --port=port [default: 7512] Kuzzle server port
1330
1416
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
1331
1417
  --ssl Use SSL to connect to Kuzzle
1418
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1332
1419
  --username=username [default: anonymous] Kuzzle username (local strategy)
1333
1420
 
1334
1421
  DESCRIPTION
@@ -1377,6 +1464,7 @@ OPTIONS
1377
1464
  --port=port [default: 7512] Kuzzle server port
1378
1465
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
1379
1466
  --ssl Use SSL to connect to Kuzzle
1467
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1380
1468
  --username=username [default: anonymous] Kuzzle username (local strategy)
1381
1469
  ```
1382
1470
 
@@ -1402,6 +1490,7 @@ OPTIONS
1402
1490
  --port=port [default: 7512] Kuzzle server port
1403
1491
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
1404
1492
  --ssl Use SSL to connect to Kuzzle
1493
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1405
1494
  --username=username [default: anonymous] Kuzzle username (local strategy)
1406
1495
  ```
1407
1496
 
@@ -1427,6 +1516,7 @@ OPTIONS
1427
1516
  --port=port [default: 7512] Kuzzle server port
1428
1517
  --protocol=protocol [default: ws] Kuzzle protocol (http or websocket)
1429
1518
  --ssl Use SSL to connect to Kuzzle
1519
+ --ttl=ttl [default: 90] Kuzzle login TTL (in seconds)
1430
1520
  --username=username [default: anonymous] Kuzzle username (local strategy)
1431
1521
  ```
1432
1522
 
@@ -0,0 +1,26 @@
1
+ import { flags } from '@oclif/command';
2
+ import { Kommand } from '../../common';
3
+ export default class DebugProxy extends Kommand {
4
+ static description: string;
5
+ static flags: {
6
+ host: flags.IOptionFlag<string>;
7
+ port: flags.IOptionFlag<string>;
8
+ ssl: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
9
+ username: flags.IOptionFlag<string>;
10
+ password: flags.IOptionFlag<string | undefined>;
11
+ protocol: flags.IOptionFlag<string>;
12
+ as: flags.IOptionFlag<string | undefined>;
13
+ 'api-key': flags.IOptionFlag<string | undefined>;
14
+ help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
15
+ forwardPort: import("@oclif/parser/lib/flags").IOptionFlag<number>;
16
+ ttl: flags.IOptionFlag<string>;
17
+ keepAuth: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
18
+ noAutoEnableDebugger: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
19
+ showDebuggerEvents: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
20
+ showDebuggerPayloads: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
21
+ };
22
+ static sdkOptions: {
23
+ protocol: string;
24
+ };
25
+ runSafe(): Promise<void>;
26
+ }
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const command_1 = require("@oclif/command");
5
+ const common_1 = require("../../common");
6
+ const kuzzle_1 = require("../../support/kuzzle");
7
+ const http_1 = tslib_1.__importDefault(require("http"));
8
+ const ws_1 = tslib_1.__importDefault(require("ws"));
9
+ // Add the proper headers and send the body in the response
10
+ function sendResponse(response, bodyObject) {
11
+ response.setHeader('Content-Type', 'application/json; charset=UTF-8');
12
+ response.setHeader('Cache-Control', 'no-cache');
13
+ const body = JSON.stringify(bodyObject);
14
+ response.setHeader('Content-Length', Buffer.byteLength(body));
15
+ response.writeHead(200);
16
+ response.end(body);
17
+ }
18
+ class DebugProxy extends common_1.Kommand {
19
+ async runSafe() {
20
+ const nodeVersionResponse = await this.sdk.query({
21
+ controller: 'debug',
22
+ action: 'nodeVersion'
23
+ });
24
+ this.logInfo(`Connected to Kuzzle node: ${nodeVersionResponse.node}`);
25
+ /**
26
+ * To allow the Chrome Debugger to see the proxy server we must implement the following routes:
27
+ * - /json/version
28
+ * - /json
29
+ */
30
+ const server = http_1.default.createServer((request, response) => {
31
+ if (request.url === '/json/version') {
32
+ sendResponse(response, {
33
+ Browser: `node.js/${nodeVersionResponse.result}`,
34
+ "Protocol-Version": "1.1"
35
+ });
36
+ return;
37
+ }
38
+ else if (request.url === '/json') {
39
+ // Here we send a bunch of information about the Remote Target to the Chrome Debugger
40
+ // Those are the informations that the Chrome Debugger uses to know how to connect to Remote Target
41
+ // We give the Chrome Inspector our own Websocket endpoint so that it can connect to our proxy server
42
+ sendResponse(response, [{
43
+ description: 'node.js instance',
44
+ devtoolsFrontendUrl: `devtools://devtools/bundled/js_app.html?experiments=true&v8only=true&ws=${request.headers.host}/kuzzle-debugger`,
45
+ devtoolsFrontendUrlCompat: `devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=${request.headers.host}/kuzzle-debugger`,
46
+ faviconUrl: 'https://nodejs.org/static/images/favicons/favicon.ico',
47
+ id: 'kuzzle-debugger',
48
+ title: `Kuzzle Debugger - ${this.flags.host}:${this.flags.port}`,
49
+ type: 'node',
50
+ webSocketDebuggerUrl: `ws://${request.headers.host}/kuzzle-debugger`
51
+ }]);
52
+ return;
53
+ }
54
+ response.writeHead(404);
55
+ });
56
+ const closeServer = async () => {
57
+ this.logInfo('Connection closed.');
58
+ if (!this.flags.noAutoEnableDebugger) {
59
+ await this.sdk.query({
60
+ controller: 'debug',
61
+ action: 'disable'
62
+ });
63
+ }
64
+ this.sdk.disconnect();
65
+ server.close();
66
+ };
67
+ const wss = new ws_1.default.Server({
68
+ server
69
+ });
70
+ if (!this.flags.noAutoEnableDebugger) {
71
+ await this.sdk.query({
72
+ controller: 'debug',
73
+ action: 'enable'
74
+ });
75
+ }
76
+ // Listen to all events emitted by the Debug Controller
77
+ await this.sdk.query({
78
+ controller: 'debug',
79
+ action: 'addListener',
80
+ body: {
81
+ event: '*'
82
+ }
83
+ });
84
+ wss.on('connection', ws => {
85
+ this.logInfo('Connection established.');
86
+ /**
87
+ * Listen to the room were events from the DebugController are sent
88
+ * and only forward events from the Chrome Devtools Protocol
89
+ */
90
+ this.sdk.sdk.protocol.on('kuzzle-debugger-event', (payload) => {
91
+ if (!payload.event || payload.event.startsWith('Kuzzle')) {
92
+ return;
93
+ }
94
+ if (this.flags.showDebuggerEvents) {
95
+ this.logInfo(JSON.stringify(payload.result, null, 2));
96
+ }
97
+ ws.send(JSON.stringify(payload.result));
98
+ });
99
+ // When receiving message from Chrome Devtools Protocol, we forward it to the DebugController
100
+ ws.on('message', async (message) => {
101
+ try {
102
+ const json = JSON.parse(message.toString());
103
+ if (json.id === undefined || json.method === undefined) {
104
+ return;
105
+ }
106
+ if (this.flags.showDebuggerPayloads) {
107
+ this.logInfo(JSON.stringify({
108
+ method: json.method,
109
+ params: json.params,
110
+ }, null, 2));
111
+ }
112
+ const response = await this.sdk.query({
113
+ controller: 'debug',
114
+ action: 'post',
115
+ body: {
116
+ method: json.method,
117
+ params: json.params,
118
+ }
119
+ });
120
+ if (this.flags.showDebuggerPayloads) {
121
+ this.logInfo(JSON.stringify({
122
+ id: json.id,
123
+ result: response.result
124
+ }, null, 2));
125
+ }
126
+ // Send back the response using the same ID received
127
+ ws.send(JSON.stringify({
128
+ id: json.id,
129
+ result: response.result
130
+ }));
131
+ }
132
+ catch (e) {
133
+ this.logKo(`${e}`);
134
+ }
135
+ });
136
+ ws.on('close', closeServer);
137
+ });
138
+ server.on('error', async (err) => {
139
+ this.logKo(err.message);
140
+ this.logKo(err.stack);
141
+ await closeServer();
142
+ });
143
+ server.listen(this.flags.forwardPort, () => {
144
+ this.logOk(`Listening on port ${this.flags.forwardPort}, forwarding to Kuzzle at ${this.flags.host}:${this.flags.port}`);
145
+ this.logInfo(`Showing to Chrome Debugger as "Kuzzle Debugger - ${this.flags.host}:${this.flags.port}"`);
146
+ this.logInfo('Waiting for Chrome Debugger to connect...');
147
+ });
148
+ let resolve;
149
+ const promise = new Promise(res => {
150
+ resolve = res;
151
+ });
152
+ server.on('close', () => {
153
+ resolve();
154
+ });
155
+ await promise;
156
+ }
157
+ }
158
+ exports.default = DebugProxy;
159
+ DebugProxy.description = 'Create a Proxy Server that allows Chrome to debug Kuzzle remotely using the DebugController';
160
+ DebugProxy.flags = Object.assign({ help: command_1.flags.help(), forwardPort: command_1.flags.integer({
161
+ description: 'Port of the forwarding server',
162
+ default: 9222
163
+ }), ttl: command_1.flags.string({
164
+ description: 'Kuzzle login TTL',
165
+ default: '1h',
166
+ }), keepAuth: command_1.flags.boolean({
167
+ description: 'Keep the user authenticated',
168
+ default: false,
169
+ }), noAutoEnableDebugger: command_1.flags.boolean({
170
+ description: 'True if Kourou should not enable and disable the Debugger automatically before and after usage',
171
+ default: false
172
+ }), showDebuggerEvents: command_1.flags.boolean({
173
+ description: 'Verbose mode to display events sent to the Chrome Debugger',
174
+ default: false,
175
+ }), showDebuggerPayloads: command_1.flags.boolean({
176
+ description: 'Verbose mode to display payloads sent by and to the Chrome Debugger',
177
+ default: false,
178
+ }) }, kuzzle_1.kuzzleFlags);
179
+ // Force the usage of Websocket otherwise each request might end up executed on a different Kuzzle Node
180
+ DebugProxy.sdkOptions = {
181
+ protocol: 'ws'
182
+ };
@@ -1,4 +1,5 @@
1
1
  import { flags } from '@oclif/command';
2
+ import { Client } from '@elastic/elasticsearch';
2
3
  import { Kommand } from '../../common';
3
4
  export default class EsMigrate extends Kommand {
4
5
  static initSdk: boolean;
@@ -10,11 +11,13 @@ export default class EsMigrate extends Kommand {
10
11
  reset: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
11
12
  'batch-size': import("@oclif/parser/lib/flags").IOptionFlag<number>;
12
13
  'no-interactive': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
14
+ 'dry-run': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
15
+ pattern: flags.IOptionFlag<string | undefined>;
16
+ scroll: flags.IOptionFlag<string>;
13
17
  };
14
18
  static examples: string[];
15
- private src;
16
- private dest;
17
19
  private migrateMappings;
18
20
  private migrateData;
21
+ runMigrate(index: string, src: Client, dest: Client): Promise<void>;
19
22
  runSafe(): Promise<void>;
20
23
  }
@@ -8,16 +8,16 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
8
  const node_emoji_1 = tslib_1.__importDefault(require("node-emoji"));
9
9
  const common_1 = require("../../common");
10
10
  class EsMigrate extends common_1.Kommand {
11
- async migrateMappings(index) {
12
- const { body } = await this.src.indices.getMapping({ index, format: 'json' });
11
+ async migrateMappings(index, src, dest) {
12
+ const { body } = await src.indices.getMapping({ index });
13
13
  const mappings = body[index];
14
- await this.dest.indices.create({ index, body: mappings });
14
+ await dest.indices.create({ index, body: { mappings: mappings.mappings } });
15
15
  }
16
- async migrateData(index, batch_size) {
16
+ async migrateData(index, batch_size, src, dest) {
17
17
  const queue = [];
18
- const { body } = await this.src.search({
18
+ const { body } = await src.search({
19
19
  index,
20
- scroll: '20s',
20
+ scroll: this.flags.scroll,
21
21
  size: batch_size,
22
22
  body: {
23
23
  query: {
@@ -42,42 +42,52 @@ class EsMigrate extends common_1.Kommand {
42
42
  bulk.push(doc._source);
43
43
  count++;
44
44
  }
45
- await this.dest.bulk({ body: bulk });
45
+ await dest.bulk({ body: bulk });
46
46
  progressBar.update(count);
47
- const { body: { hits } } = await this.src.scroll({
48
- scrollId,
49
- scroll: '20s'
47
+ const { body: { hits } } = await src.scroll({
48
+ scroll_id: scrollId,
49
+ scroll: this.flags.scroll
50
50
  });
51
51
  queue.push(hits);
52
52
  }
53
53
  progressBar.stop();
54
54
  return total;
55
55
  }
56
+ async runMigrate(index, src, dest) {
57
+ this.logInfo(`Importing ${chalk_1.default.bold(index)} to ${chalk_1.default.bold(this.flags.dest)}`);
58
+ await this.migrateMappings(index, src, dest);
59
+ this.logOk('Mappings successfully imported!');
60
+ const count = await this.migrateData(index, this.flags['batch-size'], src, dest);
61
+ if (count === 0) {
62
+ this.logInfo('No documents to import\n');
63
+ }
64
+ else {
65
+ this.logOk(`${chalk_1.default.bold(count)} document(s) imported!\n`);
66
+ }
67
+ }
56
68
  async runSafe() {
57
- this.src = new elasticsearch_1.Client({ node: this.flags.src });
58
- this.dest = new elasticsearch_1.Client({ node: this.flags.dest });
69
+ const src = new elasticsearch_1.Client({ node: this.flags.src });
70
+ const dest = new elasticsearch_1.Client({ node: this.flags.dest });
59
71
  if (this.flags.reset && !this.flags['no-interactive']) {
60
72
  this.log(chalk_1.default.red(`${node_emoji_1.default.get('fire')} Are you sure you want to reset ${chalk_1.default.bold(this.flags.dest)}?`));
61
73
  await cli_ux_1.default.confirm(chalk_1.default.redBright(` ${node_emoji_1.default.get('fire')} You will lose all the data stored in it (Type "yes" to confirm)`));
62
- await this.dest.indices.delete({ index: '_all' });
74
+ await dest.indices.delete({ index: '_all' });
63
75
  }
64
76
  this.logInfo(`Fetching indices list from ${chalk_1.default.bold(this.flags.src)}`);
65
- const { body } = await this.src.cat.indices({ format: 'json' });
66
- const indices = body
77
+ const srcBody = await src.cat.indices({ format: 'json' });
78
+ const srcIndices = srcBody.body
67
79
  .map(({ index }) => index)
80
+ .filter((index) => index.match(this.flags.pattern))
68
81
  .sort();
69
- this.logOk(`Found ${chalk_1.default.bold(indices.length)} indices in the source Elasticsearch server\n`);
70
- this.logInfo(`Starting indices migration from ${chalk_1.default.bold(this.flags.src)} to ${chalk_1.default.bold(this.flags.dest)}`);
71
- for (const index of indices) {
72
- this.logInfo(`Importing ${chalk_1.default.bold(index)} to ${chalk_1.default.bold(this.flags.dest)}`);
73
- await this.migrateMappings(index);
74
- this.logOk('Mappings successfully imported!');
75
- const count = await this.migrateData(index, this.flags['batch-size']);
76
- if (count === 0) {
77
- this.logInfo('No documents to import\n');
78
- }
79
- else {
80
- this.logOk(`${chalk_1.default.bold(count)} document(s) imported!\n`);
82
+ this.logOk(`Found ${chalk_1.default.bold(srcIndices.length)} indices in the source Elasticsearch server\n`);
83
+ if (this.flags['dry-run']) {
84
+ this.log(`${chalk_1.default.bold(srcIndices)}`);
85
+ this.logInfo(`${chalk_1.default.bold(srcIndices.length)} indices will be migrated`);
86
+ }
87
+ else {
88
+ this.logInfo(`Starting indices migration from ${chalk_1.default.bold(this.flags.src)} to ${chalk_1.default.bold(this.flags.dest)}`);
89
+ for (const index of srcIndices) {
90
+ await this.runMigrate(index, src, dest);
81
91
  }
82
92
  }
83
93
  }
@@ -109,6 +119,17 @@ EsMigrate.flags = {
109
119
  description: 'Skip confirmation interactive prompts (perfect for scripting)',
110
120
  default: false,
111
121
  }),
122
+ 'dry-run': command_1.flags.boolean({
123
+ description: 'Print witch collections will be migrated',
124
+ default: false,
125
+ }),
126
+ 'pattern': command_1.flags.string({
127
+ description: 'Pattern to match indices to migrate'
128
+ }),
129
+ 'scroll': command_1.flags.string({
130
+ description: 'Scroll duration for Elasticsearch scrolling',
131
+ default: '30s'
132
+ }),
112
133
  };
113
134
  EsMigrate.examples = [
114
135
  'kourou es:migrate --src http://elasticsearch:9200 --dest http://otherElasticsearch:9200 --reset --batch-size 2000',
@@ -1,11 +1,11 @@
1
1
  import { flags } from '@oclif/command';
2
2
  import { PaasKommand } from '../../support/PaasKommand';
3
- declare class PaasPublish extends PaasKommand {
3
+ declare class PaasDeploy extends PaasKommand {
4
4
  static description: string;
5
5
  static flags: {
6
6
  help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
7
7
  token: flags.IOptionFlag<string | undefined>;
8
- namespace: flags.IOptionFlag<string | undefined>;
8
+ project: flags.IOptionFlag<string | undefined>;
9
9
  };
10
10
  static args: {
11
11
  name: string;
@@ -15,4 +15,4 @@ declare class PaasPublish extends PaasKommand {
15
15
  runSafe(): Promise<void>;
16
16
  getCredentials(): Promise<any>;
17
17
  }
18
- export default PaasPublish;
18
+ export default PaasDeploy;
@@ -6,57 +6,62 @@ const command_1 = require("@oclif/command");
6
6
  const cli_ux_1 = tslib_1.__importDefault(require("cli-ux"));
7
7
  const login_1 = tslib_1.__importDefault(require("./login"));
8
8
  const PaasKommand_1 = require("../../support/PaasKommand");
9
- class PaasPublish extends PaasKommand_1.PaasKommand {
9
+ class PaasDeploy extends PaasKommand_1.PaasKommand {
10
10
  async runSafe() {
11
11
  const apiKey = await this.getCredentials();
12
12
  await this.initPaasClient({ apiKey });
13
13
  const user = await this.paas.auth.getCurrentUser();
14
- this.logInfo(`Logged as "${user._id}" for project "${this.args.project}"`);
14
+ this.logInfo(`Logged as "${user._id}" for project "${this.flags.project || this.getProject()}"`);
15
15
  const [image, tag] = this.args.image.split(':');
16
16
  this.logInfo(`Deploy application with image "${image}:${tag}"`);
17
17
  await this.paas.query({
18
- controller: 'config',
19
- action: 'updateImage',
18
+ controller: 'application',
19
+ action: 'deploy',
20
+ environmentId: this.args.environment,
21
+ projectId: this.flags.project || this.getProject(),
22
+ applicationId: this.args.applicationId,
20
23
  body: {
21
- namespace: this.args.project,
22
- image,
23
- tag,
24
+ image: {
25
+ name: image,
26
+ tag,
27
+ },
24
28
  }
25
29
  });
26
30
  this.logOk('Deployment in progress');
27
31
  }
28
32
  async getCredentials() {
29
- const namespace = this.getNamespace();
30
- const namespaceFile = this.fileNamespaceCredentials(namespace);
31
- if (!fs_1.default.existsSync(namespaceFile)) {
33
+ const project = this.getProject();
34
+ const projectFile = this.fileProjectCredentials(project);
35
+ if (!fs_1.default.existsSync(projectFile)) {
32
36
  this.log('');
33
- const nextStep = await cli_ux_1.default.prompt('Cannot find credentials for this namespace. Do you want to login first? [Y/N]', { type: 'single' });
37
+ const nextStep = await cli_ux_1.default.prompt('Cannot find credentials for this project. Do you want to login first? [Y/N]', { type: 'single' });
34
38
  this.log('');
35
39
  if (nextStep.toLowerCase().startsWith('y')) {
36
- await login_1.default.run(['--namespace', namespace]);
40
+ await login_1.default.run(['--project', project]);
37
41
  }
38
42
  else {
39
43
  this.logKo('Aborting.');
40
44
  process.exit(1);
41
45
  }
42
46
  }
43
- const credentials = JSON.parse(fs_1.default.readFileSync(namespaceFile, 'utf8'));
47
+ const credentials = JSON.parse(fs_1.default.readFileSync(projectFile, 'utf8'));
44
48
  return credentials.apiKey;
45
49
  }
46
50
  }
47
- PaasPublish.description = 'Deploy a new version of the application in the PaaS';
48
- PaasPublish.flags = {
51
+ PaasDeploy.description = 'Deploy a new version of the application in the PaaS';
52
+ PaasDeploy.flags = {
49
53
  help: command_1.flags.help(),
50
54
  token: command_1.flags.string({
51
55
  default: process.env.KUZZLE_PAAS_TOKEN,
52
56
  description: 'Authentication token'
53
57
  }),
54
- namespace: command_1.flags.string({
55
- description: 'Current PaaS namespace'
58
+ project: command_1.flags.string({
59
+ description: 'Current PaaS project',
56
60
  }),
57
61
  };
58
- PaasPublish.args = [
59
- { name: 'project', description: 'Project name', required: true },
60
- { name: 'image', description: 'Image name and hash', required: true },
62
+ PaasDeploy.args = [
63
+ { name: 'environment', description: 'Project environment name', required: true },
64
+ { name: 'applicationId', description: 'Application Identifier', required: true },
65
+ { name: 'image', description: 'Image name and hash as myimage:mytag', required: true },
61
66
  ];
62
- exports.default = PaasPublish;
67
+ exports.default = PaasDeploy;
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const path_1 = tslib_1.__importDefault(require("path"));
5
5
  const fs_1 = tslib_1.__importDefault(require("fs"));
6
- const cli_ux_1 = require("cli-ux");
7
6
  const command_1 = require("@oclif/command");
8
- const login_1 = tslib_1.__importDefault(require("./login"));
9
7
  const PaasKommand_1 = require("../../support/PaasKommand");
10
8
  class PaasInit extends PaasKommand_1.PaasKommand {
11
9
  async runSafe() {
@@ -17,25 +15,17 @@ class PaasInit extends PaasKommand_1.PaasKommand {
17
15
  this.logInfo('Add the "kuzzle" property inside project package.json.');
18
16
  packageJson.kuzzle = {
19
17
  paas: {
20
- application: 'kuzzle',
21
- namespace: this.args.namespace,
18
+ project: this.args.project,
22
19
  },
23
20
  };
24
21
  fs_1.default.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
25
- this.log('');
26
- const nextStep = await cli_ux_1.cli.prompt('Do you want to login to the namespace? [Y/N]', { type: 'single' });
27
- this.log('');
28
- if (nextStep.toLowerCase().startsWith('y')) {
29
- await login_1.default.run(['--username', this.args.username, '--namespace', this.args.namespace]);
30
- }
31
22
  }
32
23
  }
33
- PaasInit.description = 'Initialize a PaaS namespace in current directory';
24
+ PaasInit.description = 'Initialize a PaaS project in current directory';
34
25
  PaasInit.flags = {
35
26
  help: command_1.flags.help(),
36
27
  };
37
28
  PaasInit.args = [
38
- { name: 'username', description: 'Username', required: true },
39
- { name: 'namespace', description: 'Namespace', required: true },
29
+ { name: 'project', description: 'Kuzzle PaaS project name', required: true },
40
30
  ];
41
31
  exports.default = PaasInit;
@@ -5,10 +5,11 @@ declare class PaasLogin extends PaasKommand {
5
5
  static description: string;
6
6
  static flags: {
7
7
  help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
8
- namespace: flags.IOptionFlag<string | undefined>;
8
+ project: flags.IOptionFlag<string | undefined>;
9
9
  username: flags.IOptionFlag<string | undefined>;
10
10
  };
11
11
  runSafe(): Promise<void>;
12
- createNamespaceCredentials(apiKey: ApiKey): void;
12
+ createProjectCredentials(apiKey: ApiKey): void;
13
+ authenticateNPM(username: string, password: string): Promise<void>;
13
14
  }
14
15
  export default PaasLogin;
@@ -2,9 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const fs_1 = tslib_1.__importDefault(require("fs"));
5
+ const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
5
6
  const command_1 = require("@oclif/command");
6
7
  const cli_ux_1 = tslib_1.__importDefault(require("cli-ux"));
7
8
  const PaasKommand_1 = require("../../support/PaasKommand");
9
+ const child_process_1 = require("child_process");
8
10
  class PaasLogin extends PaasKommand_1.PaasKommand {
9
11
  async runSafe() {
10
12
  this.createKourouDir();
@@ -16,24 +18,44 @@ class PaasLogin extends PaasKommand_1.PaasKommand {
16
18
  : await cli_ux_1.default.prompt(` Password`, { type: 'hide' });
17
19
  await this.initPaasClient({ username, password });
18
20
  const apiKey = await this.paas.auth.createApiKey('Kourou PaaS API Key');
19
- this.createNamespaceCredentials(apiKey);
21
+ this.createProjectCredentials(apiKey);
22
+ await this.authenticateNPM(username, password);
23
+ this.logOk(`Successfully logged in as ${username}. Your Kuzzle Enterprise license is now enabled on this host.`);
20
24
  }
21
- createNamespaceCredentials(apiKey) {
22
- const namespace = this.getNamespace();
23
- const namespaceFile = this.fileNamespaceCredentials(namespace);
25
+ createProjectCredentials(apiKey) {
26
+ const project = this.getProject();
27
+ const projectFile = this.fileProjectCredentials(project);
24
28
  const credentials = {
25
29
  apiKey: apiKey._source.token,
26
30
  };
27
- this.logInfo(`Saving credentials for namespace "${namespace}" in "${namespaceFile}".`);
28
- fs_1.default.writeFileSync(namespaceFile, JSON.stringify(credentials, null, 2));
29
- fs_1.default.chmodSync(namespaceFile, 0o600);
31
+ this.logInfo(`Saving credentials for project "${project}" in "${projectFile}".`);
32
+ fs_1.default.writeFileSync(projectFile, JSON.stringify(credentials, null, 2));
33
+ fs_1.default.chmodSync(projectFile, 0o600);
34
+ }
35
+ async authenticateNPM(username, password) {
36
+ const options = {
37
+ method: 'PUT',
38
+ headers: {
39
+ 'Content-Type': 'application/json',
40
+ 'Accept': 'application/json',
41
+ 'Authorization': `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`
42
+ },
43
+ body: JSON.stringify({
44
+ name: username,
45
+ password,
46
+ })
47
+ };
48
+ const response = await (0, node_fetch_1.default)(`https://packages.paas.kuzzle.io/-/user/org.couchdb.user:${username}`, options);
49
+ const { token } = await response.json();
50
+ (0, child_process_1.spawnSync)('npm', ['config', 'set', '@kuzzleio:registry', 'https://packages.paas.kuzzle.io'], { stdio: 'inherit' });
51
+ (0, child_process_1.spawnSync)('npm', ['set', '//packages.paas.kuzzle.io/:_authToken', token], { stdio: 'inherit' });
30
52
  }
31
53
  }
32
- PaasLogin.description = 'Login for a PaaS namespace';
54
+ PaasLogin.description = 'Login for a PaaS project';
33
55
  PaasLogin.flags = {
34
56
  help: command_1.flags.help(),
35
- namespace: command_1.flags.string({
36
- description: 'Current PaaS namespace'
57
+ project: command_1.flags.string({
58
+ description: 'Current PaaS project'
37
59
  }),
38
60
  username: command_1.flags.string({
39
61
  description: 'PaaS username',
@@ -0,0 +1,17 @@
1
+ import { flags } from "@oclif/command";
2
+ import { PaasKommand } from "../../support/PaasKommand";
3
+ declare class PaasLogs extends PaasKommand {
4
+ static description: string;
5
+ static flags: {
6
+ help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
7
+ project: flags.IOptionFlag<string | undefined>;
8
+ };
9
+ static args: {
10
+ name: string;
11
+ description: string;
12
+ required: boolean;
13
+ }[];
14
+ runSafe(): Promise<void>;
15
+ getCredentials(): Promise<any>;
16
+ }
17
+ export default PaasLogs;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const command_1 = require("@oclif/command");
5
+ const PaasKommand_1 = require("../../support/PaasKommand");
6
+ const fs_1 = tslib_1.__importDefault(require("fs"));
7
+ const login_1 = tslib_1.__importDefault(require("./login"));
8
+ const cli_ux_1 = require("cli-ux");
9
+ class PaasLogs extends PaasKommand_1.PaasKommand {
10
+ async runSafe() {
11
+ const apiKey = await this.getCredentials();
12
+ await this.initPaasClient({ apiKey });
13
+ const user = await this.paas.auth.getCurrentUser();
14
+ this.logInfo(`Logged as "${user._id}" for project "${this.flags.project || this.getProject()}"`);
15
+ const logs = await this.paas.query({
16
+ controller: 'application',
17
+ action: 'logs',
18
+ environmentId: this.args.environment,
19
+ projectId: this.flags.project || this.getProject(),
20
+ applicationId: this.args.application,
21
+ });
22
+ this.logOk(logs.result.join('\n '));
23
+ }
24
+ async getCredentials() {
25
+ const project = this.getProject();
26
+ const projectFile = this.fileProjectCredentials(project);
27
+ if (!fs_1.default.existsSync(projectFile)) {
28
+ this.log('');
29
+ const nextStep = await cli_ux_1.cli.prompt('Cannot find credentials for this project. Do you want to login first? [Y/N]', { type: 'single' });
30
+ this.log('');
31
+ if (nextStep.toLowerCase().startsWith('y')) {
32
+ await login_1.default.run(['--project', project]);
33
+ }
34
+ else {
35
+ this.logKo('Aborting.');
36
+ process.exit(1);
37
+ }
38
+ }
39
+ const credentials = JSON.parse(fs_1.default.readFileSync(projectFile, 'utf8'));
40
+ return credentials.apiKey;
41
+ }
42
+ }
43
+ PaasLogs.description = 'Show logs of the targeted application';
44
+ PaasLogs.flags = {
45
+ help: command_1.flags.help(),
46
+ project: command_1.flags.string({
47
+ description: 'Current PaaS project'
48
+ }),
49
+ };
50
+ PaasLogs.args = [
51
+ { name: 'environment', description: 'Kuzzle PaaS environment', required: true },
52
+ { name: 'application', description: 'Kuzzle PaaS application', required: true },
53
+ ];
54
+ exports.default = PaasLogs;
package/lib/common.js CHANGED
@@ -104,10 +104,16 @@ class Kommand extends command_1.Command {
104
104
  ? ` (https://docs.kuzzle.io/core/2/api/errors/error-codes/${error.id.split('.')[0]})`
105
105
  : '';
106
106
  this.logKo(`Error stack: \n${stack || error.message}\n\nError status: ${error.status}\n\nError id: ${error.id}${errorLink}`);
107
- for (const e of error.errors) {
108
- this.logKo(`${e.document._id} : ${e.reason}`);
107
+ if (Array.isArray(error.errors)) {
108
+ for (const e of error.errors) {
109
+ this.logKo(`${e.document._id} : ${e.reason}`);
110
+ }
111
+ }
112
+ else {
113
+ this.logKo(JSON.stringify(error.reason));
109
114
  }
110
115
  err = true;
116
+ this.exitCode = 1;
111
117
  }
112
118
  finally {
113
119
  if (kommand.id !== undefined) {
@@ -122,6 +128,7 @@ class Kommand extends command_1.Command {
122
128
  ]);
123
129
  }
124
130
  this.sdk.disconnect();
131
+ process.exit(this.exitCode);
125
132
  }
126
133
  return this.exitCode;
127
134
  }
@@ -10,13 +10,13 @@ export declare class PaasKommand extends Kommand {
10
10
  static initSdk: boolean;
11
11
  protected host: string;
12
12
  protected port: number;
13
- protected ssl: boolean;
13
+ protected ssl: any;
14
14
  protected paas: KuzzleSDK;
15
15
  initPaasClient(credentials: PaaSClientCredentials): Promise<void>;
16
- fileNamespaceCredentials(namespace: string): string;
16
+ fileProjectCredentials(project: string): string;
17
17
  /**
18
- * Retrieve the current namespace name from the command line or current package.json
18
+ * Retrieve the current project name from the command line or current package.json
19
19
  */
20
- getNamespace(): any;
20
+ getProject(): any;
21
21
  }
22
22
  export {};
@@ -9,9 +9,15 @@ const kuzzle_1 = require("./kuzzle");
9
9
  class PaasKommand extends common_1.Kommand {
10
10
  constructor() {
11
11
  super(...arguments);
12
- this.host = 'api.console.paas.kuzzle.io';
13
- this.port = 443;
14
- this.ssl = true;
12
+ this.host = process.env.KUZZLE_PAAS_HOST
13
+ ? process.env.KUZZLE_PAAS_HOST
14
+ : 'console.paas.kuzzle.io';
15
+ this.port = process.env.KUZZLE_PAAS_PORT
16
+ ? parseInt(process.env.KUZZLE_PAAS_PORT)
17
+ : 443;
18
+ this.ssl = process.env.KUZZLE_PAAS_SSL
19
+ ? JSON.parse(process.env.KUZZLE_PAAS_SSL)
20
+ : true;
15
21
  // Instantiate a dummy SDK to avoid the this.paas? notation everywhere -_-
16
22
  this.paas = new kuzzle_1.KuzzleSDK({});
17
23
  }
@@ -28,24 +34,24 @@ class PaasKommand extends common_1.Kommand {
28
34
  throw error;
29
35
  }
30
36
  }
31
- fileNamespaceCredentials(namespace) {
32
- return path_1.default.join(this.kourouDir, `${namespace}.paas.json`);
37
+ fileProjectCredentials(project) {
38
+ return path_1.default.join(this.kourouDir, `${project}.paas.json`);
33
39
  }
34
40
  /**
35
- * Retrieve the current namespace name from the command line or current package.json
41
+ * Retrieve the current project name from the command line or current package.json
36
42
  */
37
- getNamespace() {
43
+ getProject() {
38
44
  const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
39
45
  if (fs_1.default.existsSync(packageJsonPath)) {
40
46
  const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
41
47
  if (packageJson.kuzzle && packageJson.kuzzle.paas) {
42
- return packageJson.kuzzle.paas.namespace;
48
+ return packageJson.kuzzle.paas.project;
43
49
  }
44
50
  }
45
- if (!this.flags.namespace) {
46
- throw new Error('Cannot find PaaS namespace in package.json or command line');
51
+ if (!this.flags.project) {
52
+ throw new Error('Cannot find PaaS project in package.json or command line');
47
53
  }
48
- return this.flags.namespace;
54
+ return this.flags.project;
49
55
  }
50
56
  }
51
57
  exports.PaasKommand = PaasKommand;
@@ -44,7 +44,7 @@ export declare class KuzzleSDK {
44
44
  get index(): import("kuzzle-sdk").IndexController;
45
45
  get security(): import("kuzzle-sdk/src/controllers/Security").SecurityController;
46
46
  get auth(): import("kuzzle-sdk").AuthController;
47
- get server(): any;
47
+ get server(): import("kuzzle-sdk").ServerController;
48
48
  get realtime(): import("kuzzle-sdk").RealtimeController;
49
49
  get ms(): any;
50
50
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kourou",
3
3
  "description": "The CLI that helps you manage your Kuzzle instances",
4
- "version": "0.21.1",
4
+ "version": "0.24.0",
5
5
  "author": "The Kuzzle Team <support@kuzzle.io>",
6
6
  "bin": {
7
7
  "kourou": "./bin/run"
@@ -39,10 +39,12 @@
39
39
  "lodash": "^4.17.21",
40
40
  "ndjson": "^2.0.0",
41
41
  "node-emoji": "^1.10.0",
42
+ "node-fetch": "^2.6.7",
42
43
  "production": "0.0.2",
43
44
  "strip-json-comments": "^3.1.1",
44
45
  "tmp": "^0.2.1",
45
- "tslib": "^2.3.1"
46
+ "tslib": "^2.3.1",
47
+ "ws": "^8.8.0"
46
48
  },
47
49
  "devDependencies": {
48
50
  "@istanbuljs/nyc-config-typescript": "^1.0.1",
@@ -54,6 +56,8 @@
54
56
  "@types/mocha": "^8.2.2",
55
57
  "@types/node": "^14.14.41",
56
58
  "@types/node-emoji": "^1.8.1",
59
+ "@types/node-fetch": "^2.6.1",
60
+ "@types/ws": "^8.5.3",
57
61
  "@typescript-eslint/eslint-plugin": "^4.22.0",
58
62
  "@typescript-eslint/parser": "^4.22.0",
59
63
  "chai": "^4.3.4",