zcatalyst-cli
Version:
Command Line Tool for CATALYST
223 lines (222 loc) • 11.6 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.iacImport = void 0;
const ansi_colors_1 = require("ansi-colors");
const http_1 = require("http");
const open_1 = __importDefault(require("open"));
const path_1 = require("path");
const url_1 = require("url");
const archiver_1 = __importDefault(require("../../archiver"));
const iac_1 = __importDefault(require("../../endpoints/lib/iac"));
const index_js_1 = __importDefault(require("../../error/index.js"));
const command_1 = __importDefault(require("../../internal/command"));
const port_resolver_1 = __importDefault(require("../../port-resolver"));
const prompt_1 = __importDefault(require("../../prompt"));
const runtime_store_1 = __importDefault(require("../../runtime-store"));
const constants_1 = require("../../util_modules/constants");
const scopes_js_1 = __importDefault(require("../../authentication/constants/scopes.js"));
const env_1 = require("../../util_modules/env");
const ASYNC = __importStar(require("../../util_modules/fs/lib/async.js"));
const SYNC = __importStar(require("../../util_modules/fs/lib/sync.js"));
const utils_js_1 = require("../../util_modules/fs/utils.js");
const js_1 = require("../../util_modules/js");
const index_1 = require("../../util_modules/logger/index");
const option_1 = require("../../util_modules/option");
const shell_1 = require("../../util_modules/shell");
const server_js_1 = require("../../util_modules/server.js");
const project_1 = require("../../util_modules/project");
const getZipAndTemplate = (filePath, stagedDeploy) => __awaiter(void 0, void 0, void 0, function* () {
const zipFile = filePath
? yield ASYNC.readFile((0, utils_js_1.untildify)(filePath), 'buffer')
: (stagedDeploy === null || stagedDeploy === void 0 ? void 0 : stagedDeploy.id)
? yield new iac_1.default().deployDownload(stagedDeploy.id)
: undefined;
if (!zipFile) {
throw filePath
? new index_js_1.default('Provided zip file path does not exists!')
: new index_js_1.default('Unable to get zip file from server!', { exit: 2 });
}
const zipArchive = new archiver_1.default().load(zipFile);
const templateFile = yield zipArchive.readFile(constants_1.REGEX.project.template);
if (!templateFile) {
throw new index_js_1.default('No project template found', {
exit: 1,
errorId: 'I-1'
});
}
return [zipArchive, templateFile];
});
const ensureUserAction = (deployRes) => __awaiter(void 0, void 0, void 0, function* () {
const userActionError = yield new Promise((res, rej) => __awaiter(void 0, void 0, void 0, function* () {
const callbackPort = yield port_resolver_1.default.getFreePort(3000, 10, false);
const accessUrl = new url_1.URL(`/baas/v1/project/import/${deployRes.id}/deploy`, `${constants_1.ORIGIN.admin}`);
accessUrl.searchParams.set('redirect_url', `http://localhost:${callbackPort}/success`);
const orgId = (0, project_1.getEnvId)();
orgId && accessUrl.searchParams.set('catalyst_org', orgId);
const server = (0, http_1.createServer)((req, resp) => __awaiter(void 0, void 0, void 0, function* () {
try {
if (req.url !== '/success') {
resp.writeHead(404);
resp.end();
return;
}
const htmlFile = yield ASYNC.readFile((0, path_1.join)(__dirname, '../../../templates/iacSuccess.html'));
resp.setHeader('Content-Type', 'text/html');
resp.writeHead(200);
resp.end(htmlFile, () => __awaiter(void 0, void 0, void 0, function* () {
req.socket.destroy();
yield destroyer.destroy().catch((err) => (0, index_1.debug)(err));
res();
}));
}
catch (e) {
yield destroyer.destroy().catch((err) => (0, index_1.debug)(err));
res(e);
}
}));
const destroyer = new server_js_1.ConnectionDestroyer(server);
server.listen(callbackPort, '127.0.0.1', () => {
const urlString = accessUrl.toString();
(0, index_1.info)();
(0, index_1.info)('Visit this URL on this device to proceed:');
(0, index_1.info)(ansi_colors_1.bold.underline(urlString));
(0, index_1.info)();
(0, open_1.default)(urlString).catch();
});
server.on('error', (err) => {
rej(err);
});
}));
if (userActionError) {
throw new index_js_1.default('Error while verifying user action', {
original: userActionError,
exit: 2
});
}
(0, index_1.info)();
(0, index_1.success)(`Successfully scheduled import job for project "${deployRes.project_details.project_name}" with jobid "${deployRes.id}"`);
if ((0, option_1.getCurrentCommand)() === 'init' || (0, env_1.isPrimaryShell)()) {
const exitListeners = process.listeners('exit');
process.removeAllListeners('exit');
const allGlobalOpts = runtime_store_1.default.get('context.opts.globalOpts', {});
const optsArr = Object.keys(allGlobalOpts).reduce((arr, key) => {
arr.push('--' + key);
if (allGlobalOpts[key]) {
arr.push(allGlobalOpts[key]);
}
return arr;
}, ['--id', deployRes.id, '--org', (0, project_1.getEnvId)() || '']);
yield (0, shell_1.spawn)('catalyst', ['iac:status', 'import', ...optsArr], {
shell: true,
stdio: 'inherit'
})
.ASYNC()
.catch((err) => (0, index_1.debug)(err));
(exitListeners || []).forEach((listner) => {
process.addListener('exit', listner);
});
}
});
const iacImport = (filePath, projectName) => __awaiter(void 0, void 0, void 0, function* () {
const iacAPI = new iac_1.default();
const allDeploys = yield iacAPI.allDeploys();
const stagedDeploy = allDeploys.find((deploy) => deploy.status === 'Staged');
const stagedAns = yield prompt_1.default.ask(prompt_1.default.question('consent', `Do you wish to continue setting up the already staged project (${stagedDeploy === null || stagedDeploy === void 0 ? void 0 : stagedDeploy.project_details.project_name}):`, {
type: 'confirm',
defaultAns: true,
suffix: '\n Note: Declining will delete the old staged project!',
when: !!stagedDeploy
}));
if (stagedDeploy && (stagedAns === null || stagedAns === void 0 ? void 0 : stagedAns.consent)) {
const [zipArchive, templateFile] = yield getZipAndTemplate(undefined, stagedDeploy);
yield ensureUserAction(stagedDeploy);
return [zipArchive, templateFile, stagedDeploy];
}
if (stagedDeploy && !(stagedAns === null || stagedAns === void 0 ? void 0 : stagedAns.consent)) {
yield iacAPI.deployDelete(stagedDeploy.id);
(0, index_1.message)(`Successfully deleted project ${stagedDeploy === null || stagedDeploy === void 0 ? void 0 : stagedDeploy.project_details.project_name} from console.`);
}
if (!filePath) {
yield prompt_1.default.register('file-path');
}
const userReply = yield prompt_1.default.ask(prompt_1.default.question('projectName', 'Provide a name for your new project:', {
when: !projectName,
validate: (ans) => ans.match(constants_1.REGEX.project.name)
? true
: `Project Name is invalid, it should match ${constants_1.REGEX.project.name}`
}), prompt_1.default.question('filePath', 'Provide the path of the zip file that you would like to use?', {
type: 'file-path',
when: !filePath,
exclude: ['**/!(*.zip)', '**/.*'],
validate: ({ value }) => __awaiter(void 0, void 0, void 0, function* () {
if (value && value.endsWith('.zip')) {
return (yield ASYNC.fileExists(value)) ? true : 'File does not exists!';
}
return 'Invalid zip file!';
})
}));
projectName = (userReply.projectName || projectName);
filePath = (userReply.filePath || filePath);
if (!filePath.endsWith('.zip')) {
throw new index_js_1.default('Provided file type is not supported. Provide a zip path.');
}
const [zipArchive, templateFile] = yield getZipAndTemplate(filePath);
const parsedJSON = js_1.JS.parseJSON(templateFile);
const format = parsedJSON ? constants_1.IAC.template_format.json : constants_1.IAC.template_format.yml;
const deployRes = yield new iac_1.default().deploy(projectName, format, SYNC.getReadStream(filePath));
yield ensureUserAction(deployRes);
return [zipArchive, templateFile, deployRes];
});
exports.iacImport = iacImport;
exports.default = new command_1.default('iac:import [file_path]')
.description('Deploy the iac zip file to console and create a new project with it.')
.option('-n, --name <project_name>', 'name of the project to be used')
.needs('auth', [
scopes_js_1.default.project_import_read,
scopes_js_1.default.project_import_create,
scopes_js_1.default.project_import_delete
])
.needs('config', { optional: true })
.needs('rc', { optional: true, skipOrgCheck: false })
.action((filePath) => __awaiter(void 0, void 0, void 0, function* () {
const nameOptValue = (0, option_1.getOptionValue)('name');
if (nameOptValue && !nameOptValue.match(constants_1.REGEX.project.name)) {
throw new index_js_1.default(`Project Name is invalid, it should match ${constants_1.REGEX.project.name}`);
}
yield (0, exports.iacImport)(filePath, nameOptValue);
}));