UNPKG

terraform-plus

Version:
255 lines (221 loc) 6.31 kB
'use strict'; const fs = require('fs-extra'); const path = require('path'); const yaml = require('js-yaml'); const AbstractCommand = require('./abstract-command'); class TerraformCommand extends AbstractCommand { /** * @desc Validates options passed via cli * * @returns {Boolean} - Returns true if options given from cli are valid. * * @private */ _validateOptions() { if (this._directory === path.basename(this._directory)) { this._logger.warn(`Option --directory='${this._directory}' is invalid. ${this._suffix}`); return false; } if (this._templates[this._directory]) { this._logger.error(`Directory template '${this._directory}' is missing. ${this._suffix}`); return false; } if (this.getFilesPath([this._directory]).length <= 0) { this._logger.error(`No terraform files were found in path '${this._directory}'`); return false; } return super._validateOptions(); } /** * @desc Gets paths which have .tf files in them. * * @param {Array} originPaths - --path value entered from cli * @param {Array} arr - Empty array which will contain dirs what have .tf files * * @returns {Array} - returns arr */ getFilesPath(originPaths, arr = []) { let dirs = []; let tfFiles = []; originPaths.forEach(srcPath => { this._logger.debug(`Initial path : ${srcPath}`); // reads Sync srcPath and joins their paths let items = this._fs.readdirSync(srcPath).map(x => this._path.join(srcPath, x)); // folders which have .tf extention //tfFiles = items.filter(file => file.match(/.*\.tf$/)); // folder which have main.tf file tfFiles = items.filter(file => file.match(/\/main.tf$/)); // analyses if a file is a directory and pushes it. dirs.push(...items.filter(file => this._fs.lstatSync(file).isDirectory())); // Pushes currentDir if they have .tf files if (tfFiles.length > 0) { let currentDir = path.dirname(tfFiles.pop()); if (this.hasProvider(currentDir) && this.include(currentDir) && this.exclude(currentDir)) { arr.push(currentDir); } dirs = dirs.filter(item => !item.includes(currentDir)); } }); if (dirs.length === 0) { return arr; } return this.getFilesPath(dirs, arr); } include(directory) { let confPath = path.join(directory,this._paramFile); if (fs.existsSync(confPath)) { let tfsConf = yaml.safeLoad(fs.readFileSync(confPath, 'utf8')); if (this._cli.include && tfsConf) { let include = this._cli.include.split(','); if (include.indexOf(tfsConf.id) < 0) { return false; } } } return true; } exclude(directory) { let confPath = path.join(directory,this._paramFile); if (fs.existsSync(confPath)) { let tfsConf = yaml.safeLoad(fs.readFileSync(confPath, 'utf8')); if (this._cli.exclude && tfsConf) { let exclude = this._cli.exclude.split(','); if (exclude.indexOf(tfsConf.id) >= 0) { return false; } } } return true; } hasProvider(directory) { let confPath = path.join(directory,this._paramFile); if (fs.existsSync(confPath)) { let tfsConf = yaml.safeLoad(fs.readFileSync(confPath, 'utf8')); if (this._provider && tfsConf) { return (tfsConf.provider === this._provider); } else { //if provider not defined, add folders return true; } } return false; } /** * * @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 = []; layer++; //this._layers[++layer] = []; for (let i in list) { if (list[i] === element) { if (!this._layers[layer]) { this._layers[layer] = []; } if (this._layers[layer].indexOf(i) < 0) { 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; } /** * * @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; } } module.exports = TerraformCommand;