read_input/main.js (135 lines of code) (raw):

/** * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*global process*/ import * as url from "node:url"; import { exec } from "child_process"; import { modifyResource } from "./resources/custom-map.js"; import { readSheetRanges } from "./read/google-sheet-read.js"; import { readMapRange, flatRanges, modifyGeneric } from "./format.js"; import { createYaml, cleanRes, uploadToGcs, writeFile, inverseObj, } from "./util.js"; export { main }; const LOCAL_CONFIG_DIR = process.env.EZTF_CONFIG_DIR || "../ezytf-gen-data/eztf-config"; class Eztf { constructor() { this.readRanges = {}; this.eztfConfig = {}; this.rangeNoteKey = {}; this.rangeResourceTfMap = {}; } } function generateEztfConfig(eztf, tfRanges) { console.log("starting ezyTF yaml config generation"); let variable = readMapRange(eztf, "variable")[0] || {}; eztf.eztfConfig["variable"] = variable; eztf.eztfConfig["eztf"] = { tf_any_module: {} }; eztf.eztfConfig["eztf"]["stacks"] = flatRanges(tfRanges); for (const stack of Object.values(tfRanges)) { for (const rangeResourceObjArray of stack) { const resourceRangeObj = inverseObj( Object.assign({}, ...rangeResourceObjArray) ); const resource = Object.keys(resourceRangeObj)[0]; const range = resourceRangeObj[resource]; if (resource === "any_module") { eztf.eztfConfig["eztf"]["tf_any_module"][range] = eztf.rangeNoteKey?.[range]?.["module"] || {}; } if (Object.prototype.hasOwnProperty.call(modifyResource, resource)) { console.log("Custom Modify: ", Object.values(resourceRangeObj).join()); modifyResource[resource](eztf, resourceRangeObj); } else { console.log("Generic Modify:", range); modifyGeneric(eztf, range); } } } let configYaml = createYaml(eztf.eztfConfig); // console.log(configYaml); return configYaml; } function writeEztfConfig(eztf, configYaml, configBucket) { console.log(`configBucket: ${configBucket}`); let configName = eztf.eztfConfig["variable"]["eztf_config_name"] || "ezytf"; let customerName = cleanRes(eztf.eztfConfig["variable"]["domain"]); let customer = `gcp-${customerName}-${configName}`; let fileName = `${configName}/${customer}.yaml`; let eztfInputConfig = fileName; if (configBucket) { eztfInputConfig = `eztf-config/${fileName}`; uploadToGcs(configBucket, eztfInputConfig, configYaml); } else { eztfInputConfig = `${LOCAL_CONFIG_DIR}/${fileName}`; writeFile(eztfInputConfig, configYaml); } console.log(`ezyTF yaml config generated, ${eztfInputConfig}`); return [eztfInputConfig, customer]; } function generateTF(eztfInputConfig, customer) { process.env.EZTF_INPUT_CONFIG = eztfInputConfig; process.env.EZTF_CDK_OUTPUT_DIR = customer; process.env.EZTF_OUTPUT_DIR = process.env.EZTF_OUTPUT_DIR || "../ezytf-gen-data/eztf-output"; process.env.CI = 1; exec( `echo $EZTF_INPUT_CONFIG && \ echo $EZTF_CDK_OUTPUT_DIR && \ if [ -f "\${EZTF_ACCESS_TOKEN_FILE}" ]; then gcloud config set auth/access_token_file $EZTF_ACCESS_TOKEN_FILE ; fi && \ cd ../generate && pwd && \ cdktf synth --hcl --output $EZTF_CDK_OUTPUT_DIR && \ python -W ignore repo.py`, (err, stdout, stderr) => { console.log(`stdout: ${stdout}`); console.log(`stderr: ${stderr}`); if (err) { console.error(err); return; } } ); } async function main(spreadsheetId, configBucket = "", generateCode = false) { let eztf = new Eztf(); const tfRanges = await readSheetRanges(eztf, spreadsheetId); logInfo(eztf); const configYaml = generateEztfConfig(eztf, tfRanges); let [eztfInputConfig, customer] = writeEztfConfig( eztf, configYaml, configBucket ); if (generateCode) { console.log("running cdktf synth"); generateTF(eztfInputConfig, customer); } } function logInfo(eztf) { // console.log(JSON.stringify(global.readRanges,null,2)) // console.log(JSON.stringify(global.rangeNoteKey, null, 2)); const usedMetadata = new Set(); for (const noteRangeValues of Object.values(eztf.rangeNoteKey)) { for (const metadataFun of Object.values(noteRangeValues["metadata"])) { metadataFun.forEach((item) => usedMetadata.add(item)); } } console.log("user used metadata:", usedMetadata); } // below code will run during node main.js if (import.meta.url.startsWith("file:")) { const modulePath = url.fileURLToPath(import.meta.url); if (process.argv[1] === modulePath) { let mode = process.argv[2]; if (mode === "read") { await main( process.env.EZTF_SHEET_ID, process.env.EZTF_CONFIG_BUCKET, false ); } else if (mode === "generate") { await main( process.env.EZTF_SHEET_ID, process.env.EZTF_CONFIG_BUCKET, true ); } } }