Skip to content

Commit

Permalink
feat(core.gbapp): New bot management (CRUD) from SharePoint packages.
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigorodriguez committed Aug 22, 2019
1 parent 4a3d472 commit 9a961e7
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 104 deletions.
7 changes: 6 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"botbuilder-choices": "4.0.0-preview1.2",
"botbuilder-dialogs": "4.4.0",
"botbuilder-prompts": "4.0.0-preview1.2",
"botlib": "^1.2.1",
"botlib": "1.2.2",
"chai": "4.2.0",
"child_process": "1.0.2",
"chokidar": "3.0.0",
Expand All @@ -76,6 +76,7 @@
"empty-dir": "^2.0.0",
"express": "4.16.4",
"express-promise-router": "3.0.3",
"express-remove-route": "^1.0.0",
"fs-extra": "8.0.0",
"ip": "1.1.5",
"js-beautify": "1.10.0",
Expand Down
31 changes: 18 additions & 13 deletions packages/admin.gbapp/dialogs/AdminDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class AdminDialog extends IGBDialog {
const packageName = text.split(' ')[1];
const importer = new GBImporter(min.core);
const deployer = new GBDeployer(min.core, importer);
await deployer.undeployPackageFromLocalPath(min.instance, urlJoin('packages', packageName));
await deployer.undeployPackageFromLocalPath(min.instance, urlJoin(GBDeployer.workFolder, packageName));
}

public static isSharePointPath(path: string) {
Expand All @@ -79,7 +79,7 @@ export class AdminDialog extends IGBDialog {
let siteName = text.split(' ')[1];
let folderName = text.split(' ')[2];

let localFolder = Path.join('tmp', Path.basename(folderName));
let localFolder = Path.join('work', Path.basename(folderName));
await s.downloadFolder(localFolder, siteName, folderName,
GBConfigService.get('CLOUD_USERNAME'), GBConfigService.get('CLOUD_PASSWORD'))
await deployer.deployPackage(min, localFolder);
Expand Down Expand Up @@ -122,20 +122,20 @@ export class AdminDialog extends IGBDialog {
const prompt = Messages[locale].authenticate;

return await step.prompt('textPrompt', prompt);
},
async step => {
const locale = step.context.activity.locale;
const sensitive = step.result;
// },
// async step => {
// const locale = step.context.activity.locale;
// const sensitive = step.result;

if (sensitive === GBConfigService.get('ADMIN_PASS')) {
await step.context.sendActivity(Messages[locale].welcome);
// if (sensitive === GBConfigService.get('ADMIN_PASS')) {
// await step.context.sendActivity(Messages[locale].welcome);

return await step.prompt('textPrompt', Messages[locale].which_task);
} else {
await step.context.sendActivity(Messages[locale].wrong_password);
// return await step.prompt('textPrompt', Messages[locale].which_task);
// } else {
// await step.context.sendActivity(Messages[locale].wrong_password);

return await step.endDialog();
}
// return await step.endDialog();
// }
},
async step => {
const locale: string = step.context.activity.locale;
Expand All @@ -161,6 +161,11 @@ export class AdminDialog extends IGBDialog {
await AdminDialog.rebuildIndexPackageCommand(min, deployer);
await step.context.sendActivity('Finished importing of that .gbkb package. Thanks.');
return await step.replaceDialog('/admin', { firstRun: false });
} else if (cmdName === 'undeployPackage') {
await step.context.sendActivity('The package is being *undeployed*...');
await AdminDialog.undeployPackageCommand(text, min);
await step.context.sendActivity('Package *undeployed*.');
return await step.replaceDialog('/admin', { firstRun: false });
} else if (cmdName === 'rebuildIndex') {
await AdminDialog.rebuildIndexPackageCommand(min, deployer);

Expand Down
34 changes: 25 additions & 9 deletions packages/azuredeployer.gbapp/services/AzureDeployerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
};
}

public async botExists(botId, group, endpoint) {
public async botExists(botId, group) {
const baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
Expand All @@ -227,17 +227,11 @@ export class AzureDeployerService implements IGBInstallationDeployer {
const accessToken = await GBAdminService.getADALTokenFromUsername(username, password);
const httpClient = new ServiceClient();

const parameters = {
properties: {
endpoint: endpoint
}
};

const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
const url = urlJoin(baseUrl, query);
const req = AzureDeployerService.createRequestObject(url, accessToken, 'GET', JSON.stringify(parameters));
const req = AzureDeployerService.createRequestObject(url, accessToken, 'GET', undefined);
const res = await httpClient.sendRequest(req);
// CHECK
if (!JSON.parse(res.bodyAsText).id) {
Expand Down Expand Up @@ -307,6 +301,28 @@ export class AzureDeployerService implements IGBInstallationDeployer {
GBLog.info(`Bot proxy updated at: ${endpoint}.`);
}

public async deleteBot(botId: string, group) {
const baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');

const accessToken = await GBAdminService.getADALTokenFromUsername(username, password);
const httpClient = new ServiceClient();

const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
const url = urlJoin(baseUrl, query);
const req = AzureDeployerService.createRequestObject(url, accessToken, 'DELETE', undefined);
const res = await httpClient.sendRequest(req);

if (res.bodyAsText !== "") {
throw res.bodyAsText;
}
GBLog.info(`Bot ${botId} was deleted from the provider.`);
}

public async openStorageFirewall(groupName, serverName) {
const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
Expand Down Expand Up @@ -590,7 +606,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
id = app.id;
}

return id.replace(/\'/gi,'');
return id.replace(/\'/gi, '');
}

private async makeNlpRequest(
Expand Down
6 changes: 6 additions & 0 deletions packages/core.gbapp/services/GBCoreService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,12 @@ STORAGE_SYNC=true
}
}

public async deleteInstance(botId:string) {
const options = { where: {} };
options.where = { botId: botId };
await GuaribasInstance.destroy(options);
}

public async saveInstance(fullInstance: any) {
const options = { where: {} };
options.where = { botId: fullInstance.botId };
Expand Down
60 changes: 50 additions & 10 deletions packages/core.gbapp/services/GBDeployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const WaitUntil = require('wait-until');
const express = require('express');
const child_process = require('child_process');
const graph = require('@microsoft/microsoft-graph-client');
const emptyDir = require('empty-dir');

import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBInstance, IGBPackage } from 'botlib';
import { AzureSearch } from 'pragmatismo-io-framework';
Expand All @@ -54,6 +55,8 @@ import { KBService } from './../../kb.gbapp/services/KBService';
import { GBConfigService } from './GBConfigService';
import { GBImporter } from './GBImporterService';
import { GBVMService } from './GBVMService';
import { min } from 'moment';
import { GBMinService } from './GBMinService';

/**
*
Expand All @@ -62,9 +65,9 @@ import { GBVMService } from './GBVMService';

export class GBDeployer {
public static deployFolder = 'packages';
public static workFolder = 'work';
public core: IGBCoreService;
public importer: GBImporter;
public workDir: string = './work';

constructor(core: IGBCoreService, importer: GBImporter) {
this.core = core;
Expand Down Expand Up @@ -93,7 +96,7 @@ export class GBDeployer {
(resolve: any, reject: any): any => {
GBLog.info(`PWD ${process.env.PWD}...`);
let totalPackages = 0;
let paths = [urlJoin(process.env.PWD, GBDeployer.deployFolder)];
let paths = [urlJoin(process.env.PWD, GBDeployer.deployFolder), urlJoin(process.env.PWD, GBDeployer.workFolder)];
const additionalPath = GBConfigService.get('ADDITIONAL_DEPLOY_PATH');
if (additionalPath !== undefined && additionalPath !== '') {
paths = paths.concat(additionalPath.toLowerCase().split(';'));
Expand Down Expand Up @@ -165,7 +168,7 @@ export class GBDeployer {
* Deploys a bot to the storage.
*/

public async deployBot(localPath: string, proxyAddress: string): Promise<void> {
public async deployBot(localPath: string, publicAddress: string): Promise<void> {
const packageName = Path.basename(localPath);

const service = new AzureDeployerService(this);
Expand All @@ -177,36 +180,66 @@ export class GBDeployer {
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
const accessToken = await GBAdminService.getADALTokenFromUsername(username, password);

if (await service.botExists(instance.botId, group, proxyAddress)) {
instance = await service.updateBot(
instance,
accessToken,
if (await service.botExists(instance.botId, group)) {
await service.updateBot(
instance.botId,
group,
instance.title,
instance.description,
proxyAddress
`${publicAddress}/api/messages/${instance.botId}`
);

} else {

instance = Object.assign(instance, GBServer.globals.bootInstance);
instance = await service.internalDeployBot(
instance,
accessToken,
instance.botId,
instance.title,
group,
instance.description,
`${proxyAddress}/api/messages/${instance.botId}`,
`${publicAddress}/api/messages/${instance.botId}`,
'global',
instance.nlpAppId,
instance.nlpKey,
instance.marketplaceId,
instance.marketplacePassword,
subscriptionId
);

await GBServer.globals.minService.mountBot(instance);
}
await this.core.saveInstance(instance);
}


/**
* Deploys a bot to the storage.
*/

public async undeployBot(botId: string, packageName: string): Promise<void> {
const service = new AzureDeployerService(this);

const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
const group = GBConfigService.get('CLOUD_GROUP');
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
const accessToken = await GBAdminService.getADALTokenFromUsername(username, password);

if (await service.botExists(botId, group)) {

await service.deleteBot(
botId, group
);

}
GBServer.globals.minService.unmountBot(botId);
await this.core.deleteInstance(botId);
const packageFolder = urlJoin(process.env.PWD, 'work', packageName);
await emptyDir(packageFolder);
}


public async deployPackageToStorage(instanceId: number, packageName: string): Promise<GuaribasPackage> {
return GuaribasPackage.create({
packageName: packageName,
Expand All @@ -233,6 +266,7 @@ export class GBDeployer {
switch (packageType) {
case '.gbot':
await this.deployBot(localPath, GBServer.globals.publicAddress);
break;

case '.gbkb':
const service = new KBService(this.core.sequelize);
Expand All @@ -257,7 +291,13 @@ export class GBDeployer {

const p = await this.getPackageByName(instance.instanceId, packageName);


switch (packageType) {
case '.gbot':
const packageObject = JSON.parse(Fs.readFileSync(urlJoin(localPath, 'package.json'), 'utf8'));
await this.undeployBot(packageObject.botId, packageName);
break;

case '.gbkb':
const service = new KBService(this.core.sequelize);

Expand Down
Loading

0 comments on commit 9a961e7

Please sign in to comment.