diff --git a/README.md b/README.md index d8d988d9..dff87e93 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ kaizen upload btfs ./build - [`kaizen install`](commands/install.md) - Install a KAIZEN project from GitHub - [`kaizen upload`](commands/upload.md) - Upload a KAIZEN project - [`kaizen plugins`](commands/plugins.md) - Plugin management for KAIZEN +- [`kaizen instances`](commands/instances.md) - Instances management for KAIZEN - [`kaizen contracts`](commands/contracts.md) - Contract management for KAIZEN - [`kaizen blockchains`](commands/blockchains.md) - Blockchain management for KAIZEN @@ -107,7 +108,7 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to help out. *Quick Start*: Check out [help wanted](https://github.com/PortalNetwork/kaizen-cli/labels/help%20wanted) or [good first issue](https://github.com/PortalNetwork/kaizen-cli/labels/good%20first%20issue) labels to find issues we want to move forward on with your help. ## 📧 Contact -For any questions, please contact chris@portal.network or join telegram: [http://bit.ly/2XjhQV2](http://bit.ly/2XjhQV2) +For any questions, please contact **chris@portal.network** or join telegram: [http://bit.ly/2XjhQV2](http://bit.ly/2XjhQV2) ## 🗒 Licence See [LICENSE](./LICENSE) for details. diff --git a/README_KR.md b/README_KR.md index cf4f53b9..edde9e9c 100644 --- a/README_KR.md +++ b/README_KR.md @@ -67,6 +67,7 @@ kaizen upload btfs ./build - [`kaizen install`](commands/install.md) - Install a KAIZEN project from GitHub - [`kaizen upload`](commands/upload.md) - Upload a KAIZEN project - [`kaizen plugins`](commands/plugins.md) - Plugin management for KAIZEN +- [`kaizen instances`](commands/instances.md) - Instances management for KAIZEN - [`kaizen contracts`](commands/contracts.md) - Contract management for KAIZEN - [`kaizen blockchains`](commands/blockchains.md) - Blockchain management for KAIZEN @@ -107,7 +108,7 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to help out. *Quick Start*: Check out [help wanted](https://github.com/PortalNetwork/kaizen-cli/labels/help%20wanted) or [good first issue](https://github.com/PortalNetwork/kaizen-cli/labels/good%20first%20issue) labels to find issues we want to move forward on with your help. ## 📧 Contact -For any questions, please contact chris@portal.network or join telegram: [http://bit.ly/2XjhQV2](http://bit.ly/2XjhQV2) +For any questions, please contact **chris@portal.network** or join telegram: [http://bit.ly/2XjhQV2](http://bit.ly/2XjhQV2) ## 🗒 라이센스 [LICENSE](./LICENSE) 참조하기 diff --git a/README_ZH.md b/README_ZH.md index 391ce987..a968bfcc 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -67,6 +67,7 @@ kaizen upload btfs ./build - [`kaizen install`](commands/install.md) - 從 GitHub 安裝已經存在的 KAIZEN - [`kaizen upload`](commands/upload.md) - 上傳 KAIZEN 專案 - [`kaizen plugins`](commands/plugins.md) - KAIZEN 插件管理功能 +- [`kaizen instances`](commands/instances.md) - KAIZEN 運行實例管理功能 - [`kaizen contracts`](commands/contracts.md) - KAIZEN 智能合約管理功能 - [`kaizen blockchains`](commands/blockchains.md) - KAIZEN 區塊鏈管理功能 @@ -107,7 +108,7 @@ KAIZEN Faucet 支援下列區塊鏈測試網路的代幣 *快速開始:您可以透過 [help wanted](https://github.com/PortalNetwork/kaizen-cli/labels/help%20wanted) 或者 [good first issue](https://github.com/PortalNetwork/kaizen-cli/labels/good%20first%20issue) 標籤找到可以參與貢獻的任務。 ## 📧 聯絡 -如果您有任何問題請聯繫 chris@portal.network 或者加入我們的 Telegram: [http://bit.ly/2XjhQV2](http://bit.ly/2XjhQV2) +如果您有任何問題請聯繫 **chris@portal.network** 或者加入我們的 Telegram: [http://bit.ly/2XjhQV2](http://bit.ly/2XjhQV2) ## 🗒 許可證 詳細內容請參考 [LICENSE](./LICENSE) diff --git a/build/components/Config/Get/index.js b/build/components/Config/Get/index.js index c3f03cef..2050adc7 100644 --- a/build/components/Config/Get/index.js +++ b/build/components/Config/Get/index.js @@ -19,8 +19,8 @@ function builder(yargs) { alias: 'k', type: 'string', describe: 'Configuration key', - choices: ['privateKey', 'provider', 'networkId'] - }).example('kaizen config get --key provider').demandOption(['key'], ''); + choices: ['privateKey', 'provider', 'networkId', 'accessKey', 'secretKey', 'region'] + }).example('kaizen config get --key provider'); //.demandOption(['key'], ''); } function handler(_x) { @@ -43,9 +43,16 @@ function _handler() { Spinner.stop(); if (kaizenrc[key]) { - Log.NormalLog('Configuration:\n'.underline.yellow + key + ': ' + kaizenrc[key].yellow); + Log.NormalLog('Kaizen Configuration:\n'.underline.yellow + key + ': ' + kaizenrc[key].yellow); } else { - Log.NormalLog("Can not find ".concat(key)); + //Log.NormalLog(`Can not find ${key}`); + Log.NormalLog('Kaizen Configuration:'.underline.yellow); + kaizenrc['privateKey'] ? Log.NormalLog('privateKey' + ': ' + kaizenrc['privateKey'].yellow) : null; + kaizenrc['provider'] ? Log.NormalLog('provider' + ': ' + kaizenrc['provider'].yellow) : null; + kaizenrc['networkId'] ? Log.NormalLog('networkId' + ': ' + kaizenrc['networkId'].yellow) : null; + kaizenrc['accessKey'] ? Log.NormalLog('accessKey' + ': ' + kaizenrc['accessKey'].yellow) : null; + kaizenrc['secretKey'] ? Log.NormalLog('secretKey' + ': ' + kaizenrc['secretKey'].yellow) : null; + kaizenrc['region'] ? Log.NormalLog('region' + ': ' + kaizenrc['region'].yellow) : null; } } catch (error) { Spinner.stop(); diff --git a/build/components/Config/Set/index.js b/build/components/Config/Set/index.js index a3fe7657..f07e6d00 100644 --- a/build/components/Config/Set/index.js +++ b/build/components/Config/Set/index.js @@ -23,7 +23,7 @@ function builder(yargs) { alias: 'k', type: 'string', describe: 'Configuration key', - choices: ['privateKey', 'provider', 'networkId'] + choices: ['privateKey', 'provider', 'networkId', 'accessKey', 'secretKey', 'region'] }).option('value', { alias: 'v', type: 'string', diff --git a/build/components/Config/Unset/index.js b/build/components/Config/Unset/index.js index 71e14cd1..a89b90c3 100644 --- a/build/components/Config/Unset/index.js +++ b/build/components/Config/Unset/index.js @@ -23,7 +23,7 @@ function builder(yargs) { alias: 'k', type: 'string', describe: 'Configuration key', - choices: ['privateKey', 'provider', 'networkId'] + choices: ['privateKey', 'provider', 'networkId', 'accessKey', 'secretKey', 'region'] }).example('kaizen config unset --key provider').demandOption(['key'], ''); } diff --git a/build/components/Instances/List/index.js b/build/components/Instances/List/index.js new file mode 100644 index 00000000..2b3a22da --- /dev/null +++ b/build/components/Instances/List/index.js @@ -0,0 +1,56 @@ +"use strict"; + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var Log = require('../../../lib/Log'); + +var path = require('path'); + +var fsx = require('fs-extra'); + +require('colors'); + +function builder(yargs) {} + +function handler(_x) { + return _handler.apply(this, arguments); +} + +function _handler() { + _handler = _asyncToGenerator( + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee(argv) { + var kaizenrc, i, instance; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + Log.NormalLog('AWS Instance list:'.underline.yellow); + kaizenrc = fsx.readJsonSync(path.resolve(__dirname, '../../../../.kaizenrc')); + + if (kaizenrc['instances']) { + for (i = 0; i < kaizenrc['instances'].length; i++) { + instance = kaizenrc['instances'][i]; + Log.NormalLog('Template: '.yellow + instance.template + ', InstanceId: '.yellow + instance.instanceId); // TODO load instance status + } + } else { + Log.NormalLog("There's no instance running on AWS"); + } + + case 3: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + return _handler.apply(this, arguments); +} + +module.exports = function (yargs) { + var command = 'list'; + var commandDescription = 'List instances of instance name'; + yargs.command(command, commandDescription, builder, handler); +}; \ No newline at end of file diff --git a/build/components/Instances/Run/index.js b/build/components/Instances/Run/index.js new file mode 100644 index 00000000..fa6efc06 --- /dev/null +++ b/build/components/Instances/Run/index.js @@ -0,0 +1,90 @@ +"use strict"; + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var Log = require('../../../lib/Log'); + +var Spinner = require('../../../lib/Spinner'); + +var nymLoopixMixnodeHandler = require('./nym-loopix-mixnode.js'); + +function builder(yargs) { + return yargs.positional('instance', { + alias: 'i', + type: 'string', + describe: 'instance name', + require: true + }).example('kaizen instances run nym-loopix-mixnode').demandOption(['instance'], ''); +} + +function handler(_x) { + return _handler.apply(this, arguments); +} + +function _handler() { + _handler = _asyncToGenerator( + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee(argv) { + var instance; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.prev = 0; + instance = argv.instance; + + if (instance) { + _context.next = 5; + break; + } + + Log.NormalLog('Missing instance name.\nPlease using \'kaizen instances run [instance]\''); + return _context.abrupt("return"); + + case 5: + _context.t0 = instance; + _context.next = _context.t0 === 'nym-loopix-mixnode' ? 8 : 15; + break; + + case 8: + Log.NormalLog("Starting ".concat(instance, " instance, please wait a second...")); + Spinner.start(); + _context.next = 12; + return nymLoopixMixnodeHandler(); + + case 12: + Spinner.stop(); + Log.SuccessLog("Start instance ".concat(instance, " Successfully")); + return _context.abrupt("break", 16); + + case 15: + Log.NormalLog('Instance not support yet'); + + case 16: + _context.next = 23; + break; + + case 18: + _context.prev = 18; + _context.t1 = _context["catch"](0); + Spinner.stop(); + Log.ErrorLog('something went wrong!'); + console.error(_context.t1); + + case 23: + case "end": + return _context.stop(); + } + } + }, _callee, this, [[0, 18]]); + })); + return _handler.apply(this, arguments); +} + +module.exports = function (yargs) { + var command = 'run [instance]'; + var commandDescription = 'Run an instance on AWS'; + yargs.command(command, commandDescription, builder, handler); +}; \ No newline at end of file diff --git a/build/components/Instances/Run/nym-loopix-mixnode.js b/build/components/Instances/Run/nym-loopix-mixnode.js new file mode 100644 index 00000000..632aaec1 --- /dev/null +++ b/build/components/Instances/Run/nym-loopix-mixnode.js @@ -0,0 +1,98 @@ +"use strict"; + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var Log = require('../../../lib/Log'); + +var AWSService = require('../../../lib/aws/AWSService'); + +var path = require('path'); + +var fsx = require('fs-extra'); + +module.exports = +/*#__PURE__*/ +_asyncToGenerator( +/*#__PURE__*/ +regeneratorRuntime.mark(function _callee() { + var kaizenrc, region, awsService, isExists, keyPair, instance, instances, configuration; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.prev = 0; + kaizenrc = fsx.readJsonSync(path.resolve(__dirname, '../../../../.kaizenrc')); + region = 'us-east-1'; + + if (!kaizenrc['accessKey']) { + Log.NormalLog("Please set AWS access key by 'kaizen config set --key accessKey --value [Access Key Value]'"); + } + + if (!kaizenrc['secretKey']) { + Log.NormalLog("Please set AWS secret key by 'kaizen config set --key secretKey --value [Secret Key Value]'"); + } + + if (kaizenrc['region']) { + region = kaizenrc['region']; + } + + awsService = new AWSService(kaizenrc['accessKey'], kaizenrc['secretKey'], region); + _context.next = 9; + return awsService.isKeyPairsExists('kaizen-cli'); + + case 9: + isExists = _context.sent; + keyPair = 'kaizen-cli'; + + if (isExists) { + _context.next = 16; + break; + } + + Log.NormalLog('Creating Key Pair:\n'.underline.yellow + 'kaizen-cli.pem'.yellow); + _context.next = 15; + return awsService.createKeyPair(); + + case 15: + keyPair = _context.sent; + + case 16: + _context.next = 18; + return awsService.runInstance('nym-loopix-mixnode'); + + case 18: + instance = _context.sent; + instances = []; + + if (kaizenrc['instances']) { + instances = kaizenrc['instances']; + } + + instances.push(instance); + configuration = _objectSpread({}, kaizenrc, { + "keyPair": keyPair, + "instances": instances + }); + fsx.writeJsonSync(path.resolve(__dirname, '../../../../.kaizenrc'), configuration); + _context.next = 30; + break; + + case 26: + _context.prev = 26; + _context.t0 = _context["catch"](0); + Log.ErrorLog('something went wrong!'); + console.error(_context.t0); + + case 30: + case "end": + return _context.stop(); + } + } + }, _callee, this, [[0, 26]]); +})); \ No newline at end of file diff --git a/build/components/Instances/Run/nym.js b/build/components/Instances/Run/nym.js new file mode 100644 index 00000000..18ac91a7 --- /dev/null +++ b/build/components/Instances/Run/nym.js @@ -0,0 +1,101 @@ +"use strict"; + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var Log = require('../../../lib/Log'); + +var AWSService = require('../../../lib/aws/AWSService'); + +var path = require('path'); + +var fsx = require('fs-extra'); + +module.exports = +/*#__PURE__*/ +_asyncToGenerator( +/*#__PURE__*/ +regeneratorRuntime.mark(function _callee() { + var kaizenrc, region, awsService, isExists, keyPair, instance, instances, configuration; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.prev = 0; + kaizenrc = fsx.readJsonSync(path.resolve(__dirname, '../../../../.kaizenrc')); + region = 'us-east-1'; + + if (kaizenrc['accessKey']) { + Log.NormalLog('Configuration:\n'.underline.yellow + 'accessKey' + ': ' + kaizenrc['accessKey'].yellow); + } else { + Log.NormalLog("Please set AWS access key by 'kaizen config set --key accessKey --value [Access Key Value]'"); + } + + if (kaizenrc['secretKey']) { + Log.NormalLog('Configuration:\n'.underline.yellow + 'secretKey' + ': ' + kaizenrc['secretKey'].yellow); + } else { + Log.NormalLog("Please set AWS secret key by 'kaizen config set --key secretKey --value [Secret Key Value]'"); + } + + if (kaizenrc['region']) { + region = kaizenrc['region']; + } + + awsService = new AWSService(kaizenrc['accessKey'], kaizenrc['secretKey'], region); + _context.next = 9; + return awsService.isKeyPairsExists('kaizen-cli'); + + case 9: + isExists = _context.sent; + keyPair = ''; + + if (isExists) { + _context.next = 15; + break; + } + + _context.next = 14; + return awsService.createKeyPair(); + + case 14: + keyPair = _context.sent; + + case 15: + _context.next = 17; + return awsService.runInstance('nym-loopix-mixnode'); + + case 17: + instance = _context.sent; + instances = []; + + if (kaizenrc['nym-loopix-mixnode']) { + instances = kaizenrc['nym-loopix-mixnode']; + instances.push(instance); + } + + configuration = _objectSpread({}, kaizenrc, { + "keyPair": keyPair, + "nym-loopix-mixnode": instances + }); + fsx.writeJsonSync(path.resolve(__dirname, '../../../../.kaizenrc'), configuration); + _context.next = 28; + break; + + case 24: + _context.prev = 24; + _context.t0 = _context["catch"](0); + Log.ErrorLog('something went wrong!'); + console.error(_context.t0); + + case 28: + case "end": + return _context.stop(); + } + } + }, _callee, this, [[0, 24]]); +})); \ No newline at end of file diff --git a/build/components/Instances/Template/index.js b/build/components/Instances/Template/index.js new file mode 100644 index 00000000..b5de3299 --- /dev/null +++ b/build/components/Instances/Template/index.js @@ -0,0 +1,44 @@ +"use strict"; + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +var Log = require('../../../lib/Log'); + +require('colors'); + +function builder(yargs) {} + +function handler(_x) { + return _handler.apply(this, arguments); +} + +function _handler() { + _handler = _asyncToGenerator( + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee(argv) { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + Log.NormalLog('Available instance template:'.underline.yellow); + Log.NormalLog('nym-loopix-mixnode'.underline.yellow + ' - Nym is a blockchain-based privacy platform.'); + Log.NormalLog("\nTo start a instance run " + "'kaizen instances run '".yellow); + Log.NormalLog("\nIt will be automatically start instance on AWS\n"); + + case 4: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + return _handler.apply(this, arguments); +} + +module.exports = function (yargs) { + var command = 'template'; + var commandDescription = 'Template lists of all available instance'; + yargs.command(command, commandDescription, builder, handler); +}; \ No newline at end of file diff --git a/build/components/Instances/index.js b/build/components/Instances/index.js new file mode 100644 index 00000000..be620ceb --- /dev/null +++ b/build/components/Instances/index.js @@ -0,0 +1,42 @@ +"use strict"; + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +function builder(yargs) { + require('./Run')(yargs); + + require('./List')(yargs); + + require('./Template')(yargs); + + return yargs.example('kaizen instances run').example('kaizen instances template').example('kaizen instances list').demandCommand(1, '').epilogue('Available instance templates:\n\n'.underline.yellow + 'nym-loopix-mixnode'.underline.yellow + ' - Nym is a blockchain-based privacy platform.\n' + '\nRun ' + '\'kaizen instances \''.yellow + ' to deploy instances to AWS.\n'); +} + +function handler(_x) { + return _handler.apply(this, arguments); +} + +function _handler() { + _handler = _asyncToGenerator( + /*#__PURE__*/ + regeneratorRuntime.mark(function _callee(argv) { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + case "end": + return _context.stop(); + } + } + }, _callee, this); + })); + return _handler.apply(this, arguments); +} + +module.exports = function (yargs) { + var command = 'instances'; + var commandDescription = 'AWS instances management power by kaizen'; + yargs.command(command, commandDescription, builder, handler); +}; \ No newline at end of file diff --git a/build/components/index.js b/build/components/index.js index 6f65b67c..10da2fda 100644 --- a/build/components/index.js +++ b/build/components/index.js @@ -38,6 +38,10 @@ require('./Platform/Nodes')(yargs); require('./Oracle')(yargs); +/** Instance Service **/ + + +require('./Instances')(yargs); yargs.demandCommand(1, '').epilogue('Welcome to KAIZEN\n\n'.yellow + 'KAIZEN Framework\n'.underline.yellow + 'Not sure how to use?\n'.gray + 'Use ' + '\'kaizen create -t react -n myproject\''.yellow + ' to start a new project.\n' + 'Try ' + '\'kaizen install -u \''.yellow + ' to download example project.\n\n' + 'KAIZEN Platform (Alpha)\n'.underline.yellow + 'Interact with KAIZEN Platform, please login first.\n'.grey + 'Use ' + '\'kaizen login\''.yellow + ' to login KAIZEN Platform.\n\n' + 'More information and documentation, please visit:\n' + 'https://github.com/PortalNetwork/kaizen-cli'.yellow.underline + '\n'); module.exports = yargs; \ No newline at end of file diff --git a/build/lib/aws/AWSService.js b/build/lib/aws/AWSService.js index 40a5d76d..29ead535 100644 --- a/build/lib/aws/AWSService.js +++ b/build/lib/aws/AWSService.js @@ -27,7 +27,6 @@ function () { _classCallCheck(this, AWSService); this.keyPem = 'kaizen-cli'; - this.instanceType = 't2.micro'; AWS.config.update({ region: region }); @@ -58,10 +57,9 @@ function () { case 5: keyPair = _context.sent; - console.log(JSON.stringify(keyPair)); + //console.log(JSON.stringify(keyPair)); fs.writeFileSync(keyPair.KeyName + '.pem', keyPair.KeyMaterial, 'utf8'); - _context.next = 13; - break; + return _context.abrupt("return", keyPair); case 10: _context.prev = 10; @@ -181,14 +179,13 @@ function () { // TODO choose AMI_ID, generate Key instanceParams = ami.ami[node]; instanceParams.KeyName = this.keyPem; - instanceParams.instanceType = this.instanceType; ec2 = new AWS.EC2({ apiVersion: '2016-11-15' }); - _context4.next = 7; + _context4.next = 6; return ec2.runInstances(instanceParams).promise(); - case 7: + case 6: instance = _context4.sent; instanceId = instance.Instances[0].InstanceId; instanceType = instance.Instances[0].InstanceType; @@ -199,28 +196,29 @@ function () { Value: node }] }; - _context4.next = 13; + _context4.next = 12; return ec2.createTags(tagParams).promise(); - case 13: + case 12: return _context4.abrupt("return", { instanceId: instanceId, instanceType: instanceType, publicDNS: instance.PublicDnsName, - name: node + name: node, + template: node }); - case 16: - _context4.prev = 16; + case 15: + _context4.prev = 15; _context4.t0 = _context4["catch"](0); console.log(_context4.t0); - case 19: + case 18: case "end": return _context4.stop(); } } - }, _callee4, this, [[0, 16]]); + }, _callee4, this, [[0, 15]]); })); return function runInstance(_x3) { diff --git a/build/lib/aws/ami.js b/build/lib/aws/ami.js index ded2e5a5..769b2ed9 100644 --- a/build/lib/aws/ami.js +++ b/build/lib/aws/ami.js @@ -1,10 +1,6 @@ "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ami = void 0; -var ami = { +exports.ami = { "ipfs-api-server-mainnet": { "ImageId": "", "InstanceType": "t2.micro", @@ -46,6 +42,11 @@ var ami = { "InstanceType": "t2.micro", "MinCount": 1, "MaxCount": 1 + }, + "nym-loopix-mixnode": { + "ImageId": "ami-0edc01100d4a88aa8", + "InstanceType": "t2.micro", + "MinCount": 1, + "MaxCount": 1 } -}; -exports.ami = ami; \ No newline at end of file +}; \ No newline at end of file diff --git a/commands/instances.md b/commands/instances.md new file mode 100644 index 00000000..54d74c3c --- /dev/null +++ b/commands/instances.md @@ -0,0 +1,78 @@ +`kaizen instances` +=============== + +Instance management for KAIZEN + +* [`kaizen instances`](#kaizen-instances) +* [`kaizen instances list`](#kaizen-instances-list) +* [`kaizen instances run`](#kaizen-instances-run) +* [`kaizen instances template`](#kaizen-instances-template) + +## `kaizen instances` + +Instance management for KAIZEN + +``` +Commands: + kaizen instances run [instance] Run an instance on AWS + kaizen instances list List instances of instance name + kaizen instances template Template lists of all available instance + +Options: + --help Show help [boolean] + --version Show version number [boolean] + +Examples: + kaizen instances run + kaizen instances template + kaizen instances list + +Available instance templates: + +nym-loopix-mixnode - Nym is a blockchain-based privacy platform. + +Run 'kaizen instances ' to deploy instances to AWS. +``` + +## `kaizen instances list` + +List running instances + +``` +List instances of instance name + +Options: + --help Show help [boolean] + --version Show version number [boolean] +``` + +## `kaizen instances run` + +Run an instance on AWS + +``` +Run an instance on AWS + +Positionals: + instance, i instance name [string] [required] + +Options: + --help Show help [boolean] + --version Show version number [boolean] + +Examples: + kaizen instances run nym-loopix-mixnode +``` + +## `kaizen instances template` + +Show all instance template support by KAIZEN + +``` +Available instance template: +nym-loopix-mixnode - Nym is a blockchain-based privacy platform. + +To start a instance run 'kaizen instances run ' + +It will be automatically start instance on AWS +``` diff --git a/commands/plugins.md b/commands/plugins.md index f8b1d7d6..30241e82 100644 --- a/commands/plugins.md +++ b/commands/plugins.md @@ -1,7 +1,7 @@ `kaizen plugins` =============== -Contract management for KAIZEN +Plugin management for KAIZEN * [`kaizen plugins`](#kaizen-plugins) * [`kaizen plugins list`](#kaizen-plugins-list) @@ -10,7 +10,7 @@ Contract management for KAIZEN ## `kaizen plugins` -Contract management for KAIZEN +Plugin management for KAIZEN ``` Commands: diff --git a/package-lock.json b/package-lock.json index 7966cc94..9609af3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "kaizen-cli", - "version": "0.0.54", + "version": "0.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e4892bdb..8743424b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kaizen-cli", - "version": "0.0.54", + "version": "0.1.0", "bin": { "kaizen": "kaizen" }, diff --git a/src/components/Config/Get/index.js b/src/components/Config/Get/index.js index 501adb8b..864340a7 100644 --- a/src/components/Config/Get/index.js +++ b/src/components/Config/Get/index.js @@ -10,10 +10,10 @@ function builder(yargs) { alias: 'k', type: 'string', describe: 'Configuration key', - choices: ['privateKey', 'provider', 'networkId'] + choices: ['privateKey', 'provider', 'networkId', 'accessKey', 'secretKey', 'region'] }) .example('kaizen config get --key provider') - .demandOption(['key'], ''); + //.demandOption(['key'], ''); } async function handler(argv) { @@ -23,9 +23,16 @@ async function handler(argv) { const kaizenrc = fsx.readJsonSync(path.resolve(__dirname, '../../../../.kaizenrc')); Spinner.stop(); if (kaizenrc[key]) { - Log.NormalLog('Configuration:\n'.underline.yellow + key + ': ' + kaizenrc[key].yellow); + Log.NormalLog('Kaizen Configuration:\n'.underline.yellow + key + ': ' + kaizenrc[key].yellow); } else { - Log.NormalLog(`Can not find ${key}`); + //Log.NormalLog(`Can not find ${key}`); + Log.NormalLog('Kaizen Configuration:'.underline.yellow); + (kaizenrc['privateKey']) ? Log.NormalLog('privateKey' + ': ' + kaizenrc['privateKey'].yellow) : null; + (kaizenrc['provider']) ? Log.NormalLog('provider' + ': ' + kaizenrc['provider'].yellow) : null; + (kaizenrc['networkId']) ? Log.NormalLog('networkId' + ': ' + kaizenrc['networkId'].yellow) : null; + (kaizenrc['accessKey']) ? Log.NormalLog('accessKey' + ': ' + kaizenrc['accessKey'].yellow) : null; + (kaizenrc['secretKey']) ? Log.NormalLog('secretKey' + ': ' + kaizenrc['secretKey'].yellow) : null; + (kaizenrc['region']) ? Log.NormalLog('region' + ': ' + kaizenrc['region'].yellow) : null; } } catch (error) { Spinner.stop(); diff --git a/src/components/Config/Set/index.js b/src/components/Config/Set/index.js index a022a69a..30c52a8b 100644 --- a/src/components/Config/Set/index.js +++ b/src/components/Config/Set/index.js @@ -10,7 +10,7 @@ function builder(yargs) { alias: 'k', type: 'string', describe: 'Configuration key', - choices: ['privateKey', 'provider', 'networkId'] + choices: ['privateKey', 'provider', 'networkId', 'accessKey', 'secretKey', 'region'] }) .option('value', { alias: 'v', diff --git a/src/components/Config/Unset/index.js b/src/components/Config/Unset/index.js index 3a259712..2ee2eeb4 100644 --- a/src/components/Config/Unset/index.js +++ b/src/components/Config/Unset/index.js @@ -10,7 +10,7 @@ function builder(yargs) { alias: 'k', type: 'string', describe: 'Configuration key', - choices: ['privateKey', 'provider', 'networkId'] + choices: ['privateKey', 'provider', 'networkId', 'accessKey', 'secretKey', 'region'] }) .example('kaizen config unset --key provider') .demandOption(['key'], ''); diff --git a/src/components/Instances/List/index.js b/src/components/Instances/List/index.js new file mode 100644 index 00000000..a3b0e048 --- /dev/null +++ b/src/components/Instances/List/index.js @@ -0,0 +1,31 @@ +const Log = require('../../../lib/Log'); +const path = require('path'); +const fsx = require('fs-extra'); +require('colors'); + +function builder(yargs) { + +} + +async function handler(argv) { + Log.NormalLog('AWS Instance list:'.underline.yellow); + + const kaizenrc = fsx.readJsonSync(path.resolve(__dirname, '../../../../.kaizenrc')); + + if (kaizenrc['instances']) { + for (let i=0;i < kaizenrc['instances'].length;i++) { + const instance = kaizenrc['instances'][i]; + Log.NormalLog('Template: '.yellow + instance.template + ', InstanceId: '.yellow + instance.instanceId); + // TODO load instance status + } + } else { + Log.NormalLog("There's no instance running on AWS"); + } + +} + +module.exports = function (yargs) { + const command = 'list'; + const commandDescription = 'List instances of instance name'; + yargs.command(command, commandDescription, builder, handler); +} \ No newline at end of file diff --git a/src/components/Instances/Run/index.js b/src/components/Instances/Run/index.js new file mode 100644 index 00000000..b77a950a --- /dev/null +++ b/src/components/Instances/Run/index.js @@ -0,0 +1,49 @@ +const Log = require('../../../lib/Log'); +const Spinner = require('../../../lib/Spinner'); +const nymLoopixMixnodeHandler = require('./nym-loopix-mixnode.js'); + +function builder(yargs) { + return yargs + .positional('instance', { + alias: 'i', + type: 'string', + describe: 'instance name', + require: true + }) + .example('kaizen instances run nym-loopix-mixnode') + .demandOption(['instance'], ''); +} + +async function handler(argv) { + try { + const { instance } = argv; + + if (!instance) { + Log.NormalLog('Missing instance name.\nPlease using \'kaizen instances run [instance]\''); + return; + } + + switch (instance) { + case 'nym-loopix-mixnode': + Log.NormalLog(`Starting ${instance} instance, please wait a second...`); + Spinner.start(); + await nymLoopixMixnodeHandler(); + Spinner.stop(); + Log.SuccessLog(`Start instance ${instance} Successfully`); + break; + default: + Log.NormalLog('Instance not support yet'); + } + + } catch (error) { + Spinner.stop(); + Log.ErrorLog('something went wrong!'); + console.error(error); + } +} + +module.exports = function (yargs) { + const command = 'run [instance]'; + const commandDescription = 'Run an instance on AWS'; + yargs.command(command, commandDescription, builder, handler); +} \ No newline at end of file diff --git a/src/components/Instances/Run/nym-loopix-mixnode.js b/src/components/Instances/Run/nym-loopix-mixnode.js new file mode 100644 index 00000000..95eba572 --- /dev/null +++ b/src/components/Instances/Run/nym-loopix-mixnode.js @@ -0,0 +1,48 @@ +const Log = require('../../../lib/Log'); +const AWSService = require('../../../lib/aws/AWSService'); +const path = require('path'); +const fsx = require('fs-extra'); + +module.exports = async function() { + try { + const kaizenrc = fsx.readJsonSync(path.resolve(__dirname, '../../../../.kaizenrc')); + let region = 'us-east-1'; + if (!kaizenrc['accessKey']) { + Log.NormalLog(`Please set AWS access key by 'kaizen config set --key accessKey --value [Access Key Value]'`); + } + if (!kaizenrc['secretKey']) { + Log.NormalLog(`Please set AWS secret key by 'kaizen config set --key secretKey --value [Secret Key Value]'`); + } + if (kaizenrc['region']) { + region = kaizenrc['region']; + } + + const awsService = new AWSService(kaizenrc['accessKey'], kaizenrc['secretKey'], region); + + const isExists = await awsService.isKeyPairsExists('kaizen-cli'); + + let keyPair = 'kaizen-cli'; + if (!isExists) { + Log.NormalLog('Creating Key Pair:\n'.underline.yellow + 'kaizen-cli.pem'.yellow); + keyPair = await awsService.createKeyPair(); + } + + const instance = await awsService.runInstance('nym-loopix-mixnode'); + + let instances = []; + if (kaizenrc['instances']) { + instances = kaizenrc['instances']; + } + instances.push(instance); + + const configuration = { + ...kaizenrc, + "keyPair": keyPair, + "instances": instances + } + fsx.writeJsonSync(path.resolve(__dirname, '../../../../.kaizenrc'), configuration); + } catch (error) { + Log.ErrorLog('something went wrong!'); + console.error(error); + } +} diff --git a/src/components/Instances/Template/index.js b/src/components/Instances/Template/index.js new file mode 100644 index 00000000..7c32c08e --- /dev/null +++ b/src/components/Instances/Template/index.js @@ -0,0 +1,21 @@ +const Log = require('../../../lib/Log'); +require('colors'); + +function builder(yargs) { + +} + +async function handler(argv) { + Log.NormalLog('Available instance template:'.underline.yellow); + Log.NormalLog('nym-loopix-mixnode'.underline.yellow + ' - Nym is a blockchain-based privacy platform.'); + + Log.NormalLog("\nTo start a instance run " + "'kaizen instances run '".yellow) + + Log.NormalLog("\nIt will be automatically start instance on AWS\n"); +} + +module.exports = function (yargs) { + const command = 'template'; + const commandDescription = 'Template lists of all available instance'; + yargs.command(command, commandDescription, builder, handler); +} \ No newline at end of file diff --git a/src/components/Instances/index.js b/src/components/Instances/index.js new file mode 100644 index 00000000..5064d1eb --- /dev/null +++ b/src/components/Instances/index.js @@ -0,0 +1,27 @@ +function builder(yargs) { + require('./Run')(yargs); + require('./List')(yargs); + require('./Template')(yargs); + + return yargs + .example('kaizen instances run') + .example('kaizen instances template') + .example('kaizen instances list') + .demandCommand(1, '') + .epilogue( + 'Available instance templates:\n\n'.underline.yellow + + 'nym-loopix-mixnode'.underline.yellow + ' - Nym is a blockchain-based privacy platform.\n' + + '\nRun ' + '\'kaizen instances \''.yellow + + ' to deploy instances to AWS.\n' + ); +} + +async function handler(argv) { + +} + +module.exports = function (yargs) { + const command = 'instances'; + const commandDescription = 'AWS instances management power by kaizen'; + yargs.command(command, commandDescription, builder, handler); +} diff --git a/src/components/index.js b/src/components/index.js index dbd23ab6..442cf1e8 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -25,6 +25,9 @@ require('./Platform/Nodes')(yargs); /** Oracle Service **/ require('./Oracle')(yargs); +/** Instance Service **/ +require('./Instances')(yargs); + yargs .demandCommand(1, '') .epilogue( diff --git a/src/lib/aws/AWSService.js b/src/lib/aws/AWSService.js index 65b3b9a3..53bd95dc 100644 --- a/src/lib/aws/AWSService.js +++ b/src/lib/aws/AWSService.js @@ -9,7 +9,6 @@ class AWSService { constructor(accessKeyId, secretAccessKey, region) { this.keyPem = 'kaizen-cli'; - this.instanceType = 't2.micro'; AWS.config.update({region: region}); const credentials = new AWS.Credentials(accessKeyId, secretAccessKey, null); AWS.config.credentials = credentials; @@ -23,8 +22,9 @@ class AWSService { }; const keyPair = await ec2.createKeyPair(params).promise(); - console.log(JSON.stringify(keyPair)); + //console.log(JSON.stringify(keyPair)); fs.writeFileSync(keyPair.KeyName + '.pem', keyPair.KeyMaterial, 'utf8'); + return keyPair; } catch (err) { console.log(err); } @@ -63,7 +63,6 @@ class AWSService { // TODO choose AMI_ID, generate Key let instanceParams = ami.ami[node]; instanceParams.KeyName = this.keyPem; - instanceParams.instanceType = this.instanceType; const ec2 = new AWS.EC2({apiVersion: '2016-11-15'}); const instance = await ec2.runInstances(instanceParams).promise(); @@ -77,7 +76,7 @@ class AWSService { ]}; await ec2.createTags(tagParams).promise(); - return {instanceId, instanceType, publicDNS: instance.PublicDnsName, name: node}; + return {instanceId, instanceType, publicDNS: instance.PublicDnsName, name: node, template: node}; } catch (err) { console.log(err); } diff --git a/src/lib/aws/ami.js b/src/lib/aws/ami.js index e3740b33..a855f3fb 100644 --- a/src/lib/aws/ami.js +++ b/src/lib/aws/ami.js @@ -1,4 +1,4 @@ -export const ami = { +exports.ami = { "ipfs-api-server-mainnet": { "ImageId": "", "InstanceType": "t2.micro", @@ -40,5 +40,11 @@ export const ami = { "InstanceType": "t2.micro", "MinCount": 1, "MaxCount": 1 + }, + "nym-loopix-mixnode": { + "ImageId": "ami-0edc01100d4a88aa8", + "InstanceType": "t2.micro", + "MinCount": 1, + "MaxCount": 1 } } \ No newline at end of file