From f0bdc422aa7093f5a5c1e3cc5c9fa57f4c1205d5 Mon Sep 17 00:00:00 2001 From: Szilard Nemeth Date: Sat, 12 Jun 2021 15:18:41 +0200 Subject: [PATCH] YARN-10816. Avoid doing delegation token ops when yarn.timeline-service.http-authentication.type=simple. Contributed by Tarun Parimi --- .../client/api/impl/TimelineClientImpl.java | 25 ++++++++++++ .../client/api/impl/TestTimelineClient.java | 39 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/client/api/impl/TimelineClientImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/client/api/impl/TimelineClientImpl.java index 07b41c3f6b..eda38c5191 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/client/api/impl/TimelineClientImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/client/api/impl/TimelineClientImpl.java @@ -29,6 +29,7 @@ import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler; +import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.hadoop.classification.InterfaceAudience.Private; @@ -88,6 +89,7 @@ public class TimelineClientImpl extends TimelineClient { private TimelineWriter timelineWriter; private String timelineServiceAddress; + private String authType; @Private @VisibleForTesting @@ -128,6 +130,12 @@ protected void serviceInit(Configuration conf) throws Exception { conf.get(YarnConfiguration.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()); super.serviceInit(conf); } @@ -193,6 +201,12 @@ private String getTimelineServiceAddress() { @Override public Token getDelegationToken( 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> getDTAction = new PrivilegedExceptionAction>() { @@ -219,6 +233,12 @@ public Token run() public long renewDelegationToken( final Token timelineDT) 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 = timelineDT.getService().toString().isEmpty(); final String scheme = isTokenServiceAddrEmpty ? null @@ -257,6 +277,11 @@ public Long run() throws Exception { public void cancelDelegationToken( final Token timelineDT) throws IOException, YarnException { + if(authType.equals(PseudoAuthenticationHandler.TYPE)) { + LOG.info("Skipping cancel timeline delegation token since authType=" + + PseudoAuthenticationHandler.TYPE); + return; + } final boolean isTokenServiceAddrEmpty = timelineDT.getService().toString().isEmpty(); final String scheme = isTokenServiceAddrEmpty ? null diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestTimelineClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestTimelineClient.java index 4d9c320673..e7110dda9f 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestTimelineClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestTimelineClient.java @@ -22,6 +22,7 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; 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 identifierToken = + tClient.getDelegationToken( + UserGroupInformation.getCurrentUser().getShortUserName()); + // Get a null token when using simple auth + Assert.assertNull(identifierToken); + + // try renew a delegation token + Token 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() { Assert.fail("Exception expected! " + "Timeline server should be off to run this test.");