mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Fixes for HDFS node expansion on BDC connections (#14174)
* Change cluster test connect to use endpoints route * Add more logging * More logging * Only connect to controller if needed * Add comments
This commit is contained in:
@@ -159,17 +159,36 @@ export class ClusterController implements IClusterController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that this cluster supports Kerberos authentication. It does this by sending a request to the Token API route
|
||||||
|
* without any credentials and verifying that it gets a 401 response back with a Negotiate www-authenticate header.
|
||||||
|
*/
|
||||||
private async verifyKerberosSupported(): Promise<boolean> {
|
private async verifyKerberosSupported(): Promise<boolean> {
|
||||||
let tokenApi = new TokenRouterApi(this._url);
|
let tokenApi = new TokenRouterApi(this._url);
|
||||||
tokenApi.setDefaultAuthentication(new SslAuth());
|
tokenApi.setDefaultAuthentication(new SslAuth());
|
||||||
try {
|
try {
|
||||||
await tokenApi.apiV1TokenPost();
|
await tokenApi.apiV1TokenPost();
|
||||||
// If we get to here, the route for endpoints doesn't require auth so state this is false
|
console.warn(`Token API returned success without any auth while verifying Kerberos support for BDC Cluster ${this._url}`);
|
||||||
|
// If we get to here, the route for tokens doesn't require auth which is an unexpected error state
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
let auths = error && error.response && error.response.statusCode === 401 && error.response.headers['www-authenticate'];
|
if (!error.response) {
|
||||||
return auths && auths.includes('Negotiate');
|
console.warn(`No response when verifying Kerberos support for BDC Cluster ${this._url} - ${error}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.response.statusCode !== 401) {
|
||||||
|
console.warn(`Got unexpected status code ${error.response.statusCode} when verifying Kerberos support for BDC Cluster ${this._url}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auths = error.response.headers['www-authenticate'] as string[] ?? [];
|
||||||
|
if (auths.includes('Negotiate')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.warn(`Didn't get expected Negotiate auth type when verifying Kerberos support for BDC Cluster ${this.url}. Supported types : ${auths.join(', ')}`);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,6 +107,12 @@ async function createSqlClusterConnInfo(sqlConnInfo: azdata.IConnectionProfile |
|
|||||||
options: {}
|
options: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// We need to populate some extra information here in order to be able to browse the HDFS nodes.
|
||||||
|
// First - if the auth type isn't integrated auth then we need to try and find the username to connect
|
||||||
|
// to the knox endpoint with.
|
||||||
|
// Next we need the knox endpoint - if we didn't get that from the SQL instance (because the user didn't have permissions
|
||||||
|
// to see the full DMV usually) then we need to connect to the controller to fetch the full list of endpoints and get it
|
||||||
|
// that way.
|
||||||
let clusterController: bdc.IClusterController | undefined = undefined;
|
let clusterController: bdc.IClusterController | undefined = undefined;
|
||||||
let authType = clusterConnInfo.options[constants.authenticationTypePropName] = sqlConnInfo.options[constants.authenticationTypePropName];
|
let authType = clusterConnInfo.options[constants.authenticationTypePropName] = sqlConnInfo.options[constants.authenticationTypePropName];
|
||||||
const controllerEndpoint = endpoints.find(ep => ep.name.toLowerCase() === 'controller');
|
const controllerEndpoint = endpoints.find(ep => ep.name.toLowerCase() === 'controller');
|
||||||
@@ -129,12 +135,11 @@ async function createSqlClusterConnInfo(sqlConnInfo: azdata.IConnectionProfile |
|
|||||||
console.log(`Unexpected error getting Knox username for SQL Cluster connection: ${err}`);
|
console.log(`Unexpected error getting Knox username for SQL Cluster connection: ${err}`);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
clusterController = await getClusterController(controllerEndpoint.endpoint, clusterConnInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let hadoopEndpointIndex = endpoints.findIndex(ep => ep.name.toLowerCase() === constants.hadoopEndpointNameGateway.toLowerCase());
|
let hadoopEndpointIndex = endpoints.findIndex(ep => ep.name.toLowerCase() === constants.hadoopEndpointNameGateway.toLowerCase());
|
||||||
if (hadoopEndpointIndex < 0) {
|
if (hadoopEndpointIndex < 0) {
|
||||||
|
clusterController = await getClusterController(controllerEndpoint.endpoint, clusterConnInfo);
|
||||||
endpoints = (await clusterController.getEndPoints()).endPoints;
|
endpoints = (await clusterController.getEndPoints()).endPoints;
|
||||||
hadoopEndpointIndex = endpoints.findIndex(ep => ep.name.toLowerCase() === constants.hadoopEndpointNameGateway.toLowerCase());
|
hadoopEndpointIndex = endpoints.findIndex(ep => ep.name.toLowerCase() === constants.hadoopEndpointNameGateway.toLowerCase());
|
||||||
}
|
}
|
||||||
@@ -156,7 +161,8 @@ async function getClusterController(controllerEndpoint: string, connInfo: Connec
|
|||||||
connInfo.options[constants.userPropName],
|
connInfo.options[constants.userPropName],
|
||||||
connInfo.options[constants.passwordPropName]);
|
connInfo.options[constants.passwordPropName]);
|
||||||
try {
|
try {
|
||||||
await controller.getClusterConfig();
|
// We just want to test the connection - so using getEndpoints since that is available to all users (not just admin)
|
||||||
|
await controller.getEndPoints();
|
||||||
return controller;
|
return controller;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Initial username/password failed so prompt user for username password until either user
|
// Initial username/password failed so prompt user for username password until either user
|
||||||
@@ -187,7 +193,8 @@ async function getClusterController(controllerEndpoint: string, connInfo: Connec
|
|||||||
}
|
}
|
||||||
const controller = bdcApi.getClusterController(controllerEndpoint, authType, username, password);
|
const controller = bdcApi.getClusterController(controllerEndpoint, authType, username, password);
|
||||||
try {
|
try {
|
||||||
await controller.getClusterConfig();
|
// We just want to test the connection - so using getEndpoints since that is available to all users (not just admin)
|
||||||
|
await controller.getEndPoints();
|
||||||
// Update our connection with the new info
|
// Update our connection with the new info
|
||||||
connInfo.options[constants.userPropName] = username;
|
connInfo.options[constants.userPropName] = username;
|
||||||
connInfo.options[constants.passwordPropName] = password;
|
connInfo.options[constants.passwordPropName] = password;
|
||||||
|
|||||||
@@ -395,7 +395,8 @@ async function getClusterController(controllerEndpoint: string, authType: bdc.Au
|
|||||||
username,
|
username,
|
||||||
password);
|
password);
|
||||||
try {
|
try {
|
||||||
await controller.getClusterConfig();
|
// We just want to test the connection - so using getEndpoints since that is available to all users (not just admin)
|
||||||
|
await controller.getEndPoints();
|
||||||
return controller;
|
return controller;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Initial username/password failed so prompt user for username password until either user
|
// Initial username/password failed so prompt user for username password until either user
|
||||||
@@ -426,7 +427,8 @@ async function getClusterController(controllerEndpoint: string, authType: bdc.Au
|
|||||||
}
|
}
|
||||||
const controller = bdcApi.getClusterController(controllerEndpoint, authType, newUsername, newPassword);
|
const controller = bdcApi.getClusterController(controllerEndpoint, authType, newUsername, newPassword);
|
||||||
try {
|
try {
|
||||||
await controller.getClusterConfig();
|
// We just want to test the connection - so using getEndpoints since that is available to all users (not just admin)
|
||||||
|
await controller.getEndPoints();
|
||||||
return controller;
|
return controller;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
errorMessage = localize('bdcConnectError', "Error: {0}. ", err.message ?? err);
|
errorMessage = localize('bdcConnectError', "Error: {0}. ", err.message ?? err);
|
||||||
|
|||||||
Reference in New Issue
Block a user