xkite-cli
Version:
A CLI for xkite-core library for prototyping and testing with Apache Kafka
369 lines • 14.3 kB
JavaScript
;
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