@cto.ai/ops
Version:
š» CTO.ai - The CLI built for Teams š
140 lines (139 loc) ⢠6.17 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const base_1 = tslib_1.__importStar(require("./../base"));
const CustomErrors_1 = require("./../errors/CustomErrors");
const env_1 = require("./../constants/env");
const utils_1 = require("./../utils");
const validate_1 = require("../utils/validate");
class Start extends base_1.default {
constructor() {
super(...arguments);
this.customParse = (options, argv) => {
const { args, flags } = require('@oclif/parser').parse(argv, Object.assign(Object.assign({}, options), { context: this }));
if (!args.nameOrPath && !flags.help) {
throw new CustomErrors_1.MissingRequiredArgument('ops run');
}
if (!args.nameOrPath)
this._help();
return { args, flags, opParams: argv.slice(1) };
};
this.sendAnalytics = (parsedArgs, config) => {
this.services.analytics.track('Ops CLI Start', {
username: config.user.username,
email: config.user.email,
team: config.team.name,
image: `${env_1.OPS_REGISTRY_HOST}/${parsedArgs.args.nameOrPath}`,
runtime: 'CLI',
cliVersion: this.config.version,
}, config);
};
this.getPublishedOps = async (config) => {
try {
const { data: opResults } = await this.services.api.find(`/private/teams/${config.team.name}/ops`, {
headers: {
Authorization: this.accessToken,
},
});
return opResults;
}
catch (err) {
this.debug('%0', err);
throw new CustomErrors_1.APIError(err);
}
};
this.isOpAvailable = (name, version, ops) => {
return ops.find(op => {
return version
? name === op.name && version === op.version
: name === op.name;
});
};
this.startRemoteOp = async (name, config, op) => {
try {
// TODO: This will ALWAYS start the latest version
const { data: runDetails } = await this.services.api.create(`/private/workflows/trigger`, {
teamID: config.team.id,
userID: config.user.id,
workflowName: name,
}, {
headers: {
Authorization: this.accessToken,
'X-Cto-Workflow-Client': 'cli',
},
});
const logsURL = (0, utils_1.genLogsURL)(env_1.OPS_API_HOST, config.team.name, runDetails.opType, op.id, runDetails.runId);
// We will only have a non-null serviceUrl if we've started a service
if (runDetails.serviceUrl) {
const full_name = this.ux.colors.successGreen(`${op.name}:${op.version}`);
let startMessage = `š Success, ${full_name} has been started.\n\nšŖµ Logs: ${this.ux.url(logsURL, logsURL)}\nš¦ URL: ${this.ux.url(runDetails.serviceUrl, runDetails.serviceUrl)}`;
if (runDetails.usageWarning) {
startMessage = startMessage + `\n\n${runDetails.usageWarning}`;
}
this.log(this.ux.colors.whiteBright(startMessage));
}
else {
this.log(this.ux.colors.whiteBright(`š Success, ${name} has been started.\nš View the logs here: ${logsURL}`));
}
}
catch (err) {
this.debug('%0', err);
let userErrMsg = `ā Sorry, we encountered an error trying to start ${name}.`;
// 403 - Tier limits reached, display error message
if (err.error[0].code === 403) {
userErrMsg = `ā Sorry, we encountered an error trying to start ${name}: ${err.error[0].message}`;
}
this.log(this.ux.colors.whiteBright(userErrMsg));
throw new CustomErrors_1.APIError(err);
}
};
}
async run() {
const config = await this.isLoggedIn();
try {
const parsedArgs = this.customParse(Start, this.argv);
const { name, version } = (0, utils_1.splitNameAndVersion)(parsedArgs.args.nameOrPath);
const ops = await this.getPublishedOps(config);
if (!ops || ops.length < 1) {
this.log(this.ux.colors.whiteBright('ā Sorry, It appears you have no workflows published'));
process.exit(1);
}
const selectedOp = this.isOpAvailable(name, version, ops);
if (!selectedOp) {
this.log(this.ux.colors.whiteBright(`ā Sorry, we cannot find the pipeline: ${parsedArgs.args.nameOrPath}. Please publish the pipeline before attempting to start it.`));
process.exit(1);
}
if ((0, validate_1.validateOpIsJob)(selectedOp)) {
this.log(this.ux.colors.whiteBright(`ā Sorry, ${parsedArgs.args.nameOrPath} cannot run outside of its parent pipeline.`));
process.exit(1);
}
await this.startRemoteOp(name, config, selectedOp);
this.sendAnalytics(parsedArgs, config);
}
catch (err) {
this.debug('%O', err);
this.config.runHook('error', {
err,
accessToken: config.tokens.accessToken,
});
}
}
}
exports.default = Start;
Start.description = 'Start a service, pipeline or command on our cloud.';
Start.flags = {
help: base_1.flags.boolean({
char: 'h',
description: 'show CLI help',
}),
};
Start.strict = false;
Start.args = [
{
name: 'nameOrPath',
description: 'Name or path of the workflow you want to run.',
parse: (input) => {
return input.toLowerCase();
},
},
];