UNPKG

azure-bake

Version:

Azure cloud deployment platform for both infrasturcture as code and software

199 lines 9.18 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BakePackage = void 0; const YAML = require("js-yaml"); const fs = require("fs"); const path = require("path"); const core_1 = require("@azbake/core"); const azcli_npm_1 = require("azcli-npm"); class BakePackage { constructor(source) { this._env = {}; this._loadEnvironment(); this._config = {}; this._loadPackage(source); } get Environment() { return this._env; } get Config() { return this._config; } _loadEnvironment() { //load environment variables || defaults into an interface this._env.toolVersion = process.env.npm_package_version || "0.0.0"; this._env.environmentName = process.env.BAKE_ENV_NAME || ""; this._env.environmentCode = process.env.BAKE_ENV_CODE || ""; this._env.regions = JSON.parse(process.env.BAKE_ENV_REGIONS || ""); this._env.authentication = {}; this._env.authentication.subscriptionId = process.env.BAKE_AUTH_SUBSCRIPTION_ID || ""; this._env.authentication.tenantId = process.env.BAKE_AUTH_TENANT_ID || ""; this._env.authentication.serviceId = process.env.BAKE_AUTH_SERVICE_ID || ""; this._env.authentication.secretKey = process.env.BAKE_AUTH_SERVICE_KEY || ""; this._env.authentication.certPath = process.env.BAKE_AUTH_SERVICE_CERT || ""; this._env.authentication.skipAuth = (process.env.BAKE_AUTH_SKIP || 'false').toLocaleLowerCase() === 'true'; this._env.logLevel = process.env.BAKE_LOG_LEVEL || "info"; //clear out the auth info process.env.BAKE_AUTH_SUBSCRIPTION_ID = process.env.BAKE_AUTH_SERVICE_ID = process.env.BAKE_AUTH_SERVICE_KEY = process.env.BAKE_AUTH_SERVICE_CERT = process.env.BAKE_AUTH_TENANT_ID = ""; //yaml parse out the global variables. let content = ""; try { let file = process.env.BAKE_VARIABLES || ""; if (file && fs.existsSync(file)) { content = fs.readFileSync(file, 'utf8'); let obj = YAML.safeLoad(content); this._env.variables = (0, core_1.objToVariableMap)(obj || []); } } catch (e) { let logger = new core_1.Logger([], this._env.logLevel); //build a logger with correct log level. logger.debug(content); logger.error("Failed to load global environment variables"); logger.error(e); } } _validatePackage(config) { if (!config.name) throw new Error('config.name not defined'); if (!config.shortName) throw new Error('config.shortName not defined'); if (!config.version) throw new Error('config.version not defined'); } objToStrMap(obj) { let strMap = new Map(); for (let k of Object.keys(obj)) { strMap.set(k, obj[k]); } return strMap; } _loadPackage(source) { let file = fs.readFileSync(source, 'utf8'); let config = {}; try { config = YAML.load(file); } catch (e) { let logger = new core_1.Logger(); logger.error("Failed to load bake file: " + source); logger.error(e); throw e; } //bind all ingredients let logger = new core_1.Logger(); logger.log('Downloading ingredients...'); //make sure the cwd path has a node_modules folder, so that we install ingredients localy let node_path = process.env['npm_ingredient_root'] || ""; if (!fs.existsSync(node_path)) { fs.mkdirSync(node_path); } let ingredients = config.ingredients || new Array(); ingredients.forEach(ingredientsType => { let cmd = "npm"; if (process.platform === "win32") cmd = "npm.cmd"; //first check if any version of this package is already installed let skipNpm = false; let npmPackageName = ""; try { let split = ingredientsType.split("@"); let ingPackage = ''; if (split.length > 2 && !ingPackage[0]) { ingPackage = "@" + split[split.length - 2]; npmPackageName = split[split.length - 2]; npmPackageName = npmPackageName.replace("azbake/", ""); } else { ingPackage = split[0]; npmPackageName = ingPackage; } const packageDir = path.join(ingPackage, 'package.json'); let packageVersion = require(packageDir).version; //making it this var means we could load the ingredient as a module. //so skip install! //NOTE: this could mean an older ingredient is installed then what is requested //this is only a problem for non-container deployments, which is mostly testing usage logger.log('- ' + ingredientsType + " [SKIPPED]"); skipNpm = true; } catch (e) { } if (!skipNpm) { logger.log('- ' + ingredientsType); var npm = new azcli_npm_1.ShellRunner(cmd).start(); npm.arg("install").arg(ingredientsType).arg("--legacy-peer-deps"); let er = npm.exec(); if (er.code != 0) { console.log(er); logger.error("failed to download ingredient: " + ingredientsType); throw new Error(); } } }); ingredients.forEach(ingredientType => { let firstIdx = ingredientType.indexOf("@"); let lastIdx = ingredientType.lastIndexOf("@"); if (lastIdx != firstIdx) { //strip off @<ver> ingredientType = ingredientType.substr(0, lastIdx); } core_1.IngredientManager.Register(ingredientType); }); logger.log('Ingredients loaded'); //start with config vars based on env based vars let vars = (0, core_1.objToVariableMap)(config.variables); //merge config vars into the env vars (overwriting as needed) config.variables = this._env.variables || new Map(); vars.forEach((v, n) => { if (config.variables) config.variables.set(n, v); }); //fix up json objects to act as hashmaps. config.parallelRegions = config.parallelRegions == undefined ? true : config.parallelRegions; config.resourceGroup = config.resourceGroup == undefined ? true : config.resourceGroup; //only set rgOverride as a BV if the field is already set if (config.rgOverride) { config.rgOverride = new core_1.BakeVariable(config.rgOverride); } config.recipe = this.objToStrMap(config.recipe); config.recipe.forEach(ingredient => { let source = ingredient.properties.source; ingredient.properties.source = new core_1.BakeVariable(source || ""); ingredient.dependsOn = ingredient.dependsOn || []; ingredient.properties = ingredient.properties || {}; let condition = ingredient.properties.condition; ingredient.properties.condition = condition ? new core_1.BakeVariable(condition) : undefined; ingredient.properties.parameters = (0, core_1.objToVariableMap)(ingredient.properties.parameters || {}); ingredient.properties.tokens = (0, core_1.objToVariableMap)(ingredient.properties.tokens || new Map()); ingredient.properties.alerts = (0, core_1.objToVariableMap)(ingredient.properties.alerts || new Map()); }); this._validatePackage(config); this._config = config; } Authenticate(callback) { return __awaiter(this, void 0, void 0, function* () { try { return yield callback(this._env.authentication); } finally { //strip auth from the public accessor, except for sub id. this._env.authentication = { subscriptionId: this._env.authentication.subscriptionId }; } }); } } exports.BakePackage = BakePackage; //# sourceMappingURL=bake-loader.js.map