diff --git a/presto-docs/src/main/sphinx/connector/hive.rst b/presto-docs/src/main/sphinx/connector/hive.rst index 7b33d6199f338..d2ac68e51bee6 100644 --- a/presto-docs/src/main/sphinx/connector/hive.rst +++ b/presto-docs/src/main/sphinx/connector/hive.rst @@ -231,6 +231,10 @@ Property Name Description ``hive.metastore.glue.default-warehouse-dir`` Hive Glue metastore default warehouse directory +``hive.metastore.glue.aws-credentials-provider`` Fully qualified name of the Java class to use for obtaining + AWS credentials. Can be used to supply a custom credentials + provider. + ``hive.metastore.glue.aws-access-key`` AWS access key to use to connect to the Glue Catalog. If specified along with ``hive.metastore.glue.aws-secret-key``, this parameter takes precedence over diff --git a/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastore.java b/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastore.java index 7f8a8e3385519..bf1be516e1f71 100644 --- a/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastore.java +++ b/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastore.java @@ -18,6 +18,7 @@ import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider; import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; import com.amazonaws.metrics.RequestMetricCollector; @@ -137,6 +138,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.collect.Comparators.lexicographical; +import static java.lang.String.format; import static java.util.Comparator.comparing; import static java.util.Objects.requireNonNull; import static java.util.function.UnaryOperator.identity; @@ -204,19 +206,41 @@ else if (config.getPinGlueClientToCurrentRegion()) { } } + asyncGlueClientBuilder.setCredentials(getAwsCredentialsProvider(config)); + + return asyncGlueClientBuilder.build(); + } + + private static AWSCredentialsProvider getAwsCredentialsProvider(GlueHiveMetastoreConfig config) + { if (config.getAwsAccessKey().isPresent() && config.getAwsSecretKey().isPresent()) { - AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider( + return new AWSStaticCredentialsProvider( new BasicAWSCredentials(config.getAwsAccessKey().get(), config.getAwsSecretKey().get())); - asyncGlueClientBuilder.setCredentials(credentialsProvider); } - else if (config.getIamRole().isPresent()) { - AWSCredentialsProvider credentialsProvider = new STSAssumeRoleSessionCredentialsProvider + if (config.getIamRole().isPresent()) { + return new STSAssumeRoleSessionCredentialsProvider .Builder(config.getIamRole().get(), "roleSessionName") .build(); - asyncGlueClientBuilder.setCredentials(credentialsProvider); + } + if (config.getAwsCredentialsProvider().isPresent()) { + return getCustomAWSCredentialsProvider(config.getAwsCredentialsProvider().get()); } - return asyncGlueClientBuilder.build(); + return DefaultAWSCredentialsProviderChain.getInstance(); + } + + private static AWSCredentialsProvider getCustomAWSCredentialsProvider(String providerClass) + { + try { + Object instance = Class.forName(providerClass).getConstructor().newInstance(); + if (!(instance instanceof AWSCredentialsProvider)) { + throw new RuntimeException("Invalid credentials provider class: " + instance.getClass().getName()); + } + return (AWSCredentialsProvider) instance; + } + catch (ReflectiveOperationException e) { + throw new RuntimeException(format("Error creating an instance of %s", providerClass), e); + } } @Managed diff --git a/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastoreConfig.java b/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastoreConfig.java index d2f17a75492d4..7054934044a12 100644 --- a/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastoreConfig.java +++ b/presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/glue/GlueHiveMetastoreConfig.java @@ -36,6 +36,7 @@ public class GlueHiveMetastoreConfig private Optional iamRole = Optional.empty(); private Optional awsAccessKey = Optional.empty(); private Optional awsSecretKey = Optional.empty(); + private Optional awsCredentialsProvider = Optional.empty(); public Optional getGlueRegion() { @@ -197,4 +198,16 @@ public GlueHiveMetastoreConfig setAwsSecretKey(String awsSecretKey) this.awsSecretKey = Optional.ofNullable(awsSecretKey); return this; } + + public Optional getAwsCredentialsProvider() + { + return awsCredentialsProvider; + } + + @Config("hive.metastore.glue.aws-credentials-provider") + public GlueHiveMetastoreConfig setAwsCredentialsProvider(String awsCredentialsProvider) + { + this.awsCredentialsProvider = Optional.ofNullable(awsCredentialsProvider); + return this; + } } diff --git a/presto-hive-metastore/src/test/java/com/facebook/presto/hive/metastore/glue/TestGlueHiveMetastoreConfig.java b/presto-hive-metastore/src/test/java/com/facebook/presto/hive/metastore/glue/TestGlueHiveMetastoreConfig.java index b7b072bf14ebd..c8bcb31add072 100644 --- a/presto-hive-metastore/src/test/java/com/facebook/presto/hive/metastore/glue/TestGlueHiveMetastoreConfig.java +++ b/presto-hive-metastore/src/test/java/com/facebook/presto/hive/metastore/glue/TestGlueHiveMetastoreConfig.java @@ -39,7 +39,8 @@ public void testDefaults() .setGetPartitionThreads(20) .setIamRole(null) .setAwsAccessKey(null) - .setAwsSecretKey(null)); + .setAwsSecretKey(null) + .setAwsCredentialsProvider(null)); } @Test @@ -58,6 +59,8 @@ public void testExplicitPropertyMapping() .put("hive.metastore.glue.iam-role", "role") .put("hive.metastore.glue.aws-access-key", "ABC") .put("hive.metastore.glue.aws-secret-key", "DEF") + .put("hive.metastore.glue.aws-credentials-provider", "custom") + .put("hive.metastore.glue.use-instance-credentials", "true") .build(); GlueHiveMetastoreConfig expected = new GlueHiveMetastoreConfig() @@ -72,7 +75,8 @@ public void testExplicitPropertyMapping() .setGetPartitionThreads(42) .setIamRole("role") .setAwsAccessKey("ABC") - .setAwsSecretKey("DEF"); + .setAwsSecretKey("DEF") + .setAwsCredentialsProvider("custom"); assertFullMapping(properties, expected); }