Features to resource deployment to add arc control create in ARC extension (#10088)

* save not yet tested work

* Merge from master.

* Screeens Shared for Feeedback

* Code complete

* remove unneeded changes

* remove unnecessary comma

* remov wss

* remove dead code

* PR feedback

* checkpoint fixes

* PR & minor fixes

* minor fix for feature of  resourceType options being optional.

* reverting experimental change

* separating out changes for future featurework.

* revert unneeded change

* review feedback fixes

* review feedback

* rename InputFieldComponent to InputComponent
This commit is contained in:
Arvind Ranasaria
2020-04-29 12:11:48 -07:00
committed by GitHub
parent a9bfdf0fc9
commit 353115668c
21 changed files with 729 additions and 175 deletions

View File

@@ -14,39 +14,49 @@ export interface KubeClusterContext {
}
export interface IKubeService {
getDefautConfigPath(): string;
getDefaultConfigPath(): string;
getClusterContexts(configFile: string): Promise<KubeClusterContext[]>;
}
export class KubeService implements IKubeService {
getDefautConfigPath(): string {
return path.join(os.homedir(), '.kube', 'config');
getDefaultConfigPath(): string {
return getDefaultKubeConfigPath();
}
getClusterContexts(configFile: string): Promise<KubeClusterContext[]> {
return fs.promises.access(configFile).catch((error) => {
if (error && error.code === 'ENOENT') {
return [];
} else {
throw error;
}
}).then(() => {
const config = yamljs.load(configFile);
const rawContexts = <any[]>config['contexts'];
const currentContext = <string>config['current-context'];
const contexts: KubeClusterContext[] = [];
if (currentContext && rawContexts && rawContexts.length > 0) {
rawContexts.forEach(rawContext => {
const name = <string>rawContext['name'];
if (name) {
contexts.push({
name: name,
isCurrentContext: name === currentContext
});
}
});
}
return contexts;
});
return getKubeConfigClusterContexts(configFile);
}
}
export function getKubeConfigClusterContexts(configFile: string): Promise<KubeClusterContext[]> {
return fs.promises.access(configFile).catch((error) => {
if (error && error.code === 'ENOENT') {
return [];
}
else {
throw error;
}
}).then(() => {
const config = yamljs.load(configFile);
const rawContexts = <any[]>config['contexts'];
const currentContext = <string>config['current-context'];
const contexts: KubeClusterContext[] = [];
if (currentContext && rawContexts && rawContexts.length > 0) {
rawContexts.forEach(rawContext => {
const name = <string>rawContext['name'];
if (name) {
contexts.push({
name: name,
isCurrentContext: name === currentContext
});
}
});
}
return contexts;
});
}
export function getDefaultKubeConfigPath(): string {
return path.join(os.homedir(), '.kube', 'config');
}

View File

@@ -4,13 +4,14 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import { EOL } from 'os';
import * as path from 'path';
import { isString } from 'util';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { IPlatformService } from './platformService';
import { NotebookInfo } from '../interfaces';
import { getErrorMessage, getDateTimeString } from '../utils';
import { getDateTimeString, getErrorMessage } from '../utils';
import { IPlatformService } from './platformService';
const localize = nls.loadMessageBundle();
export interface Notebook {
@@ -36,6 +37,7 @@ export interface INotebookService {
launchNotebookWithContent(title: string, content: string): Thenable<azdata.nb.NotebookEditor>;
getNotebook(notebook: string | NotebookInfo): Promise<Notebook>;
executeNotebook(notebook: any, env?: NodeJS.ProcessEnv): Promise<NotebookExecutionResult>;
backgroundExecuteNotebook(taskName: string | undefined, notebookInfo: string | NotebookInfo, tempNoteBookPrefix: string, platformService: IPlatformService): void;
}
export class NotebookService implements INotebookService {
@@ -107,6 +109,43 @@ export class NotebookService implements INotebookService {
}
}
public backgroundExecuteNotebook(taskName: string | undefined, notebookInfo: string | NotebookInfo, tempNotebookPrefix: string, platformService: IPlatformService): void {
azdata.tasks.startBackgroundOperation({
displayName: taskName!,
description: taskName!,
isCancelable: false,
operation: async op => {
op.updateStatus(azdata.TaskStatus.InProgress);
const notebook = await this.getNotebook(notebookInfo);
const result = await this.executeNotebook(notebook);
if (result.succeeded) {
op.updateStatus(azdata.TaskStatus.Succeeded);
} else {
op.updateStatus(azdata.TaskStatus.Failed, result.errorMessage);
if (result.outputNotebook) {
const viewErrorDetail = localize('resourceDeployment.ViewErrorDetail', "View error detail");
const taskFailedMessage = localize('resourceDeployment.BackgroundExecutionFailed', "The task \"{0}\" has failed.", taskName);
const selectedOption = await vscode.window.showErrorMessage(taskFailedMessage, viewErrorDetail);
platformService.logToOutputChannel(taskFailedMessage);
if (selectedOption === viewErrorDetail) {
try {
this.launchNotebookWithContent(`${tempNotebookPrefix}-${getDateTimeString()}`, result.outputNotebook);
} catch (error) {
const launchNotebookError = localize('resourceDeployment.FailedToOpenNotebook', "An error occurred launching the output notebook. {1}{2}.", EOL, getErrorMessage(error));
platformService.logToOutputChannel(launchNotebookError);
vscode.window.showErrorMessage(launchNotebookError);
}
}
} else {
const errorMessage = localize('resourceDeployment.TaskFailedWithNoOutputNotebook', "The task \"{0}\" failed and no output Notebook was generated.", taskName);
platformService.logToOutputChannel(errorMessage);
vscode.window.showErrorMessage(errorMessage);
}
}
}
});
}
async getNotebookFullPath(notebook: string | NotebookInfo): Promise<string> {
const notebookPath = this.getNotebookPath(notebook);
let notebookExists = await this.platformService.fileExists(notebookPath);

View File

@@ -13,11 +13,13 @@ import * as nls from 'vscode-nls';
import { INotebookService } from './notebookService';
import { IPlatformService } from './platformService';
import { IToolsService } from './toolsService';
import { ResourceType, ResourceTypeOption, NotebookInfo, DeploymentProvider, instanceOfWizardDeploymentProvider, instanceOfDialogDeploymentProvider, instanceOfNotebookDeploymentProvider, instanceOfDownloadDeploymentProvider, instanceOfWebPageDeploymentProvider, instanceOfCommandDeploymentProvider, instanceOfNotebookBasedDialogInfo } from '../interfaces';
import { ResourceType, ResourceTypeOption, NotebookInfo, DeploymentProvider, instanceOfWizardDeploymentProvider, instanceOfDialogDeploymentProvider, instanceOfNotebookDeploymentProvider, instanceOfDownloadDeploymentProvider, instanceOfWebPageDeploymentProvider, instanceOfCommandDeploymentProvider, instanceOfNotebookBasedDialogInfo, instanceOfNotebookWizardDeploymentProvider } from '../interfaces';
import { DeployClusterWizard } from '../ui/deployClusterWizard/deployClusterWizard';
import { DeploymentInputDialog } from '../ui/deploymentInputDialog';
import { KubeService } from './kubeService';
import { AzdataService } from './azdataService';
import { NotebookWizard } from '../ui/notebookWizard/notebookWizard';
const localize = nls.loadMessageBundle();
export interface IResourceTypeService {
@@ -66,8 +68,11 @@ export class ResourceTypeService implements IResourceTypeService {
} else if (instanceOfDialogDeploymentProvider(provider) && instanceOfNotebookBasedDialogInfo(provider.dialog)) {
this.updateNotebookPath(provider.dialog, extensionPath);
}
else if ('wizard' in provider) {
this.updateNotebookPath(provider.wizard, extensionPath);
else if ('bdcWizard' in provider) {
this.updateNotebookPath(provider.bdcWizard, extensionPath);
}
else if ('notebookWizard' in provider) {
this.updateNotebookPath(provider.notebookWizard, extensionPath);
}
});
}
@@ -168,6 +173,7 @@ export class ResourceTypeService implements IResourceTypeService {
resourceType.providers.forEach(provider => {
const providerPositionInfo = `${positionInfo}, provider index: ${providerIndex} `;
if (!instanceOfWizardDeploymentProvider(provider)
&& !instanceOfNotebookWizardDeploymentProvider(provider)
&& !instanceOfDialogDeploymentProvider(provider)
&& !instanceOfNotebookDeploymentProvider(provider)
&& !instanceOfDownloadDeploymentProvider(provider)
@@ -203,24 +209,27 @@ export class ResourceTypeService implements IResourceTypeService {
private getProvider(resourceType: ResourceType, selectedOptions: { option: string, value: string }[]): DeploymentProvider | undefined {
for (let i = 0; i < resourceType.providers.length; i++) {
const provider = resourceType.providers[i];
if (provider.when === undefined || provider.when.toString().toLowerCase() === 'true') {
return provider;
} else {
const expected = provider.when.replace(' ', '').split('&&').sort();
let actual: string[] = [];
selectedOptions.forEach(option => {
actual.push(`${option.option}=${option.value}`);
});
actual = actual.sort();
const expected = provider.when.replace(' ', '').split('&&').sort();
let actual: string[] = [];
selectedOptions.forEach(option => {
actual.push(`${option.option}=${option.value}`);
});
actual = actual.sort();
if (actual.length === expected.length) {
let matches = true;
for (let j = 0; j < actual.length; j++) {
if (actual[j] !== expected[j]) {
matches = false;
break;
if (actual.length === expected.length) {
let matches = true;
for (let j = 0; j < actual.length; j++) {
if (actual[j] !== expected[j]) {
matches = false;
break;
}
}
if (matches) {
return provider;
}
}
if (matches) {
return provider;
}
}
}
@@ -230,7 +239,10 @@ export class ResourceTypeService implements IResourceTypeService {
public startDeployment(provider: DeploymentProvider): void {
const self = this;
if (instanceOfWizardDeploymentProvider(provider)) {
const wizard = new DeployClusterWizard(provider.wizard, new KubeService(), new AzdataService(this.platformService), this.notebookService);
const wizard = new DeployClusterWizard(provider.bdcWizard, new KubeService(), new AzdataService(this.platformService), this.notebookService);
wizard.open();
} else if (instanceOfNotebookWizardDeploymentProvider(provider)) {
const wizard = new NotebookWizard(provider.notebookWizard, this.notebookService, this.platformService);
wizard.open();
} else if (instanceOfDialogDeploymentProvider(provider)) {
const dialog = new DeploymentInputDialog(this.notebookService, this.platformService, provider.dialog);