UNPKG

acs

Version:
462 lines (414 loc) 20.5 kB
'use strict'; /** * nettle - a command line for ACS custom node.js services Appcelerator * Proprietary - DO NOT REDISTRIBUTE Copyright (c) 2012 by Appcelerator, Inc. */ var program = require('commander'), u = require('./util.js'), logger = require('./logger'), ccommander = require('./ccommander'), nettleLogger = require('./nettlelogger'), colors = require('colors'), _ = require('underscore'), pkginfo = require('pkginfo')(module, 'name', 'version'); program.name = 'ack'; exports.toString = function() { return program.name; }; ccommander.customize(program, copyright); program.version(module.exports.version, '-v, --version') .description('Deploy multiple containerized apps to AMPLIFY Runtime Services or Kubernetes') .usage('[COMMAND] [COMMON OPTIONS]') .option('--host <ars-api-host>', 'Host of ARS API server') .option('--port <ars-api-port>', 'Port of ARS API server') .option('-b, --no-colors', 'Turn off colors') .option('--no-banner', 'Turn off banner') .option('-l, --loglevel <level>', 'Level for logging: fatal, error, warn, info, debug, trace. default: info') .option('--dates', 'Turn on dates in logging'); program.removeAllListeners('version'); program.on('version', function() { var args = _.rest(program.rawArgs, 2); if (program.rawArgs.length > 5 || _.difference(args, ['-v', '--version', '-nc', '--no-colors', '--no-banner']).length > 0) { console.log('-v, --version can not be used with options other than \'--no-colors\' and \'--no-banner\'.'); } else { console.log(program._version); } process.exit(0); }); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ack commands >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> program.command('new <name>') .description('Create a new helm chart from the built-in template') .aliases(['create']) .option('-d, --dir <path>', 'Specify a path where the chart will be created') .action(function() { var cmd = ccommander.restoreParams(this); this.dir = cmd.dir; }); program.command('list [name]') .description('List namespaces or check a specific namespace') .aliases(['ls']) .option('-o, --org <orgid>', 'Specify the organization for the namespace') .option('-m, --mine', 'List namespaces created by the current user only') .option('--start-date <start-date>', 'Specify start date for namespaces') .option('--end-date <end-date>', 'Specify end date for namespaces') .option('--per-page <per-page>', 'Specify item number in a single page, defaults to 100') .option('--more', 'Get next page of namespaces') .action(function() { var cmd = ccommander.restoreParams(this); this.org = cmd.org; this.mine = cmd.mine; this.start_date = cmd.startDate; this.end_date = cmd.endDate; this.per_page = cmd.perPage; this.more = cmd.more; }); var getCmd = program.command('get [type] [name]') .description('Get details of a release') .detail('The "type" argument specifies the type of information to check. ' + 'Supported types fall into 2 groups: ' + '\n Helm release data: status, history, hooks, manifest, notes, values' + '\n Deployed resources: ingresses(ing), services(svc), pods(po), deployments(deploy), replicasets(rs), statefulsets(sts), jobs, horizontalpodautoscalers(hpa), all') .option('-n, --namespace <namespace-name>', 'Specify the namespace to check its release') .option('-o, --output <format>', 'Specify the output format (list|table|json)') .option('-a, --all', 'Dump all (computed) values (for "get values" only)') .option('-r, --release <release-name>', 'Specify the release name for checking certificate secret') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.output = cmd.output; this.all = cmd.all; this.release = cmd.release; }); getCmd.command('cert <certname>') .description('Show the secret holding the specified certificate') .option('-n, --namespace <namespace-name>', 'The namespace for the certificate') .action(function(args) { var cmd = this.getChildCommand('cert'); program.namespace = cmd.namespace; }); program.command('init <namespace>') .description('Create a new namespace') .option('-o, --org <orgid>', 'Specify the organization for the namespace') .option('-s, --size <serversize>', 'Specify the default server size for the workloads in this namespace. Available options: \'Dev\' \'Small\' \'Medium\' \'Large\' \'XLarge\'.') .option(' --proxy <proxy enabler>', 'Specify if proxy is required for application deployment. This option leads to access log unavailable. Available options : \'true\' or \'false\'.') .action(function() { var cmd = ccommander.restoreParams(this); this.org = cmd.org; this.size = cmd.size; this.proxy = cmd.proxy; }); var installCmd = program.command('install <release-name>') .description('Install new release') .option('-n, --namespace <namespace-name>', 'Specify the namespace to install the chart to') .option('-f, --file <chart-path>', 'Specify the path to the chart package or directory') .option(' --values <chart-values-file-path>', 'Specify the path to the chart values file') .option('--force', 'Proceed with install even when there are existing resources in the namespace') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.chartFilePath = cmd.file; this.chartValues = cmd.values; this.force = cmd.force; }); installCmd.command('cert <certname>') .description('Add a certificate by installing a helm release holding a secret for it') .option('-n, --namespace <namespace-name>', 'The namespace for the certificate') .option('--cert <certfile>', 'The certificate file for creating a TLS secret') .option('--key <keyfile>', 'The key file for creating a TLS secret') .option('--file <cert-archive>', 'The certificate archive file (e.g. .p12 or .pfx file) that includes certificate, key, and any intermediate certificates') .option('-y, --yes', 'Skip asking for confirmation') .action(function(args) { // args include arguments after command name 'add' // If a command does not need any argument args will include the Command object only. // get current command. 'this' is parent Command object var cmd = this.getChildCommand('cert'); program.namespace = cmd.namespace; }); var updateCmd = program.command('update <namespace|release> <name>') .description('Update a namespace or a release') .option('-o, --org <orgid>', 'Specify the organization for the namespace to update') .option('-s, --size <serversize>', 'Specify the default server size for updating namespace. Available options: \'Dev\' \'Small\' \'Medium\' \'Large\' \'XLarge\'.') .option('-n, --namespace <namespace-name>', 'Specify the namespace for the release to update') .option('-f, --file <chart-file-path>', 'Specify the path to the chart package or directory') .option(' --values <chart-values-file-path>', 'Specify the path to the chart values file') .action(function() { var cmd = ccommander.restoreParams(this); this.org = cmd.org; this.size = cmd.size; this.namespace = cmd.namespace; this.chartFilePath = cmd.file; this.chartValues = cmd.values; }); updateCmd.command('cert <certname>') .description('Update a certificate by upgrading the helm release holding it') .option('-n, --namespace <namespace-name>', 'The namespace for the certificate') .option('--cert <certfile>', 'The certificate file for updating a TLS secret') .option('--key <keyfile>', 'The key file for updating a TLS secret') .option('--file <cert-archive>', 'The certificate archive file (e.g. .p12 or .pfx file) that includes certificate, key, and any intermediate certificates') .option('-y, --yes', 'Skip asking for confirmation') .action(function(args) { var cmd = this.getChildCommand('cert'); program.namespace = cmd.namespace; }); program.command('rollback <release-name>') .description('Rollback a release to a specific revision') .option('-n, --namespace <namespace-name>', 'Specify the namespace for the release.') .option('-r, --revision <revision>', 'Specify the revision to rollback to') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.revision = cmd.revision; }); var removeCmd = program.command('remove <namespace|release|hpa> <name>') .description('Delete a namespace, release, or horizontalpodautoscalers(hpa)') .aliases(['rm', 'delete']) .option('-o, --org <orgid>', 'Specify the organization for the namespace') .option('-n, --namespace <namespace-name>', 'The namespace for the release to delete') .option('-f, --force', 'Delete releases that may be in inconsistent state') .action(function() { var cmd = ccommander.restoreParams(this); this.org = cmd.org; this.namespace = cmd.namespace; this.force = cmd.force; }); removeCmd.command('cert <certname>') .description('Delete the helm release holding the specified certificate') .option('-n, --namespace <namespace-name>', 'The namespace for the certificate') .option('-y, --yes', 'Skip asking for confirmation') .action(function(args) { var cmd = this.getChildCommand('cert'); program.namespace = cmd.namespace; }); program.command('clean <namespace>') .description('Delete all resources in a namespace') .detail('This is meant for cleaning the left (orphan) resources after "ack rm release".') .option('-o, --org <orgid>', 'Specify the organization for the namespace') .option('-f, --force', 'Delete resources without asking for confirmation') .action(function() { var cmd = ccommander.restoreParams(this); this.org = cmd.org; this.force = cmd.force; }); program.command('config [kubeconfigfile]') .description('Config the specified or default (~/.acs.kube) kubeconfig file') .option('-g, --generate', 'Generate a new kubeconfig file') .option('-n, --namespace <namespace>', 'Set default namespace in the kubeconfig file') .option('-t, --token', 'Update token in the kubeconfig file') .action(function() { var cmd = ccommander.restoreParams(this); this.generate = cmd.generate; this.namespace = cmd.namespace; this.token = cmd.token; }); program.command('publish <appname>') .description('Publish a docker image to ARS') .detail('* A helm chart will be created for deploying the docker image to ARS.\n' + ' * The docker image will be retagged as <ARS-registry-domain>/<orgid>/<appname>:<app-version> and pushed to the ARS docker registry.') .option('-n, --namespace <namespace-name>', 'Specify the namespace to publish to') .option('--image <name[:tag]>', 'The name of the docker image. Will use \'latest\' if tag is not specified.') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.org = cmd.org; this.image = cmd.image; }); program.command('log') .description('List console logs of pods and their containers') .option('-n, --namespace <namespace-name>', 'Specify the namespace to get logs') .option('-d, --controller-name <controller-name>', 'Filter logs by deployment/statefultset/job/cronjob name') .option('-p, --pod <pod-name>', 'Filter logs by pod name') .option('-c, --container <container-name>', 'Filter logs by container name') .option('--show-pod-containers', 'Show pod and container name in logs') .option('--start-date <start-date>', 'Specify start date for logs') .option('--end-date <end-date>', 'Specify end date for logs') .option('--per-page <per-page>', 'Specify item number in a single page, defaults to 100') .option('--more', 'Get next page of log entries') .option('--tail', 'Tail the log entries, tailing will ignore --start-date, --end-date, --per-page, and --more options') .option('--tail-interval <tail-interval>', 'Tail the log entries with the specified interval(in seconds)') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.ars_deployment_name = cmd.controllerName; this.pod = cmd.pod; this.container = cmd.container; this.show_pod_containers = cmd.showPodContainers; this.start_date = cmd.startDate; this.end_date = cmd.endDate; this.per_page = cmd.perPage; this.more = cmd.more; this.tail = cmd.tail; this.tail_interval = cmd.tailInterval; }); program.command('accesslog') .description('List access logs of all pods') .option('-n, --namespace <namespace-name>', 'Specify the namespace to get access logs') .option('-d, --controller-name <controller-name>', 'Filter access logs by deployment/statefultset name') .option('--serverid <serverid>', 'Filter access logs by serverid (pod)') .option('--show-serverid', 'Show serverid (pod) in access logs') .option('--start-date <start-date>', 'Specify start date for access logs') .option('--end-date <end-date>', 'Specify end date for access logs') .option('--per-page <per-page>', 'Specify item number in a single page, defaults to 100') .option('--more', 'Get next page of log entries') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.serverid = cmd.serverid; this.ars_deployment_name = cmd.controllerName; this.show_serverid = cmd.showServerid; this.start_date = cmd.startDate; this.end_date = cmd.endDate; this.per_page = cmd.perPage; this.more = cmd.more; }); program.command('usage') .description('List the resource usage of containers in a helm release') .option('-n, --namespace <namespace-name>', 'Specify the namespace to get resource usage') .option('-d, --controller-name <controller-name>', 'Filter resource usage by deployment/statefultset/job/cronjob name') .option('-c, --container <container-name>', 'Filter resource usage by container name') .option('--serverid <serverid>', 'Filter resource usage by serverid (pod)') .option('--show-serverid', 'Show serverid (pod) in resource usage') .option('--start-date <start-date>', 'Specify start date for filtering resource usage, example: 2020-06-23 18:30') .option('--end-date <end-date>', 'Specify end date for filtering resource usage, example: 2020-06-23 18:36') .option('--per-page <per-page>', 'Specify item number in a single page, defaults to 100, maximum is 1000') .option('--more', 'Get next page of resource usage entries') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.ars_deployment_name = cmd.controllerName; this.container = cmd.container; this.serverid = cmd.serverid; this.show_serverid = cmd.showServerid; this.start_date = cmd.startDate; this.end_date = cmd.endDate; this.per_page = cmd.perPage; this.more = cmd.more; }); program.command('autoscale <type> <name>') .description('Create a autosaler (hpa) for a deployed resource') .option('-n, --namespace <namespace-name>', 'The namespace of the resource') .option('--hpa-name <hpa-name>', 'The name for the autoscaler. If not specified, the name of the input resource will be used.') .option('--min <min-pods>', 'The lower limit for the number of pods. default: 1') .option('--max <max-pods>', 'The upper limit for the number of pods') .option('--cpa-percent <cpu-percent>', 'The target average CPU utilization (represented as a percent of requested CPU) over all the pods. default: 80') .option('--update', 'Update an existing horizontal autoscaler') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.scalerName = cmd.hpaName; this.min = cmd.min; this.max = cmd.max; this.cpuPercent = cmd.cpuPercent this.update = cmd.update; }); program.command('restart <resourceType> <resourceName>') .description('Restart a workload ("deployment" or "statefulset")') .option('-n, --namespace <namespace-name>', 'The namespace of the resource') .option('-y, --yes', 'Skip asking for confirmation') .action(function() { var cmd = ccommander.restoreParams(this); this.namespace = cmd.namespace; this.yes = cmd.yes; }); program.command('login-registry') .description('Login to the in-cluster docker registry. This should be run after you have been authenticated with "axway auth login".') .action(function() { ccommander.restoreParams(this); }); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> program.parse(process.argv); //setup colors logger.colors(program.colors); logger.dates(program.dates); var loglevel = program.loglevel || 'info' nettleLogger.setLevel(loglevel); if (!program.colors) { colors.mode = 'none'; } process.on('uncaughtException', function(err) { if (err && err.code === 'EADDRINUSE') { u.die('Assigned port is already in use. Please see if you have a running instance of this service on this machine.'); } nettleLogger.error(err.stack? err.stack: err); }); var killSignals = [ 'SIGINT', 'SIGTERM' ]; for ( var i = 0; i < killSignals.length; i++) { process.on(killSignals[i], function() { process.exit(); }); } function copyright() { var c = 'ACK CLI'.cyan + ', version ' + module.exports.version + '\n' + 'Copyright (c) 2012-' + new Date().getFullYear() + ', Axway, Inc. All Rights Reserved.\n'; if (!program.colors) { c = colors.stripColors(c); } return c; } function help() { console.log(program.helpInformation()); process.exit(1); } function main(args) { if (args.length === 0) { help(); } var cmd = (program.runningSubCommand && program.runningSubCommand.name) || args[0]; // for child commands var cmdObj = args[args.length-1]; var childCommand = false; if(typeof cmdObj == 'object') { cmd = cmdObj.parent.name + "-" + cmdObj.name; childCommand = true; } var validCmdNames = ['install-cert', 'update-cert', 'remove-cert', 'get-cert']; program.commands.forEach(function(command) { validCmdNames.push(command.name); if(command.aliases()) { validCmdNames.push(...command.aliases()); } }); if(validCmdNames.includes(cmd)) { if(program.banner) { console.log(copyright()); } u.findAuthToken(program, execCommand); // u.getAccessToken(program, execCommand); } else { console.log(); logger.error('Unknown command: ' + cmd.red); help(); } function execCommand() { var globalConfig = u.getGlobalConfig(); var cmdPath = './command/kube/'; if(!childCommand) { args = args.splice(1); } if ((globalConfig && globalConfig.cookie) || program.accessToken || program.iamUser) { require(cmdPath + getCmdFile(cmd)).run(args, program); } else { // need authentication and no cookie/access token exists u.requireLogin([], program, function() { process.stdin.destroy(); // continue previous command after user login successfully program.isCallback = true; require(cmdPath + getCmdFile(cmd)).run(args, program); }); } } } const cmdFileMapping = { 'install-cert': 'crt-add', 'update-cert': 'crt-update', 'remove-cert': 'crt-delete', 'get-cert': 'crt-show' }; function getCmdFile(cmd) { let cmdFile = cmdFileMapping[cmd]; if (cmdFile) { return cmdFile; } return cmd; } main(program.args);