mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-14 18:46:34 -05:00
Fix HDFS support for CU5+ BDC instances (#10577)
* Fix HDFS node auth for non-root username * more changes
This commit is contained in:
@@ -194,7 +194,7 @@ export function isEditorTitleFree(title: string): boolean {
|
||||
return !hasTextDoc && !hasNotebookDoc;
|
||||
}
|
||||
|
||||
export function getClusterEndpoints(serverInfo: azdata.ServerInfo): IEndpoint[] | undefined {
|
||||
export function getClusterEndpoints(serverInfo: azdata.ServerInfo): IEndpoint[] {
|
||||
let endpoints: RawEndpoint[] = serverInfo.options['clusterEndpoints'];
|
||||
if (!endpoints || endpoints.length === 0) { return []; }
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ const localize = nls.loadMessageBundle();
|
||||
import { JupyterKernel } from './jupyterKernel';
|
||||
import { Deferred } from '../common/promise';
|
||||
import { JupyterServerInstallation } from './jupyterServerInstallation';
|
||||
import * as bdc from 'bdc';
|
||||
|
||||
const configBase = {
|
||||
'kernel_python_credentials': {
|
||||
@@ -56,11 +57,11 @@ const configBase = {
|
||||
const KNOX_ENDPOINT_SERVER = 'host';
|
||||
const KNOX_ENDPOINT_PORT = 'knoxport';
|
||||
const KNOX_ENDPOINT_GATEWAY = 'gateway';
|
||||
const CONTROLLER_ENDPOINT = 'controller';
|
||||
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 {
|
||||
private _ready: Deferred<void>;
|
||||
@@ -272,34 +273,50 @@ export class JupyterSession implements nb.ISession {
|
||||
await fs.writeFile(configFilePath, JSON.stringify(config));
|
||||
}
|
||||
|
||||
public async configureConnection(connection: IConnectionProfile): Promise<void> {
|
||||
if (connection && connection.providerName && this.isSparkKernel(this.sessionImpl.kernel.name)) {
|
||||
// TODO may need to reenable a way to get the credential
|
||||
// await this._connection.getCredential();
|
||||
public async configureConnection(connectionProfile: IConnectionProfile): Promise<void> {
|
||||
if (connectionProfile && connectionProfile.providerName && this.isSparkKernel(this.sessionImpl.kernel.name)) {
|
||||
// %_do_not_call_change_endpoint is a SparkMagic command that lets users change endpoint options,
|
||||
// such as user/profile/host name/auth type
|
||||
|
||||
//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);
|
||||
if (!clusterEndpoint) {
|
||||
if (connectionProfile.providerName === SQL_PROVIDER) {
|
||||
const endpoints = await this.getClusterEndpoints(connectionProfile.id);
|
||||
const gatewayEndpoint: utils.IEndpoint = endpoints?.find(ep => ep.serviceName.toLowerCase() === KNOX_ENDPOINT_GATEWAY);
|
||||
if (!gatewayEndpoint) {
|
||||
return Promise.reject(new Error(localize('connectionNotValid', "Spark kernels require a connection to a SQL Server Big Data Cluster master instance.")));
|
||||
}
|
||||
let hostAndPort = utils.getHostAndPortFromEndpoint(clusterEndpoint.endpoint);
|
||||
connection.options[KNOX_ENDPOINT_SERVER] = hostAndPort.host;
|
||||
connection.options[KNOX_ENDPOINT_PORT] = hostAndPort.port;
|
||||
connection.options[USER] = DEFAULT_CLUSTER_USER_NAME;
|
||||
let gatewayHostAndPort = utils.getHostAndPortFromEndpoint(gatewayEndpoint.endpoint);
|
||||
connectionProfile.options[KNOX_ENDPOINT_SERVER] = gatewayHostAndPort.host;
|
||||
connectionProfile.options[KNOX_ENDPOINT_PORT] = gatewayHostAndPort.port;
|
||||
// root is the default username for pre-CU5 instances, so while we prefer to use the connection username
|
||||
// as a default now we'll still fall back to root if it's empty for some reason. (but the calls below should
|
||||
// get the actual correct value regardless)
|
||||
connectionProfile.options[USER] = connectionProfile.userName || 'root';
|
||||
|
||||
try {
|
||||
const bdcApi = <bdc.IExtension>await vscode.extensions.getExtension(bdc.constants.extensionName).activate();
|
||||
const controllerEndpoint = endpoints.find(ep => ep.serviceName.toLowerCase() === CONTROLLER_ENDPOINT);
|
||||
const controller = bdcApi.getClusterController(controllerEndpoint.endpoint, 'basic', connectionProfile.userName, connectionProfile.password);
|
||||
connectionProfile.options[USER] = await controller.getKnoxUsername(connectionProfile.userName);
|
||||
} catch (err) {
|
||||
console.log(`Unexpected error getting Knox username for Spark kernel: ${err}`);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
connection.options[KNOX_ENDPOINT_PORT] = this.getKnoxPortOrDefault(connection);
|
||||
connectionProfile.options[KNOX_ENDPOINT_PORT] = this.getKnoxPortOrDefault(connectionProfile);
|
||||
}
|
||||
this.setHostAndPort(':', connection);
|
||||
this.setHostAndPort(',', connection);
|
||||
this.setHostAndPort(':', connectionProfile);
|
||||
this.setHostAndPort(',', connectionProfile);
|
||||
|
||||
let server = vscode.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 server = vscode.Uri.parse(utils.getLivyUrl(connectionProfile.options[KNOX_ENDPOINT_SERVER], connectionProfile.options[KNOX_ENDPOINT_PORT])).toString();
|
||||
let doNotCallChangeEndpointParams: string;
|
||||
if (this.isIntegratedAuth(connectionProfile)) {
|
||||
doNotCallChangeEndpointParams = `%_do_not_call_change_endpoint --server=${server} --auth=Kerberos`;
|
||||
} else {
|
||||
const credentials = await connection.getCredentials(connectionProfile.id);
|
||||
doNotCallChangeEndpointParams = `%_do_not_call_change_endpoint --username=${connectionProfile.options[USER]} --password=${credentials.password} --server=${server} --auth=Basic_Access`;
|
||||
}
|
||||
let future = this.sessionImpl.kernel.requestExecute({
|
||||
code: doNotCallChangeEndpointParams
|
||||
}, true);
|
||||
@@ -348,16 +365,12 @@ export class JupyterSession implements nb.ISession {
|
||||
return port;
|
||||
}
|
||||
|
||||
private async getClusterEndpoint(profileId: string, serviceName: string): Promise<utils.IEndpoint> {
|
||||
private async getClusterEndpoints(profileId: string): Promise<utils.IEndpoint[]> {
|
||||
let serverInfo: ServerInfo = await connection.getServerInfo(profileId);
|
||||
if (!serverInfo || !serverInfo.options) {
|
||||
return undefined;
|
||||
return [];
|
||||
}
|
||||
let endpoints: utils.IEndpoint[] = utils.getClusterEndpoints(serverInfo);
|
||||
if (!endpoints || endpoints.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return endpoints.find(ep => ep.serviceName.toLowerCase() === serviceName.toLowerCase());
|
||||
return utils.getClusterEndpoints(serverInfo);
|
||||
}
|
||||
|
||||
private async setEnvironmentVars(skip: boolean = false): Promise<void> {
|
||||
|
||||
1
extensions/notebook/src/typings/refs.d.ts
vendored
1
extensions/notebook/src/typings/refs.d.ts
vendored
@@ -6,4 +6,5 @@
|
||||
/// <reference path='../../../../src/sql/azdata.d.ts'/>
|
||||
/// <reference path='../../../../src/sql/azdata.proposed.d.ts'/>
|
||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path='../../../big-data-cluster/src/bdc.d.ts'/>
|
||||
/// <reference types='@types/node'/>
|
||||
|
||||
Reference in New Issue
Block a user