Initial AD support for BDCs (#6741)

Partially working AD support for BDCs with some known issues
- Plumbed through kerberos support to Notebooks.
  - Using "gateway-0" for service temporarily as service endpoints API doesn't yet return correct DNS name. Will update in separate PR once available
- Plumbed kerberos auth to HDFS, Spark. Only partially working as we use same token on each call 
  - Will fix in separate PR, as this requires a refactor of WebHDFS library. Will need to either get new token every time or set a cookie, both of which require refactors
- Fixed error when Data Service node expansion failed and blocked all OE expansion
- Support for SqlToolsService change to use new cluster endpoints DMV
  -  Updated API to add new endpoints field to replace IP + port
  - Added logic to handle case where endpoints for Yarn, Grafana etc. are in the list
  - Sort list and use expected new localized strings

- Updated SqlToolsService to include support for new DMV
- Add "gateway-0" handling in Jupyter session as workaround for lack of domain names in endpoints list
This commit is contained in:
Kevin Cunnane
2019-08-14 18:09:41 -07:00
committed by GitHub
parent 4e8c06f36d
commit 52f8984a99
31 changed files with 639 additions and 189 deletions

View File

@@ -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; };
}
}