YARN-3725. App submission via REST API is broken in secure mode due to Timeline DT service address is empty. (Zhijie Shen via wangda)
(cherry picked from commit5cc3fced95
) (cherry picked from commita3734f67d3
) (cherry picked from commit 9ccc22e2ac89990f3e7997f1d89594523c66e76a)
This commit is contained in:
parent
1c6a287bf5
commit
ae0fac3efa
|
@ -150,6 +150,9 @@ Release 2.6.1 - UNRELEASED
|
||||||
YARN-2900. Application (Attempt and Container) Not Found in AHS results
|
YARN-2900. Application (Attempt and Container) Not Found in AHS results
|
||||||
in InternalServer Error (500). (Zhijie Shen and Mit Desai via xgong)
|
in InternalServer Error (500). (Zhijie Shen and Mit Desai via xgong)
|
||||||
|
|
||||||
|
YARN-3725. App submission via REST API is broken in secure mode due to
|
||||||
|
Timeline DT service address is empty. (Zhijie Shen via wangda)
|
||||||
|
|
||||||
Release 2.6.0 - 2014-11-18
|
Release 2.6.0 - 2014-11-18
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.io.IOException;
|
||||||
import java.lang.reflect.UndeclaredThrowableException;
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
|
@ -44,6 +45,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
||||||
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.security.SecurityUtil;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.security.authentication.client.AuthenticationException;
|
import org.apache.hadoop.security.authentication.client.AuthenticationException;
|
||||||
import org.apache.hadoop.security.authentication.client.ConnectionConfigurator;
|
import org.apache.hadoop.security.authentication.client.ConnectionConfigurator;
|
||||||
|
@ -362,6 +364,12 @@ public class TimelineClientImpl extends TimelineClient {
|
||||||
public long renewDelegationToken(
|
public long renewDelegationToken(
|
||||||
final Token<TimelineDelegationTokenIdentifier> timelineDT)
|
final Token<TimelineDelegationTokenIdentifier> timelineDT)
|
||||||
throws IOException, YarnException {
|
throws IOException, YarnException {
|
||||||
|
final boolean isTokenServiceAddrEmpty =
|
||||||
|
timelineDT.getService().toString().isEmpty();
|
||||||
|
final String scheme = isTokenServiceAddrEmpty ? null
|
||||||
|
: (YarnConfiguration.useHttps(this.getConfig()) ? "https" : "http");
|
||||||
|
final InetSocketAddress address = isTokenServiceAddrEmpty ? null
|
||||||
|
: SecurityUtil.getTokenServiceAddr(timelineDT);
|
||||||
PrivilegedExceptionAction<Long> renewDTAction =
|
PrivilegedExceptionAction<Long> renewDTAction =
|
||||||
new PrivilegedExceptionAction<Long>() {
|
new PrivilegedExceptionAction<Long>() {
|
||||||
|
|
||||||
|
@ -377,6 +385,11 @@ public class TimelineClientImpl extends TimelineClient {
|
||||||
DelegationTokenAuthenticatedURL authUrl =
|
DelegationTokenAuthenticatedURL authUrl =
|
||||||
new DelegationTokenAuthenticatedURL(authenticator,
|
new DelegationTokenAuthenticatedURL(authenticator,
|
||||||
connConfigurator);
|
connConfigurator);
|
||||||
|
// If the token service address is not available, fall back to use
|
||||||
|
// the configured service address.
|
||||||
|
final URI serviceURI = isTokenServiceAddrEmpty ? resURI
|
||||||
|
: new URI(scheme, null, address.getHostName(),
|
||||||
|
address.getPort(), RESOURCE_URI_STR, null, null);
|
||||||
return authUrl
|
return authUrl
|
||||||
.renewDelegationToken(resURI.toURL(), token, doAsUser);
|
.renewDelegationToken(resURI.toURL(), token, doAsUser);
|
||||||
}
|
}
|
||||||
|
@ -389,6 +402,12 @@ public class TimelineClientImpl extends TimelineClient {
|
||||||
public void cancelDelegationToken(
|
public void cancelDelegationToken(
|
||||||
final Token<TimelineDelegationTokenIdentifier> timelineDT)
|
final Token<TimelineDelegationTokenIdentifier> timelineDT)
|
||||||
throws IOException, YarnException {
|
throws IOException, YarnException {
|
||||||
|
final boolean isTokenServiceAddrEmpty =
|
||||||
|
timelineDT.getService().toString().isEmpty();
|
||||||
|
final String scheme = isTokenServiceAddrEmpty ? null
|
||||||
|
: (YarnConfiguration.useHttps(this.getConfig()) ? "https" : "http");
|
||||||
|
final InetSocketAddress address = isTokenServiceAddrEmpty ? null
|
||||||
|
: SecurityUtil.getTokenServiceAddr(timelineDT);
|
||||||
PrivilegedExceptionAction<Void> cancelDTAction =
|
PrivilegedExceptionAction<Void> cancelDTAction =
|
||||||
new PrivilegedExceptionAction<Void>() {
|
new PrivilegedExceptionAction<Void>() {
|
||||||
|
|
||||||
|
@ -404,7 +423,12 @@ public class TimelineClientImpl extends TimelineClient {
|
||||||
DelegationTokenAuthenticatedURL authUrl =
|
DelegationTokenAuthenticatedURL authUrl =
|
||||||
new DelegationTokenAuthenticatedURL(authenticator,
|
new DelegationTokenAuthenticatedURL(authenticator,
|
||||||
connConfigurator);
|
connConfigurator);
|
||||||
authUrl.cancelDelegationToken(resURI.toURL(), token, doAsUser);
|
// If the token service address is not available, fall back to use
|
||||||
|
// the configured service address.
|
||||||
|
final URI serviceURI = isTokenServiceAddrEmpty ? resURI
|
||||||
|
: new URI(scheme, null, address.getHostName(),
|
||||||
|
address.getPort(), RESOURCE_URI_STR, null, null);
|
||||||
|
authUrl.cancelDelegationToken(serviceURI.toURL(), token, doAsUser);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -240,12 +240,21 @@ public class TestTimelineAuthenticationFilter {
|
||||||
Assert.assertEquals(new Text(HTTP_USER), tDT.getOwner());
|
Assert.assertEquals(new Text(HTTP_USER), tDT.getOwner());
|
||||||
|
|
||||||
// Renew token
|
// Renew token
|
||||||
|
Assert.assertFalse(token.getService().toString().isEmpty());
|
||||||
|
// Renew the token from the token service address
|
||||||
long renewTime1 = httpUserClient.renewDelegationToken(token);
|
long renewTime1 = httpUserClient.renewDelegationToken(token);
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
token.setService(new Text());
|
||||||
|
Assert.assertTrue(token.getService().toString().isEmpty());
|
||||||
|
// If the token service address is not avaiable, it still can be renewed
|
||||||
|
// from the configured address
|
||||||
long renewTime2 = httpUserClient.renewDelegationToken(token);
|
long renewTime2 = httpUserClient.renewDelegationToken(token);
|
||||||
Assert.assertTrue(renewTime1 < renewTime2);
|
Assert.assertTrue(renewTime1 < renewTime2);
|
||||||
|
|
||||||
// Cancel token
|
// Cancel token
|
||||||
|
Assert.assertTrue(token.getService().toString().isEmpty());
|
||||||
|
// If the token service address is not avaiable, it still can be canceled
|
||||||
|
// from the configured address
|
||||||
httpUserClient.cancelDelegationToken(token);
|
httpUserClient.cancelDelegationToken(token);
|
||||||
// Renew should not be successful because the token is canceled
|
// Renew should not be successful because the token is canceled
|
||||||
try {
|
try {
|
||||||
|
@ -280,6 +289,8 @@ public class TestTimelineAuthenticationFilter {
|
||||||
Assert.assertTrue(renewTime1 < renewTime2);
|
Assert.assertTrue(renewTime1 < renewTime2);
|
||||||
|
|
||||||
// Cancel token
|
// Cancel token
|
||||||
|
Assert.assertFalse(tokenToRenew.getService().toString().isEmpty());
|
||||||
|
// Cancel the token from the token service address
|
||||||
fooUserClient.cancelDelegationToken(tokenToRenew);
|
fooUserClient.cancelDelegationToken(tokenToRenew);
|
||||||
|
|
||||||
// Renew should not be successful because the token is canceled
|
// Renew should not be successful because the token is canceled
|
||||||
|
|
Loading…
Reference in New Issue