diff --git a/extensions/mssql/package.json b/extensions/mssql/package.json index 8ab7f0e6dc..0482022017 100644 --- a/extensions/mssql/package.json +++ b/extensions/mssql/package.json @@ -25,7 +25,6 @@ "figures": "^2.0.0", "find-remove": "1.2.1", "fs-extra": "^3.0.1", - "kerberos": "^1.1.2", "request": "^2.88.0", "request-promise": "^4.2.2", "service-downloader": "github:anthonydresser/service-downloader#0.1.6", @@ -948,8 +947,5 @@ } ] } - }, - "devDependencies": { - "@types/kerberos": "^1.1.0" } } diff --git a/extensions/mssql/src/config.json b/extensions/mssql/src/config.json index 1daba5dde5..3df67917d1 100644 --- a/extensions/mssql/src/config.json +++ b/extensions/mssql/src/config.json @@ -1,6 +1,6 @@ { "downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}", - "version": "2.0.0-release.4", + "version": "2.0.0-release.2", "downloadFileNames": { "Windows_86": "win-x86-netcoreapp2.2.zip", "Windows_64": "win-x64-netcoreapp2.2.zip", diff --git a/extensions/mssql/src/constants.ts b/extensions/mssql/src/constants.ts index 5857567b6e..56b572130f 100644 --- a/extensions/mssql/src/constants.ts +++ b/extensions/mssql/src/constants.ts @@ -13,10 +13,9 @@ export const extensionConfigSectionName = 'mssql'; // DATA PROTOCOL VALUES /////////////////////////////////////////////////////////// export const mssqlClusterProviderName = 'mssqlCluster'; +export const hadoopEndpointNameKnox = 'Knox'; export const hadoopEndpointNameGateway = 'gateway'; export const protocolVersion = '1.0'; -export const authenticationTypePropName = 'authenticationType'; -export const integratedAuth = 'integrated'; export const hostPropName = 'host'; export const userPropName = 'user'; export const knoxPortPropName = 'knoxport'; @@ -27,6 +26,8 @@ export const groupIdName = 'groupId'; export const sqlProviderName = 'MSSQL'; export const dataService = 'Data Services'; +export const hdfsHost = 'host'; +export const hdfsUser = 'user'; export const UNTITLED_SCHEMA = 'untitled'; export const hadoopConnectionTimeoutSeconds = 15; diff --git a/extensions/mssql/src/dashboard/serviceEndpoints.ts b/extensions/mssql/src/dashboard/serviceEndpoints.ts index 83ac24a653..2361e2cd58 100644 --- a/extensions/mssql/src/dashboard/serviceEndpoints.ts +++ b/extensions/mssql/src/dashboard/serviceEndpoints.ts @@ -8,74 +8,46 @@ import * as azdata from 'azdata'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import * as utils from '../utils'; - -const mgmtProxyName = 'mgmtproxy'; -const grafanaEndpointName = 'metricsui'; -const grafanaDescription = localize('grafana', "Metrics Dashboard"); -const logsuiEndpointName = 'logsui'; -const logsuiDescription = localize('kibana', "Log Search Dashboard"); -const sparkHistoryEndpointName = 'spark-history'; -const sparkHistoryDescription = localize('sparkHistory', "Spark Jobs Management and Monitoring Dashboard"); -const yarnUiEndpointName = 'yarn-ui'; -const yarnHistoryDescription = localize('yarnHistory', "Spark Diagnostics and Monitoring Dashboard"); -const hyperlinkedEndpoints = [grafanaEndpointName, logsuiEndpointName, sparkHistoryEndpointName, yarnUiEndpointName]; +import * as Utils from '../utils'; export function registerServiceEndpoints(context: vscode.ExtensionContext): void { azdata.ui.registerModelViewProvider('bdc-endpoints', async (view) => { - let endpointsArray: Array = Object.assign([], utils.getClusterEndpoints(view.serverInfo)); + const endpointsArray: Array = Object.assign([], view.serverInfo.options['clusterEndpoints']); + endpointsArray.forEach(endpointInfo => { + endpointInfo.hyperlink = 'https://' + endpointInfo.ipAddress + ':' + endpointInfo.port; + + }); if (endpointsArray.length > 0) { - const grafanaEp = endpointsArray.find(e => e.serviceName === grafanaEndpointName); - if (grafanaEp) { - // Update to have correct URL - grafanaEp.endpoint += '/d/wZx3OUdmz'; - } - const kibanaEp = endpointsArray.find(e => e.serviceName === logsuiEndpointName); - if (kibanaEp) { - // Update to have correct URL - kibanaEp.endpoint += '/app/kibana#/discover'; + const managementProxyEp = endpointsArray.find(e => e.serviceName === 'management-proxy' || e.serviceName === 'mgmtproxy'); + if (managementProxyEp) { + endpointsArray.push(getCustomEndpoint(managementProxyEp, localize("grafana", "Metrics Dashboard"), '/grafana/d/wZx3OUdmz')); + endpointsArray.push(getCustomEndpoint(managementProxyEp, localize("kibana", "Log Search Dashboard"), '/kibana/app/kibana#/discover')); } - if (!grafanaEp) { - // We are on older CTP, need to manually add some endpoints. - // TODO remove once CTP support goes away - const managementProxyEp = endpointsArray.find(e => e.serviceName === mgmtProxyName); - if (managementProxyEp) { - endpointsArray.push(getCustomEndpoint(managementProxyEp, grafanaEndpointName, grafanaDescription, '/grafana/d/wZx3OUdmz')); - endpointsArray.push(getCustomEndpoint(managementProxyEp, logsuiEndpointName, logsuiDescription, '/kibana/app/kibana#/discover')); - } - - const gatewayEp = endpointsArray.find(e => e.serviceName === 'gateway'); - if (gatewayEp) { - endpointsArray.push(getCustomEndpoint(gatewayEp, sparkHistoryEndpointName, sparkHistoryDescription, '/gateway/default/sparkhistory')); - endpointsArray.push(getCustomEndpoint(gatewayEp, yarnUiEndpointName, yarnHistoryDescription, '/gateway/default/yarn')); - } + const gatewayEp = endpointsArray.find(e => e.serviceName === 'gateway'); + if (gatewayEp) { + endpointsArray.push(getCustomEndpoint(gatewayEp, localize("sparkHostory", "Spark Job Monitoring"), '/gateway/default/sparkhistory')); + endpointsArray.push(getCustomEndpoint(gatewayEp, localize("yarnHistory", "Spark Resource Management"), '/gateway/default/yarn')); } - endpointsArray = endpointsArray.map(e => { - e.description = getFriendlyEndpointNames(e); - return e; - }).sort((a, b) => a.endpoint.localeCompare(b.endpoint)); - const container = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'column', width: '100%', height: '100%', alignItems: 'left' }).component(); endpointsArray.forEach(endpointInfo => { - const endPointRow = view.modelBuilder.flexContainer().withLayout({ flexFlow: 'row' }).component(); - const nameCell = view.modelBuilder.text().withProperties({ value: endpointInfo.description }).component(); + const nameCell = view.modelBuilder.text().withProperties({ value: getFriendlyEndpointNames(endpointInfo.serviceName) }).component(); endPointRow.addItem(nameCell, { CSSStyles: { 'width': '35%', 'font-weight': '600', 'user-select': 'text' } }); - if (hyperlinkedEndpoints.findIndex(e => e === endpointInfo.serviceName) >= 0) { - const linkCell = view.modelBuilder.hyperlink().withProperties({ label: endpointInfo.endpoint, url: endpointInfo.endpoint }).component(); + if (endpointInfo.isHyperlink) { + const linkCell = view.modelBuilder.hyperlink().withProperties({ label: endpointInfo.hyperlink, url: endpointInfo.hyperlink }).component(); endPointRow.addItem(linkCell, { CSSStyles: { 'width': '62%', 'color': '#0078d4', 'text-decoration': 'underline', 'padding-top': '10px' } }); } else { - const endpointCell = view.modelBuilder.text().withProperties({ value: endpointInfo.endpoint }).component(); + const endpointCell = view.modelBuilder.text().withProperties({ value: endpointInfo.ipAddress + ':' + endpointInfo.port }).component(); endPointRow.addItem(endpointCell, { CSSStyles: { 'width': '62%', 'user-select': 'text' } }); } const copyValueCell = view.modelBuilder.button().component(); copyValueCell.iconPath = { light: context.asAbsolutePath('resources/light/copy.png'), dark: context.asAbsolutePath('resources/dark/copy_inverse.png') }; copyValueCell.onDidClick(() => { - vscode.env.clipboard.writeText(endpointInfo.endpoint); + vscode.env.clipboard.writeText(endpointInfo.hyperlink); }); copyValueCell.title = localize("copyText", "Copy"); copyValueCell.iconHeight = '14px'; @@ -92,57 +64,40 @@ export function registerServiceEndpoints(context: vscode.ExtensionContext): void }); } -function getCustomEndpoint(parentEndpoint: utils.IEndpoint, serviceName: string, description: string, serviceUrl?: string): utils.IEndpoint { +function getCustomEndpoint(parentEndpoint: Utils.IEndpoint, serviceName: string, serviceUrl?: string): Utils.IEndpoint { if (parentEndpoint) { - let endpoint: utils.IEndpoint = { + let endpoint: Utils.IEndpoint = { serviceName: serviceName, - description: description, - endpoint: parentEndpoint.endpoint + serviceUrl, - protocol: 'https' + ipAddress: parentEndpoint.ipAddress, + port: parentEndpoint.port, + isHyperlink: serviceUrl ? true : false, + hyperlink: 'https://' + parentEndpoint.ipAddress + ':' + parentEndpoint.port + serviceUrl }; return endpoint; } return null; } -function getFriendlyEndpointNames(endpointInfo: utils.IEndpoint): string { - let friendlyName: string = endpointInfo.description || endpointInfo.serviceName; - switch (endpointInfo.serviceName) { +function getFriendlyEndpointNames(name: string): string { + let friendlyName: string = name; + switch (name) { case 'app-proxy': - friendlyName = localize('approxy.description', "Application Proxy"); + friendlyName = localize("appproxy", "Application Proxy"); break; case 'controller': - friendlyName = localize('controller.description', "Cluster Management Service"); + friendlyName = localize("controller", "Cluster Management Service"); break; case 'gateway': - friendlyName = localize('gateway.description', "HDFS and Spark"); + friendlyName = localize("gateway", "HDFS and Spark"); break; - case mgmtProxyName: - friendlyName = localize('mgmtproxy.description', "Management Proxy"); + case 'management-proxy': + friendlyName = localize("managementproxy", "Management Proxy"); break; - case logsuiEndpointName: - friendlyName = logsuiDescription; - break; - case grafanaEndpointName: - friendlyName = grafanaDescription; - break; - case sparkHistoryEndpointName: - friendlyName = sparkHistoryDescription; - break; - case yarnUiEndpointName: - friendlyName = yarnHistoryDescription; - break; - case 'sql-server-master': - friendlyName = localize('sqlmaster.description', "SQL Server Master Instance Front-End"); - break; - case 'webhdfs': - friendlyName = localize('webhdfs.description', "HDFS File System Proxy"); - break; - case 'livy': - friendlyName = localize('livy.description', "Proxy for running Spark statements, jobs, applications"); + case 'mgmtproxy': + friendlyName = localize("mgmtproxy", "Management Proxy"); break; default: break; } return friendlyName; -} +} \ No newline at end of file diff --git a/extensions/mssql/src/objectExplorerNodeProvider/connection.ts b/extensions/mssql/src/objectExplorerNodeProvider/connection.ts index 62430be6e4..be1884aa75 100644 --- a/extensions/mssql/src/objectExplorerNodeProvider/connection.ts +++ b/extensions/mssql/src/objectExplorerNodeProvider/connection.ts @@ -26,6 +26,7 @@ export class SqlClusterConnection { this._connection = this.toConnection(this._profile); } else { this._connection = connectionInfo; + this._profile = this.toConnectionProfile(this._connection); } this._host = this._connection.options[constants.hostPropName]; this._port = this._connection.options[constants.knoxPortPropName]; @@ -34,6 +35,7 @@ export class SqlClusterConnection { } public get connection(): azdata.connection.Connection { return this._connection; } + public get profile(): azdata.IConnectionProfile { return this._profile; } public get host(): string { return this._host; } public get port(): number { return this._port ? Number.parseInt(this._port) : constants.defaultKnoxPort; } public get user(): string { return this._user; } @@ -48,7 +50,7 @@ export class SqlClusterConnection { .every(e => options1[e] === options2[e]); } - public async createHdfsFileSource(): Promise { + public createHdfsFileSource(): IFileSource { let options: IHdfsOptions = { protocol: 'https', host: this.host, @@ -56,24 +58,13 @@ export class SqlClusterConnection { user: this.user, path: 'gateway/default/webhdfs/v1', requestParams: { + auth: { + user: this.user, + pass: this.password + } } }; - if (this.isIntegratedAuth()) { - options.requestParams.isKerberos = this.isIntegratedAuth(); - options.requestParams.auth = undefined; - } else { - options.requestParams.auth = { - user: this.user, - pass: this.password - }; - } - let fileSource = await FileSourceFactory.instance.createHdfsFileSource(options); - return fileSource; - } - - public isIntegratedAuth(): boolean { - let authType: string = this._connection.options[constants.authenticationTypePropName]; - return authType && authType.toLowerCase() === constants.integratedAuth; + return FileSourceFactory.instance.createHdfsFileSource(options); } public updatePassword(password: string): void { @@ -99,12 +90,10 @@ export class SqlClusterConnection { private getMissingProperties(connectionInfo: azdata.ConnectionInfo): string[] { if (!connectionInfo || !connectionInfo.options) { return undefined; } - let requiredProps = [constants.hostPropName, constants.knoxPortPropName]; - let authType = connectionInfo.options[constants.authenticationTypePropName] && connectionInfo.options[constants.authenticationTypePropName].toLowerCase(); - if (authType !== constants.integratedAuth) { - requiredProps.push(constants.userPropName, constants.passwordPropName); - } - return requiredProps.filter(e => connectionInfo.options[e] === undefined); + return [ + constants.hostPropName, constants.knoxPortPropName, + constants.userPropName, constants.passwordPropName + ].filter(e => connectionInfo.options[e] === undefined); } private toConnection(connProfile: azdata.IConnectionProfile): azdata.connection.Connection { @@ -112,4 +101,18 @@ export class SqlClusterConnection { { connectionId: this._profile.id }); return connection; } + + private toConnectionProfile(connectionInfo: azdata.connection.Connection): azdata.IConnectionProfile { + let options = connectionInfo.options; + let connProfile: azdata.IConnectionProfile = Object.assign({}, + connectionInfo, + { + serverName: `${options[constants.hostPropName]},${options[constants.knoxPortPropName]}`, + userName: options[constants.userPropName], + password: options[constants.passwordPropName], + id: connectionInfo.connectionId, + } + ); + return connProfile; + } } diff --git a/extensions/mssql/src/objectExplorerNodeProvider/fileSources.ts b/extensions/mssql/src/objectExplorerNodeProvider/fileSources.ts index 1545c3c3c9..f200c3b362 100644 --- a/extensions/mssql/src/objectExplorerNodeProvider/fileSources.ts +++ b/extensions/mssql/src/objectExplorerNodeProvider/fileSources.ts @@ -16,7 +16,6 @@ import * as nls from 'vscode-nls'; import * as constants from '../constants'; import { WebHDFS, HdfsError } from './webhdfs'; -import * as auth from '../util/auth'; const localize = nls.loadMessageBundle(); @@ -85,13 +84,11 @@ export interface IHdfsOptions { export interface IRequestParams { auth?: IHttpAuthentication; - isKerberos?: boolean; /** * Timeout in milliseconds to wait for response */ timeout?: number; agent?: https.Agent; - headers?: {}; } export interface IHdfsFileStatus { @@ -109,10 +106,10 @@ export class FileSourceFactory { return FileSourceFactory._instance; } - public async createHdfsFileSource(options: IHdfsOptions): Promise { + public createHdfsFileSource(options: IHdfsOptions): IFileSource { options = options && options.host ? FileSourceFactory.removePortFromHost(options) : options; let requestParams: IRequestParams = options.requestParams ? options.requestParams : {}; - if (requestParams.auth || requestParams.isKerberos) { + if (requestParams.auth) { // TODO Remove handling of unsigned cert once we have real certs in our Knox service let agentOptions = { host: options.host, @@ -122,11 +119,6 @@ export class FileSourceFactory { }; let agent = new https.Agent(agentOptions); requestParams['agent'] = agent; - - } - if (requestParams.isKerberos) { - let kerberosToken = await auth.authenticateKerberos(options.host); - requestParams.headers = { Authorization: `Negotiate ${kerberosToken}` }; } return new HdfsFileSource(WebHDFS.createClient(options, requestParams)); } diff --git a/extensions/mssql/src/objectExplorerNodeProvider/hdfsProvider.ts b/extensions/mssql/src/objectExplorerNodeProvider/hdfsProvider.ts index 53d63d4448..c5ea3bb7bb 100644 --- a/extensions/mssql/src/objectExplorerNodeProvider/hdfsProvider.ts +++ b/extensions/mssql/src/objectExplorerNodeProvider/hdfsProvider.ts @@ -63,9 +63,9 @@ export class HdfsProvider implements vscode.TreeDataProvider, ITreeCha } } - public async addHdfsConnection(options: IHdfsOptions): Promise { + addHdfsConnection(options: IHdfsOptions): void { let displayName = `${options.user}@${options.host}:${options.port}`; - let fileSource = await FileSourceFactory.instance.createHdfsFileSource(options); + let fileSource = FileSourceFactory.instance.createHdfsFileSource(options); this.addConnection(displayName, fileSource); } diff --git a/extensions/mssql/src/objectExplorerNodeProvider/objectExplorerNodeProvider.ts b/extensions/mssql/src/objectExplorerNodeProvider/objectExplorerNodeProvider.ts index 0848ec17e4..24449f4386 100644 --- a/extensions/mssql/src/objectExplorerNodeProvider/objectExplorerNodeProvider.ts +++ b/extensions/mssql/src/objectExplorerNodeProvider/objectExplorerNodeProvider.ts @@ -120,10 +120,10 @@ export class MssqlObjectExplorerNodeProvider extends ProviderBase implements azd if (children.length === 1 && this.hasExpansionError(children)) { if (children[0].errorStatusCode === 401) { //Prompt for password - let password: string = await this.promptPassword(localize('prmptPwd', "Please provide the password to connect to HDFS:")); + let password: string = await this.promptPassword(localize('prmptPwd', 'Please provide the password to connect to HDFS:')); if (password && password.length > 0) { session.sqlClusterConnection.updatePassword(password); - await node.updateFileSource(session.sqlClusterConnection); + node.updateFileSource(session.sqlClusterConnection); children = await node.getChildren(true); } } @@ -181,7 +181,7 @@ export class MssqlObjectExplorerNodeProvider extends ProviderBase implements azd try { let session = this.getSqlClusterSessionForNode(node); if (!session) { - this.appContext.apiWrapper.showErrorMessage(localize('sessionNotFound', "Session for node {0} does not exist", node.nodePathValue)); + this.appContext.apiWrapper.showErrorMessage(localize('sessionNotFound', 'Session for node {0} does not exist', node.nodePathValue)); } else { let nodeInfo = node.getNodeInfo(); let expandInfo: azdata.ExpandNodeInfo = { @@ -191,7 +191,7 @@ export class MssqlObjectExplorerNodeProvider extends ProviderBase implements azd await this.refreshNode(expandInfo); } } catch (err) { - mssqlOutputChannel.appendLine(localize('notifyError', "Error notifying of node change: {0}", err)); + mssqlOutputChannel.appendLine(localize('notifyError', 'Error notifying of node change: {0}', err)); } } @@ -295,7 +295,7 @@ class SqlClusterRootNode extends TreeNode { getNodeInfo(): azdata.NodeInfo { let nodeInfo: azdata.NodeInfo = { - label: localize('rootLabel', "Root"), + label: localize('rootLabel', 'Root'), isLeaf: false, errorMessage: undefined, metadata: undefined, @@ -325,27 +325,22 @@ class DataServicesNode extends TreeNode { public getChildren(refreshChildren: boolean): TreeNode[] | Promise { if (refreshChildren || !this._children) { - return this.refreshChildren(); + this._children = []; + let fileSource: IFileSource = this.session.sqlClusterConnection.createHdfsFileSource(); + let hdfsNode = new ConnectionNode(this._context, localize('hdfsFolder', 'HDFS'), fileSource); + hdfsNode.parent = this; + this._children.push(hdfsNode); } return this._children; } - private async refreshChildren(): Promise { - this._children = []; - let fileSource: IFileSource = await this.session.sqlClusterConnection.createHdfsFileSource(); - let hdfsNode = new ConnectionNode(this._context, localize('hdfsFolder', "HDFS"), fileSource); - hdfsNode.parent = this; - this._children.push(hdfsNode); - return this._children; - } - getTreeItem(): vscode.TreeItem | Promise { throw new Error('Not intended for use in a file explorer view.'); } getNodeInfo(): azdata.NodeInfo { let nodeInfo: azdata.NodeInfo = { - label: localize('dataServicesLabel', "Data Services"), + label: localize('dataServicesLabel', 'Data Services'), isLeaf: false, errorMessage: undefined, metadata: undefined, @@ -357,4 +352,4 @@ class DataServicesNode extends TreeNode { }; return nodeInfo; } -} +} \ No newline at end of file diff --git a/extensions/mssql/src/objectExplorerNodeProvider/treeNodes.ts b/extensions/mssql/src/objectExplorerNodeProvider/treeNodes.ts index 68f7c28c2e..b62a5f5e20 100644 --- a/extensions/mssql/src/objectExplorerNodeProvider/treeNodes.ts +++ b/extensions/mssql/src/objectExplorerNodeProvider/treeNodes.ts @@ -78,8 +78,8 @@ export abstract class TreeNode implements ITreeNode { return undefined; } - public async updateFileSource(connection: SqlClusterConnection): Promise { - this.fileSource = await connection.createHdfsFileSource(); + public updateFileSource(connection: SqlClusterConnection): void { + this.fileSource = connection.createHdfsFileSource(); } /** * The value to use for this node in the node path diff --git a/extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts b/extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts index dc65257a59..02da36a98b 100644 --- a/extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts +++ b/extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts @@ -482,17 +482,15 @@ export class WebHDFS { let stream = undefined; let canResume: boolean = true; - let params: any = Object.assign( + let params = Object.assign( { method: append ? 'POST' : 'PUT', url: endpoint, json: true, + headers: { 'content-type': 'application/octet-stream' } }, this._requestParams ); - params.headers = params.headers || {}; - params.headers['content-type'] = 'application/octet-stream'; - let req = request(params, (error, response, body) => { // Handle redirect only if there was not an error (e.g. res is defined) diff --git a/extensions/mssql/src/sparkFeature/dialog/sparkJobSubmission/sparkJobSubmissionModel.ts b/extensions/mssql/src/sparkFeature/dialog/sparkJobSubmission/sparkJobSubmissionModel.ts index 99b083298c..366927d403 100644 --- a/extensions/mssql/src/sparkFeature/dialog/sparkJobSubmission/sparkJobSubmissionModel.ts +++ b/extensions/mssql/src/sparkFeature/dialog/sparkJobSubmission/sparkJobSubmissionModel.ts @@ -147,7 +147,7 @@ export class SparkJobSubmissionModel { return Promise.reject(LocalizedConstants.sparkJobSubmissionLocalFileNotExisted(localFilePath)); } - let fileSource: IFileSource = await this._sqlClusterConnection.createHdfsFileSource(); + let fileSource: IFileSource = this._sqlClusterConnection.createHdfsFileSource(); await fileSource.writeFile(new File(localFilePath, false), hdfsFolderPath); } catch (error) { return Promise.reject(error); @@ -160,7 +160,7 @@ export class SparkJobSubmissionModel { return Promise.reject(localize('sparkJobSubmission_PathNotSpecified.', 'Property Path is not specified. ')); } - let fileSource: IFileSource = await this._sqlClusterConnection.createHdfsFileSource(); + let fileSource: IFileSource = this._sqlClusterConnection.createHdfsFileSource(); return await fileSource.exists(path); } catch (error) { return Promise.reject(error); diff --git a/extensions/mssql/src/sparkFeature/dialog/sparkJobSubmission/sparkJobSubmissionService.ts b/extensions/mssql/src/sparkFeature/dialog/sparkJobSubmission/sparkJobSubmissionService.ts index 6a37fbf634..83c46a4dab 100644 --- a/extensions/mssql/src/sparkFeature/dialog/sparkJobSubmission/sparkJobSubmissionService.ts +++ b/extensions/mssql/src/sparkFeature/dialog/sparkJobSubmission/sparkJobSubmissionService.ts @@ -11,7 +11,6 @@ const localize = nls.loadMessageBundle(); import * as constants from '../../../constants'; import { SqlClusterConnection } from '../../../objectExplorerNodeProvider/connection'; import * as utils from '../../../utils'; -import * as auth from '../../../util/auth'; export class SparkJobSubmissionService { private _requestPromise: (args: any) => any; @@ -29,10 +28,6 @@ export class SparkJobSubmissionService { public async submitBatchJob(submissionArgs: SparkJobSubmissionInput): Promise { try { let livyUrl: string = `https://${submissionArgs.host}:${submissionArgs.port}${submissionArgs.livyPath}/`; - - // Get correct authentication headers - let headers = await this.getAuthenticationHeaders(submissionArgs); - let options = { uri: livyUrl, method: 'POST', @@ -46,7 +41,9 @@ export class SparkJobSubmissionService { name: submissionArgs.jobName }, // authentication headers - headers: headers + headers: { + 'Authorization': 'Basic ' + Buffer.from(submissionArgs.user + ':' + submissionArgs.password).toString('base64') + } }; // Set arguments @@ -93,30 +90,18 @@ export class SparkJobSubmissionService { } } - private async getAuthenticationHeaders(submissionArgs: SparkJobSubmissionInput) { - let headers = {}; - if (submissionArgs.isIntegratedAuth) { - let kerberosToken = await auth.authenticateKerberos(submissionArgs.host); - headers = { Authorization: `Negotiate ${kerberosToken}` }; - } - else { - headers = { Authorization: 'Basic ' + Buffer.from(submissionArgs.user + ':' + submissionArgs.password).toString('base64') }; - } - return headers; - } - public async getYarnAppId(submissionArgs: SparkJobSubmissionInput, livyBatchId: string): Promise { try { let livyUrl = `https://${submissionArgs.host}:${submissionArgs.port}${submissionArgs.livyPath}/${livyBatchId}/log`; - let headers = await this.getAuthenticationHeaders(submissionArgs); - let options = { uri: livyUrl, method: 'GET', json: true, rejectUnauthorized: false, // authentication headers - headers: headers + headers: { + 'Authorization': 'Basic ' + Buffer.from(submissionArgs.user + ':' + submissionArgs.password).toString('base64') + } }; const response = await this._requestPromise(options); @@ -160,8 +145,7 @@ export class SparkJobSubmissionInput { this._port = sqlClusterConnection.port; this._livyPath = constants.mssqlClusterLivySubmitPath; this._user = sqlClusterConnection.user; - this._password = sqlClusterConnection.password; - this._isIntegratedAuth = sqlClusterConnection.isIntegratedAuth(); + this._passWord = sqlClusterConnection.password; } constructor( @@ -176,8 +160,7 @@ export class SparkJobSubmissionInput { private _port?: number, private _livyPath?: string, private _user?: string, - private _password?: string, - private _isIntegratedAuth?: boolean) { + private _passWord?: string) { } public get jobName(): string { return this._jobName; } @@ -191,8 +174,7 @@ export class SparkJobSubmissionInput { public get port(): number { return this._port; } public get livyPath(): string { return this._livyPath; } public get user(): string { return this._user; } - public get password(): string { return this._password; } - public get isIntegratedAuth(): boolean { return this._isIntegratedAuth; } + public get password(): string { return this._passWord; } } export enum SparkFileSource { diff --git a/extensions/mssql/src/sparkFeature/sparkUtils.ts b/extensions/mssql/src/sparkFeature/sparkUtils.ts index 1990479516..503d9ad246 100644 --- a/extensions/mssql/src/sparkFeature/sparkUtils.ts +++ b/extensions/mssql/src/sparkFeature/sparkUtils.ts @@ -5,12 +5,12 @@ import * as childProcess from 'child_process'; import * as fs from 'fs-extra'; +import * as nls from 'vscode-nls'; import * as path from 'path'; import * as azdata from 'azdata'; import * as vscode from 'vscode'; import * as which from 'which'; -import * as constants from '../constants'; -import * as nls from 'vscode-nls'; + const localize = nls.loadMessageBundle(); export function getDropdownValue(dropdownValue: string | azdata.CategoryValue): string { @@ -23,8 +23,8 @@ export function getDropdownValue(dropdownValue: string | azdata.CategoryValue): export function getServerAddressFromName(connection: azdata.ConnectionInfo | string): string { // Strip TDS port number from the server URI - if ((connection).options && (connection).options[constants.hostPropName]) { - return (connection).options[constants.hostPropName].split(',')[0].split(':')[0]; + if ((connection).options && (connection).options['host']) { + return (connection).options['host'].split(',')[0].split(':')[0]; } else if ((connection).options && (connection).options['server']) { return (connection).options['server'].split(',')[0].split(':')[0]; } else { diff --git a/extensions/mssql/src/sqlClusterLookUp.ts b/extensions/mssql/src/sqlClusterLookUp.ts index 5051fabc0b..69aa11f37b 100644 --- a/extensions/mssql/src/sqlClusterLookUp.ts +++ b/extensions/mssql/src/sqlClusterLookUp.ts @@ -11,9 +11,10 @@ import * as UUID from 'vscode-languageclient/lib/utils/uuid'; import { AppContext } from './appContext'; import { SqlClusterConnection } from './objectExplorerNodeProvider/connection'; import { ICommandObjectExplorerContext } from './objectExplorerNodeProvider/command'; -import { IEndpoint, getClusterEndpoints, getHostAndPortFromEndpoint } from './utils'; +import { IEndpoint } from './utils'; import { MssqlObjectExplorerNodeProvider } from './objectExplorerNodeProvider/objectExplorerNodeProvider'; + export function findSqlClusterConnection( obj: ICommandObjectExplorerContext | azdata.IConnectionProfile, appContext: AppContext): SqlClusterConnection { @@ -75,10 +76,14 @@ async function createSqlClusterConnInfo(sqlConnInfo: azdata.IConnectionProfile | let serverInfo = await azdata.connection.getServerInfo(connectionId); if (!serverInfo || !serverInfo.options) { return undefined; } - let endpoints: IEndpoint[] = getClusterEndpoints(serverInfo); + let endpoints: IEndpoint[] = serverInfo.options[constants.clusterEndpointsProperty]; if (!endpoints || endpoints.length === 0) { return undefined; } - let index = endpoints.findIndex(ep => ep.serviceName.toLowerCase() === constants.hadoopEndpointNameGateway.toLowerCase()); + let index = endpoints.findIndex(ep => { + let serviceName: string = ep.serviceName.toLowerCase(); + return serviceName === constants.hadoopEndpointNameKnox.toLowerCase() || + serviceName === constants.hadoopEndpointNameGateway.toLowerCase(); + }); if (index < 0) { return undefined; } let credentials = await azdata.connection.getCredentials(connectionId); @@ -90,27 +95,15 @@ async function createSqlClusterConnInfo(sqlConnInfo: azdata.IConnectionProfile | options: {} }; - let hostAndIp = getHostAndPortFromEndpoint(endpoints[index].endpoint); - clusterConnInfo.options[constants.hostPropName] = hostAndIp.host; - // TODO should we default the port? Or just ignore later? - clusterConnInfo.options[constants.knoxPortPropName] = hostAndIp.port || constants.defaultKnoxPort; - let authType = clusterConnInfo.options[constants.authenticationTypePropName] = sqlConnInfo.options[constants.authenticationTypePropName]; - if (authType && authType.toLowerCase() !== constants.integratedAuth) { - clusterConnInfo.options[constants.userPropName] = 'root'; //should be the same user as sql master - clusterConnInfo.options[constants.passwordPropName] = credentials.password; - } else { - // Hack: for now, we need to use gateway-0 for integrated auth - let sqlDnsName: string = sqlConnInfo.options['server'].split(',')[0]; - let parts = sqlDnsName.split('.'); - parts[0] = 'gateway-0'; - clusterConnInfo.options[constants.hostPropName] = parts.join('.'); - } + clusterConnInfo.options[constants.hostPropName] = endpoints[index].ipAddress; + clusterConnInfo.options[constants.knoxPortPropName] = endpoints[index].port; + clusterConnInfo.options[constants.userPropName] = 'root'; //should be the same user as sql master + clusterConnInfo.options[constants.passwordPropName] = credentials.password; clusterConnInfo = connToConnectionParam(clusterConnInfo); return clusterConnInfo; } - function connProfileToConnectionParam(connectionProfile: azdata.IConnectionProfile): ConnectionParam { let result = Object.assign(connectionProfile, { connectionId: connectionProfile.id }); return result; @@ -125,7 +118,6 @@ function connToConnectionParam(connection: azdata.connection.Connection): Connec userName: options[constants.userPropName], password: options[constants.passwordPropName], id: connectionId, - authenticationType: options[constants.authenticationTypePropName] } ); return result; @@ -149,4 +141,4 @@ class ConnectionParam implements azdata.connection.Connection, azdata.IConnectio public connectionId: string; public options: { [name: string]: any; }; -} +} \ No newline at end of file diff --git a/extensions/mssql/src/util/auth.ts b/extensions/mssql/src/util/auth.ts deleted file mode 100644 index c6bb89672d..0000000000 --- a/extensions/mssql/src/util/auth.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as kerberos from 'kerberos'; - -export async function authenticateKerberos(hostname: string): Promise { - const service = 'HTTP' + (process.platform === 'win32' ? '/' : '@') + hostname; - const mechOID = kerberos.GSS_MECH_OID_KRB5; - let client = await kerberos.initializeClient(service, { mechOID }); - let response = await client.step(''); - return response; -} diff --git a/extensions/mssql/src/utils.ts b/extensions/mssql/src/utils.ts index 25f1817fda..b22ca4edf0 100644 --- a/extensions/mssql/src/utils.ts +++ b/extensions/mssql/src/utils.ts @@ -232,55 +232,36 @@ export function getUserHome(): string { return process.env.HOME || process.env.USERPROFILE; } -export function getClusterEndpoints(serverInfo: azdata.ServerInfo): IEndpoint[] | undefined { - let endpoints: RawEndpoint[] = serverInfo.options[constants.clusterEndpointsProperty]; - if (!endpoints || endpoints.length === 0) { return []; } +export async function getClusterEndpoint(profileId: string, serviceName: string): Promise { - return endpoints.map(e => { - // If endpoint is missing, we're on CTP bits. All endpoints from the CTP serverInfo should be treated as HTTPS - let endpoint = e.endpoint ? e.endpoint : `https://${e.ipAddress}:${e.port}`; - let updatedEndpoint: IEndpoint = { - serviceName: e.serviceName, - description: e.description, - endpoint: endpoint, - protocol: e.protocol - }; - return updatedEndpoint; - }); -} - -export type HostAndIp = { host: string, port: string }; - -export function getHostAndPortFromEndpoint(endpoint: string): HostAndIp { - let authority = vscode.Uri.parse(endpoint).authority; - let hostAndPortRegex = /^(.*)([,:](\d+))/g; - let match = hostAndPortRegex.exec(authority); - if (match) { - return { - host: match[1], - port: match[3] - }; + let serverInfo: azdata.ServerInfo = await azdata.connection.getServerInfo(profileId); + if (!serverInfo || !serverInfo.options) { + return undefined; } - return { - host: authority, - port: undefined + let endpoints: IEndpoint[] = serverInfo.options[constants.clusterEndpointsProperty]; + if (!endpoints || endpoints.length === 0) { + return undefined; + } + let index = endpoints.findIndex(ep => ep.serviceName === serviceName); + if (index === -1) { + return undefined; + } + let clusterEndpoint: IEndpoint = { + serviceName: endpoints[index].serviceName, + ipAddress: endpoints[index].ipAddress, + port: endpoints[index].port, + isHyperlink: false, + hyperlink: null }; -} - -interface RawEndpoint { - serviceName: string; - description?: string; - endpoint?: string; - protocol?: string; - ipAddress?: string; - port?: number; + return clusterEndpoint; } export interface IEndpoint { serviceName: string; - description: string; - endpoint: string; - protocol: string; + ipAddress: string; + port: number; + isHyperlink: boolean; + hyperlink: string; } export function isValidNumber(maybeNumber: any) { diff --git a/extensions/mssql/yarn.lock b/extensions/mssql/yarn.lock index dda89ad112..040f891368 100644 --- a/extensions/mssql/yarn.lock +++ b/extensions/mssql/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@types/kerberos@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@types/kerberos/-/kerberos-1.1.0.tgz#fb1e5bc4f7272d152f67714deb100d5de7cb3e48" - integrity sha512-ixpV6PSSMnIVpMNCLQ0gWguC2+pBxc0LeUCv9Ugj54opVSVFXfPNYP6sMa7UHvicYGDXAyHQSAzQC8VYEIgdFQ== - agent-base@4, agent-base@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -24,16 +19,6 @@ ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - applicationinsights@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.6.tgz#bc201810de91cea910dab34e8ad35ecde488edeb" @@ -43,19 +28,6 @@ applicationinsights@1.0.6: diagnostic-channel-publishers "0.2.1" zone.js "0.7.6" -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -100,13 +72,6 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bindings@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - bl@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" @@ -174,16 +139,6 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chownr@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" @@ -203,11 +158,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -240,13 +190,6 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" @@ -300,26 +243,11 @@ decompress@^4.2.0: pify "^2.3.0" strip-dirs "^2.0.0" -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - diagnostic-channel-publishers@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3" @@ -340,7 +268,7 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -end-of-stream@^1.0.0, end-of-stream@^1.1.0: +end-of-stream@^1.0.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== @@ -376,11 +304,6 @@ eventemitter2@^5.0.1: resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-5.0.1.tgz#6197a095d5fb6b57e8942f6fd7eaad63a09c9452" integrity sha1-YZegldX7a1folC9v1+qtY6CclFI= -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -435,11 +358,6 @@ file-type@^6.1.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - find-remove@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/find-remove/-/find-remove-1.2.1.tgz#afd93400d23890e018ea197591e9d850d3d049a2" @@ -486,20 +404,6 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - get-stream@^2.2.0: version "2.3.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" @@ -515,11 +419,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= - glob@^7.0.5: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" @@ -555,11 +454,6 @@ har-validator@~5.1.0: ajv "^6.5.5" har-schema "^2.0.0" -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - http-proxy-agent@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" @@ -603,11 +497,6 @@ inherits@2, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" @@ -618,18 +507,6 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - is-natural-number@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" @@ -692,15 +569,6 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -kerberos@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/kerberos/-/kerberos-1.1.2.tgz#f213dae89c57e729786664fcf99117221e18e257" - integrity sha512-N+CeRTi0f6ov85Fx+w/epVPTBy6bovoWjUCD6pvXoHWBWeqI6+ViV2psdoSc4CRtiZfJkhvYO3b47I4hJfOu7Q== - dependencies: - bindings "^1.3.0" - nan "^2.10.0" - prebuild-install "^5.0.0" - lodash@^4.13.1: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" @@ -725,11 +593,6 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "~1.38.0" -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -742,11 +605,6 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -764,65 +622,23 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -nan@^2.10.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -napi-build-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.1.tgz#1381a0f92c39d66bf19852e7873432fc2123e508" - integrity sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA== - -node-abi@^2.7.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.10.0.tgz#894bc6625ee042627ed9b5e9270d80bb63ef5045" - integrity sha512-OT0WepUvYHXdki6DU8LWhEkuo3M44i2paWBYtH9qXtPb9YiKlYEKa5WUII20XEcOv7UJPzfB0kZfPZdW46zdkw== - dependencies: - semver "^5.4.1" - -noop-logger@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" - integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= - -npmlog@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0: +object-assign@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" -os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -865,28 +681,6 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -prebuild-install@^5.0.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.0.tgz#58b4d8344e03590990931ee088dd5401b03004c8" - integrity sha512-aaLVANlj4HgZweKttFNUVNRxDukytuIuxeK2boIMHjagNJCiVKWFsKF4tCE3ql3GbrD2tExPQ7/pwtEJcHNZeg== - dependencies: - detect-libc "^1.0.3" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.0" - mkdirp "^0.5.1" - napi-build-utils "^1.0.1" - node-abi "^2.7.0" - noop-logger "^0.1.1" - npmlog "^4.0.1" - os-homedir "^1.0.1" - pump "^2.0.1" - rc "^1.2.7" - simple-get "^2.7.0" - tar-fs "^1.13.0" - tunnel-agent "^0.6.0" - which-pm-runs "^1.0.0" - process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" @@ -897,22 +691,6 @@ psl@^1.1.24, psl@^1.1.28: resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== -pump@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" - integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -928,17 +706,7 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.3.0, readable-stream@^2.3.5: +readable-stream@^2.1.4, readable-stream@^2.3.0, readable-stream@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -1023,11 +791,6 @@ semver@^5.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== -semver@^5.4.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^5.5.0: version "5.7.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" @@ -1044,30 +807,6 @@ semver@^5.5.0: mkdirp "^0.5.1" tmp "^0.0.33" -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-concat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" - integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= - -simple-get@^2.7.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" - integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw== - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -1095,23 +834,6 @@ stream-meter@^1.0.4: dependencies: readable-stream "^2.1.4" -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -1119,20 +841,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - strip-dirs@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" @@ -1140,22 +848,7 @@ strip-dirs@^2.0.0: dependencies: is-natural-number "^4.0.1" -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -tar-fs@^1.13.0: - version "1.16.3" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" - integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw== - dependencies: - chownr "^1.0.1" - mkdirp "^0.5.1" - pump "^1.0.0" - tar-stream "^1.1.2" - -tar-stream@^1.1.2, tar-stream@^1.5.2: +tar-stream@^1.5.2: version "1.6.2" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== @@ -1291,18 +984,6 @@ vscode-nls@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002" integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw== -which-pm-runs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" - integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/extensions/notebook/src/common/utils.ts b/extensions/notebook/src/common/utils.ts index 6c0db5460d..7a2313f321 100644 --- a/extensions/notebook/src/common/utils.ts +++ b/extensions/notebook/src/common/utils.ts @@ -141,4 +141,4 @@ export function isEditorTitleFree(title: string): boolean { let hasTextDoc = vscode.workspace.textDocuments.findIndex(doc => doc.isUntitled && doc.fileName === title) > -1; let hasNotebookDoc = azdata.nb.notebookDocuments.findIndex(doc => doc.isUntitled && doc.fileName === title) > -1; return !hasTextDoc && !hasNotebookDoc; -} +} \ No newline at end of file diff --git a/extensions/notebook/src/jupyter/jupyterSessionManager.ts b/extensions/notebook/src/jupyter/jupyterSessionManager.ts index 4b7382bc89..3f956c9114 100644 --- a/extensions/notebook/src/jupyter/jupyterSessionManager.ts +++ b/extensions/notebook/src/jupyter/jupyterSessionManager.ts @@ -55,11 +55,10 @@ const configBase = { const KNOX_ENDPOINT_SERVER = 'host'; const KNOX_ENDPOINT_PORT = 'knoxport'; +const KNOX_ENDPOINT_KNOX = 'knox'; const KNOX_ENDPOINT_GATEWAY = 'gateway'; const SQL_PROVIDER = 'MSSQL'; const USER = 'user'; -const AUTHTYPE = 'authenticationType'; -const INTEGRATED_AUTH = 'integrated'; const DEFAULT_CLUSTER_USER_NAME = 'root'; export class JupyterSessionManager implements nb.SessionManager { @@ -243,19 +242,13 @@ export class JupyterSession implements nb.ISession { //Update server info with bigdata endpoint - Unified Connection if (connection.providerName === SQL_PROVIDER) { - let clusterEndpoint: utils.IEndpoint = await this.getClusterEndpoint(connection.id, KNOX_ENDPOINT_GATEWAY); + let clusterEndpoint: utils.IEndpoint = + await this.getClusterEndpoint(connection.id, KNOX_ENDPOINT_KNOX) || + await this.getClusterEndpoint(connection.id, KNOX_ENDPOINT_GATEWAY); if (!clusterEndpoint) { return Promise.reject(new Error(localize('connectionNotValid', "Spark kernels require a connection to a SQL Server big data cluster master instance."))); } - if (this.isIntegratedAuth(connection)) { - // Hack: for now, we need to use gateway-0 for integrated auth - let sqlDnsName: string = connection.options['server'].split(',')[0]; - let parts = sqlDnsName.split('.'); - parts[0] = 'gateway-0'; - connection.options[KNOX_ENDPOINT_SERVER] = parts.join('.'); - } else { - connection.options[KNOX_ENDPOINT_SERVER] = clusterEndpoint.ipAddress; - } + connection.options[KNOX_ENDPOINT_SERVER] = clusterEndpoint.ipAddress; connection.options[KNOX_ENDPOINT_PORT] = clusterEndpoint.port; connection.options[USER] = DEFAULT_CLUSTER_USER_NAME; } @@ -266,9 +259,8 @@ export class JupyterSession implements nb.ISession { this.setHostAndPort(',', connection); let server = Uri.parse(utils.getLivyUrl(connection.options[KNOX_ENDPOINT_SERVER], connection.options[KNOX_ENDPOINT_PORT])).toString(); - let doNotCallChangeEndpointParams = this.isIntegratedAuth(connection) ? - `%_do_not_call_change_endpoint --server=${server} --auth=Kerberos` - : `%_do_not_call_change_endpoint --username=${connection.options[USER]} --password=${connection.options['password']} --server=${server} --auth=Basic_Access`; + let doNotCallChangeEndpointParams = + `%_do_not_call_change_endpoint --username=${connection.options[USER]} --password=${connection.options['password']} --server=${server} --auth=Basic_Access`; let future = this.sessionImpl.kernel.requestExecute({ code: doNotCallChangeEndpointParams }, true); @@ -276,10 +268,6 @@ export class JupyterSession implements nb.ISession { } } - private isIntegratedAuth(connection: IConnectionProfile): boolean { - return connection.options[AUTHTYPE] && connection.options[AUTHTYPE].toLowerCase() === INTEGRATED_AUTH.toLowerCase(); - } - private isSparkKernel(kernelName: string): boolean { return kernelName && kernelName.toLowerCase().indexOf('spark') > -1; } @@ -342,4 +330,4 @@ interface ISparkMagicConfig { } } }; -} +} \ No newline at end of file diff --git a/resources/xlf/de/mssql.de.xlf b/resources/xlf/de/mssql.de.xlf index ab47558452..a54eca279a 100644 --- a/resources/xlf/de/mssql.de.xlf +++ b/resources/xlf/de/mssql.de.xlf @@ -922,7 +922,7 @@ Log Search Dashboard Dashboard für Protokollsuche - + Spark Job Monitoring Überwachung von Spark-Aufträgen @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/en/mssql.xlf b/resources/xlf/en/mssql.xlf index e5375c20b4..b30a3cda57 100644 --- a/resources/xlf/en/mssql.xlf +++ b/resources/xlf/en/mssql.xlf @@ -674,7 +674,7 @@ Log Search Dashboard - + Spark Job Monitoring @@ -773,4 +773,4 @@ No Sql Server big data cluster found. - + \ No newline at end of file diff --git a/resources/xlf/es/mssql.es.xlf b/resources/xlf/es/mssql.es.xlf index a7035e3d5d..ecd5a890d4 100644 --- a/resources/xlf/es/mssql.es.xlf +++ b/resources/xlf/es/mssql.es.xlf @@ -922,7 +922,7 @@ Log Search Dashboard Panel de búsqueda de registros - + Spark Job Monitoring Supervisión de trabajos de Spark @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/fr/mssql.fr.xlf b/resources/xlf/fr/mssql.fr.xlf index 9ea8aec86e..94fc553d87 100644 --- a/resources/xlf/fr/mssql.fr.xlf +++ b/resources/xlf/fr/mssql.fr.xlf @@ -922,7 +922,7 @@ Log Search Dashboard Tableau de bord de recherche dans les journaux - + Spark Job Monitoring Supervision du travail Spark @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/it/mssql.it.xlf b/resources/xlf/it/mssql.it.xlf index 58d8920735..5478be71d5 100644 --- a/resources/xlf/it/mssql.it.xlf +++ b/resources/xlf/it/mssql.it.xlf @@ -922,7 +922,7 @@ Log Search Dashboard Dashboard di ricerca log - + Spark Job Monitoring Monitoraggio processi Spark @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/ja/mssql.ja.xlf b/resources/xlf/ja/mssql.ja.xlf index 90dd9b94b4..ca2f627e40 100644 --- a/resources/xlf/ja/mssql.ja.xlf +++ b/resources/xlf/ja/mssql.ja.xlf @@ -922,7 +922,7 @@ Log Search Dashboard ログ検索ダッシュボード - + Spark Job Monitoring Spark ジョブの監視 @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/ko/mssql.ko.xlf b/resources/xlf/ko/mssql.ko.xlf index 7cbce247ac..55eceae057 100644 --- a/resources/xlf/ko/mssql.ko.xlf +++ b/resources/xlf/ko/mssql.ko.xlf @@ -922,7 +922,7 @@ Log Search Dashboard 로그 검색 대시보드 - + Spark Job Monitoring Spark 작업 모니터링 @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/pt-br/mssql.pt-BR.xlf b/resources/xlf/pt-br/mssql.pt-BR.xlf index 0d5827f8bb..4b76a041a1 100644 --- a/resources/xlf/pt-br/mssql.pt-BR.xlf +++ b/resources/xlf/pt-br/mssql.pt-BR.xlf @@ -922,7 +922,7 @@ Log Search Dashboard Painel de Pesquisa de Logs - + Spark Job Monitoring Monitoramento de trabalho do Spark @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/ru/mssql.ru.xlf b/resources/xlf/ru/mssql.ru.xlf index e9fbff2347..883792b20c 100644 --- a/resources/xlf/ru/mssql.ru.xlf +++ b/resources/xlf/ru/mssql.ru.xlf @@ -922,7 +922,7 @@ Log Search Dashboard Панель мониторинга поиска по журналам - + Spark Job Monitoring Мониторинг заданий Spark @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/zh-hans/mssql.zh-Hans.xlf b/resources/xlf/zh-hans/mssql.zh-Hans.xlf index 1cd127a84f..f8f92d69a4 100644 --- a/resources/xlf/zh-hans/mssql.zh-Hans.xlf +++ b/resources/xlf/zh-hans/mssql.zh-Hans.xlf @@ -922,7 +922,7 @@ Log Search Dashboard 日志搜索仪表板 - + Spark Job Monitoring Spark 作业监视 @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/resources/xlf/zh-hant/mssql.zh-Hant.xlf b/resources/xlf/zh-hant/mssql.zh-Hant.xlf index 469fe10121..5c2befd835 100644 --- a/resources/xlf/zh-hant/mssql.zh-Hant.xlf +++ b/resources/xlf/zh-hant/mssql.zh-Hant.xlf @@ -922,7 +922,7 @@ Log Search Dashboard 記錄搜尋儀表板 - + Spark Job Monitoring Spark 作業監視 @@ -1056,4 +1056,4 @@ - + \ No newline at end of file diff --git a/src/sql/workbench/services/objectExplorer/common/objectExplorerService.ts b/src/sql/workbench/services/objectExplorer/common/objectExplorerService.ts index bde8d2b648..de1722ca65 100644 --- a/src/sql/workbench/services/objectExplorer/common/objectExplorerService.ts +++ b/src/sql/workbench/services/objectExplorer/common/objectExplorerService.ts @@ -124,8 +124,6 @@ export interface TopLevelChildrenPath { providerObject: azdata.ObjectExplorerNodeProvider | azdata.ObjectExplorerProvider; } -const errSessionCreateFailed = nls.localize('OeSessionFailedError', "Failed to create Object Explorer session"); - export class ObjectExplorerService implements IObjectExplorerService { public _serviceBrand: any; @@ -233,18 +231,19 @@ export class ObjectExplorerService implements IObjectExplorerService { if (session && session.success) { this.handleSessionCreated(session); } else { - let errorMessage = session && session.errorMessage ? session.errorMessage : errSessionCreateFailed; + let errorMessage = session && session.errorMessage ? session.errorMessage : + nls.localize('OeSessionFailedError', "Failed to create Object Explorer session"); this.logService.error(errorMessage); } } private async handleSessionCreated(session: azdata.ObjectExplorerSession): Promise { - let connection: ConnectionProfile = undefined; - let errorMessage: string = undefined; - if (this._sessions[session.sessionId]) { - connection = this._sessions[session.sessionId].connection; + try { + let connection: ConnectionProfile = undefined; + let errorMessage: string = undefined; + if (this._sessions[session.sessionId]) { + connection = this._sessions[session.sessionId].connection; - try { if (session.success && session.rootNode) { let server = this.toTreeNode(session.rootNode, null); server.connection = connection; @@ -252,7 +251,8 @@ export class ObjectExplorerService implements IObjectExplorerService { this._activeObjectExplorerNodes[connection.id] = server; } else { - errorMessage = session && session.errorMessage ? session.errorMessage : errSessionCreateFailed; + errorMessage = session && session.errorMessage ? session.errorMessage : + nls.localize('OeSessionFailedError', "Failed to create Object Explorer session"); this.logService.error(errorMessage); } // Send on session created about the session to all node providers so they can prepare for node expansion @@ -261,14 +261,14 @@ export class ObjectExplorerService implements IObjectExplorerService { let promises: Thenable[] = nodeProviders.map(p => p.handleSessionOpen(session)); await Promise.all(promises); } - } catch (error) { - this.logService.warn(`cannot handle the session ${session.sessionId} in all nodeProviders`); - } finally { - this.sendUpdateNodeEvent(connection, errorMessage); } - } - else { - this.logService.warn(`cannot find session ${session.sessionId}`); + else { + this.logService.warn(`cannot find session ${session.sessionId}`); + } + + this.sendUpdateNodeEvent(connection, errorMessage); + } catch (error) { + this.logService.warn(`cannot handle the session ${session.sessionId} in all nodeProviders`); } }