Fix #6845 Notebook: Pyspark3 links incorrectly mapped when AD enabled (#6885)

This commit is contained in:
Kevin Cunnane
2019-08-27 14:28:14 -07:00
committed by GitHub
parent a27b759b10
commit 4d19610c94
2 changed files with 79 additions and 21 deletions

View File

@@ -24,6 +24,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents';
let modelId = 0;
export class CellModel implements ICellModel {
private _cellType: nb.CellType;
private _source: string | string[];
@@ -471,17 +472,20 @@ export class CellModel implements ICellModel {
if (result && result.data && result.data['text/html']) {
let model = (this as CellModel).options.notebook as NotebookModel;
if (model.activeConnection) {
let endpoint = this.getKnoxEndpoint(model.activeConnection);
let host = endpoint && endpoint.ipAddress ? endpoint.ipAddress : model.activeConnection.serverName;
let port = endpoint && endpoint.port ? ':' + endpoint.port.toString() : defaultPort;
let html = result.data['text/html'];
// CTP 3.1 and earlier Spark link
html = this.rewriteUrlUsingRegex(/(https?:\/\/master.*\/proxy)(.*)/g, html, host, port, yarnUi);
// CTP 3.2 and later spark link
html = this.rewriteUrlUsingRegex(/(https?:\/\/sparkhead.*\/proxy)(.*)/g, html, host, port, yarnUi);
// Driver link
html = this.rewriteUrlUsingRegex(/(https?:\/\/storage.*\/containerlogs)(.*)/g, html, host, port, driverLog);
(<nb.IDisplayResult>output).data['text/html'] = html;
let gatewayEndpointInfo = this.getGatewayEndpoint(model.activeConnection);
if (gatewayEndpointInfo) {
let hostAndIp = notebookUtils.getHostAndPortFromEndpoint(gatewayEndpointInfo.endpoint);
let host = gatewayEndpointInfo && hostAndIp.host ? hostAndIp.host : model.activeConnection.serverName;
let port = gatewayEndpointInfo && hostAndIp.port ? ':' + hostAndIp.port : defaultPort;
let html = result.data['text/html'];
// CTP 3.1 and earlier Spark link
html = this.rewriteUrlUsingRegex(/(https?:\/\/master.*\/proxy)(.*)/g, html, host, port, yarnUi);
// CTP 3.2 and later spark link
html = this.rewriteUrlUsingRegex(/(https?:\/\/sparkhead.*\/proxy)(.*)/g, html, host, port, yarnUi);
// Driver link
html = this.rewriteUrlUsingRegex(/(https?:\/\/storage.*\/containerlogs)(.*)/g, html, host, port, driverLog);
(<nb.IDisplayResult>output).data['text/html'] = html;
}
}
}
}
@@ -601,23 +605,21 @@ export class CellModel implements ICellModel {
// Get Knox endpoint from IConnectionProfile
// TODO: this will be refactored out into the notebooks extension as a contribution point
private getKnoxEndpoint(activeConnection: IConnectionProfile): notebookUtils.IEndpoint {
private getGatewayEndpoint(activeConnection: IConnectionProfile): notebookUtils.IEndpoint {
let endpoint;
if (this._connectionManagementService && activeConnection && activeConnection.providerName.toLowerCase() === notebookConstants.SQL_CONNECTION_PROVIDER.toLowerCase()) {
let serverInfo: ServerInfo = this._connectionManagementService.getServerInfo(activeConnection.id);
if (serverInfo && serverInfo.options && serverInfo.options['clusterEndpoints']) {
let endpoints: notebookUtils.IEndpoint[] = serverInfo.options['clusterEndpoints'];
if (serverInfo) {
let endpoints: notebookUtils.IEndpoint[] = notebookUtils.getClusterEndpoints(serverInfo);
if (endpoints && endpoints.length > 0) {
endpoint = endpoints.find(ep => {
let serviceName: string = ep.serviceName.toLowerCase();
return serviceName === 'knox' || serviceName === 'gateway';
});
endpoint = endpoints.find(ep => ep.serviceName.toLowerCase() === notebookUtils.hadoopEndpointNameGateway);
}
}
}
return endpoint;
}
private getMultilineSource(source: string | string[]): string | string[] {
if (typeof source === 'string') {
let sourceMultiline = source.split('\n');

View File

@@ -4,13 +4,16 @@
*--------------------------------------------------------------------------------------------*/
import * as path from 'vs/base/common/path';
import { nb } from 'azdata';
import { nb, ServerInfo } from 'azdata';
import { DEFAULT_NOTEBOOK_PROVIDER, DEFAULT_NOTEBOOK_FILETYPE, INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ICellModel } from 'sql/workbench/parts/notebook/common/models/modelInterfaces';
import { URI } from 'vs/base/common/uri';
export const clusterEndpointsProperty = 'clusterEndpoints';
export const hadoopEndpointNameGateway = 'gateway';
/**
* Test whether an output is from a stream.
*/
@@ -79,10 +82,12 @@ export interface IStandardKernelWithProvider {
readonly notebookProvider: string;
}
export interface IEndpoint {
serviceName: string;
ipAddress: string;
port: number;
description: string;
endpoint: string;
protocol: string;
}
export function tryMatchCellMagic(input: string): string {
@@ -125,3 +130,54 @@ export function convertVscodeResourceToFileInSubDirectories(htmlContent: string,
export function useInProcMarkdown(configurationService: IConfigurationService): boolean {
return configurationService.getValue('notebook.useInProcMarkdown');
}
export function getClusterEndpoints(serverInfo: ServerInfo): IEndpoint[] | undefined {
let endpoints: RawEndpoint[] = serverInfo.options[clusterEndpointsProperty];
if (!endpoints || endpoints.length === 0) { return []; }
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 = URI.parse(endpoint).authority;
let hostAndPortRegex = /^(.*)([,:](\d+))/g;
let match = hostAndPortRegex.exec(authority);
if (match) {
return {
host: match[1],
port: match[3]
};
}
return {
host: authority,
port: undefined
};
}
interface RawEndpoint {
serviceName: string;
description?: string;
endpoint?: string;
protocol?: string;
ipAddress?: string;
port?: number;
}
export interface IEndpoint {
serviceName: string;
description: string;
endpoint: string;
protocol: string;
}