kourou
Advanced tools
Comparing version 0.1.2 to 0.2.0
@@ -7,2 +7,3 @@ import { flags } from '@oclif/command'; | ||
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>; | ||
check: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>; | ||
version: flags.IOptionFlag<string>; | ||
@@ -15,5 +16,5 @@ }; | ||
checkPrerequisites(): Promise<boolean>; | ||
getDocoFileName(): string; | ||
generateDocoFile(version?: string): string; | ||
getESVersion(kuzzleVersion: string): string; | ||
private generateDocoFile; | ||
private isPortAvailable; | ||
private findAvailablePort; | ||
} |
@@ -8,10 +8,81 @@ "use strict"; | ||
const cli_ux_1 = tslib_1.__importDefault(require("cli-ux")); | ||
const common_1 = require("../../common"); | ||
const compare_version_1 = tslib_1.__importDefault(require("compare-version")); | ||
const node_emoji_1 = tslib_1.__importDefault(require("node-emoji")); | ||
const execa_1 = tslib_1.__importDefault(require("execa")); | ||
const fs_1 = require("fs"); | ||
const listr_1 = tslib_1.__importDefault(require("listr")); | ||
const net_1 = tslib_1.__importDefault(require("net")); | ||
const node_emoji_1 = tslib_1.__importDefault(require("node-emoji")); | ||
const common_1 = require("../../common"); | ||
const MIN_MAX_MAP_COUNT = 262144; | ||
const MIN_DOCO_VERSION = '1.12.0'; | ||
const kuzzleStackV1 = (increment) => ` | ||
version: '3' | ||
services: | ||
kuzzle: | ||
image: kuzzleio/kuzzle:1 | ||
ports: | ||
- "${7512 + increment}:7512" | ||
- "${1883 + increment}:1883" | ||
- "${9229 + increment}:9229" | ||
cap_add: | ||
- SYS_PTRACE | ||
depends_on: | ||
- redis | ||
- elasticsearch | ||
environment: | ||
- kuzzle_services__db__client__host=http://elasticsearch:9200 | ||
- kuzzle_services__internalCache__node__host=redis | ||
- kuzzle_services__memoryStorage__node__host=redis | ||
- NODE_ENV=development | ||
- DEBUG=kuzzle:*,-kuzzle:entry-point:protocols:websocket | ||
redis: | ||
image: redis:5 | ||
elasticsearch: | ||
image: kuzzleio/elasticsearch:5.6.10 | ||
ports: | ||
- "${9200 + increment}:9200" | ||
ulimits: | ||
nofile: 65536 | ||
environment: | ||
- cluster.name=kuzzle | ||
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" | ||
`; | ||
const kuzzleStackV2 = (increment) => ` | ||
version: '3' | ||
services: | ||
kuzzle: | ||
image: kuzzleio/kuzzle:2 | ||
ports: | ||
- "${7512 + increment}:7512" | ||
- "${1883 + increment}:1883" | ||
- "${9229 + increment}:9229" | ||
cap_add: | ||
- SYS_PTRACE | ||
depends_on: | ||
- redis | ||
- elasticsearch | ||
environment: | ||
- kuzzle_services__storageEngine__client__node=http://elasticsearch:9200 | ||
- kuzzle_services__internalCache__node__host=redis | ||
- kuzzle_services__memoryStorage__node__host=redis | ||
- kuzzle_server__protocols__mqtt__enabled=true | ||
- kuzzle_server__protocols__mqtt__developmentMode=false | ||
- kuzzle_limits__loginsPerSecond=50 | ||
- NODE_ENV=development | ||
- DEBUG=kuzzle:*,-kuzzle:entry-point:protocols:websocket | ||
redis: | ||
image: redis:5 | ||
elasticsearch: | ||
image: kuzzleio/elasticsearch:7 | ||
ports: | ||
- "${9200 + increment}:9200" | ||
ulimits: | ||
nofile: 65536 | ||
`; | ||
class InstanceSpawn extends common_1.Kommand { | ||
@@ -22,26 +93,20 @@ /** | ||
async run() { | ||
this.log(''); | ||
this.log(`${common_1.printCliName()} - ${InstanceSpawn.description}`); | ||
this.log(''); | ||
const { flags } = this.parse(InstanceSpawn); | ||
const dockerComposeFileName = this.getDocoFileName(); | ||
if ((await this.checkPrerequisites()) === true) { | ||
this.log(''); | ||
this.log(`${node_emoji_1.default.get('ok_hand')} Prerequisites are ${chalk_1.default.green.bold('OK')}!`); | ||
this.log(`\n${common_1.printCliName()} - ${InstanceSpawn.description}\n`); | ||
const { flags: userFlags } = this.parse(InstanceSpawn); | ||
const portIndex = await this.findAvailablePort(); | ||
const dockerComposeFileName = `/tmp/kuzzle-stack-${portIndex}.yml`; | ||
const successfullCheck = userFlags.check ? | ||
await this.checkPrerequisites() : | ||
true; | ||
if (userFlags.check && successfullCheck) { | ||
this.log(`\n${node_emoji_1.default.get('ok_hand')} Prerequisites are ${chalk_1.default.green.bold('OK')}!`); | ||
} | ||
else { | ||
this.log(''); | ||
else if (userFlags.check && !successfullCheck) { | ||
throw new Error(`${node_emoji_1.default.get('shrug')} Your system doesn't satisfy all the prerequisites. Cannot run Kuzzle.`); | ||
} | ||
this.log(''); | ||
this.log(chalk_1.default.grey(`Writing docker-compose file to ${dockerComposeFileName}...`)); | ||
fs_1.writeFileSync(dockerComposeFileName, this.generateDocoFile(flags.version)); | ||
const doco = child_process_1.spawn('docker-compose', [ | ||
'-f', | ||
dockerComposeFileName, | ||
'up', | ||
'-d' | ||
]); | ||
cli_ux_1.default.action.start(` ${node_emoji_1.default.get('rocket')} Kuzzle version ${flags.version} is launching`, undefined, { | ||
stdout: true | ||
this.log(chalk_1.default.grey(`\nWriting docker-compose file to ${dockerComposeFileName}...`)); | ||
fs_1.writeFileSync(dockerComposeFileName, this.generateDocoFile(userFlags.version, portIndex)); | ||
const doco = child_process_1.spawn('docker-compose', ['-f', dockerComposeFileName, '-p', `stack-${portIndex}`, 'up', '-d']); | ||
cli_ux_1.default.action.start(` ${node_emoji_1.default.get('rocket')} Kuzzle version ${userFlags.version} is launching`, undefined, { | ||
stdout: true, | ||
}); | ||
@@ -51,7 +116,9 @@ doco.on('close', docoCode => { | ||
cli_ux_1.default.action.stop('done'); | ||
this.log(''); | ||
this.log(`${node_emoji_1.default.get('thumbsup')} ${chalk_1.default.bold('Kuzzle is booting')} in the background right now.`); | ||
this.log(`\n${node_emoji_1.default.get('thumbsup')} ${chalk_1.default.bold('Kuzzle is booting')} in the background right now.`); | ||
this.log(chalk_1.default.grey('To watch the logs, run')); | ||
this.log(chalk_1.default.grey(` docker-compose -f ${this.getDocoFileName()} logs -f`)); | ||
this.log(''); | ||
this.log(chalk_1.default.grey(` docker-compose -f ${dockerComposeFileName} -p stack-${portIndex} logs -f\n`)); | ||
this.log(` Kuzzle port: ${7512 + portIndex}`); | ||
this.log(` MQTT port: ${1883 + portIndex}`); | ||
this.log(` Node.js debugger port: ${9229 + portIndex}`); | ||
this.log(` Elasticsearch port: ${9200 + portIndex}`); | ||
} | ||
@@ -61,4 +128,3 @@ else { | ||
this.log(chalk_1.default.grey('If you want to investigate the problem, try running')); | ||
this.log(chalk_1.default.grey(` docker-compose -f ${this.getDocoFileName()} up`)); | ||
this.log(''); | ||
this.log(chalk_1.default.grey(` docker-compose -f ${dockerComposeFileName} -p stack-${portIndex} up\n`)); | ||
throw new Error('docker-compose exited witn non-zero status'); | ||
@@ -80,9 +146,9 @@ } | ||
} | ||
const version = matches.length > 0 ? matches[1] : null; | ||
if (version === null) { | ||
throw new Error('Unable to read docker-compose verson. This is weird.'); | ||
const docoVersion = matches.length > 0 ? matches[1] : null; | ||
if (docoVersion === null) { | ||
throw new Error('Unable to read docker-compose version. This is weird.'); | ||
} | ||
try { | ||
if (compare_version_1.default(version, MIN_DOCO_VERSION) === -1) { | ||
throw new Error(`The detected version of docker-compose (${version}) is not recent enough (${MIN_DOCO_VERSION})`); | ||
if (compare_version_1.default(docoVersion, MIN_DOCO_VERSION) === -1) { | ||
throw new Error(`The detected version of docker-compose (${docoVersion}) is not recent enough (${MIN_DOCO_VERSION})`); | ||
} | ||
@@ -97,3 +163,3 @@ } | ||
} | ||
} | ||
}, | ||
}, | ||
@@ -106,3 +172,3 @@ { | ||
'-n', | ||
'vm.max_map_count' | ||
'vm.max_map_count', | ||
]); | ||
@@ -120,4 +186,4 @@ if (sysctl.exitCode !== 0) { | ||
} | ||
} | ||
} | ||
}, | ||
}, | ||
]); | ||
@@ -133,42 +199,33 @@ try { | ||
} | ||
getDocoFileName() { | ||
return '/tmp/kuzzle-stack.yml'; | ||
generateDocoFile(kuzzleMajor, portIndex) { | ||
if (kuzzleMajor === '1') { | ||
return kuzzleStackV1(portIndex); | ||
} | ||
return kuzzleStackV2(portIndex); | ||
} | ||
generateDocoFile(version = '2') { | ||
return `version: '3' | ||
services: | ||
kuzzle: | ||
image: kuzzleio/kuzzle:${version} | ||
ports: | ||
- "7512:7512" | ||
- "1883:1883" | ||
cap_add: | ||
- SYS_PTRACE | ||
depends_on: | ||
- redis | ||
- elasticsearch | ||
environment: | ||
- kuzzle_services__storageEngine__client__node=http://elasticsearch:9200 | ||
- kuzzle_services__internalCache__node__host=redis | ||
- kuzzle_services__memoryStorage__node__host=redis | ||
- kuzzle_server__protocols__mqtt__enabled=true | ||
- NODE_ENV=production | ||
redis: | ||
image: redis:5 | ||
elasticsearch: | ||
image: kuzzleio/elasticsearch:${this.getESVersion(version)} | ||
ulimits: | ||
nofile: 65536`; | ||
isPortAvailable(port) { | ||
return new Promise((resolve, reject) => { | ||
const tester = net_1.default.createServer() | ||
.once('error', error => { | ||
if (!error.message.match(/EADDRINUSE/)) { | ||
reject(error); | ||
} | ||
resolve(false); | ||
}) | ||
.once('listening', () => { | ||
tester | ||
.once('close', () => resolve(true)) | ||
.close(); | ||
}) | ||
.listen(port); | ||
}); | ||
} | ||
getESVersion(kuzzleVersion) { | ||
switch (kuzzleVersion) { | ||
case '1': | ||
return '5.6.10'; | ||
case '2': | ||
return '7.4.0'; | ||
default: | ||
throw new Error(`Invalid Kuzzle Core version number: ${kuzzleVersion}`); | ||
async findAvailablePort() { | ||
let i = 0; | ||
// eslint-disable-next-line | ||
while (true) { | ||
if (await this.isPortAvailable(7512 + i)) { | ||
return i; | ||
} | ||
i++; | ||
} | ||
@@ -180,8 +237,12 @@ } | ||
InstanceSpawn.flags = { | ||
help: command_1.flags.help({ char: 'h' }), | ||
help: command_1.flags.help(), | ||
check: command_1.flags.boolean({ | ||
description: 'Check prerequisite before running Kuzzle', | ||
default: false, | ||
}), | ||
version: command_1.flags.string({ | ||
char: 'v', | ||
description: 'Core-version of the instance to spawn', | ||
default: '2' | ||
}) | ||
default: '2', | ||
}), | ||
}; |
@@ -1,1 +0,1 @@ | ||
{"version":"0.1.2","commands":{"instance:spawn":{"id":"instance:spawn","description":"Spawn a new Kuzzle instance","pluginName":"kourou","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"version":{"name":"version","type":"option","char":"v","description":"Core-version of the instance to spawn","default":"2"}},"args":[]}}} | ||
{"version":"0.2.0","commands":{"api-key:create":{"id":"api-key:create","description":"Creates a new API Key for an user","pluginName":"kourou","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","description":"show CLI help","allowNo":false},"user":{"name":"user","type":"option","char":"u","description":"User kuid","required":true},"description":{"name":"description","type":"option","char":"d","description":"API Key description","required":true},"id":{"name":"id","type":"option","description":"API Key unique ID"},"expire":{"name":"expire","type":"option","description":"API Key validity","default":"-1"},"host":{"name":"host","type":"option","char":"h","description":"Kuzzle server host","default":"localhost"},"port":{"name":"port","type":"option","char":"p","description":"Kuzzle server port","default":"7512"},"ssl":{"name":"ssl","type":"boolean","description":"Use SSL to connect to Kuzzle","allowNo":false},"username":{"name":"username","type":"option","description":"Kuzzle user","default":"anonymous"},"password":{"name":"password","type":"option","description":"Kuzzle user password"}},"args":[]},"api-key:delete":{"id":"api-key:delete","description":"Deletes a new API Key for an user","pluginName":"kourou","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","description":"show CLI help","allowNo":false},"user":{"name":"user","type":"option","char":"u","description":"User kuid","required":true},"id":{"name":"id","type":"option","description":"API Key unique ID"},"host":{"name":"host","type":"option","char":"h","description":"Kuzzle server host","default":"localhost"},"port":{"name":"port","type":"option","char":"p","description":"Kuzzle server port","default":"7512"},"ssl":{"name":"ssl","type":"boolean","description":"Use SSL to connect to Kuzzle","allowNo":false},"username":{"name":"username","type":"option","description":"Kuzzle user","default":"anonymous"},"password":{"name":"password","type":"option","description":"Kuzzle user password"}},"args":[]},"api-key:search":{"id":"api-key:search","description":"List an user API Keys","pluginName":"kourou","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","description":"show CLI help","allowNo":false},"user":{"name":"user","type":"option","char":"u","description":"User kuid","required":true},"filter":{"name":"filter","type":"option","description":"Filter to match the API Key descriptions"},"host":{"name":"host","type":"option","char":"h","description":"Kuzzle server host","default":"localhost"},"port":{"name":"port","type":"option","char":"p","description":"Kuzzle server port","default":"7512"},"ssl":{"name":"ssl","type":"boolean","description":"Use SSL to connect to Kuzzle","allowNo":false},"username":{"name":"username","type":"option","description":"Kuzzle user","default":"anonymous"},"password":{"name":"password","type":"option","description":"Kuzzle user password"}},"args":[]},"instance:spawn":{"id":"instance:spawn","description":"Spawn a new Kuzzle instance","pluginName":"kourou","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","description":"show CLI help","allowNo":false},"check":{"name":"check","type":"boolean","description":"Check prerequisite before running Kuzzle","allowNo":false},"version":{"name":"version","type":"option","char":"v","description":"Core-version of the instance to spawn","default":"2"}},"args":[]}}} |
{ | ||
"name": "kourou", | ||
"description": "The CLI that helps you manage your Kuzzle instances", | ||
"version": "0.1.2", | ||
"author": "Luca Marchesini @xbill82", | ||
"version": "0.2.0", | ||
"author": "The Kuzzle Team <support@kuzzle.io>", | ||
"bin": { | ||
@@ -18,2 +18,3 @@ "kourou": "./bin/run" | ||
"execa": "^3.4.0", | ||
"kuzzle-sdk": "^7.0.1", | ||
"listr": "^0.14.3", | ||
@@ -33,2 +34,3 @@ "node-emoji": "^1.10.0", | ||
"chai": "^4.2.0", | ||
"cucumber": "^6.0.5", | ||
"eslint": "^5.16.0", | ||
@@ -42,2 +44,3 @@ "eslint-config-oclif": "^3.1.0", | ||
"ts-node": "^8.5.4", | ||
"should": "^13.2.3", | ||
"typescript": "^3.7.4" | ||
@@ -59,3 +62,3 @@ }, | ||
], | ||
"license": "MIT", | ||
"license": "Apache-2.0", | ||
"main": "lib/index.js", | ||
@@ -72,8 +75,10 @@ "oclif": { | ||
"postpack": "rm -f oclif.manifest.json", | ||
"posttest": "eslint . --ext .ts --config .eslintrc", | ||
"prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme", | ||
"test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"", | ||
"version": "oclif-dev readme && git add README.md" | ||
"version": "oclif-dev readme && git add README.md", | ||
"test:lint": "eslint . --fix --ext .ts --config .eslintrc", | ||
"test:functional": "npm run test:functional:stdout && npm run test:functional:cucumber", | ||
"test:functional:stdout": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"", | ||
"test:functional:cucumber": "./node_modules/.bin/cucumber-js" | ||
}, | ||
"types": "lib/index.d.ts" | ||
} |
@@ -25,3 +25,3 @@ # kourou | ||
$ kourou (-v|--version|version) | ||
kourou/0.1.2 linux-x64 node-v10.12.0 | ||
kourou/0.2.0 linux-x64 node-v12.14.0 | ||
$ kourou --help [COMMAND] | ||
@@ -34,8 +34,98 @@ USAGE | ||
## Connect and authenticate to Kuzzle API | ||
Commands that needs to send requests to Kuzzle API can specify the Kuzzle server address and authentication informations. | ||
By command line: | ||
``` | ||
-h, --host=host [default: localhost] Kuzzle server host | ||
-p, --port=port [default: 7512] Kuzzle server port | ||
--username=username [default: anonymous] Kuzzle user | ||
--password=password Kuzzle user password | ||
--ssl [default: true for port 443] Use SSL to connect to Kuzzle | ||
``` | ||
By environment variables: | ||
``` | ||
KUZZLE_HOST [default: localhost] Kuzzle server host | ||
KUZZLE_PORT [default: 7512] Kuzzle server port | ||
KUZZLE_USERNAME [default: anonymous] Kuzzle user | ||
KUZZLE_PASSWORD Kuzzle user password | ||
KUZZLE_SSL Use SSL to connect to Kuzzle | ||
``` | ||
# Commands | ||
<!-- commands --> | ||
* [`kourou api-key:create`](#kourou-api-keycreate) | ||
* [`kourou api-key:delete`](#kourou-api-keydelete) | ||
* [`kourou api-key:search`](#kourou-api-keysearch) | ||
* [`kourou help [COMMAND]`](#kourou-help-command) | ||
* [`kourou instance:spawn`](#kourou-instancespawn) | ||
## `kourou api-key:create` | ||
Creates a new API Key for an user | ||
``` | ||
USAGE | ||
$ kourou api-key:create | ||
OPTIONS | ||
-d, --description=description (required) API Key description | ||
-h, --host=host [default: localhost] Kuzzle server host | ||
-p, --port=port [default: 7512] Kuzzle server port | ||
-u, --user=user (required) User kuid | ||
--expire=expire [default: -1] API Key validity | ||
--help show CLI help | ||
--id=id API Key unique ID | ||
--password=password Kuzzle user password | ||
--ssl Use SSL to connect to Kuzzle | ||
--username=username [default: anonymous] Kuzzle user | ||
``` | ||
_See code: [src/commands/api-key/create.ts](https://github.com/kuzzleio/kourou/blob/v0.2.0/src/commands/api-key/create.ts)_ | ||
## `kourou api-key:delete` | ||
Deletes a new API Key for an user | ||
``` | ||
USAGE | ||
$ kourou api-key:delete | ||
OPTIONS | ||
-h, --host=host [default: localhost] Kuzzle server host | ||
-p, --port=port [default: 7512] Kuzzle server port | ||
-u, --user=user (required) User kuid | ||
--help show CLI help | ||
--id=id API Key unique ID | ||
--password=password Kuzzle user password | ||
--ssl Use SSL to connect to Kuzzle | ||
--username=username [default: anonymous] Kuzzle user | ||
``` | ||
_See code: [src/commands/api-key/delete.ts](https://github.com/kuzzleio/kourou/blob/v0.2.0/src/commands/api-key/delete.ts)_ | ||
## `kourou api-key:search` | ||
List an user API Keys | ||
``` | ||
USAGE | ||
$ kourou api-key:search | ||
OPTIONS | ||
-h, --host=host [default: localhost] Kuzzle server host | ||
-p, --port=port [default: 7512] Kuzzle server port | ||
-u, --user=user (required) User kuid | ||
--filter=filter Filter to match the API Key descriptions | ||
--help show CLI help | ||
--password=password Kuzzle user password | ||
--ssl Use SSL to connect to Kuzzle | ||
--username=username [default: anonymous] Kuzzle user | ||
``` | ||
_See code: [src/commands/api-key/search.ts](https://github.com/kuzzleio/kourou/blob/v0.2.0/src/commands/api-key/search.ts)_ | ||
## `kourou help [COMMAND]` | ||
@@ -67,7 +157,8 @@ | ||
OPTIONS | ||
-h, --help show CLI help | ||
-v, --version=version [default: 2] Core-version of the instance to spawn | ||
--check Check prerequisite before running Kuzzle | ||
--help show CLI help | ||
``` | ||
_See code: [src/commands/instance/spawn.ts](https://github.com/kuzzleio/kourou/blob/v0.1.2/src/commands/instance/spawn.ts)_ | ||
_See code: [src/commands/instance/spawn.ts](https://github.com/kuzzleio/kourou/blob/v0.2.0/src/commands/instance/spawn.ts)_ | ||
<!-- commandsstop --> | ||
@@ -74,0 +165,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 5 instances in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
31718
19
548
166
11
20
7
4
+ Addedkuzzle-sdk@^7.0.1
+ Addedkuzzle-sdk@7.11.3(transitive)
+ Addedmin-req-promise@1.0.1(transitive)
+ Addedws@8.17.1(transitive)