fix(core.gbapp): Self-replication on Azure.

This commit is contained in:
Rodrigo Rodriguez 2019-05-26 20:25:08 -03:00
parent ba2657844c
commit 4b7d29ded2
6 changed files with 97 additions and 30 deletions

View file

@ -63,6 +63,14 @@ export class GBAdminService implements IGBAdminService {
return msRestAzure.generateUuid(); return msRestAzure.generateUuid();
} }
public static getNodeVersion() {
const packageJson = urlJoin(process.cwd(), 'package.json');
// tslint:disable-next-line: non-literal-require
const pjson = require(packageJson);
return pjson.engines.node.replace('=', '');
}
public static async getADALTokenFromUsername(username: string, password: string) { public static async getADALTokenFromUsername(username: string, password: string) {
const credentials = await GBAdminService.getADALCredentialsFromUsername(username, password); const credentials = await GBAdminService.getADALCredentialsFromUsername(username, password);

View file

@ -100,8 +100,6 @@ export class StartDialog {
authoringKey = this.retrieveAuthoringKey(); authoringKey = this.retrieveAuthoringKey();
} }
process.stdout.write(`${GBAdminService.GB_PROMPT}Thank you. That is enough information.\nNow building farm...`);
// Prepares the first instance on bot farm. // Prepares the first instance on bot farm.
const instance = <IGBInstance>{}; const instance = <IGBInstance>{};
@ -206,7 +204,7 @@ generate manually an App ID and App Secret.\n`
map[index++] = element; map[index++] = element;
}); });
let subscriptionIndex; let subscriptionIndex;
if (!subscriptionIndex) { if (!subscriptionIndex && subscriptionId === undefined) {
process.stdout.write('CLOUD_SUBSCRIPTIONID (type a number):'); process.stdout.write('CLOUD_SUBSCRIPTIONID (type a number):');
subscriptionIndex = scanf('%d'); subscriptionIndex = scanf('%d');
subscriptionId = map[subscriptionIndex].subscriptionId; subscriptionId = map[subscriptionIndex].subscriptionId;

View file

@ -42,7 +42,7 @@ import { SearchManagementClient } from 'azure-arm-search';
import { SqlManagementClient } from 'azure-arm-sql'; import { SqlManagementClient } from 'azure-arm-sql';
import { WebSiteManagementClient } from 'azure-arm-website'; import { WebSiteManagementClient } from 'azure-arm-website';
//tslint:disable-next-line:no-submodule-imports //tslint:disable-next-line:no-submodule-imports
import { AppServicePlan } from 'azure-arm-website/lib/models'; import { AppServicePlan, Site, SiteConfigResource, SiteSourceControl, SiteLogsConfig } from 'azure-arm-website/lib/models';
import { GBLog, IGBInstallationDeployer, IGBInstance } from 'botlib'; import { GBLog, IGBInstallationDeployer, IGBInstance } from 'botlib';
import { HttpHeaders, HttpMethods, ServiceClient, WebResource } from 'ms-rest-js'; import { HttpHeaders, HttpMethods, ServiceClient, WebResource } from 'ms-rest-js';
import { GBAdminService } from '../../../packages/admin.gbapp/services/GBAdminService'; import { GBAdminService } from '../../../packages/admin.gbapp/services/GBAdminService';
@ -51,6 +51,9 @@ import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigS
import { GBDeployer } from '../../../packages/core.gbapp/services/GBDeployer'; import { GBDeployer } from '../../../packages/core.gbapp/services/GBDeployer';
const Spinner = require('cli-spinner').Spinner; const Spinner = require('cli-spinner').Spinner;
// tslint:disable-next-line: no-submodule-imports
import * as simplegit from 'simple-git/promise';
const git = simplegit();
// tslint:disable-next-line:no-submodule-imports // tslint:disable-next-line:no-submodule-imports
import { CognitiveServicesAccount } from 'azure-arm-cognitiveservices/lib/models'; import { CognitiveServicesAccount } from 'azure-arm-cognitiveservices/lib/models';
@ -230,7 +233,6 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} }
} }
public async updateBotProxy(botId, group, endpoint) { public async updateBotProxy(botId, group, endpoint) {
const baseUrl = `https://management.azure.com/`; const baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME'); const username = GBConfigService.get('CLOUD_USERNAME');
@ -260,7 +262,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} }
public async updateBot(botId: string, group: string, name: string, public async updateBot(botId: string, group: string, name: string,
description: string, endpoint: string, iconUrl: string) { description: string, endpoint: string) {
const baseUrl = `https://management.azure.com/`; const baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME'); const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD'); const password = GBConfigService.get('CLOUD_PASSWORD');
@ -328,20 +330,16 @@ export class AzureDeployerService implements IGBInstallationDeployer {
GBLog.info(`Deploying Bot Server...`); GBLog.info(`Deploying Bot Server...`);
const serverFarm = await this.createHostingPlan(name, `${name}-server-plan`, instance.cloudLocation); const serverFarm = await this.createHostingPlan(name, `${name}-server-plan`, instance.cloudLocation);
await this.createServer(serverFarm.id, name, `${name}-server`, instance.cloudLocation); const serverName = `${name}-server`;
await this.createServer(serverFarm.id, name, serverName, instance.cloudLocation);
GBLog.info(`Deploying Bot Storage...`); GBLog.info(`Deploying Bot Storage...`);
const administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`; const administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`;
const administratorPassword = GBAdminService.getRndPassword(); const administratorPassword = GBAdminService.getRndPassword();
const storageServer = `${name.toLowerCase()}-storage-server`; const storageServer = `${name.toLowerCase()}-storage-server`;
const storageName = `${name}-storage`; const storageName = `${name}-storage`;
await this.createStorageServer( await this.createStorageServer(name, storageServer, administratorLogin,
name, administratorPassword, storageServer, instance.cloudLocation
storageServer,
administratorLogin,
administratorPassword,
storageServer,
instance.cloudLocation
); );
await this.createStorage(name, storageServer, storageName, instance.cloudLocation); await this.createStorage(name, storageServer, storageName, instance.cloudLocation);
instance.storageUsername = administratorLogin; instance.storageUsername = administratorLogin;
@ -407,6 +405,9 @@ export class AzureDeployerService implements IGBInstallationDeployer {
instance.cloudSubscriptionId instance.cloudSubscriptionId
); );
GBLog.info('Updating server environment variables...');
await this.updateWebisteConfig(name, serverName, serverFarm.id, instance);
spinner.stop(); spinner.stop();
return instance; return instance;
@ -536,7 +537,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
fullyQualifiedDomainName: `${serverName}.database.windows.net` fullyQualifiedDomainName: `${serverName}.database.windows.net`
}; };
return this.storageClient.servers.createOrUpdate(group, name, params); return await this.storageClient.servers.createOrUpdate(group, name, params);
} }
private async registerProviders(subscriptionId, baseUrl, accessToken) { private async registerProviders(subscriptionId, baseUrl, accessToken) {
@ -604,7 +605,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
location: location location: location
}; };
return this.searchClient.services.createOrUpdate(group, name, params); return await this.searchClient.services.createOrUpdate(group, name, params);
} }
private async createStorage(group, serverName, name, location) { private async createStorage(group, serverName, name, location) {
@ -614,7 +615,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
location: location location: location
}; };
return this.storageClient.databases.createOrUpdate(group, serverName, name, params); return await this.storageClient.databases.createOrUpdate(group, serverName, name, params);
} }
private async createCognitiveServices(group, name, location, kind): Promise<CognitiveServicesAccount> { private async createCognitiveServices(group, name, location, kind): Promise<CognitiveServicesAccount> {
@ -648,7 +649,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
private async createDeployGroup(name, location) { private async createDeployGroup(name, location) {
const params = { location: location }; const params = { location: location };
return this.resourceClient.resourceGroups.createOrUpdate(name, params); return await this.resourceClient.resourceGroups.createOrUpdate(name, params);
} }
private async createHostingPlan(group, name, location): Promise<AppServicePlan> { private async createHostingPlan(group, name, location): Promise<AppServicePlan> {
@ -662,15 +663,75 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} }
}; };
return this.webSiteClient.appServicePlans.createOrUpdate(group, name, params); return await this.webSiteClient.appServicePlans.createOrUpdate(group, name, params);
} }
private async createServer(farmId, group, name, location) { private async createServer(farmId, group, name, location) {
const parameters = { const parameters: Site = {
location: location, location: location,
serverFarmId: farmId serverFarmId: farmId,
siteConfig: {
netFrameworkVersion
nodeVersion: GBAdminService.getNodeVersion(),
detailedErrorLoggingEnabled: true,
requestTracingEnabled: true
}
};
const server = await this.webSiteClient.webApps.createOrUpdate(group, name, parameters);
const siteLogsConfig: SiteLogsConfig = {
applicationLogs: {
fileSystem: { level: 'Error' }
}
};
await this.webSiteClient.webApps.updateDiagnosticLogsConfig(group, name, siteLogsConfig);
await this.webSiteClient.webApps.update
const souceControlConfig: SiteSourceControl = {
repoUrl: 'https://github.com/GeneralBots/BotServer.git',
branch: 'master',
isManualIntegration: true,
isMercurial: false,
deploymentRollbackEnabled: false
}; };
return this.webSiteClient.webApps.createOrUpdate(group, name, parameters); await this.webSiteClient.webApps.createOrUpdateSourceControl(group, name, souceControlConfig);
// await this.webSiteClient.webApps.syncRepository(name, name);
return server;
} }
private async updateWebisteConfig(group, name, serverFarmId, instance: IGBInstance) {
const parameters: Site = {
location: instance.cloudLocation,
serverFarmId: serverFarmId,
siteConfig: {
appSettings: [
{ name: 'WEBSITE_NODE_DEFAULT_VERSION', value: GBAdminService.getNodeVersion() },
{ name: 'ADDITIONAL_DEPLOY_PATH', value: `` },
{ name: 'ADMIN_PASS', value: `${instance.adminPass}` },
{ name: 'CLOUD_SUBSCRIPTIONID', value: `${instance.cloudSubscriptionId}` },
{ name: 'CLOUD_LOCATION', value: `${instance.cloudLocation}` },
{ name: 'CLOUD_GROUP', value: `${instance.botId}` },
{ name: 'CLOUD_USERNAME', value: `${instance.cloudUsername}` },
{ name: 'CLOUD_PASSWORD', value: `${instance.cloudPassword}` },
{ name: 'MARKETPLACE_ID', value: `${instance.marketplaceId}` },
{ name: 'MARKETPLACE_SECRET', value: `${instance.marketplacePassword}` },
{ name: 'NLP_AUTHORING_KEY', value: `${instance.nlpAuthoringKey}` },
{ name: 'STORAGE_DIALECT', value: `${instance.storageDialect}` },
{ name: 'STORAGE_SERVER', value: `${instance.storageServer}.database.windows.net` },
{ name: 'STORAGE_NAME', value: `${instance.storageName}` },
{ name: 'STORAGE_USERNAME', value: `${instance.storageUsername}` },
{ name: 'STORAGE_PASSWORD', value: `${instance.storagePassword}` },
{ name: 'STORAGE_SYNC', value: `true` }]
}
};
return await this.webSiteClient.webApps.createOrUpdate(group, name, parameters);
}
} }

View file

@ -42,15 +42,15 @@ import { GBLog } from 'botlib';
* Base configuration for the server like storage. * Base configuration for the server like storage.
*/ */
export class GBConfigService { export class GBConfigService {
public static getServerPort(): number { public static getServerPort(): string {
if (process.env.PORT) { if (process.env.PORT) {
return Number(process.env.PORT); return process.env.PORT;
} }
if (process.env.port) { if (process.env.port) {
return Number(process.env.port); return process.env.port;
} }
return 4242; return '4242';
} }
public static init(): any { public static init(): any {

View file

@ -183,8 +183,7 @@ export class GBDeployer {
accessToken, accessToken,
instance.title, instance.title,
instance.description, instance.description,
proxyAddress, proxyAddress
''
); );
} else { } else {

View file

@ -72,6 +72,7 @@ export class GBServer {
public static run() { public static run() {
GBLog.info(`The Bot Server is in STARTING mode...`); GBLog.info(`The Bot Server is in STARTING mode...`);
process.env.PWD = process.cwd();
// Creates a basic HTTP server that will serve several URL, one for each // Creates a basic HTTP server that will serve several URL, one for each
// bot instance. // bot instance.