|
@@ -18,14 +18,17 @@
|
|
|
|
|
|
package org.apache.hadoop.ozone.container.ozoneimpl;
|
|
|
|
|
|
-import org.apache.commons.io.IOUtils;
|
|
|
+import org.apache.commons.lang3.RandomUtils;
|
|
|
import org.apache.hadoop.fs.FileUtil;
|
|
|
import org.apache.hadoop.hdds.HddsConfigKeys;
|
|
|
import org.apache.hadoop.hdds.protocol.DatanodeDetails;
|
|
|
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
|
|
|
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
|
|
+import org.apache.hadoop.hdds.security.token.OzoneBlockTokenIdentifier;
|
|
|
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
|
|
|
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
|
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
|
|
+import org.apache.hadoop.ozone.client.CertificateClientTestImpl;
|
|
|
import org.apache.hadoop.ozone.container.ContainerTestHelper;
|
|
|
import org.apache.hadoop.hdds.scm.TestUtils;
|
|
|
import org.apache.hadoop.hdds.scm.XceiverClientGrpc;
|
|
@@ -33,13 +36,10 @@ import org.apache.hadoop.hdds.scm.XceiverClientSpi;
|
|
|
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
|
|
|
import org.apache.hadoop.ozone.container.common.statemachine.DatanodeStateMachine;
|
|
|
import org.apache.hadoop.ozone.container.common.statemachine.StateContext;
|
|
|
+import org.apache.hadoop.ozone.security.OzoneBlockTokenSecretManager;
|
|
|
+import org.apache.hadoop.security.token.Token;
|
|
|
import org.apache.hadoop.test.GenericTestUtils;
|
|
|
-import org.apache.hadoop.util.ThreadUtil;
|
|
|
-import org.junit.Assert;
|
|
|
-import org.junit.Before;
|
|
|
-import org.junit.Ignore;
|
|
|
-import org.junit.Rule;
|
|
|
-import org.junit.Test;
|
|
|
+import org.junit.*;
|
|
|
import org.junit.rules.TemporaryFolder;
|
|
|
import org.junit.rules.Timeout;
|
|
|
import org.junit.runner.RunWith;
|
|
@@ -49,13 +49,11 @@ import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.io.OutputStream;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Collection;
|
|
|
+import java.util.EnumSet;
|
|
|
import java.util.UUID;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_KEY_DIR_NAME;
|
|
|
import static org.apache.hadoop.hdds.HddsConfigKeys.HDDS_KEY_DIR_NAME_DEFAULT;
|
|
@@ -81,34 +79,24 @@ public class TestOzoneContainerWithTLS {
|
|
|
public TemporaryFolder tempFolder = new TemporaryFolder();
|
|
|
|
|
|
private OzoneConfiguration conf;
|
|
|
- private SecurityConfig secConfig;
|
|
|
- private Boolean requireMutualTls;
|
|
|
-
|
|
|
- public TestOzoneContainerWithTLS(Boolean requireMutualTls) {
|
|
|
- this.requireMutualTls = requireMutualTls;
|
|
|
+ private OzoneBlockTokenSecretManager secretManager;
|
|
|
+ private CertificateClientTestImpl caClient;
|
|
|
+ private boolean blockTokenEnabled;
|
|
|
|
|
|
+ public TestOzoneContainerWithTLS(boolean blockTokenEnabled) {
|
|
|
+ this.blockTokenEnabled = blockTokenEnabled;
|
|
|
}
|
|
|
|
|
|
@Parameterized.Parameters
|
|
|
- public static Collection<Object[]> encryptionOptions() {
|
|
|
+ public static Collection<Object[]> enableBlockToken() {
|
|
|
return Arrays.asList(new Object[][] {
|
|
|
- {true},
|
|
|
- {false}
|
|
|
+ {false},
|
|
|
+ {true}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- private void copyResource(String inputResourceName, File outputFile) throws
|
|
|
- IOException {
|
|
|
- InputStream is = ThreadUtil.getResourceAsStream(inputResourceName);
|
|
|
- try (OutputStream os = new FileOutputStream(outputFile)) {
|
|
|
- IOUtils.copy(is, os);
|
|
|
- } finally {
|
|
|
- IOUtils.closeQuietly(is);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
@Before
|
|
|
- public void setup() throws IOException{
|
|
|
+ public void setup() throws Exception {
|
|
|
conf = new OzoneConfiguration();
|
|
|
String ozoneMetaPath =
|
|
|
GenericTestUtils.getTempPath("ozoneMeta");
|
|
@@ -125,21 +113,24 @@ public class TestOzoneContainerWithTLS {
|
|
|
conf.setBoolean(HddsConfigKeys.HDDS_GRPC_TLS_ENABLED, true);
|
|
|
|
|
|
conf.setBoolean(HddsConfigKeys.HDDS_GRPC_TLS_TEST_CERT, true);
|
|
|
- secConfig = new SecurityConfig(conf);
|
|
|
|
|
|
- copyResource("ssl/ca.crt", secConfig.getTrustStoreFile());
|
|
|
- copyResource("ssl/server.pem", secConfig.getServerPrivateKeyFile());
|
|
|
- copyResource("ssl/client.pem", secConfig.getClientPrivateKeyFile());
|
|
|
- copyResource("ssl/client.crt", secConfig.getClientCertChainFile());
|
|
|
- copyResource("ssl/server.crt", secConfig.getServerCertChainFile());
|
|
|
+ long expiryTime = conf.getTimeDuration(
|
|
|
+ HddsConfigKeys.HDDS_BLOCK_TOKEN_EXPIRY_TIME,
|
|
|
+ HddsConfigKeys.HDDS_BLOCK_TOKEN_EXPIRY_TIME_DEFAULT,
|
|
|
+ TimeUnit.MILLISECONDS);
|
|
|
+
|
|
|
+ caClient = new CertificateClientTestImpl(conf);
|
|
|
+ secretManager = new OzoneBlockTokenSecretManager(new SecurityConfig(conf),
|
|
|
+ expiryTime, caClient.getCertificate().
|
|
|
+ getSerialNumber().toString());
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
public void testCreateOzoneContainer() throws Exception {
|
|
|
- LOG.info("testCreateOzoneContainer with Mutual TLS: {}",
|
|
|
- requireMutualTls);
|
|
|
- conf.setBoolean(HddsConfigKeys.HDDS_GRPC_MUTUAL_TLS_REQUIRED,
|
|
|
- requireMutualTls);
|
|
|
+ LOG.info("testCreateOzoneContainer with TLS and blockToken enabled: {}",
|
|
|
+ blockTokenEnabled);
|
|
|
+ conf.setBoolean(HddsConfigKeys.HDDS_BLOCK_TOKEN_ENABLED,
|
|
|
+ blockTokenEnabled);
|
|
|
|
|
|
long containerID = ContainerTestHelper.getTestContainerID();
|
|
|
OzoneContainer container = null;
|
|
@@ -154,13 +145,25 @@ public class TestOzoneContainerWithTLS {
|
|
|
conf.setBoolean(
|
|
|
OzoneConfigKeys.DFS_CONTAINER_IPC_RANDOM_PORT, false);
|
|
|
|
|
|
- container = new OzoneContainer(dn, conf, getContext(dn), null);
|
|
|
+ container = new OzoneContainer(dn, conf, getContext(dn), caClient);
|
|
|
//Set scmId and manually start ozone container.
|
|
|
container.start(UUID.randomUUID().toString());
|
|
|
|
|
|
- XceiverClientGrpc client = new XceiverClientGrpc(pipeline, conf);
|
|
|
- client.connect();
|
|
|
- createContainerForTesting(client, containerID);
|
|
|
+ XceiverClientGrpc client = new XceiverClientGrpc(pipeline, conf,
|
|
|
+ caClient.getCACertificate());
|
|
|
+
|
|
|
+ if (blockTokenEnabled) {
|
|
|
+ secretManager.start(caClient);
|
|
|
+ Token<OzoneBlockTokenIdentifier> token = secretManager.generateToken(
|
|
|
+ "123", EnumSet.allOf(
|
|
|
+ HddsProtos.BlockTokenSecretProto.AccessModeProto.class),
|
|
|
+ RandomUtils.nextLong());
|
|
|
+ client.connect(token.encodeToUrlString());
|
|
|
+ createSecureContainerForTesting(client, containerID, token);
|
|
|
+ } else {
|
|
|
+ createContainerForTesting(client, containerID);
|
|
|
+ client.connect();
|
|
|
+ }
|
|
|
} finally {
|
|
|
if (container != null) {
|
|
|
container.stop();
|
|
@@ -170,7 +173,6 @@ public class TestOzoneContainerWithTLS {
|
|
|
|
|
|
public static void createContainerForTesting(XceiverClientSpi client,
|
|
|
long containerID) throws Exception {
|
|
|
- // Create container
|
|
|
ContainerProtos.ContainerCommandRequestProto request =
|
|
|
ContainerTestHelper.getCreateContainerRequest(
|
|
|
containerID, client.getPipeline());
|
|
@@ -179,6 +181,18 @@ public class TestOzoneContainerWithTLS {
|
|
|
Assert.assertNotNull(response);
|
|
|
}
|
|
|
|
|
|
+ public static void createSecureContainerForTesting(XceiverClientSpi client,
|
|
|
+ long containerID, Token<OzoneBlockTokenIdentifier> token)
|
|
|
+ throws Exception {
|
|
|
+ ContainerProtos.ContainerCommandRequestProto request =
|
|
|
+ ContainerTestHelper.getCreateContainerSecureRequest(
|
|
|
+ containerID, client.getPipeline(), token);
|
|
|
+ ContainerProtos.ContainerCommandResponseProto response =
|
|
|
+ client.sendCommand(request);
|
|
|
+ Assert.assertNotNull(response);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
private StateContext getContext(DatanodeDetails datanodeDetails) {
|
|
|
DatanodeStateMachine stateMachine = Mockito.mock(
|
|
|
DatanodeStateMachine.class);
|