UNPKG

terraform-plus

Version:
233 lines (207 loc) 5.67 kB
'use strict'; // const { exec } = require('child_process'); // const path = require('path'); const treeify = require('treeify'); const fs = require('fs'); const yaml = require('js-yaml'); const TerraformCommand = require('../terraform-command'); class GraphCommand 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 Executes `terraform apply` across multiple terraform scripts */ run() { this._layers=[[]]; this._logger.debug(`templates : ${this.templates}`); this._graph = {}; this.getFilesPath([this._directory]).forEach(element => { if (fs.existsSync(element)) { let tfsConf = yaml.safeLoad(fs.readFileSync(`${element}/${this._paramFile}`, 'utf8')); if (tfsConf && tfsConf.parent) { this._graph[tfsConf.id] = tfsConf.parent ; } else { if (!this._graph[tfsConf.id]){ this._graph[tfsConf.id] = null; this._layers[0].push(tfsConf.id); } } } }); //let test = this.listToTree(this._graph); //console.log(this._graph); if (this._cli.branch){ console.log(treeify.asTree(this.listToTree(this.findBranch(this._graph)),true)); } else { console.log(treeify.asTree(this.listToTree(this._graph), true)); } //console.log(this.listToTree(this._graph)); // console.log(this.findBranch(this._graph)); //console.log(treeify.asTree(this.listToTree(this.findBranch(this._graph)),true)); //console.log(this._layers); return Promise.resolve(); } /** * * @param {Array} list * @return {*} */ findBranch(list){ let result = {}; if (this._cli.branch){ //console.log(list[this._cli.branch]); let child = this.findElement(list,this._cli.branch,0) if (child && Object.keys(child).length > 0 ) { for (let i in child) { result[i] = this._cli.branch; if (child[i]){ // TODO: too many nested blocks :( for ( let j in child[i]) { result[j] = i; } } } } let parent = this.findParent(list,this._cli.branch); if (Object.keys(parent).length > 0 ) { for (let i in parent) { result[parent[i]] = i; } for (let i in parent) { if (!result[i]) { result[i] = null; this._layers[0] =[i]; } } } else { result[this._cli.branch] = null; this._layers[0] =[this._cli.branch]; } return result; } } /** * * @param {Array} list * @param {String} value * @param {Array} arr * @return {*} */ findParent ( list, value, arr={} ) { if (list[value] && list[value] !== null){ arr[list[value]] = value; let result = this.findParent(list,list[value], arr); if (result) { return result; } else { return arr; } } return false; } /** * * @param {Array} list * @return {Array} */ listToTree(list) { let result = []; this._layers[0].forEach(id => { let element = this.findElement(list,id,0) result[id] = element; }); return result; } /** * * @param {Array} list * @param {String} element * @param {Number} layer * @return {Array|Null} */ findElement(list,element,layer){ let arr = []; for (let i in list){ if (list[i]=== element) { this._layers[++layer]=[]; this._layers[layer].push(i); let result = this.findElement(list,i,layer); if (arr[i]) { arr[i] = {}; } if (result) { arr[i] = this.extend({}, arr[i],result); } else { arr[i] = null; } } } return Object.keys(arr).length > 0 ? arr : null; // if (list[element] && list[element] !== null){ // this._layers[++layer]=[]; // this._layers[layer].push(element); // let result = this.findElement(list,list[element],layer); // if (result) { // arr[list[element]] = result; // } else { // arr[list[element]] = null; // } // return arr; // } //return null; } /** * * @param {Object} target * @return {Object} */ extend(target) { var sources = [].slice.call(arguments, 1); sources.forEach(function (source) { for (var prop in source) { target[prop] = source[prop]; } }); return target; } /** * @returns {String} */ static get DESCRIPTION() { return 'show dependency graph across multiple terraform scripts' } /** * @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 = GraphCommand;