|
@@ -17,13 +17,12 @@
|
|
|
|
|
|
package org.apache.hadoop.yarn.server.resourcemanager;
|
|
|
|
|
|
-import static org.junit.Assert.assertTrue;
|
|
|
-import static org.junit.Assert.fail;
|
|
|
-import static org.mockito.Mockito.doReturn;
|
|
|
-import static org.mockito.Mockito.mock;
|
|
|
+import static org.junit.Assert.*;
|
|
|
+import static org.mockito.Mockito.*;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.lang.reflect.UndeclaredThrowableException;
|
|
|
+import java.net.InetAddress;
|
|
|
import java.net.InetSocketAddress;
|
|
|
import java.security.PrivilegedAction;
|
|
|
import java.security.PrivilegedExceptionAction;
|
|
@@ -34,9 +33,15 @@ import org.apache.commons.logging.Log;
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
|
|
|
+import org.apache.hadoop.io.Text;
|
|
|
import org.apache.hadoop.ipc.RPC;
|
|
|
+import org.apache.hadoop.ipc.Server;
|
|
|
+import org.apache.hadoop.security.SecurityUtil;
|
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
|
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
|
|
|
+import org.apache.hadoop.security.token.SecretManager;
|
|
|
+import org.apache.hadoop.security.token.Token;
|
|
|
+import org.apache.hadoop.security.token.TokenIdentifier;
|
|
|
import org.apache.hadoop.yarn.api.ClientRMProtocol;
|
|
|
import org.apache.hadoop.yarn.api.protocolrecords.CancelDelegationTokenRequest;
|
|
|
import org.apache.hadoop.yarn.api.protocolrecords.GetDelegationTokenRequest;
|
|
@@ -46,12 +51,14 @@ import org.apache.hadoop.yarn.api.records.DelegationToken;
|
|
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
|
|
import org.apache.hadoop.yarn.exceptions.YarnRemoteException;
|
|
|
import org.apache.hadoop.yarn.ipc.YarnRPC;
|
|
|
+import org.apache.hadoop.yarn.security.client.RMDelegationTokenIdentifier;
|
|
|
import org.apache.hadoop.yarn.server.RMDelegationTokenSecretManager;
|
|
|
import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
|
|
|
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
|
|
import org.apache.hadoop.yarn.util.BuilderUtils;
|
|
|
import org.apache.hadoop.yarn.util.ProtoUtils;
|
|
|
import org.apache.hadoop.yarn.util.Records;
|
|
|
+import org.junit.Before;
|
|
|
import org.junit.Test;
|
|
|
|
|
|
|
|
@@ -59,6 +66,10 @@ public class TestClientRMTokens {
|
|
|
|
|
|
private static final Log LOG = LogFactory.getLog(TestClientRMTokens.class);
|
|
|
|
|
|
+ @Before
|
|
|
+ public void resetSecretManager() {
|
|
|
+ RMDelegationTokenIdentifier.Renewer.setSecretManager(null, null);
|
|
|
+ }
|
|
|
|
|
|
@Test
|
|
|
public void testDelegationToken() throws IOException, InterruptedException {
|
|
@@ -200,7 +211,122 @@ public class TestClientRMTokens {
|
|
|
RPC.stopProxy(clientRMWithDT);
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testShortCircuitRenewCancel()
|
|
|
+ throws IOException, InterruptedException {
|
|
|
+ InetSocketAddress addr =
|
|
|
+ new InetSocketAddress(InetAddress.getLocalHost(), 123);
|
|
|
+ checkShortCircuitRenewCancel(addr, addr, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testShortCircuitRenewCancelWildcardAddress()
|
|
|
+ throws IOException, InterruptedException {
|
|
|
+ InetSocketAddress rmAddr = new InetSocketAddress(123);
|
|
|
+ checkShortCircuitRenewCancel(
|
|
|
+ rmAddr,
|
|
|
+ new InetSocketAddress(InetAddress.getLocalHost(), rmAddr.getPort()),
|
|
|
+ true);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testShortCircuitRenewCancelSameHostDifferentPort()
|
|
|
+ throws IOException, InterruptedException {
|
|
|
+ InetSocketAddress rmAddr =
|
|
|
+ new InetSocketAddress(InetAddress.getLocalHost(), 123);
|
|
|
+ checkShortCircuitRenewCancel(
|
|
|
+ rmAddr,
|
|
|
+ new InetSocketAddress(rmAddr.getAddress(), rmAddr.getPort()+1),
|
|
|
+ false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testShortCircuitRenewCancelDifferentHostSamePort()
|
|
|
+ throws IOException, InterruptedException {
|
|
|
+ InetSocketAddress rmAddr =
|
|
|
+ new InetSocketAddress(InetAddress.getLocalHost(), 123);
|
|
|
+ checkShortCircuitRenewCancel(
|
|
|
+ rmAddr,
|
|
|
+ new InetSocketAddress("1.1.1.1", rmAddr.getPort()),
|
|
|
+ false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testShortCircuitRenewCancelDifferentHostDifferentPort()
|
|
|
+ throws IOException, InterruptedException {
|
|
|
+ InetSocketAddress rmAddr =
|
|
|
+ new InetSocketAddress(InetAddress.getLocalHost(), 123);
|
|
|
+ checkShortCircuitRenewCancel(
|
|
|
+ rmAddr,
|
|
|
+ new InetSocketAddress("1.1.1.1", rmAddr.getPort()+1),
|
|
|
+ false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ private void checkShortCircuitRenewCancel(InetSocketAddress rmAddr,
|
|
|
+ InetSocketAddress serviceAddr,
|
|
|
+ boolean shouldShortCircuit
|
|
|
+ ) throws IOException, InterruptedException {
|
|
|
+ Configuration conf = new Configuration();
|
|
|
+ conf.setClass(YarnConfiguration.IPC_RPC_IMPL,
|
|
|
+ YarnBadRPC.class, YarnRPC.class);
|
|
|
|
|
|
+ RMDelegationTokenSecretManager secretManager =
|
|
|
+ mock(RMDelegationTokenSecretManager.class);
|
|
|
+ RMDelegationTokenIdentifier.Renewer.setSecretManager(secretManager, rmAddr);
|
|
|
+
|
|
|
+ RMDelegationTokenIdentifier ident = new RMDelegationTokenIdentifier(
|
|
|
+ new Text("owner"), new Text("renewer"), null);
|
|
|
+ Token<RMDelegationTokenIdentifier> token =
|
|
|
+ new Token<RMDelegationTokenIdentifier>(ident, secretManager);
|
|
|
+
|
|
|
+ SecurityUtil.setTokenService(token, serviceAddr);
|
|
|
+ if (shouldShortCircuit) {
|
|
|
+ token.renew(conf);
|
|
|
+ verify(secretManager).renewToken(eq(token), eq("renewer"));
|
|
|
+ reset(secretManager);
|
|
|
+ token.cancel(conf);
|
|
|
+ verify(secretManager).cancelToken(eq(token), eq("renewer"));
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ token.renew(conf);
|
|
|
+ fail();
|
|
|
+ } catch (RuntimeException e) {
|
|
|
+ assertEquals("getProxy", e.getMessage());
|
|
|
+ }
|
|
|
+ verify(secretManager, never()).renewToken(any(Token.class), anyString());
|
|
|
+ try {
|
|
|
+ token.cancel(conf);
|
|
|
+ fail();
|
|
|
+ } catch (RuntimeException e) {
|
|
|
+ assertEquals("getProxy", e.getMessage());
|
|
|
+ }
|
|
|
+ verify(secretManager, never()).cancelToken(any(Token.class), anyString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("rawtypes")
|
|
|
+ public static class YarnBadRPC extends YarnRPC {
|
|
|
+ @Override
|
|
|
+ public Object getProxy(Class protocol, InetSocketAddress addr,
|
|
|
+ Configuration conf) {
|
|
|
+ throw new RuntimeException("getProxy");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void stopProxy(Object proxy, Configuration conf) {
|
|
|
+ throw new RuntimeException("stopProxy");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Server getServer(Class protocol, Object instance,
|
|
|
+ InetSocketAddress addr, Configuration conf,
|
|
|
+ SecretManager<? extends TokenIdentifier> secretManager,
|
|
|
+ int numHandlers, String portRangeConfig) {
|
|
|
+ throw new RuntimeException("getServer");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// Get the delegation token directly as it is a little difficult to setup
|