Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get PrestoS3FileSystem to work with the AWS Default Credentials Provider #741

Merged
merged 1 commit into from
Jun 28, 2019
Merged

Conversation

anoopj
Copy link
Member

@anoopj anoopj commented May 10, 2019

DefaultAWSCredentialsProviderChain is frequently used by AWS customers
and it provides access from a documented list of sources. This
especially makes it easier to run Presto on non-EC2 hosts where you
don't have the instance profile. (e.g. Macs, during development). This
change also makes PrestoS3FileSystem to be consistent with the Glue connector
in Presto.

See:
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html

Fixes #625

}

throw new RuntimeException("S3 credentials not configured");
return Optional.empty();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not com.amazonaws.auth.DefaultAWSCredentialsProviderChain#getInstance?
Then you perhaps wouldn't need the other changes, like making it Optional.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this to be consistent with the Glue client, but can make this change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This is what the client does internally:

private AWSCredentialsProvider resolveCredentials() {
    return (credentials == null) ? DefaultAWSCredentialsProviderChain.getInstance() : credentials;
}

Not setting credentials results in it being null.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I will get rid of the Optional.

@@ -155,7 +156,7 @@ public void testAssumeRoleCredentials()
}
}

@Test(expectedExceptions = RuntimeException.class, expectedExceptionsMessageRegExp = "S3 credentials not configured")
@Test
public void testInstanceCredentialsDisabled()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename the test method to eg testDefaultCredentials.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

@cla-bot cla-bot bot added the cla-signed label May 10, 2019
@trinodb trinodb deleted a comment from martint May 10, 2019
@trinodb trinodb deleted a comment from cla-bot bot May 10, 2019
@trinodb trinodb deleted a comment from cla-bot bot May 10, 2019
Copy link
Member

@electrum electrum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks good. We need to make the same change in PrestoS3ClientFactory so that it works for S3 select (unfortunately it's a different code path).

@@ -243,8 +243,11 @@ public void close()
{
try (Closer closer = Closer.create()) {
closer.register(super::close);
if (credentialsProvider instanceof Closeable) {
closer.register((Closeable) credentialsProvider);
if (credentialsProvider.isPresent()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@findepi has a good point about not needing Optional. But a general FYI, you can simplify code like this using ifPresent:

credentialsProvider.ifPresent(provider -> {
    if (provider instanceof Closeable) { ... }
});

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Thanks.

}

throw new RuntimeException("S3 credentials not configured");
return Optional.empty();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This is what the client does internally:

private AWSCredentialsProvider resolveCredentials() {
    return (credentials == null) ? DefaultAWSCredentialsProviderChain.getInstance() : credentials;
}

Not setting credentials results in it being null.

@@ -744,27 +748,27 @@ private AmazonS3 createAmazonS3Client(Configuration hadoopConfig, ClientConfigur
}
}

private AWSCredentialsProvider createAwsCredentialsProvider(URI uri, Configuration conf)
private Optional<AWSCredentialsProvider> createAwsCredentialsProvider(URI uri, Configuration conf)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about access to Glue Metastore?

I think io.prestosql.plugin.hive.s3.PrestoS3FileSystem#createAwsCredentialsProvider should be extracted, properly parametrized and also used in io.prestosql.plugin.hive.metastore.glue.GlueHiveMetastore#createAsyncGlueClient

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will fix it too. I would rather avoid factoring them in because a customer should be able to use different AWS accounts for each of these.

Copy link
Member

@sopel39 sopel39 May 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

customer should be able to use different AWS accounts for each of these.

That should be the case anyway. What I meant is that IAM feature toggles should be similar for both S3 and Glue to avoid confusion

@anoopj
Copy link
Member Author

anoopj commented May 19, 2019

Updated the PR incorporating review feedback.

@@ -764,7 +765,8 @@ private AWSCredentialsProvider createAwsCredentialsProvider(URI uri, Configurati
return getCustomAWSCredentialsProvider(uri, conf, providerClass);
}

throw new RuntimeException("S3 credentials not configured");
// No credentials configured. Fall back to the default credentials provider.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In https://github.com/prestosql/presto/pull/741/files#diff-2902dc1ae71e318999f5a777a0e0176fR155 you didn't find the comment necessary. I think it's not necessary here as well.

Copy link
Member Author

@anoopj anoopj Jun 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove.


return asyncGlueClientBuilder.build();
else {
credentialsProvider = new DefaultAWSCredentialsProviderChain();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably call DefaultAWSCredentialsProviderChain.getInstance()

(then you should rename the method to getAwsCredentialsProvider, the same way it was in s3 code)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

@@ -168,19 +169,28 @@ else if (config.getPinGlueClientToCurrentRegion()) {
}
}

AWSCredentialsProvider credentialsProvider = createAwsCredentialsProvider(config);
asyncGlueClientBuilder.setCredentials(credentialsProvider);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please inline credentialsProvider variable and (optionally) add a blank line before final return

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure


private static AWSCredentialsProvider createAwsCredentialsProvider(GlueHiveMetastoreConfig config)
{
AWSCredentialsProvider credentialsProvider;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for this variable. Just return in each if block. Then, don't use else (will become redundant).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I like reducing the independent paths (cyclomatic complexity), but don't mind making the change.

…Default Credentials Provider

DefaultAWSCredentialsProviderChain is frequently used by AWS customers
and it provides access from a documented list of sources. This
especially makes it easier to run Presto on non-EC2 hosts where you
don't have the instance profile. (e.g. Macs, during development). This
change also makes PrestoS3FileSystem to be consistent with the Glue
connector in Presto.

See:
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/DefaultAWSCredentialsProviderChain.html
@anoopj
Copy link
Member Author

anoopj commented Jun 21, 2019

I think I've incorporated all comments. Let me know if there is more feedback.

@sopel39
Copy link
Member

sopel39 commented Jun 27, 2019

Will merge tomorrow if nobody else has any comments, @electrum @findepi ?

Copy link
Member

@findepi findepi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a follow-up, we could think about deprecating use-instance-credentials.

@sopel39 sopel39 merged commit b8e1c47 into trinodb:master Jun 28, 2019
@sopel39
Copy link
Member

sopel39 commented Jun 28, 2019

@anoopj Could you add a release note to #1000?

@anoopj anoopj mentioned this pull request Jun 29, 2019
6 tasks
@anoopj
Copy link
Member Author

anoopj commented Jun 29, 2019

@sopel39 Done. Not sure if it's in the right format, please feel free to edit.

v-jizhang added a commit to v-jizhang/presto that referenced this pull request Jun 2, 2021
Cherry-pick of trinodb/trino#1363,
trinodb/trino#741 and
trinodb/trino#3689

Add config hive.metastore.glue.aws-credentials-provider for glue
credential provider. where value is fully qualified class name of
custom aws credential provider implementation.

Co-authored-by: Li Yu <[email protected]>
Co-authored-by: Anoop Johnson <[email protected]>
Co-authored-by: Ashhar Hasan <[email protected]>
v-jizhang added a commit to v-jizhang/presto that referenced this pull request Jul 23, 2021
Cherry-pick of trinodb/trino#741

DefaultAWSCredentialsProviderChain is frequently used by AWS customers
and it provides access from a documented list of sources. This
especially makes it easier to run Presto on non-EC2 hosts where you
don't have the instance profile. (e.g. Macs, during development). This
change also makes PrestoS3FileSystem to be consistent with the Glue
connector in Presto.

Co-authored-by: Anoop Johnson <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

PrestoS3ClientFactory should use the AWS Java SDK default credential provider
4 participants