UNPKG

xkite-cli

Version:

A CLI for xkite-core library for prototyping and testing with Apache Kafka

369 lines 14.3 kB
#! /usr/bin/env node "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const { Command } = require('commander'); const figlet = require('figlet'); const fs = require('fs'); const path = require('path'); const { Kite } = require('xkite-core'); const { default_ports } = require('xkite-core'); const pjson = require('../package.json'); const program = new Command(); // ASCII ART console.log(figlet.textSync('xkite')); program .version(pjson.version) .description('CLI for xkite, an Apache Kafka Prototype and Test Tool') .option('-s, --server <server:port>', 'connect to an xkite server: i.e xkite-cli -s http://localhost:3000') // .option('-i, --input <value>', 'Input configuration file for xkite') // file .option('-b, --broker <# of brokers> <# of replicas> <port1,...,portn> <1 = enable jmx>', 'Kafka broker setup (default to 1 if not chosen)') .option('-z, --zookeeper <# of zookeepers> <port1,...,portn>', 'Zookeeper setup (default to 1 if not chosen)') .option('-db, --database <type: ksql | postgresql> <port>', 'Creates Source Database (default none if not chosen)') .option('-sk, --sink <type: jupyter | spark> <port>', 'Creates Sink at specified port (default none if not chosen)') .option('-gr, --grafana <port>', 'Creates Grafana instance at specified port (default none if not chosen') .option('-pr, --prometheus <port> <scrape_interval> <evaluation_interval>', 'Creates Prometheus instance at specified port with settings for scrape and eval interval (in seconds)') .option('-o, --output <value>', 'Output directory for package.zip for current configuration') //default to current dir .option('-r --run ', 'Runs configured docker instances') // either deploy or unpause .option('-p --pause ', 'Pauses active docker instances') .option('-q --quit ', 'Shuts down all docker instances and removes associated container/volumes') .parse(process.argv); const options = program.opts(); // Option functions let config; const selectedPorts = new Set(); function readInputFile(filepath) { try { const file = fs.readFileSync(filepath, 'utf-8'); config = JSON.parse(file); } catch (error) { console.error('Error occurred while reading input file!', error); } } function configureBrokers(n, r, ports, jmxEn) { try { if (n === undefined) throw TypeError('missing'); let brokerPorts; if (ports.search(',') >= 0) brokerPorts = ports.split(',').map((p) => Number(p)); else brokerPorts = [Number(ports)]; const nBrokers = Number(n); const max = 50; if (nBrokers > max) throw TypeError(`Number of Brokers (${nBrokers}) exceeds ${max}`); const nReplicas = Number(r) <= nBrokers ? Number(r) : nBrokers; let newCfg = { kafka: { brokers: { size: nBrokers, replicas: nReplicas !== null && nReplicas !== void 0 ? nReplicas : nBrokers, ports: { brokers: brokerPorts, }, }, zookeepers: { //default size: 1, ports: { client: [default_ports.zookeeper.client.external], }, }, }, }; if (jmxEn === '1') configureJMX(); config = Object.assign({}, config, newCfg); } catch (error) { console.error('Error while configuring brokers for kite!', error); } } function configureJMX(ports) { try { if (config === undefined || config.kafka === undefined) configureBrokers('2', '2', '9092,9093'); const newCfg = Object.assign(Object.assign({}, config), { kafka: Object.assign(Object.assign({}, config.kafka), { jmx: { ports: new Array(config.kafka.brokers.size).fill(default_ports.jmx.external), } }) }); config = Object.assign({}, config, newCfg); } catch (error) { console.error('Error while configuring JMX for kite!', error); } } function configureZookeepers(n, ports) { try { if (n === undefined) throw TypeError('missing'); let zkPorts; if (ports !== undefined) { if (ports.search(',') >= 0) zkPorts = ports.split(',').map((p) => Number(p)); else zkPorts = [Number(ports)]; } const nZk = Number(n); const max = 1000; if (nZk > max) throw TypeError(`Number of Brokers (${nZk}) exceeds ${max}`); if (config === undefined || config.kafka === undefined) configureBrokers('2', '2', '9092,9093'); const newCfg = Object.assign(Object.assign({}, config), { kafka: Object.assign(Object.assign({}, config.kafka), { zookeepers: Object.assign(Object.assign({}, config.kafka.zookeepers), { size: nZk, ports: { client: zkPorts !== null && zkPorts !== void 0 ? zkPorts : new Array(nZk).fill(default_ports.zookeeper.client.external), } }) }) }); config = Object.assign({}, config, newCfg); } catch (error) { console.error('Error while configuring zookeeper for kite!', error); } } function configureDB(name, port) { try { if (name === undefined) throw TypeError('missing'); if (config === undefined || config.kafka === undefined) configureBrokers('2', '2', '9092,9093'); config = Object.assign(Object.assign({}, config), { db: Object.assign(Object.assign({}, config.db), { name: name === 'ksql' ? name : 'postgresql', port: name === 'ksql' ? port !== undefined ? Number(port) : default_ports.ksql.external : port !== undefined ? Number(port) : default_ports.postgresql.external, kafkaconnect: { port: default_ports.kafkaconnect_src.external, } }) }); } catch (error) { console.error('Error while configuring db for kite!', error); } } function configureSink(name, port) { try { if (name === undefined) throw TypeError('missing'); if (config === undefined || config.kafka === undefined) configureBrokers('2', '2', '9092,9093'); config = Object.assign(Object.assign({}, config), { sink: Object.assign(Object.assign({}, config.sink), { name: name === 'spark' ? name : 'jupyter', port: name === 'spark' ? port !== undefined ? Number(port) : default_ports.spark.webui.external : port !== undefined ? Number(port) : default_ports.jupyter.external, kafkaconnect: { port: default_ports.kafkaconnect_sink.external, } }) }); } catch (error) { console.error('Error while configuring db for kite!', error); } } function configureGrafana(port) { try { if (config === undefined || config.prometheus === undefined) configurePrometheus(); config = Object.assign(Object.assign({}, config), { grafana: Object.assign(Object.assign({}, config.grafana), { port: port !== undefined ? Number(port) : default_ports.grafana.external }) }); } catch (error) { console.error('Error while configuring grafana for kite!', error); } } function configureSpring(port) { try { if (config === undefined || config.kafka === undefined) configureBrokers('2', '2', '9092,9093', '1'); config = Object.assign(Object.assign({}, config), { kafka: Object.assign(Object.assign({}, config.kafka), { spring: { port: port !== undefined ? Number(port) : default_ports.spring.external, } }) }); } catch (error) { console.error('Error while configuring spring for kite!', error); } } function configurePrometheus(port, _scrape, _eval) { try { if (config === undefined || config.kafka === undefined) { configureBrokers('2', '2', '9092,9093', '1'); } if (config.kafka.jmx === undefined) { configureJMX(); } configureSpring(); config = Object.assign(Object.assign({}, config), { prometheus: Object.assign(Object.assign({}, config.prometheus), { port: port !== undefined ? Number(port) : default_ports.prometheus.external, scrape_interval: _scrape !== undefined ? Number(_scrape) : 10, evaluation_interval: _eval !== undefined ? Number(_eval) : 5 }) }); } catch (error) { console.error('Error while configuring grafana for kite!', error); } } function connect(server) { return __awaiter(this, void 0, void 0, function* () { try { yield Kite.configure(server); } catch (error) { console.error('Error while configuring kite!', error); } }); } function configure() { return __awaiter(this, void 0, void 0, function* () { try { if (config === undefined) console.log('No configuration provided, using default'); yield Kite.configure(config); } catch (error) { console.error('Error while configuring kite!', error); } }); } function output(filepath) { return __awaiter(this, void 0, void 0, function* () { try { const pkg = yield Kite.getPackageBuild(); if (filepath !== undefined) fs.writeFileSync(path.resolve(filepath, 'package.zip'), Buffer.from(pkg.fileStream)); else fs.writeFileSync(path.resolve(__dirname, 'package.zip'), Buffer.from(pkg.fileStream)); // } } catch (error) { console.error('Error while writing package.zip from kite!', error); } }); } function run() { return __awaiter(this, void 0, void 0, function* () { try { if ((yield Kite.getKiteState()) === 'Paused') yield Kite.unpause(); else yield Kite.deploy(); } catch (error) { console.error('Error while running kite!', error); } }); } function pause() { return __awaiter(this, void 0, void 0, function* () { try { yield Kite.pause(); } catch (error) { console.error('Error while running kite!', error); } }); } function quit() { return __awaiter(this, void 0, void 0, function* () { try { yield Kite.shutdown(); } catch (error) { console.error('Error while running kite!', error); } }); } function main() { return __awaiter(this, void 0, void 0, function* () { if (options.server) { yield connect(options.server); console.log(`Kite remote server state = ${Kite.getKiteServerState()}`); } if (options.input) { // using a file + cmd line readInputFile(options.input); configOptions(); yield configure(); } else if (configOptions()) { //cmd line configuration yield configure(); } // can only run one of the following at a time if (options.quit) { yield quit(); } else if (options.run) { yield run(); } else if (options.pause) { yield pause(); } if (options.output) { yield output(options.output); } }); } function findOptions(str, longStr) { let startIdx = -1; let endIdx = -1; for (let i = 0; i < process.argv.length; i++) { if (process.argv[i] === str || process.argv[i] === longStr) { let j = i + 1; startIdx = j; endIdx = j; while (j < process.argv.length && process.argv[j].search('-') !== 0) { endIdx = ++j; } break; } } return process.argv.slice(startIdx, endIdx); } function configOptions() { let configure = false; if (options.broker) { configure = true; const args = findOptions('-b', '--broker'); // console.log(args); configureBrokers(args[0], args[1], args[2], args[3]); } if (options.zookeeper) { configure = true; const args = findOptions('-z', '--zookeeper'); // console.log(args); configureZookeepers(args[0], args[1]); } if (options.database) { configure = true; const args = findOptions('-db', '--database'); // console.log(args); configureDB(args[0], args[1]); } if (options.sink) { configure = true; const args = findOptions('-sk', '--sink'); // console.log(args); configureSink(args[0], args[1]); } if (options.grafana) { configure = true; const args = findOptions('-gr', '--grafana'); // console.log(args); configureGrafana(args[0]); } if (options.prometheus) { configure = true; const args = findOptions('-pr', '--prometheus'); // console.log(args); configurePrometheus(args[0], args[1], args[2]); } return configure; } main(); if (!process.argv.slice(2).length) { program.outputHelp(); } //# sourceMappingURL=index.js.map