terraform-plus
Version:
Terraform Plus
233 lines (207 loc) • 5.67 kB
JavaScript
'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;