UNPKG

terraform-plus

Version:
151 lines (134 loc) 4.24 kB
'use strict'; const fs = require('fs'); const yaml = require('js-yaml'); const treeify = require('treeify'); const ProgressBar = require('progress'); const Aws = require('../helpers/aws'); const TerraformCommand = require('../terraform-command'); class DeployCommand extends TerraformCommand { /** * @desc Validates options passed via cli * * @returns {Boolean} - Returns true if options given from cli are valid. * * @private */ _validateOptions() { this._logger.debug(`this._cli : ${this._cli}`); return super._validateOptions(); } /** * @desc Deploys software from predefined deploy.yml config files */ run() { this._layers = [[]]; this._logger.debug(`templates : ${this.templates}`); this._folders = {}; this._graph = {}; this.getFilesPath([this._directory]).forEach(element => { if (fs.existsSync(element)) { let tfsConf = yaml.safeLoad(fs.readFileSync(`${element}/${this._paramFile}`, 'utf8')); this._folders[tfsConf.id] = element; if (tfsConf && tfsConf.parent && !this._cli.include) { this._graph[tfsConf.id] = tfsConf.parent; } else if (!this._graph[tfsConf.id]) { this._graph[tfsConf.id] = null; this._layers[0].push(tfsConf.id); } } }); console.log('Building tree:'); let graph = this._graph; if (this._cli.branch) { graph = this.findBranch(this._graph); console.log(treeify.asTree(this.listToTree(graph), true)); } else { console.log(treeify.asTree(this.listToTree(graph), true)); } console.log('Start terraform deploy\n'); if (!this._verbose) { this.bar = new ProgressBar('Run deploy [:bar] :percent :elapseds', { total: Object.keys(graph).length * 2, width: 30 }); this.bar.tick(0); } this.deploy(); return Promise.resolve(); } /** * * @return {Promise<void>} */ async deploy() { let bar = this.bar; let tf = this.terraform(); let verbose = this._verbose; for (let id in this._layers) { let folders = this._folders; let deploy = this; let promises = this._layers[id].map(async function(element) { let elementPath = folders[element]; if (!verbose) { bar.tick(); } await deploy.execPromise(tf, elementPath, element); if (!verbose) { bar.tick(); } }); await Promise.all(promises); } } /** * * @param tf * @param elementPath * @return {Promise<any>} */ execPromise(tf, elementPath, element) { let paramFolder = DeployCommand.TFS_PATH; let deployFile = DeployCommand.TFS_DEPLOY_CONFIG; return new Promise(function(resolve, reject) { tf.then((terraform) => { terraform.apply(elementPath).then(() => { if (fs.existsSync(`${elementPath}/${paramFolder}/${deployFile}`)) { let tfsConf = yaml.safeLoad(fs.readFileSync(`${elementPath}/${paramFolder}/${deployFile}`, 'utf8')); let s3Paths = tfsConf.aws.s3; s3Paths.forEach((s3Path) => { Aws.s3upload(element, `${elementPath}/${s3Path.path}`, s3Path.key); }); } }).then(() => { resolve(); }); }); }); } /** * @returns {String} */ static get DESCRIPTION() { return 'deploy software from predefined deploy.yml config files' } /** * @returns {String} */ static get OPTIONS() { return [{ opt: '-p, --provider [provider]', desc: 'terraform provider name (e.g. aws, azurerm, google)' }, { opt: '-i, --include [comma_separated_values]', desc: 'comma separated values of terraform scripts or folders to be included' }, { opt: '-e, --exclude [comma_separated_values]', desc: 'comma separated values of terraform scripts or folders to be excluded' }, { opt: '-d, --directory [directory]', desc: 'path where terraform will be executed (default value - current working directory)' }, { opt: '-b, --branch [branch]', desc: 'path where terraform will be executed (default value - current working directory)' }]; } } module.exports = DeployCommand;