Bot deployment and key getting done.
This commit is contained in:
parent
c3d49e3288
commit
d030ed8278
5 changed files with 124 additions and 74 deletions
|
@ -47,6 +47,7 @@ import * as simplegit from "simple-git/promise";
|
||||||
import { AppServicePlan } from "azure-arm-website/lib/models";
|
import { AppServicePlan } from "azure-arm-website/lib/models";
|
||||||
import { GBConfigService } from "../../../deploy/core.gbapp/services/GBConfigService";
|
import { GBConfigService } from "../../../deploy/core.gbapp/services/GBConfigService";
|
||||||
|
|
||||||
|
const Spinner = require('cli-spinner').Spinner;
|
||||||
const scanf = require("scanf");
|
const scanf = require("scanf");
|
||||||
const msRestAzure = require("ms-rest-azure");
|
const msRestAzure = require("ms-rest-azure");
|
||||||
const git = simplegit();
|
const git = simplegit();
|
||||||
|
@ -68,6 +69,7 @@ export class AzureDeployerService extends GBService {
|
||||||
accessToken: string;
|
accessToken: string;
|
||||||
location: string;
|
location: string;
|
||||||
public subscriptionId: string;
|
public subscriptionId: string;
|
||||||
|
static apiVersion = "2017-12-01";
|
||||||
|
|
||||||
constructor(credentials, subscriptionId, location) {
|
constructor(credentials, subscriptionId, location) {
|
||||||
super();
|
super();
|
||||||
|
@ -103,26 +105,11 @@ export class AzureDeployerService extends GBService {
|
||||||
let instance: any = {};
|
let instance: any = {};
|
||||||
let culture = "en-us";
|
let culture = "en-us";
|
||||||
|
|
||||||
logger.info(`Starting infrastructure deployment...`);
|
let spinner = new Spinner('%s');
|
||||||
|
spinner.start();
|
||||||
|
spinner.setSpinnerString("⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈");
|
||||||
|
|
||||||
let keys: any;
|
let keys: any;
|
||||||
logger.info(`Deploying NLP...`);
|
|
||||||
let nlp = await this.createNLP(name, `${name}-nlp`, location);
|
|
||||||
keys = await this.cognitiveClient.accounts.listKeys(name, nlp.name);
|
|
||||||
let nlpAppId = await this.createLUISApp(name, name, location, culture);
|
|
||||||
|
|
||||||
|
|
||||||
await this.deployBootBot(
|
|
||||||
instance,
|
|
||||||
name,
|
|
||||||
proxyAddress,
|
|
||||||
nlpAppId,
|
|
||||||
keys.key1,
|
|
||||||
this.subscriptionId
|
|
||||||
);
|
|
||||||
instance.nlpEndpoint = nlp.endpoint;
|
|
||||||
instance.nlpKey = keys.key1;
|
|
||||||
instance.nlpAppId = nlpAppId;
|
|
||||||
|
|
||||||
logger.info(`Deploying Deploy Group...`);
|
logger.info(`Deploying Deploy Group...`);
|
||||||
await this.createDeployGroup(name, location);
|
await this.createDeployGroup(name, location);
|
||||||
|
@ -174,7 +161,13 @@ export class AzureDeployerService extends GBService {
|
||||||
instance.searchIndexer = "azuresql-indexer";
|
instance.searchIndexer = "azuresql-indexer";
|
||||||
instance.searchKey = searchKeys[0].key;
|
instance.searchKey = searchKeys[0].key;
|
||||||
|
|
||||||
////////////// LUS
|
logger.info(`Deploying NLP...`);
|
||||||
|
let nlp = await this.createNLP(name, `${name}-nlp`, location);
|
||||||
|
keys = await this.cognitiveClient.accounts.listKeys(name, nlp.name);
|
||||||
|
let nlpAppId = await this.createLUISApp(name, name, location, culture);
|
||||||
|
instance.nlpEndpoint = nlp.endpoint;
|
||||||
|
instance.nlpKey = keys.key1;
|
||||||
|
instance.nlpAppId = nlpAppId;
|
||||||
|
|
||||||
logger.info(`Deploying Speech...`);
|
logger.info(`Deploying Speech...`);
|
||||||
let speech = await this.createSpeech(name, `${name}-speech`, location);
|
let speech = await this.createSpeech(name, `${name}-speech`, location);
|
||||||
|
@ -208,6 +201,20 @@ export class AzureDeployerService extends GBService {
|
||||||
instance.textAnalyticsEndpoint = textAnalytics.endpoint;
|
instance.textAnalyticsEndpoint = textAnalytics.endpoint;
|
||||||
instance.textAnalyticsKey = keys.key1;
|
instance.textAnalyticsKey = keys.key1;
|
||||||
|
|
||||||
|
let appId = msRestAzure.generateUuid();
|
||||||
|
logger.info(`Deploying Bot...`);
|
||||||
|
instance = await this.deployBootBot(
|
||||||
|
instance,
|
||||||
|
name,
|
||||||
|
`${proxyAddress}/api/messages/${name}`,
|
||||||
|
nlpAppId,
|
||||||
|
keys.key1,
|
||||||
|
this.subscriptionId,
|
||||||
|
appId
|
||||||
|
);
|
||||||
|
|
||||||
|
spinner.stop();
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,12 +224,19 @@ export class AzureDeployerService extends GBService {
|
||||||
endpoint,
|
endpoint,
|
||||||
nlpAppId,
|
nlpAppId,
|
||||||
nlpKey,
|
nlpKey,
|
||||||
subscriptionId
|
subscriptionId,
|
||||||
|
appId
|
||||||
) {
|
) {
|
||||||
logger.info(`Deploying Bot...`);
|
logger.info(`Deploying Bot...`);
|
||||||
await this.internalDeployBot(
|
|
||||||
|
let botId = name + AzureDeployerService.getRndBotId();
|
||||||
|
|
||||||
|
[
|
||||||
|
instance.marketplacePassword,
|
||||||
|
instance.webchatKey
|
||||||
|
] = await this.internalDeployBot(
|
||||||
this.accessToken,
|
this.accessToken,
|
||||||
name,
|
botId,
|
||||||
name,
|
name,
|
||||||
name,
|
name,
|
||||||
"General BootBot",
|
"General BootBot",
|
||||||
|
@ -230,11 +244,11 @@ export class AzureDeployerService extends GBService {
|
||||||
"global",
|
"global",
|
||||||
nlpAppId,
|
nlpAppId,
|
||||||
nlpKey,
|
nlpKey,
|
||||||
subscriptionId
|
subscriptionId,
|
||||||
|
appId
|
||||||
);
|
);
|
||||||
instance.webchatKey = "********";
|
instance.marketplaceId = appId;
|
||||||
instance.marketplaceId = "0ff1ce73-0aea-442a-a222-dcc340eca294";
|
instance.botId = botId;
|
||||||
instance.marketplacePassword = "************";
|
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -280,29 +294,33 @@ export class AzureDeployerService extends GBService {
|
||||||
let res = await httpClient.sendRequest(req);
|
let res = await httpClient.sendRequest(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://github.com/Azure/azure-rest-api-specs/blob/master/specification/botservice/resource-manager/Microsoft.BotService/preview/2017-12-01/botservice.json
|
||||||
|
*/
|
||||||
private async internalDeployBot(
|
private async internalDeployBot(
|
||||||
accessToken,
|
accessToken,
|
||||||
botId,
|
botId,
|
||||||
group,
|
|
||||||
name,
|
name,
|
||||||
|
group,
|
||||||
description,
|
description,
|
||||||
endpoint,
|
endpoint,
|
||||||
location,
|
location,
|
||||||
nlpAppId,
|
nlpAppId,
|
||||||
nlpKey,
|
nlpKey,
|
||||||
subscriptionId
|
subscriptionId,
|
||||||
|
appId
|
||||||
) {
|
) {
|
||||||
let baseUrl = `https://management.azure.com/`;
|
let baseUrl = `https://management.azure.com/`;
|
||||||
this.registerProviders(subscriptionId, baseUrl, accessToken);
|
await this.registerProviders(subscriptionId, baseUrl, accessToken);
|
||||||
let appId = msRestAzure.generateUuid();
|
|
||||||
|
let appPassword = AzureDeployerService.getRndPassword();
|
||||||
|
|
||||||
let parameters = {
|
let parameters = {
|
||||||
location: location,
|
location: location,
|
||||||
sku: {
|
sku: {
|
||||||
name: "F0"
|
name: "F0"
|
||||||
},
|
},
|
||||||
name: name,
|
name: botId,
|
||||||
id: botId,
|
|
||||||
kind: "sdk",
|
kind: "sdk",
|
||||||
properties: {
|
properties: {
|
||||||
description: description,
|
description: description,
|
||||||
|
@ -311,30 +329,49 @@ export class AzureDeployerService extends GBService {
|
||||||
iconUrl: iconUrl,
|
iconUrl: iconUrl,
|
||||||
luisAppIds: [nlpAppId],
|
luisAppIds: [nlpAppId],
|
||||||
luisKey: nlpKey,
|
luisKey: nlpKey,
|
||||||
msaAppId: appId
|
msaAppId: appId,
|
||||||
|
msaAppPassword: appPassword
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let httpClient = new ServiceClient();
|
||||||
|
|
||||||
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
|
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
|
||||||
this.provider
|
this.provider
|
||||||
}/botServices/${botId}?api-version=2017-12-01`;
|
}/botServices/${botId}?api-version=${AzureDeployerService.apiVersion}`;
|
||||||
let requestUrl = UrlJoin(baseUrl, query);
|
let url = UrlJoin(baseUrl, query);
|
||||||
|
let req = this.createRequestObject(
|
||||||
|
url,
|
||||||
|
accessToken,
|
||||||
|
JSON.stringify(parameters)
|
||||||
|
);
|
||||||
|
let res = await httpClient.sendRequest(req);
|
||||||
|
|
||||||
|
query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${
|
||||||
|
AzureDeployerService.apiVersion
|
||||||
|
}`;
|
||||||
|
url = UrlJoin(baseUrl, query);
|
||||||
|
req = this.createRequestObject(
|
||||||
|
url,
|
||||||
|
accessToken,
|
||||||
|
JSON.stringify(parameters)
|
||||||
|
);
|
||||||
|
let resChannel = await httpClient.sendRequest(req);
|
||||||
|
|
||||||
|
let key = (resChannel.bodyAsJson as any).properties.properties.sites[0].key;
|
||||||
|
return [appPassword, key];
|
||||||
|
}
|
||||||
|
|
||||||
|
private createRequestObject(url: string, accessToken: string, body) {
|
||||||
let req = new WebResource();
|
let req = new WebResource();
|
||||||
req.method = "PUT";
|
req.method = "PUT";
|
||||||
req.url = requestUrl;
|
req.url = url;
|
||||||
req.headers = {};
|
req.headers = {};
|
||||||
req.headers["Content-Type"] = "application/json";
|
req.headers["Content-Type"] = "application/json";
|
||||||
req.headers["accept-language"] = "*";
|
req.headers["accept-language"] = "*";
|
||||||
req.headers["Authorization"] = "Bearer " + accessToken;
|
req.headers["Authorization"] = "Bearer " + accessToken;
|
||||||
|
req.body = body;
|
||||||
let requestContent = JSON.stringify(parameters);
|
return req;
|
||||||
req.body = requestContent;
|
|
||||||
|
|
||||||
let httpClient = new ServiceClient();
|
|
||||||
let res = await httpClient.sendRequest(req);
|
|
||||||
|
|
||||||
return JSON.parse(res.bodyAsJson as string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createLUISApp(
|
private async createLUISApp(
|
||||||
|
@ -350,14 +387,14 @@ export class AzureDeployerService extends GBService {
|
||||||
};
|
};
|
||||||
let requestUrl = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/apps/`;
|
let requestUrl = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/apps/`;
|
||||||
let req = new WebResource();
|
let req = new WebResource();
|
||||||
|
|
||||||
req.method = "POST";
|
req.method = "POST";
|
||||||
req.url = requestUrl;
|
req.url = requestUrl;
|
||||||
req.headers = {};
|
req.headers = {};
|
||||||
req.headers["Content-Type"] = "application/json";
|
req.headers["Content-Type"] = "application/json";
|
||||||
req.headers["accept-language"] = "*";
|
req.headers["accept-language"] = "*";
|
||||||
|
|
||||||
let authoringKey;
|
let authoringKey = GBConfigService.get("NLP_AUTHORING_KEY");
|
||||||
let retriveAuthoringKey = () => {
|
let retriveAuthoringKey = () => {
|
||||||
if (!authoringKey) {
|
if (!authoringKey) {
|
||||||
process.stdout.write(
|
process.stdout.write(
|
||||||
|
@ -378,7 +415,7 @@ export class AzureDeployerService extends GBService {
|
||||||
let httpClient = new ServiceClient();
|
let httpClient = new ServiceClient();
|
||||||
let res = await httpClient.sendRequest(req);
|
let res = await httpClient.sendRequest(req);
|
||||||
|
|
||||||
return res.bodyAsText;
|
return res.bodyAsJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createSearch(group, name, location) {
|
private async createSearch(group, name, location) {
|
||||||
|
@ -540,6 +577,20 @@ export class AzureDeployerService extends GBService {
|
||||||
return `sa${generated}`;
|
return `sa${generated}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static getRndBotId() {
|
||||||
|
const passwordGenerator = new PasswordGenerator();
|
||||||
|
const options = {
|
||||||
|
upperCaseAlpha: false,
|
||||||
|
lowerCaseAlpha: true,
|
||||||
|
number: true,
|
||||||
|
specialCharacter: false,
|
||||||
|
minimumLength: 8,
|
||||||
|
maximumLength: 8
|
||||||
|
};
|
||||||
|
let generated = passwordGenerator.generatePassword(options);
|
||||||
|
return `${generated}`;
|
||||||
|
}
|
||||||
|
|
||||||
private static getRndPassword() {
|
private static getRndPassword() {
|
||||||
const passwordGenerator = new PasswordGenerator();
|
const passwordGenerator = new PasswordGenerator();
|
||||||
const options = {
|
const options = {
|
||||||
|
@ -548,7 +599,7 @@ export class AzureDeployerService extends GBService {
|
||||||
number: true,
|
number: true,
|
||||||
specialCharacter: true,
|
specialCharacter: true,
|
||||||
minimumLength: 8,
|
minimumLength: 8,
|
||||||
maximumLength: 8
|
maximumLength: 14
|
||||||
};
|
};
|
||||||
let password = passwordGenerator.generatePassword(options);
|
let password = passwordGenerator.generatePassword(options);
|
||||||
return password;
|
return password;
|
||||||
|
|
|
@ -1,22 +1,8 @@
|
||||||
export const Messages = {
|
export const Messages = {
|
||||||
"en-US": {
|
"en-US": {
|
||||||
about_suggestions: "Suggestions are welcomed and improve my quality...",
|
about_suggestions: "Suggestions are welcomed and improve my quality...",
|
||||||
what_about_service: "What about my service?",
|
|
||||||
glad_you_liked: "I'm glad you liked. I'm here for you.",
|
|
||||||
we_will_improve: "Let's take note of that, thanks for sharing.",
|
|
||||||
what_about_me: "What about the service, please rate between 1 and 5.",
|
|
||||||
thanks: "Thanks!",
|
|
||||||
im_sorry_lets_try: "I'm sorry. Let's try again...",
|
|
||||||
great_thanks: "Great, thanks for sharing your thoughts."
|
|
||||||
},
|
},
|
||||||
"pt-BR": {
|
"pt-BR": {
|
||||||
about_suggestions: "Sugestões melhoram muito minha qualidade...",
|
about_suggestions: "Sugestões melhoram muito minha qualidade...",
|
||||||
what_about_service:"O que achou do meu atendimento?",
|
|
||||||
glad_you_liked: "Bom saber que você gostou. Conte comigo.",
|
|
||||||
we_will_improve: "Vamos registrar sua questão, obrigado pela sinceridade.",
|
|
||||||
what_about_me: "O que achou do meu atendimento, de 1 a 5?",
|
|
||||||
thanks: "Obrigado!",
|
|
||||||
im_sorry_lets_try: "Desculpe-me, vamos tentar novamente.",
|
|
||||||
great_thanks: "Ótimo, obrigado por contribuir com sua resposta."
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,6 @@ import * as fs from "fs";
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
export class GBConfigService {
|
export class GBConfigService {
|
||||||
|
|
||||||
static init(): any {
|
static init(): any {
|
||||||
try {
|
try {
|
||||||
require("dotenv-extended").load({
|
require("dotenv-extended").load({
|
||||||
|
@ -52,9 +51,8 @@ export class GBConfigService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public writeEntry(name, value) {
|
public writeEntry(name, value) {
|
||||||
|
|
||||||
if (fs.exists) {
|
if (fs.exists) {
|
||||||
fs.appendFileSync('.env',`${name}=${value}`);
|
fs.appendFileSync(".env", `${name}=${value}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,35 +61,48 @@ export class GBConfigService {
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
|
case "CLOUD_USERNAME":
|
||||||
|
value = undefined;
|
||||||
|
break;
|
||||||
|
case "CLOUD_PASSWORD":
|
||||||
|
value = undefined;
|
||||||
|
break;
|
||||||
|
case "CLOUD_SUBSCRIPTIONID":
|
||||||
|
value = undefined;
|
||||||
|
break;
|
||||||
|
case "CLOUD_LOCATION":
|
||||||
|
value = undefined;
|
||||||
|
break;
|
||||||
|
case "NLP_AUTHORING_KEY":
|
||||||
|
value = undefined;
|
||||||
|
break;
|
||||||
case "STORAGE_DIALECT":
|
case "STORAGE_DIALECT":
|
||||||
value = "sqlite";
|
value = "sqlite";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "STORAGE_STORAGE":
|
case "STORAGE_STORAGE":
|
||||||
value = "./guaribas.sqlite";
|
value = "./guaribas.sqlite";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ADDITIONAL_DEPLOY_PATH":
|
case "ADDITIONAL_DEPLOY_PATH":
|
||||||
value = undefined;
|
value = undefined;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "STORAGE_SYNC":
|
case "STORAGE_SYNC":
|
||||||
|
value = "false";
|
||||||
|
break;
|
||||||
case "STORAGE_SYNC_ALTER":
|
case "STORAGE_SYNC_ALTER":
|
||||||
|
value = "false";
|
||||||
|
break;
|
||||||
case "STORAGE_SYNC_FORCE":
|
case "STORAGE_SYNC_FORCE":
|
||||||
value = "false";
|
value = "false";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "STORAGE_LOGGING":
|
case "STORAGE_LOGGING":
|
||||||
value = "false";
|
value = "false";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "STORAGE_ENCRYPT":
|
case "STORAGE_ENCRYPT":
|
||||||
value = "true";
|
value = "true";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logger.info(
|
logger.warn(
|
||||||
`Guaribas General Error: Invalid key on .env file: '${key}'`
|
`Invalid key on .env file: '${key}'`
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
"child_process": "^1.0.2",
|
"child_process": "^1.0.2",
|
||||||
"chokidar": "2.0.4",
|
"chokidar": "2.0.4",
|
||||||
|
"cli-spinner": "^0.2.8",
|
||||||
"csv-parse": "3.1.3",
|
"csv-parse": "3.1.3",
|
||||||
"dotenv-extended": "2.3.0",
|
"dotenv-extended": "2.3.0",
|
||||||
"express": "4.16.4",
|
"express": "4.16.4",
|
||||||
|
|
|
@ -97,8 +97,9 @@ export class GBServer {
|
||||||
|
|
||||||
// Ensures cloud / on-premises infrastructure is setup.
|
// Ensures cloud / on-premises infrastructure is setup.
|
||||||
|
|
||||||
logger.info(`Connecting to the infrastructure...`);
|
logger.info(`Establishing a development local proxy...`);
|
||||||
let proxyAddress = await core.ensureProxy();
|
let proxyAddress = await core.ensureProxy();
|
||||||
|
logger.info(`Ensuring services availability...`);
|
||||||
let cloudDeployer = await AzureDeployerService.ensureDeployer();
|
let cloudDeployer = await AzureDeployerService.ensureDeployer();
|
||||||
let instance = await cloudDeployer.deployFarm('gbot', 'westus', proxyAddress);
|
let instance = await cloudDeployer.deployFarm('gbot', 'westus', proxyAddress);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue