mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
Re-add AD auth for SQL big data cluster (#6759)
* Revert "Revert "Initial AD support for BDCs (#6741)" as it breaks linux (#6758)"
This reverts commit 51660b25ef.
* Install kerberos package on linux
This commit is contained in:
@@ -14,6 +14,7 @@ steps:
|
||||
sudo chmod +x /etc/init.d/xvfb
|
||||
sudo update-rc.d xvfb defaults
|
||||
sudo service xvfb start
|
||||
sudo apt-get install -y libkrb5-dev
|
||||
# sh -e /etc/init.d/xvfb start
|
||||
# sleep 3
|
||||
displayName: 'Linux preinstall'
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"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",
|
||||
@@ -947,5 +948,8 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/kerberos": "^1.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||
"version": "2.0.0-release.2",
|
||||
"version": "2.0.0-release.4",
|
||||
"downloadFileNames": {
|
||||
"Windows_86": "win-x86-netcoreapp2.2.zip",
|
||||
"Windows_64": "win-x64-netcoreapp2.2.zip",
|
||||
|
||||
@@ -13,9 +13,10 @@ 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';
|
||||
@@ -26,8 +27,6 @@ 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;
|
||||
|
||||
@@ -8,46 +8,74 @@ import * as azdata from 'azdata';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import * as Utils from '../utils';
|
||||
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];
|
||||
|
||||
export function registerServiceEndpoints(context: vscode.ExtensionContext): void {
|
||||
azdata.ui.registerModelViewProvider('bdc-endpoints', async (view) => {
|
||||
let endpointsArray: Array<utils.IEndpoint> = Object.assign([], utils.getClusterEndpoints(view.serverInfo));
|
||||
|
||||
const endpointsArray: Array<Utils.IEndpoint> = Object.assign([], view.serverInfo.options['clusterEndpoints']);
|
||||
endpointsArray.forEach(endpointInfo => {
|
||||
endpointInfo.hyperlink = 'https://' + endpointInfo.ipAddress + ':' + endpointInfo.port;
|
||||
|
||||
});
|
||||
if (endpointsArray.length > 0) {
|
||||
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'));
|
||||
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 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'));
|
||||
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'));
|
||||
}
|
||||
}
|
||||
|
||||
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<azdata.TextComponentProperties>({ value: getFriendlyEndpointNames(endpointInfo.serviceName) }).component();
|
||||
const nameCell = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: endpointInfo.description }).component();
|
||||
endPointRow.addItem(nameCell, { CSSStyles: { 'width': '35%', 'font-weight': '600', 'user-select': 'text' } });
|
||||
if (endpointInfo.isHyperlink) {
|
||||
const linkCell = view.modelBuilder.hyperlink().withProperties<azdata.HyperlinkComponentProperties>({ label: endpointInfo.hyperlink, url: endpointInfo.hyperlink }).component();
|
||||
if (hyperlinkedEndpoints.findIndex(e => e === endpointInfo.serviceName) >= 0) {
|
||||
const linkCell = view.modelBuilder.hyperlink().withProperties<azdata.HyperlinkComponentProperties>({ label: endpointInfo.endpoint, url: endpointInfo.endpoint }).component();
|
||||
endPointRow.addItem(linkCell, { CSSStyles: { 'width': '62%', 'color': '#0078d4', 'text-decoration': 'underline', 'padding-top': '10px' } });
|
||||
}
|
||||
else {
|
||||
const endpointCell = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: endpointInfo.ipAddress + ':' + endpointInfo.port }).component();
|
||||
const endpointCell = view.modelBuilder.text().withProperties<azdata.TextComponentProperties>({ value: endpointInfo.endpoint }).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.hyperlink);
|
||||
vscode.env.clipboard.writeText(endpointInfo.endpoint);
|
||||
});
|
||||
copyValueCell.title = localize("copyText", "Copy");
|
||||
copyValueCell.iconHeight = '14px';
|
||||
@@ -64,40 +92,57 @@ export function registerServiceEndpoints(context: vscode.ExtensionContext): void
|
||||
});
|
||||
}
|
||||
|
||||
function getCustomEndpoint(parentEndpoint: Utils.IEndpoint, serviceName: string, serviceUrl?: string): Utils.IEndpoint {
|
||||
function getCustomEndpoint(parentEndpoint: utils.IEndpoint, serviceName: string, description: string, serviceUrl?: string): utils.IEndpoint {
|
||||
if (parentEndpoint) {
|
||||
let endpoint: Utils.IEndpoint = {
|
||||
let endpoint: utils.IEndpoint = {
|
||||
serviceName: serviceName,
|
||||
ipAddress: parentEndpoint.ipAddress,
|
||||
port: parentEndpoint.port,
|
||||
isHyperlink: serviceUrl ? true : false,
|
||||
hyperlink: 'https://' + parentEndpoint.ipAddress + ':' + parentEndpoint.port + serviceUrl
|
||||
description: description,
|
||||
endpoint: parentEndpoint.endpoint + serviceUrl,
|
||||
protocol: 'https'
|
||||
};
|
||||
return endpoint;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getFriendlyEndpointNames(name: string): string {
|
||||
let friendlyName: string = name;
|
||||
switch (name) {
|
||||
function getFriendlyEndpointNames(endpointInfo: utils.IEndpoint): string {
|
||||
let friendlyName: string = endpointInfo.description || endpointInfo.serviceName;
|
||||
switch (endpointInfo.serviceName) {
|
||||
case 'app-proxy':
|
||||
friendlyName = localize("appproxy", "Application Proxy");
|
||||
friendlyName = localize('approxy.description', "Application Proxy");
|
||||
break;
|
||||
case 'controller':
|
||||
friendlyName = localize("controller", "Cluster Management Service");
|
||||
friendlyName = localize('controller.description', "Cluster Management Service");
|
||||
break;
|
||||
case 'gateway':
|
||||
friendlyName = localize("gateway", "HDFS and Spark");
|
||||
friendlyName = localize('gateway.description', "HDFS and Spark");
|
||||
break;
|
||||
case 'management-proxy':
|
||||
friendlyName = localize("managementproxy", "Management Proxy");
|
||||
case mgmtProxyName:
|
||||
friendlyName = localize('mgmtproxy.description', "Management Proxy");
|
||||
break;
|
||||
case 'mgmtproxy':
|
||||
friendlyName = localize("mgmtproxy", "Management Proxy");
|
||||
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");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return friendlyName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ 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];
|
||||
@@ -35,7 +34,6 @@ 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; }
|
||||
@@ -50,7 +48,7 @@ export class SqlClusterConnection {
|
||||
.every(e => options1[e] === options2[e]);
|
||||
}
|
||||
|
||||
public createHdfsFileSource(): IFileSource {
|
||||
public async createHdfsFileSource(): Promise<IFileSource> {
|
||||
let options: IHdfsOptions = {
|
||||
protocol: 'https',
|
||||
host: this.host,
|
||||
@@ -58,13 +56,24 @@ export class SqlClusterConnection {
|
||||
user: this.user,
|
||||
path: 'gateway/default/webhdfs/v1',
|
||||
requestParams: {
|
||||
auth: {
|
||||
user: this.user,
|
||||
pass: this.password
|
||||
}
|
||||
}
|
||||
};
|
||||
return FileSourceFactory.instance.createHdfsFileSource(options);
|
||||
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;
|
||||
}
|
||||
|
||||
public updatePassword(password: string): void {
|
||||
@@ -90,10 +99,12 @@ export class SqlClusterConnection {
|
||||
|
||||
private getMissingProperties(connectionInfo: azdata.ConnectionInfo): string[] {
|
||||
if (!connectionInfo || !connectionInfo.options) { return undefined; }
|
||||
return [
|
||||
constants.hostPropName, constants.knoxPortPropName,
|
||||
constants.userPropName, constants.passwordPropName
|
||||
].filter(e => connectionInfo.options[e] === 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);
|
||||
}
|
||||
|
||||
private toConnection(connProfile: azdata.IConnectionProfile): azdata.connection.Connection {
|
||||
@@ -101,18 +112,4 @@ 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(<azdata.IConnectionProfile>{},
|
||||
connectionInfo,
|
||||
{
|
||||
serverName: `${options[constants.hostPropName]},${options[constants.knoxPortPropName]}`,
|
||||
userName: options[constants.userPropName],
|
||||
password: options[constants.passwordPropName],
|
||||
id: connectionInfo.connectionId,
|
||||
}
|
||||
);
|
||||
return connProfile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ 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();
|
||||
|
||||
@@ -84,11 +85,13 @@ 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 {
|
||||
@@ -106,10 +109,10 @@ export class FileSourceFactory {
|
||||
return FileSourceFactory._instance;
|
||||
}
|
||||
|
||||
public createHdfsFileSource(options: IHdfsOptions): IFileSource {
|
||||
public async createHdfsFileSource(options: IHdfsOptions): Promise<IFileSource> {
|
||||
options = options && options.host ? FileSourceFactory.removePortFromHost(options) : options;
|
||||
let requestParams: IRequestParams = options.requestParams ? options.requestParams : {};
|
||||
if (requestParams.auth) {
|
||||
if (requestParams.auth || requestParams.isKerberos) {
|
||||
// TODO Remove handling of unsigned cert once we have real certs in our Knox service
|
||||
let agentOptions = {
|
||||
host: options.host,
|
||||
@@ -119,6 +122,11 @@ 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));
|
||||
}
|
||||
|
||||
@@ -63,9 +63,9 @@ export class HdfsProvider implements vscode.TreeDataProvider<TreeNode>, ITreeCha
|
||||
}
|
||||
}
|
||||
|
||||
addHdfsConnection(options: IHdfsOptions): void {
|
||||
public async addHdfsConnection(options: IHdfsOptions): Promise<void> {
|
||||
let displayName = `${options.user}@${options.host}:${options.port}`;
|
||||
let fileSource = FileSourceFactory.instance.createHdfsFileSource(options);
|
||||
let fileSource = await FileSourceFactory.instance.createHdfsFileSource(options);
|
||||
this.addConnection(displayName, fileSource);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
node.updateFileSource(session.sqlClusterConnection);
|
||||
await 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,22 +325,27 @@ class DataServicesNode extends TreeNode {
|
||||
|
||||
public getChildren(refreshChildren: boolean): TreeNode[] | Promise<TreeNode[]> {
|
||||
if (refreshChildren || !this._children) {
|
||||
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.refreshChildren();
|
||||
}
|
||||
return this._children;
|
||||
}
|
||||
|
||||
private async refreshChildren(): Promise<TreeNode[]> {
|
||||
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<vscode.TreeItem> {
|
||||
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,
|
||||
@@ -352,4 +357,4 @@ class DataServicesNode extends TreeNode {
|
||||
};
|
||||
return nodeInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,8 +78,8 @@ export abstract class TreeNode implements ITreeNode {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public updateFileSource(connection: SqlClusterConnection): void {
|
||||
this.fileSource = connection.createHdfsFileSource();
|
||||
public async updateFileSource(connection: SqlClusterConnection): Promise<void> {
|
||||
this.fileSource = await connection.createHdfsFileSource();
|
||||
}
|
||||
/**
|
||||
* The value to use for this node in the node path
|
||||
|
||||
@@ -482,15 +482,17 @@ export class WebHDFS {
|
||||
|
||||
let stream = undefined;
|
||||
let canResume: boolean = true;
|
||||
let params = Object.assign(
|
||||
let params: any = 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)
|
||||
|
||||
@@ -147,7 +147,7 @@ export class SparkJobSubmissionModel {
|
||||
return Promise.reject(LocalizedConstants.sparkJobSubmissionLocalFileNotExisted(localFilePath));
|
||||
}
|
||||
|
||||
let fileSource: IFileSource = this._sqlClusterConnection.createHdfsFileSource();
|
||||
let fileSource: IFileSource = await 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 = this._sqlClusterConnection.createHdfsFileSource();
|
||||
let fileSource: IFileSource = await this._sqlClusterConnection.createHdfsFileSource();
|
||||
return await fileSource.exists(path);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
|
||||
@@ -11,6 +11,7 @@ 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;
|
||||
@@ -28,6 +29,10 @@ export class SparkJobSubmissionService {
|
||||
public async submitBatchJob(submissionArgs: SparkJobSubmissionInput): Promise<string> {
|
||||
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',
|
||||
@@ -41,9 +46,7 @@ export class SparkJobSubmissionService {
|
||||
name: submissionArgs.jobName
|
||||
},
|
||||
// authentication headers
|
||||
headers: {
|
||||
'Authorization': 'Basic ' + Buffer.from(submissionArgs.user + ':' + submissionArgs.password).toString('base64')
|
||||
}
|
||||
headers: headers
|
||||
};
|
||||
|
||||
// Set arguments
|
||||
@@ -90,18 +93,30 @@ 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<LivyLogResponse> {
|
||||
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: {
|
||||
'Authorization': 'Basic ' + Buffer.from(submissionArgs.user + ':' + submissionArgs.password).toString('base64')
|
||||
}
|
||||
headers: headers
|
||||
};
|
||||
|
||||
const response = await this._requestPromise(options);
|
||||
@@ -145,7 +160,8 @@ export class SparkJobSubmissionInput {
|
||||
this._port = sqlClusterConnection.port;
|
||||
this._livyPath = constants.mssqlClusterLivySubmitPath;
|
||||
this._user = sqlClusterConnection.user;
|
||||
this._passWord = sqlClusterConnection.password;
|
||||
this._password = sqlClusterConnection.password;
|
||||
this._isIntegratedAuth = sqlClusterConnection.isIntegratedAuth();
|
||||
}
|
||||
|
||||
constructor(
|
||||
@@ -160,7 +176,8 @@ export class SparkJobSubmissionInput {
|
||||
private _port?: number,
|
||||
private _livyPath?: string,
|
||||
private _user?: string,
|
||||
private _passWord?: string) {
|
||||
private _password?: string,
|
||||
private _isIntegratedAuth?: boolean) {
|
||||
}
|
||||
|
||||
public get jobName(): string { return this._jobName; }
|
||||
@@ -174,7 +191,8 @@ 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 password(): string { return this._password; }
|
||||
public get isIntegratedAuth(): boolean { return this._isIntegratedAuth; }
|
||||
}
|
||||
|
||||
export enum SparkFileSource {
|
||||
|
||||
@@ -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 ((<azdata.ConnectionInfo>connection).options && (<azdata.ConnectionInfo>connection).options['host']) {
|
||||
return (<azdata.ConnectionInfo>connection).options['host'].split(',')[0].split(':')[0];
|
||||
if ((<azdata.ConnectionInfo>connection).options && (<azdata.ConnectionInfo>connection).options[constants.hostPropName]) {
|
||||
return (<azdata.ConnectionInfo>connection).options[constants.hostPropName].split(',')[0].split(':')[0];
|
||||
} else if ((<azdata.ConnectionInfo>connection).options && (<azdata.ConnectionInfo>connection).options['server']) {
|
||||
return (<azdata.ConnectionInfo>connection).options['server'].split(',')[0].split(':')[0];
|
||||
} else {
|
||||
|
||||
@@ -11,10 +11,9 @@ 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 } from './utils';
|
||||
import { IEndpoint, getClusterEndpoints, getHostAndPortFromEndpoint } from './utils';
|
||||
import { MssqlObjectExplorerNodeProvider } from './objectExplorerNodeProvider/objectExplorerNodeProvider';
|
||||
|
||||
|
||||
export function findSqlClusterConnection(
|
||||
obj: ICommandObjectExplorerContext | azdata.IConnectionProfile,
|
||||
appContext: AppContext): SqlClusterConnection {
|
||||
@@ -76,14 +75,10 @@ async function createSqlClusterConnInfo(sqlConnInfo: azdata.IConnectionProfile |
|
||||
let serverInfo = await azdata.connection.getServerInfo(connectionId);
|
||||
if (!serverInfo || !serverInfo.options) { return undefined; }
|
||||
|
||||
let endpoints: IEndpoint[] = serverInfo.options[constants.clusterEndpointsProperty];
|
||||
let endpoints: IEndpoint[] = getClusterEndpoints(serverInfo);
|
||||
if (!endpoints || endpoints.length === 0) { return undefined; }
|
||||
|
||||
let index = endpoints.findIndex(ep => {
|
||||
let serviceName: string = ep.serviceName.toLowerCase();
|
||||
return serviceName === constants.hadoopEndpointNameKnox.toLowerCase() ||
|
||||
serviceName === constants.hadoopEndpointNameGateway.toLowerCase();
|
||||
});
|
||||
let index = endpoints.findIndex(ep => ep.serviceName.toLowerCase() === constants.hadoopEndpointNameGateway.toLowerCase());
|
||||
if (index < 0) { return undefined; }
|
||||
|
||||
let credentials = await azdata.connection.getCredentials(connectionId);
|
||||
@@ -95,15 +90,27 @@ async function createSqlClusterConnInfo(sqlConnInfo: azdata.IConnectionProfile |
|
||||
options: {}
|
||||
};
|
||||
|
||||
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;
|
||||
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 = connToConnectionParam(clusterConnInfo);
|
||||
|
||||
return clusterConnInfo;
|
||||
}
|
||||
|
||||
|
||||
function connProfileToConnectionParam(connectionProfile: azdata.IConnectionProfile): ConnectionParam {
|
||||
let result = Object.assign(connectionProfile, { connectionId: connectionProfile.id });
|
||||
return <ConnectionParam>result;
|
||||
@@ -118,6 +125,7 @@ function connToConnectionParam(connection: azdata.connection.Connection): Connec
|
||||
userName: options[constants.userPropName],
|
||||
password: options[constants.passwordPropName],
|
||||
id: connectionId,
|
||||
authenticationType: options[constants.authenticationTypePropName]
|
||||
}
|
||||
);
|
||||
return <ConnectionParam>result;
|
||||
@@ -141,4 +149,4 @@ class ConnectionParam implements azdata.connection.Connection, azdata.IConnectio
|
||||
public connectionId: string;
|
||||
|
||||
public options: { [name: string]: any; };
|
||||
}
|
||||
}
|
||||
|
||||
14
extensions/mssql/src/util/auth.ts
Normal file
14
extensions/mssql/src/util/auth.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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<string> {
|
||||
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;
|
||||
}
|
||||
@@ -232,36 +232,55 @@ export function getUserHome(): string {
|
||||
return process.env.HOME || process.env.USERPROFILE;
|
||||
}
|
||||
|
||||
export async function getClusterEndpoint(profileId: string, serviceName: string): Promise<IEndpoint> {
|
||||
export function getClusterEndpoints(serverInfo: azdata.ServerInfo): IEndpoint[] | undefined {
|
||||
let endpoints: RawEndpoint[] = serverInfo.options[constants.clusterEndpointsProperty];
|
||||
if (!endpoints || endpoints.length === 0) { return []; }
|
||||
|
||||
let serverInfo: azdata.ServerInfo = await azdata.connection.getServerInfo(profileId);
|
||||
if (!serverInfo || !serverInfo.options) {
|
||||
return undefined;
|
||||
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 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
|
||||
return {
|
||||
host: authority,
|
||||
port: undefined
|
||||
};
|
||||
return clusterEndpoint;
|
||||
}
|
||||
|
||||
interface RawEndpoint {
|
||||
serviceName: string;
|
||||
description?: string;
|
||||
endpoint?: string;
|
||||
protocol?: string;
|
||||
ipAddress?: string;
|
||||
port?: number;
|
||||
}
|
||||
|
||||
export interface IEndpoint {
|
||||
serviceName: string;
|
||||
ipAddress: string;
|
||||
port: number;
|
||||
isHyperlink: boolean;
|
||||
hyperlink: string;
|
||||
description: string;
|
||||
endpoint: string;
|
||||
protocol: string;
|
||||
}
|
||||
|
||||
export function isValidNumber(maybeNumber: any) {
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
# 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"
|
||||
@@ -19,6 +24,16 @@ 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"
|
||||
@@ -28,6 +43,19 @@ 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"
|
||||
@@ -72,6 +100,13 @@ 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"
|
||||
@@ -139,6 +174,16 @@ 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"
|
||||
@@ -158,6 +203,11 @@ 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"
|
||||
@@ -190,6 +240,13 @@ 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"
|
||||
@@ -243,11 +300,26 @@ 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"
|
||||
@@ -268,7 +340,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.0.0, end-of-stream@^1.1.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==
|
||||
@@ -304,6 +376,11 @@ 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"
|
||||
@@ -358,6 +435,11 @@ 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"
|
||||
@@ -404,6 +486,20 @@ 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"
|
||||
@@ -419,6 +515,11 @@ 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"
|
||||
@@ -454,6 +555,11 @@ 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"
|
||||
@@ -497,6 +603,11 @@ 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"
|
||||
@@ -507,6 +618,18 @@ 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"
|
||||
@@ -569,6 +692,15 @@ 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"
|
||||
@@ -593,6 +725,11 @@ 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"
|
||||
@@ -605,6 +742,11 @@ 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"
|
||||
@@ -622,23 +764,65 @@ 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.0.1, object-assign@^4.1.0:
|
||||
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.4.0:
|
||||
once@^1.3.0, once@^1.3.1, 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"
|
||||
@@ -681,6 +865,28 @@ 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"
|
||||
@@ -691,6 +897,22 @@ 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"
|
||||
@@ -706,7 +928,17 @@ qs@~6.5.2:
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
readable-stream@^2.1.4, readable-stream@^2.3.0, readable-stream@^2.3.5:
|
||||
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:
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
|
||||
integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
|
||||
@@ -791,6 +1023,11 @@ 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"
|
||||
@@ -807,6 +1044,30 @@ 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"
|
||||
@@ -834,6 +1095,23 @@ 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"
|
||||
@@ -841,6 +1119,20 @@ 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"
|
||||
@@ -848,7 +1140,22 @@ strip-dirs@^2.0.0:
|
||||
dependencies:
|
||||
is-natural-number "^4.0.1"
|
||||
|
||||
tar-stream@^1.5.2:
|
||||
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:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
|
||||
integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
|
||||
@@ -984,6 +1291,18 @@ 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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,10 +55,11 @@ 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 {
|
||||
@@ -242,13 +243,19 @@ 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_KNOX) ||
|
||||
await this.getClusterEndpoint(connection.id, KNOX_ENDPOINT_GATEWAY);
|
||||
let clusterEndpoint: utils.IEndpoint = 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.")));
|
||||
}
|
||||
connection.options[KNOX_ENDPOINT_SERVER] = clusterEndpoint.ipAddress;
|
||||
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_PORT] = clusterEndpoint.port;
|
||||
connection.options[USER] = DEFAULT_CLUSTER_USER_NAME;
|
||||
}
|
||||
@@ -259,8 +266,9 @@ 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 =
|
||||
`%_do_not_call_change_endpoint --username=${connection.options[USER]} --password=${connection.options['password']} --server=${server} --auth=Basic_Access`;
|
||||
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 future = this.sessionImpl.kernel.requestExecute({
|
||||
code: doNotCallChangeEndpointParams
|
||||
}, true);
|
||||
@@ -268,6 +276,10 @@ 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;
|
||||
}
|
||||
@@ -330,4 +342,4 @@ interface ISparkMagicConfig {
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">Dashboard für Protokollsuche</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Überwachung von Spark-Aufträgen</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -674,7 +674,7 @@
|
||||
<trans-unit id="kibana">
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="yarnHistory">
|
||||
@@ -773,4 +773,4 @@
|
||||
<source xml:lang="en">No Sql Server big data cluster found.</source>
|
||||
</trans-unit>
|
||||
</body></file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">Panel de búsqueda de registros</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Supervisión de trabajos de Spark</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">Tableau de bord de recherche dans les journaux</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Supervision du travail Spark</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">Dashboard di ricerca log</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Monitoraggio processi Spark</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">ログ検索ダッシュボード</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Spark ジョブの監視</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">로그 검색 대시보드</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Spark 작업 모니터링</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">Painel de Pesquisa de Logs</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Monitoramento de trabalho do Spark</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">Панель мониторинга поиска по журналам</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Мониторинг заданий Spark</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">日志搜索仪表板</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Spark 作业监视</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -922,7 +922,7 @@
|
||||
<source xml:lang="en">Log Search Dashboard</source>
|
||||
<target state="translated">記錄搜尋儀表板</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sparkHostory">
|
||||
<trans-unit id="sparkHistory">
|
||||
<source xml:lang="en">Spark Job Monitoring</source>
|
||||
<target state="translated">Spark 作業監視</target>
|
||||
</trans-unit>
|
||||
@@ -1056,4 +1056,4 @@
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
|
||||
@@ -124,6 +124,8 @@ 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;
|
||||
@@ -231,19 +233,18 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
if (session && session.success) {
|
||||
this.handleSessionCreated(session);
|
||||
} else {
|
||||
let errorMessage = session && session.errorMessage ? session.errorMessage :
|
||||
nls.localize('OeSessionFailedError', "Failed to create Object Explorer session");
|
||||
let errorMessage = session && session.errorMessage ? session.errorMessage : errSessionCreateFailed;
|
||||
this.logService.error(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private async handleSessionCreated(session: azdata.ObjectExplorerSession): Promise<void> {
|
||||
try {
|
||||
let connection: ConnectionProfile = undefined;
|
||||
let errorMessage: string = undefined;
|
||||
if (this._sessions[session.sessionId]) {
|
||||
connection = this._sessions[session.sessionId].connection;
|
||||
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;
|
||||
@@ -251,8 +252,7 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
this._activeObjectExplorerNodes[connection.id] = server;
|
||||
}
|
||||
else {
|
||||
errorMessage = session && session.errorMessage ? session.errorMessage :
|
||||
nls.localize('OeSessionFailedError', "Failed to create Object Explorer session");
|
||||
errorMessage = session && session.errorMessage ? session.errorMessage : errSessionCreateFailed;
|
||||
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<boolean>[] = 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}`);
|
||||
}
|
||||
|
||||
this.sendUpdateNodeEvent(connection, errorMessage);
|
||||
} catch (error) {
|
||||
this.logService.warn(`cannot handle the session ${session.sessionId} in all nodeProviders`);
|
||||
}
|
||||
else {
|
||||
this.logService.warn(`cannot find session ${session.sessionId}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user