YARN-10816. Avoid doing delegation token ops when yarn.timeline-service.http-authentication.type=simple. Contributed by Tarun Parimi

This commit is contained in:
Szilard Nemeth 2021-06-12 15:18:41 +02:00
parent 7003997e36
commit f0bdc422aa
2 changed files with 64 additions and 0 deletions

View File

@ -29,6 +29,7 @@
import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options; import org.apache.commons.cli.Options;
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler; import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHandler;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.classification.InterfaceAudience.Private;
@ -88,6 +89,7 @@ public class TimelineClientImpl extends TimelineClient {
private TimelineWriter timelineWriter; private TimelineWriter timelineWriter;
private String timelineServiceAddress; private String timelineServiceAddress;
private String authType;
@Private @Private
@VisibleForTesting @VisibleForTesting
@ -128,6 +130,12 @@ protected void serviceInit(Configuration conf) throws Exception {
conf.get(YarnConfiguration.TIMELINE_SERVICE_WEBAPP_ADDRESS, conf.get(YarnConfiguration.TIMELINE_SERVICE_WEBAPP_ADDRESS,
YarnConfiguration.DEFAULT_TIMELINE_SERVICE_WEBAPP_ADDRESS); YarnConfiguration.DEFAULT_TIMELINE_SERVICE_WEBAPP_ADDRESS);
} }
String defaultAuth = UserGroupInformation.isSecurityEnabled() ?
KerberosAuthenticationHandler.TYPE :
PseudoAuthenticationHandler.TYPE;
authType = conf.get(YarnConfiguration.TIMELINE_HTTP_AUTH_TYPE,
defaultAuth);
LOG.info("Timeline service address: " + getTimelineServiceAddress()); LOG.info("Timeline service address: " + getTimelineServiceAddress());
super.serviceInit(conf); super.serviceInit(conf);
} }
@ -193,6 +201,12 @@ private String getTimelineServiceAddress() {
@Override @Override
public Token<TimelineDelegationTokenIdentifier> getDelegationToken( public Token<TimelineDelegationTokenIdentifier> getDelegationToken(
final String renewer) throws IOException, YarnException { final String renewer) throws IOException, YarnException {
if(authType.equals(PseudoAuthenticationHandler.TYPE)) {
LOG.info("Skipping get timeline delegation token since authType="
+ PseudoAuthenticationHandler.TYPE);
// Null tokens are ignored by YarnClient so this is safe
return null;
}
PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>> PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>>
getDTAction = getDTAction =
new PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>>() { new PrivilegedExceptionAction<Token<TimelineDelegationTokenIdentifier>>() {
@ -219,6 +233,12 @@ public Token<TimelineDelegationTokenIdentifier> run()
public long renewDelegationToken( public long renewDelegationToken(
final Token<TimelineDelegationTokenIdentifier> timelineDT) final Token<TimelineDelegationTokenIdentifier> timelineDT)
throws IOException, YarnException { throws IOException, YarnException {
if(authType.equals(PseudoAuthenticationHandler.TYPE)) {
LOG.info("Skipping renew timeline delegation token since authType="
+ PseudoAuthenticationHandler.TYPE);
// RM will skip renew if expirytime less than 0
return -1;
}
final boolean isTokenServiceAddrEmpty = final boolean isTokenServiceAddrEmpty =
timelineDT.getService().toString().isEmpty(); timelineDT.getService().toString().isEmpty();
final String scheme = isTokenServiceAddrEmpty ? null final String scheme = isTokenServiceAddrEmpty ? null
@ -257,6 +277,11 @@ public Long run() throws Exception {
public void cancelDelegationToken( public void cancelDelegationToken(
final Token<TimelineDelegationTokenIdentifier> timelineDT) final Token<TimelineDelegationTokenIdentifier> timelineDT)
throws IOException, YarnException { throws IOException, YarnException {
if(authType.equals(PseudoAuthenticationHandler.TYPE)) {
LOG.info("Skipping cancel timeline delegation token since authType="
+ PseudoAuthenticationHandler.TYPE);
return;
}
final boolean isTokenServiceAddrEmpty = final boolean isTokenServiceAddrEmpty =
timelineDT.getService().toString().isEmpty(); timelineDT.getService().toString().isEmpty();
final String scheme = isTokenServiceAddrEmpty ? null final String scheme = isTokenServiceAddrEmpty ? null

View File

@ -22,6 +22,7 @@
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@ -316,6 +317,44 @@ public void testDelegationTokenOperationsRetry() throws Exception {
} }
} }
/**
* Test actual delegation token operations are not carried out when
* simple auth is configured for timeline.
* @throws Exception
*/
@Test
public void testDelegationTokenDisabledOnSimpleAuth() throws Exception {
YarnConfiguration conf = new YarnConfiguration();
conf.setBoolean(YarnConfiguration.TIMELINE_SERVICE_ENABLED, true);
conf.set(YarnConfiguration.TIMELINE_HTTP_AUTH_TYPE, "simple");
UserGroupInformation.setConfiguration(conf);
TimelineClientImpl tClient = createTimelineClient(conf);
TimelineConnector spyConnector = spy(tClient.connector);
tClient.connector = spyConnector;
try {
// try getting a delegation token
Token<TimelineDelegationTokenIdentifier> identifierToken =
tClient.getDelegationToken(
UserGroupInformation.getCurrentUser().getShortUserName());
// Get a null token when using simple auth
Assert.assertNull(identifierToken);
// try renew a delegation token
Token<TimelineDelegationTokenIdentifier> dummyToken = new Token<>();
long renewTime = tClient.renewDelegationToken(dummyToken);
// Get invalid expiration time so that RM skips renewal
Assert.assertEquals(renewTime, -1);
// try cancel a delegation token
tClient.cancelDelegationToken(dummyToken);
// Shouldn't try to cancel and connect to authURL
verify(spyConnector, never()).getDelegationTokenAuthenticatedURL();
} finally {
tClient.stop();
}
}
private static void assertFail() { private static void assertFail() {
Assert.fail("Exception expected! " Assert.fail("Exception expected! "
+ "Timeline server should be off to run this test."); + "Timeline server should be off to run this test.");