Browse Source

HADOOP-16565. Region must be provided when requesting session credentials or SdkClientException will be thrown (#1454). Contributed by Gabor Bota.

Gabor Bota 5 years ago
parent
commit
e97f0f1ed9

+ 23 - 9
hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/MarshalledCredentialBinding.java

@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 import com.amazonaws.ClientConfiguration;
+import com.amazonaws.SdkClientException;
 import com.amazonaws.auth.AWSCredentials;
 import com.amazonaws.auth.AWSCredentialsProvider;
 import com.amazonaws.auth.AWSSessionCredentials;
@@ -33,6 +34,8 @@ import com.amazonaws.auth.BasicSessionCredentials;
 import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
 import com.amazonaws.services.securitytoken.model.Credentials;
 import com.google.common.annotations.VisibleForTesting;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.s3a.Invoker;
@@ -53,6 +56,9 @@ import static org.apache.hadoop.fs.s3a.S3AUtils.lookupPassword;
  */
 public final class MarshalledCredentialBinding {
 
+  private static final Logger LOG =
+      LoggerFactory.getLogger(MarshalledCredentialBinding.class);
+
   private MarshalledCredentialBinding() {
   }
 
@@ -194,15 +200,23 @@ public final class MarshalledCredentialBinding {
       final String stsRegion,
       final int duration,
       final Invoker invoker) throws IOException {
-    final AWSSecurityTokenService tokenService =
-        STSClientFactory.builder(parentCredentials,
-            awsConf,
-            stsEndpoint.isEmpty() ? null : stsEndpoint,
-            stsRegion)
-            .build();
-    return fromSTSCredentials(
-        STSClientFactory.createClientConnection(tokenService, invoker)
-            .requestSessionCredentials(duration, TimeUnit.SECONDS));
+    try {
+      final AWSSecurityTokenService tokenService =
+          STSClientFactory.builder(parentCredentials,
+              awsConf,
+              stsEndpoint.isEmpty() ? null : stsEndpoint,
+              stsRegion)
+              .build();
+      return fromSTSCredentials(
+          STSClientFactory.createClientConnection(tokenService, invoker)
+              .requestSessionCredentials(duration, TimeUnit.SECONDS));
+    } catch (SdkClientException e) {
+      if (stsRegion.isEmpty()) {
+        LOG.error("Region must be provided when requesting session credentials.",
+            e);
+      }
+      throw e;
+    }
   }
 
 }

+ 22 - 0
hadoop-tools/hadoop-aws/src/site/markdown/tools/hadoop-aws/troubleshooting_s3a.md

@@ -419,6 +419,28 @@ When trying to write or read SEE-KMS-encrypted data, the client gets a
 The caller does not have the permissions to access
 the key with which the data was encrypted.
 
+### <a name="no_region_session_credentials"></a> "Unable to find a region via the region provider chain." when using session credentials.
+
+Region must be provided when requesting session credentials, or an exception will be thrown with the message:
+```
+com.amazonaws.SdkClientException: Unable to find a region via the region provider
+chain. Must provide an explicit region in the builder or setup environment to supply a region.
+```
+In this case you have to set the `fs.s3a.assumed.role.sts.endpoint` property to a valid
+S3 sts endpoint and region like the following:
+
+```xml
+<property>
+    <name>fs.s3a.assumed.role.sts.endpoint</name>
+    <value>${sts.endpoint}</value>
+</property>
+<property>
+    <name>fs.s3a.assumed.role.sts.endpoint.region</name>
+    <value>${sts.region}</value>
+</property>
+```
+
+
 ## <a name="connectivity"></a> Connectivity Problems
 
 ### <a name="bad_endpoint"></a> Error message "The bucket you are attempting to access must be addressed using the specified endpoint"