UNPKG

sleeveforarm

Version:
257 lines 13 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs-extra"); const Path = require("path"); const ReplaceInFile = require("replace-in-file"); const Winston = require("winston"); const applicationInsights_1 = require("./applicationInsights"); // tslint:disable-next-line:max-line-length const ApplicationInsightsInfrastructure = require("./applicationInsightsInfrastructure"); const CommonUtilities = require("./common-utilities"); const Data = require("./data"); const keyvault_1 = require("./keyvault"); const KeyVaultInfrastructure = require("./keyvaultInfrastructure"); const mysql_azure_1 = require("./mysql-azure"); const MySqlAzureInfrastructure = require("./mysql-azureInfrastructure"); const Resource = require("./resource"); const resourcegroup_1 = require("./resourcegroup"); const ResourceGroupInfrastructure = require("./resourcegroupInfrastructure"); const webapp_node_azure_1 = require("./webapp-node-azure"); // tslint:disable-next-line:max-line-length const WebappNodeAzureInfrastructure = require("./webapp-node-azureInfrastructure"); function createInfraResource(resource, targetDirectoryPath) { let infraResource = null; if (CommonUtilities.isClass(resource, resourcegroup_1.default)) { infraResource = new ResourceGroupInfrastructure.ResourceGroupInfrastructure(); } if (CommonUtilities.isClass(resource, keyvault_1.default)) { infraResource = new KeyVaultInfrastructure.KeyVaultInfrastructure(); } if (CommonUtilities.isClass(resource, webapp_node_azure_1.default)) { infraResource = new WebappNodeAzureInfrastructure.WebappNodeAzureInfrastructure(); } if (CommonUtilities.isClass(resource, mysql_azure_1.default)) { infraResource = new MySqlAzureInfrastructure.MySqlAzureInfrastructure(); } if (CommonUtilities.isClass(resource, applicationInsights_1.default)) { infraResource = new ApplicationInsightsInfrastructure.ApplicationInsightsInfrastructure(); } if (infraResource === null) { throw new Error("Unrecognized resource type!"); } infraResource.initialize(resource, targetDirectoryPath); return infraResource; } function init(currentWorkingDirectory) { return __awaiter(this, void 0, void 0, function* () { const assetPath = Path.join(__dirname, "..", "assets", "cliInit"); if (!(yield CommonUtilities.validateResource(Path.basename(process.cwd()), Data.data.ProjectNameLength))) { throw new Error(`Project name should be less than \ ${Data.data.ProjectNameLength} characters, contains only \ alphanumeric characters and start with a letter\n`); } yield fs.copy(assetPath, currentWorkingDirectory); const aiInfrastructure = new ApplicationInsightsInfrastructure.ApplicationInsightsInfrastructure(); const aiSleevePath = Path.join(currentWorkingDirectory, "AppInsights"); yield aiInfrastructure .initialize(null, aiSleevePath) .setup(); const aiReplaceOptions = { files: Path.join(aiSleevePath, "sleeve.js"), from: /new applicationInsights\(\);/, to: "new applicationInsights().setGlobalDefault(true);" }; yield ReplaceInFile(aiReplaceOptions); // NPM publish turns all .gitignore into .npmignore. For awhile it // seemed that you could put in both a .gitignore and a .npmignore // and the .gitignore would be ignored but no longer. So now we // ship a .npmignore and then rename it after install. yield fs.move(Path.join(currentWorkingDirectory, ".npmignore"), Path.join(currentWorkingDirectory, ".gitignore")); const locations = yield CommonUtilities.azAppServiceListLocations(); const dataCenterEnum = locations[0].name.replace(/ /g, ""); const replaceInFileOptions = { files: Path.join(currentWorkingDirectory, "sleeve.js"), from: /XXXX/, to: `DataCenterNames.${dataCenterEnum}` }; yield ReplaceInFile(replaceInFileOptions); yield CommonUtilities.npmSetup(currentWorkingDirectory); yield CommonUtilities.executeOnSleeveResources(currentWorkingDirectory, (path) => { return CommonUtilities.npmSetup(path); }); if ((yield fs.pathExists(Path.join(currentWorkingDirectory, ".git"))) === false) { CommonUtilities.exec("git init", currentWorkingDirectory); } }); } exports.init = init; function setup(currentWorkingDirectory, serviceName, serviceType) { return __awaiter(this, void 0, void 0, function* () { const rootPath = yield CommonUtilities.findGitRootDir(currentWorkingDirectory); const targetPath = Path.join(rootPath, serviceName); let infraResource; switch (serviceType) { case Resource.ResourcesWeSupportSettingUp.MySqlAzure: { infraResource = new MySqlAzureInfrastructure.MySqlAzureInfrastructure(); break; } case Resource.ResourcesWeSupportSettingUp.WebAppNode: { infraResource = new WebappNodeAzureInfrastructure.WebappNodeAzureInfrastructure(); break; } default: { throw new Error(`Unsupported resource type ${serviceType}`); } } infraResource.initialize(null, targetPath); yield infraResource.setup(); return targetPath; }); } exports.setup = setup; function hydrateEnvironment(currentWorkingDirectory, deploymentType) { return __awaiter(this, void 0, void 0, function* () { const resourcesInEnvironment = []; const rootOfDeploymentPath = yield CommonUtilities.findGitRootDir(currentWorkingDirectory); const rootSleevePath = Path.join(rootOfDeploymentPath, "sleeve.js"); if (!(fs.existsSync(rootSleevePath))) { // tslint:disable-next-line:no-console console.log("There is no sleeve.js in the root, \ this is not a properly configured project"); process.exit(-1); } yield CommonUtilities.npmSetup(rootOfDeploymentPath); const rootResourceGroup = require(rootSleevePath); // tslint:disable-next-line:max-line-length const rootResourceGroupInfra = createInfraResource(rootResourceGroup, rootOfDeploymentPath); yield rootResourceGroupInfra.hydrate(resourcesInEnvironment, deploymentType); resourcesInEnvironment.push(rootResourceGroupInfra); yield CommonUtilities.executeOnSleeveResources(rootOfDeploymentPath, (candidatePath) => __awaiter(this, void 0, void 0, function* () { yield CommonUtilities.npmSetup(candidatePath); const sleevePath = Path.join(candidatePath, "sleeve.js"); const resource = require(sleevePath); const infraResource = createInfraResource(resource, candidatePath); resourcesInEnvironment.push(yield infraResource.hydrate(resourcesInEnvironment, deploymentType)); })); return resourcesInEnvironment; }); } // TODO: developmentDeploy is really just intended for Node WebAPPs so that // we deploy code in Azure that will properly set up the environment // to take a version of Sleeve from the local machine and not look to // NPM. But we really need to shove this into some kind of property bag // as the name and usage is confusing. function deployResources(currentWorkingDirectory, deploymentType, developmentDeploy = false) { return __awaiter(this, void 0, void 0, function* () { const resourcesInEnvironment = yield hydrateEnvironment(currentWorkingDirectory, deploymentType); if (resourcesInEnvironment.length === 0) { // tslint:disable-next-line:no-console console.log("There are no resources to deploy"); process.exit(-1); } const promisesToWaitFor = []; for (const resource of resourcesInEnvironment) { promisesToWaitFor.push(resource.deployResource(developmentDeploy)); } yield Promise.all(promisesToWaitFor); if (deploymentType === Resource.DeployType.Production) { for (const resource of resourcesInEnvironment) { if (resource instanceof WebappNodeAzureInfrastructure.WebappNodeAzureInfrastructure) { const baseDeployWebApp = // tslint:disable-next-line:max-line-length yield resource .getBaseDeployClassInstance(); console.log(`Web app ${resource.baseName} is available at \ ${yield baseDeployWebApp.getDeployedURL()}`); } } } return resourcesInEnvironment; }); } exports.deployResources = deployResources; function getAppInsightsURL(aiName, resourceGroupName) { return CommonUtilities.runAzCommand(`az resource show --name ${aiName} \ --resource-group ${resourceGroupName} \ --resource-type Microsoft.Insights/components`) .then((result) => { if (result && result.properties) { return `https://ms.portal.azure.com/#resource/subscriptions/\ ${result.properties.TenantId}/resourceGroups/${resourceGroupName}\ /providers/Microsoft.Insights/components/${aiName}/overview`; } return ""; }); } function createEnvironmentToGetAiLocation(currentWorkingDirectory, deploymentType) { return __awaiter(this, void 0, void 0, function* () { const resourcesInEnvironment = yield hydrateEnvironment(currentWorkingDirectory, deploymentType); const rootResourceGroupInfra = CommonUtilities .findGlobalDefaultResourceByType(resourcesInEnvironment, // tslint:disable-next-line:max-line-length ResourceGroupInfrastructure.ResourceGroupInfrastructure); const rootAiInfra = CommonUtilities .findGlobalDefaultResourceByType(resourcesInEnvironment, // tslint:disable-next-line:max-line-length ApplicationInsightsInfrastructure.ApplicationInsightsInfrastructure); return getAppInsightsURL(rootAiInfra.appInsightsFullName, rootResourceGroupInfra.resourceGroupName); }); } function getManageResourceData(currentWorkingDirectory) { return __awaiter(this, void 0, void 0, function* () { const results = {}; results[Resource.DeployType.LocalDevelopment] = yield createEnvironmentToGetAiLocation(currentWorkingDirectory, Resource.DeployType.LocalDevelopment); results[Resource.DeployType.Production] = yield createEnvironmentToGetAiLocation(currentWorkingDirectory, Resource.DeployType.Production); return results; }); } exports.getManageResourceData = getManageResourceData; function printManageResults(deployType, deployResult) { const printPrefix = `${deployType} deployment:`; if (deployResult === "") { console.log(`${printPrefix} NO DEPLOYMENT`); return; } console.log(`${printPrefix} ${deployResult}`); } function manageResource(currentWorkingDirectory) { return __awaiter(this, void 0, void 0, function* () { const manageResults = yield getManageResourceData(currentWorkingDirectory); const devDeployResults = manageResults[Resource.DeployType.LocalDevelopment]; const productionDeployResults = manageResults[Resource.DeployType.Production]; printManageResults(Resource.DeployType.LocalDevelopment, devDeployResults); printManageResults(Resource.DeployType.Production, productionDeployResults); }); } exports.manageResource = manageResource; function setLoggingIfNeeded(argv) { if (argv.verbose) { Winston.add(Winston.transports.File, { filename: "log.txt", level: "silly" }); Winston.remove(Winston.transports.Console); Winston.add(Winston.transports.Console, { level: "silly", stderrLevels: [] }); } } exports.setLoggingIfNeeded = setLoggingIfNeeded; //# sourceMappingURL=cliUtilities.js.map