kourou 0.21.1 → 0.22.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.22.0 linux-x64 node-v16.15.0
30
30
  $ kourou --help [COMMAND]
31
31
  USAGE
32
32
  $ kourou COMMAND
@@ -155,9 +155,10 @@ All other arguments and options will be passed as-is to the `sdk:query` method.
155
155
  * [`kourou instance:list`](#kourou-instancelist)
156
156
  * [`kourou instance:logs`](#kourou-instancelogs)
157
157
  * [`kourou instance:spawn`](#kourou-instancespawn)
158
- * [`kourou paas:init USERNAME NAMESPACE`](#kourou-paasinit-username-namespace)
158
+ * [`kourou paas:deploy ENVIRONMENT IMAGE`](#kourou-paasdeploy-environment-image)
159
+ * [`kourou paas:init PROJECT`](#kourou-paasinit-project)
159
160
  * [`kourou paas:login`](#kourou-paaslogin)
160
- * [`kourou paas:publish PROJECT IMAGE`](#kourou-paaspublish-project-image)
161
+ * [`kourou paas:logs ENVIRONMENT APPLICATION`](#kourou-paaslogs-environment-application)
161
162
  * [`kourou profile:export`](#kourou-profileexport)
162
163
  * [`kourou profile:import PATH`](#kourou-profileimport-path)
163
164
  * [`kourou realtime:subscribe INDEX COLLECTION [FILTERS]`](#kourou-realtimesubscribe-index-collection-filters)
@@ -602,9 +603,12 @@ USAGE
602
603
  OPTIONS
603
604
  --batch-size=batch-size [default: 1000] How many documents to move in batch per operation
604
605
  --dest=dest (required) Destination Elasticsearch server URL
606
+ --dry-run Print witch collections will be migrated
605
607
  --help show CLI help
606
608
  --no-interactive Skip confirmation interactive prompts (perfect for scripting)
609
+ --pattern=pattern Pattern to match indices to migrate
607
610
  --reset Reset destination Elasticsearch server
611
+ --scroll=scroll [default: 30s] Scroll duration for Elasticsearch scrolling
608
612
  --src=src (required) Source Elasticsearch server URL
609
613
 
610
614
  EXAMPLES
@@ -915,17 +919,36 @@ OPTIONS
915
919
 
916
920
  _See code: [src/commands/instance/spawn.ts](src/commands/instance/spawn.ts)_
917
921
 
918
- ## `kourou paas:init USERNAME NAMESPACE`
922
+ ## `kourou paas:deploy ENVIRONMENT IMAGE`
919
923
 
920
- Initialize a PaaS namespace in current directory
924
+ Deploy a new version of the application in the PaaS
925
+
926
+ ```
927
+ USAGE
928
+ $ kourou paas:deploy ENVIRONMENT IMAGE
929
+
930
+ ARGUMENTS
931
+ ENVIRONMENT Project environment name
932
+ IMAGE Image name and hash as myimage:mytag
933
+
934
+ OPTIONS
935
+ --help show CLI help
936
+ --project=project Current PaaS project
937
+ --token=token Authentication token
938
+ ```
939
+
940
+ _See code: [src/commands/paas/deploy.ts](src/commands/paas/deploy.ts)_
941
+
942
+ ## `kourou paas:init PROJECT`
943
+
944
+ Initialize a PaaS project in current directory
921
945
 
922
946
  ```
923
947
  USAGE
924
- $ kourou paas:init USERNAME NAMESPACE
948
+ $ kourou paas:init PROJECT
925
949
 
926
950
  ARGUMENTS
927
- USERNAME Username
928
- NAMESPACE Namespace
951
+ PROJECT Kuzzle PaaS project name
929
952
 
930
953
  OPTIONS
931
954
  --help show CLI help
@@ -935,39 +958,38 @@ _See code: [src/commands/paas/init.ts](src/commands/paas/init.ts)_
935
958
 
936
959
  ## `kourou paas:login`
937
960
 
938
- Login for a PaaS namespace
961
+ Login for a PaaS project
939
962
 
940
963
  ```
941
964
  USAGE
942
965
  $ kourou paas:login
943
966
 
944
967
  OPTIONS
945
- --help show CLI help
946
- --namespace=namespace Current PaaS namespace
947
- --username=username PaaS username
968
+ --help show CLI help
969
+ --project=project Current PaaS project
970
+ --username=username PaaS username
948
971
  ```
949
972
 
950
973
  _See code: [src/commands/paas/login.ts](src/commands/paas/login.ts)_
951
974
 
952
- ## `kourou paas:publish PROJECT IMAGE`
975
+ ## `kourou paas:logs ENVIRONMENT APPLICATION`
953
976
 
954
- Deploy a new version of the application in the PaaS
977
+ Show logs of the targeted application
955
978
 
956
979
  ```
957
980
  USAGE
958
- $ kourou paas:publish PROJECT IMAGE
981
+ $ kourou paas:logs ENVIRONMENT APPLICATION
959
982
 
960
983
  ARGUMENTS
961
- PROJECT Project name
962
- IMAGE Image name and hash
984
+ ENVIRONMENT Kuzzle PaaS environment
985
+ APPLICATION Kuzzle PaaS application
963
986
 
964
987
  OPTIONS
965
- --help show CLI help
966
- --namespace=namespace Current PaaS namespace
967
- --token=token Authentication token
988
+ --help show CLI help
989
+ --project=project Current PaaS project
968
990
  ```
969
991
 
970
- _See code: [src/commands/paas/publish.ts](src/commands/paas/publish.ts)_
992
+ _See code: [src/commands/paas/logs.ts](src/commands/paas/logs.ts)_
971
993
 
972
994
  ## `kourou profile:export`
973
995
 
@@ -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,61 @@ 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: 'kuzzle',
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: 'image', description: 'Image name and hash as myimage:mytag', required: true },
61
65
  ];
62
- exports.default = PaasPublish;
66
+ 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,8 +104,13 @@ 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;
111
116
  }
@@ -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
+ : 'api.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.22.0",
5
5
  "author": "The Kuzzle Team <support@kuzzle.io>",
6
6
  "bin": {
7
7
  "kourou": "./bin/run"
@@ -39,6 +39,7 @@
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",
@@ -54,6 +55,7 @@
54
55
  "@types/mocha": "^8.2.2",
55
56
  "@types/node": "^14.14.41",
56
57
  "@types/node-emoji": "^1.8.1",
58
+ "@types/node-fetch": "^2.6.1",
57
59
  "@typescript-eslint/eslint-plugin": "^4.22.0",
58
60
  "@typescript-eslint/parser": "^4.22.0",
59
61
  "chai": "^4.3.4",